Changeset 4654


Ignore:
Timestamp:
16/12/08 10:45:01 (11 years ago)
Author:
pjkersha
Message:

#884: add capability to X509Cert.isValidTime to warn when X.509 certificates are due to expire within a certain time limit (default 30 days). isValidTime is now called from read and parsing routines. warnings.warn and logging.warning are called so logs from security services will display the messages.

Location:
TI12-security/trunk/python
Files:
15 added
10 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/MyProxyClient/documentation/Makefile

    r4642 r4654  
    2121EPYDOC_FRAMES_OPT=--no-frames 
    2222epydoc: 
    23         ${EPYDOC} ../myproxy.py ../openssl.py -o ${EPYDOC_OUTDIR} \ 
    24         --name ${EPYDOC_NAME} ${EPYDOC_FRAMES_OPT} --include-log --graph=all -v \ 
    25         > ${EPYDOC_LOGFILE} 
     23        ${EPYDOC} ../myproxy -o ${EPYDOC_OUTDIR} --name ${EPYDOC_NAME} \ 
     24        ${EPYDOC_FRAMES_OPT} --include-log --graph=all -v > ${EPYDOC_LOGFILE} 
    2625         
    2726clean: 
  • TI12-security/trunk/python/MyProxyClient/myproxy/utils/openssl.py

    r4647 r4654  
    102102            homeDir = os.environ.get('HOME') 
    103103            if homeDir: 
    104                 self._caDir=os.path.join(os.environ['HOME'],self._gridCASubDir) 
     104                self._caDir = os.path.join(homeDir, self._gridCASubDir) 
    105105            else: 
    106106                self._caDir = None 
  • TI12-security/trunk/python/MyProxyClient/test/README

    r4624 r4654  
    3636 * See the installation guide for MyProxy trouble shooting information. 
    3737 
     38Certificates and private keys are from a test CA and are not for use production 
     39use. 
     40 
    3841P J Kershaw 12/12/08 
  • TI12-security/trunk/python/MyProxyClient/test/test_myproxyclient.py

    r4647 r4654  
    11#!/usr/bin/env python 
    2 """NDG MyProxy client unit tests 
     2"""MyProxy Client unit tests 
    33 
    44NERC Data Grid Project 
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/X509.py

    r4606 r4654  
    1111__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1212__revision__ = '$Id$' 
    13  
     13import logging 
     14log = logging.getLogger(__name__) 
     15from warnings import warn # warn of impendiong certificate expiry 
    1416 
    1517import types 
     
    2729    """Exception handling for NDG X.509 Certificate handling class.""" 
    2830 
     31class X509CertReadError(X509CertError): 
     32    """Error reading in certificate from file""" 
     33     
    2934class X509CertInvalidNotBeforeTime(X509CertError): 
    3035    """Call from X509Cert.isValidTime if certificates not before time is 
     
    5560         
    5661 
    57     def read(self, filePath=None): 
    58         """Read a certificate from file""" 
     62    def read(self, filePath=None, **isValidTimeKw): 
     63        """Read a certificate from PEM encoded file 
     64         
     65        @type filePath: basestring 
     66        @param filePath: file path of PEM format file to be read 
     67         
     68        @type isValidTimeKw: dict 
     69        @param isValidTimeKw: keywords to isValidTime() call""" 
    5970         
    6071        # Check for optional input certificate file path 
    6172        if filePath is not None: 
    6273            if not isinstance(filePath, basestring): 
    63                 raise X509CertError( 
    64                     "Certificate File Path input must be a valid string") 
     74                raise X509CertError("Certificate File Path input must be a " 
     75                                    "valid string") 
    6576             
    6677            self.__filePath = filePath 
     
    6980            self.__m2CryptoX509 = M2Crypto.X509.load_cert(self.__filePath) 
    7081        except Exception, e: 
    71             raise X509CertError("Error loading certificate \"%s\": %s" % \ 
    72                                 (self.__filePath, str(e))) 
     82            raise X509CertReadError("Error loading certificate \"%s\": %s" % 
     83                                    (self.__filePath, e)) 
    7384 
    7485        # Update DN and validity times from M2Crypto X509 object just 
    7586        # created 
    7687        self.__setM2CryptoX509() 
    77  
    78  
    79     def parse(self, certTxt): 
    80         """Read a certificate input as a string""" 
     88         
     89        if 'warningStackLevel'not in isValidTimeKw: 
     90            isValidTimeKw['warningStackLevel'] = 3 
     91             
     92        self.isValidTime(**isValidTimeKw) 
     93 
     94 
     95    def parse(self, certTxt, **isValidTimeKw): 
     96        """Read a certificate input as a string 
     97         
     98        @type certTxt: basestring 
     99        @param certTxt: PEM encoded certificate to parse  
     100         
     101        @type isValidTimeKw: dict 
     102        @param isValidTimeKw: keywords to isValidTime() call""" 
    81103 
    82104        try: 
     
    90112             
    91113        except Exception, e: 
    92             raise X509CertError, "Error loading certificate: %s" % str(e) 
     114            raise X509CertError("Error loading certificate: %s" % e) 
    93115 
    94116        # Update DN and validity times from M2Crypto X509 object just 
    95117        # created 
    96118        self.__setM2CryptoX509() 
     119         
     120         
     121        if 'warningStackLevel'not in isValidTimeKw: 
     122            isValidTimeKw['warningStackLevel'] = 3 
     123                     
     124        self.isValidTime(**isValidTimeKw) 
    97125 
    98126       
     
    103131        if m2CryptoX509 is not None: 
    104132            if not isinstance(m2CryptoX509, M2Crypto.X509.X509): 
    105                 raise TypeError, \ 
    106                     "Incorrect type for input M2Crypto.X509.X509 object" 
     133                raise TypeError("Incorrect type for input M2Crypto.X509.X509 " 
     134                                "object") 
    107135                     
    108136            self.__m2CryptoX509 = m2CryptoX509 
     
    127155                                         
    128156        except Exception, e: 
    129             raise X509CertError, "Not Before time: " + str(e) 
     157            raise X509CertError("Not Before time: %s" % e) 
    130158 
    131159         
     
    135163                                     
    136164        except Exception, e: 
    137             raise X509CertError, "Not After time: " + str(e) 
     165            raise X509CertError("Not After time: %s" % e) 
    138166 
    139167 
     
    259287 
    260288 
    261     def isValidTime(self, raiseExcep=False): 
     289    def isValidTime(self,  
     290                    raiseExcep=False,  
     291                    expiryWarning=True,  
     292                    nDaysBeforeExpiryLimit=30, 
     293                    warningStackLevel=2): 
    262294        """Check Certificate for expiry 
    263295 
    264         raiseExcep: set True to raise an exception if certificate is invalid""" 
     296        @type raiseExcep: bool 
     297        @param raiseExcep: set True to raise an exception if certificate is  
     298        invalid 
     299         
     300        @type expiryWarning: bool 
     301        @param expiryWarning: set to True to output a warning message if the  
     302        certificate is due to expire in less than nDaysBeforeExpiryLimit days.  
     303        Message is sent using warnings.warn and through logging.warning.  No  
     304        message is set if the certificate has an otherwise invalid time 
     305         
     306        @type nDaysBeforeExpiryLimit: int 
     307        @param nDaysBeforeExpiryLimit: used in conjunction with the  
     308        expiryWarning flag.  Set the number of days in advance of certificate 
     309        expiry from which to start outputing warnings 
     310         
     311        @type warningStackLevel: int 
     312        @param warningStackLevel: set where in the stack to flag the warning 
     313        from.  Level 2 will flag it at the level of the caller of this  
     314        method.  Level 3 would flag at the level of the caller of the caller 
     315        and so on. 
     316         
     317        @raise X509CertInvalidNotBeforeTime: current time is before the  
     318        certificate's notBefore time 
     319        @raise X509CertExpired: current time is after the certificate's  
     320        notAfter time""" 
    265321 
    266322        if not isinstance(self.__dtNotBefore, datetime): 
     
    271327        
    272328        dtNow = datetime.utcnow() 
    273  
    274         if raiseExcep: 
    275             if dtNow < self.__dtNotBefore: 
    276                 raise X509CertInvalidNotBeforeTime, \ 
    277                     "Current time is before the certificate's Not Before Time" 
    278              
    279             elif dtNow > self.__dtNotAfter: 
    280                 raise X509CertExpired, \ 
    281                     "Certificate, %s, has expired: the time now is %s  \ 
    282                     and the certificate expiry is %s." \ 
    283                     %(self.__filePath, dtNow, self.__dtNotAfter) 
     329        isValidTime = dtNow > self.__dtNotBefore and dtNow < self.__dtNotAfter 
     330 
     331        # Helper string for message output 
     332        if self.__filePath: 
     333            fileInfo = ' "%s"' % self.__filePath 
    284334        else: 
    285             return dtNow > self.__dtNotBefore and dtNow < self.__dtNotAfter 
     335            fileInfo = '' 
     336              
     337         
     338        # Set a warning message for impending expiry of certificate but only 
     339        # if the certificate is not any other way invalid - see below 
     340        if isValidTime and expiryWarning: 
     341            dtTime2Expiry = self.__dtNotAfter - dtNow 
     342            if dtTime2Expiry.days < nDaysBeforeExpiryLimit: 
     343                msg = ('Certificate%s with DN "%s" will expire in %d days on: ' 
     344                       '%s' % (fileInfo,  
     345                               self.dn,  
     346                               dtTime2Expiry.days,  
     347                               self.__dtNotAfter)) 
     348                warn(msg, stacklevel=warningStackLevel) 
     349                log.warning(msg) 
     350         
     351                      
     352        if dtNow < self.__dtNotBefore: 
     353            msg = ("Current time %s is before the certificate's Not Before " 
     354                   'Time %s for certificate%s with DN "%s"' %  
     355                   (dtNow, self.__dtNotBefore, fileInfo, self.dn)) 
     356            log.error(msg) 
     357            if raiseExcep: 
     358                raise X509CertInvalidNotBeforeTime(msg) 
     359             
     360        elif dtNow > self.__dtNotAfter: 
     361            msg = ('Certificate%s with DN "%s" has expired: the time now is ' 
     362                   '%s and the certificate expiry is %s.' %(fileInfo, 
     363                                                            self.dn,  
     364                                                            dtNow,  
     365                                                            self.__dtNotAfter)) 
     366            if raiseExcep: 
     367                raise X509CertExpired(msg) 
     368 
     369        # If exception flag is not set return validity as bool 
     370        return isValidTime 
    286371 
    287372 
     
    330415 
    331416    @classmethod 
    332     def Read(cls, filePath): 
     417    def Read(cls, filePath, **isValidTimeKw): 
    333418        """Create a new X509 certificate read in from a file""" 
    334419     
    335420        x509Cert = cls(filePath=filePath) 
    336         x509Cert.read() 
     421         
     422        if 'warningStackLevel' not in isValidTimeKw: 
     423            isValidTimeKw['warningStackLevel'] = 4 
     424             
     425        x509Cert.read(**isValidTimeKw) 
    337426         
    338427        return x509Cert 
    339428     
    340429    @classmethod 
    341     def Parse(cls, x509CertTxt): 
     430    def Parse(cls, x509CertTxt, **isValidTimeKw): 
    342431        """Create a new X509 certificate from string of file content""" 
    343432     
    344433        x509Cert = cls() 
    345         x509Cert.parse(x509CertTxt) 
     434         
     435        if 'warningStackLevel' not in isValidTimeKw: 
     436            isValidTimeKw['warningStackLevel'] = 4 
     437             
     438        x509Cert.parse(x509CertTxt, **isValidTimeKw) 
    346439         
    347440        return x509Cert 
    348441         
    349442# Alternative AttCert constructors 
    350 def X509CertRead(filePath): 
     443def X509CertRead(filePath, **isValidTimeKw): 
    351444    """Create a new X509 certificate read in from a file""" 
    352445 
    353446    x509Cert = X509Cert(filePath=filePath) 
    354     x509Cert.read() 
     447     
     448    if 'warningStackLevel' not in isValidTimeKw: 
     449        isValidTimeKw['warningStackLevel'] = 4 
     450         
     451    x509Cert.read(**isValidTimeKw) 
    355452     
    356453    return x509Cert 
    357454 
    358 def X509CertParse(x509CertTxt): 
     455def X509CertParse(x509CertTxt, **isValidTimeKw): 
    359456    """Create a new X509 certificate from string of file content""" 
    360457 
    361458    x509Cert = X509Cert() 
    362     x509Cert.parse(x509CertTxt) 
     459    if 'warningStackLevel' not in isValidTimeKw: 
     460        isValidTimeKw['warningStackLevel'] = 4 
     461             
     462    x509Cert.parse(x509CertTxt, **isValidTimeKw) 
    363463     
    364464    return x509Cert 
     
    430530                                       X509CertParse(x509Cert).m2CryptoX509)             
    431531        else: 
    432             raise X509StackError, "Expecting M2Crypto.X509.X509, " + \ 
    433                 "ndg.security.common.X509.X509Cert or string type" 
     532            raise X509StackError("Expecting M2Crypto.X509.X509, ndg.security." 
     533                                 "common.X509.X509Cert or string type") 
    434534                 
    435535    def pop(self): 
  • TI12-security/trunk/python/ndg.security.common/setup.py

    r4611 r4654  
    6161    description = \ 
    6262'''NERC DataGrid Security virtual package containing common utilities used 
    63 noth by server and client packages''', 
     63by both server and client packages''', 
    6464    long_description =          'Software for securing NDG resources', 
    6565    author =                    'Philip Kershaw', 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/attributeauthority.py

    r4573 r4654  
    183183             
    184184        except Exception, e: 
    185             raise AttributeAuthorityError("Attribute Authority's certificate is " 
    186                                     "invalid: " + str(e)) 
     185            raise AttributeAuthorityError("Attribute Authority's certificate " 
     186                                          "is invalid: %s" % e) 
    187187         
    188188        # Check CA certificate 
     
    267267 
    268268        except OSError, osError: 
    269             raise AttributeAuthorityConfigError('Invalid directory path Attribute ' 
    270                                     'Certificates store "%s": %s' % \ 
    271                                     (self.__prop['attCertDir'],  
    272                                      osError.strerror)) 
     269            raise AttributeAuthorityConfigError('Invalid directory path for ' 
     270                                                'Attribute Certificates store ' 
     271                                                '"%s": %s' %  
     272                                                (self.__prop['attCertDir'],  
     273                                                 osError.strerror)) 
    273274 
    274275         
     
    511512                 
    512513            except Exception, e: 
    513                 log.error("User X.509 certificate is invalid: " + str(e)) 
     514                log.error("User X.509 certificate is invalid: " + e) 
    514515                raise 
    515516 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/attributeauthorityclient/test_attributeauthorityclient.py

    r4573 r4654  
    2727from os.path import expandvars as xpdVars 
    2828from os.path import join as jnPath 
    29 mkPath = lambda file: jnPath(os.environ['NDGSEC_AACLNT_UNITTEST_DIR'], file) 
     29mkPath = lambda file: jnPath(os.environ['NDGSEC_AA_UNITTEST_DIR'], file) 
    3030 
    3131 
     
    5858            pdb.set_trace() 
    5959         
    60         if 'NDGSEC_AACLNT_UNITTEST_DIR' not in os.environ: 
    61             os.environ['NDGSEC_AACLNT_UNITTEST_DIR'] = \ 
     60        if 'NDGSEC_AA_UNITTEST_DIR' not in os.environ: 
     61            os.environ['NDGSEC_AA_UNITTEST_DIR'] = \ 
    6262                os.path.abspath(os.path.dirname(__file__)) 
    6363 
    6464        self.cfgParser = CaseSensitiveConfigParser() 
    65         cfgFilePath = jnPath(os.environ['NDGSEC_AACLNT_UNITTEST_DIR'], 
     65        cfgFilePath = jnPath(os.environ['NDGSEC_AA_UNITTEST_DIR'], 
    6666                                'attAuthorityClientTest.cfg') 
    6767        self.cfgParser.read(cfgFilePath) 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/combinedservices/siteAAttributeAuthority/siteA-aa.crt

    r4464 r4654  
    22    Data: 
    33        Version: 3 (0x2) 
    4         Serial Number: 54 (0x36) 
     4        Serial Number: 253 (0xfd) 
    55        Signature Algorithm: md5WithRSAEncryption 
    66        Issuer: O=NDG, OU=BADC, CN=Test CA 
    77        Validity 
    8             Not Before: Dec 12 13:52:16 2007 GMT 
    9             Not After : Dec 11 13:52:16 2008 GMT 
     8            Not Before: Dec 15 16:35:24 2008 GMT 
     9            Not After : Dec 14 16:35:24 2013 GMT 
    1010        Subject: O=NDG Security Test, OU=Site A, CN=AttributeAuthority 
    1111        Subject Public Key Info: 
     
    2424                Exponent: 65537 (0x10001) 
    2525        X509v3 extensions: 
    26             Netscape Cert Type: 
     26            Netscape Cert Type:  
    2727                SSL Client, SSL Server, S/MIME, Object Signing 
    2828    Signature Algorithm: md5WithRSAEncryption 
    29         9e:3d:25:d5:5c:13:b8:ea:8f:f5:8a:79:fc:3d:ab:5f:51:3b: 
    30         48:78:eb:a5:3e:34:3f:48:ee:8c:ad:4a:4e:b6:1d:f7:c1:0b: 
    31         21:de:46:ea:d4:76:0e:03:95:da:47:ec:4a:f4:10:b8:74:5d: 
    32         2c:7d:4b:19:a8:c0:a8:c4:ac:81:5e:3a:a4:64:e3:c9:2b:d6: 
    33         03:77:cc:bb:6a:99:85:90:fe:f8:da:2f:29:37:ab:ac:a7:b3: 
    34         5f:99:2a:52:54:3d:a7:cd:1b:a7:2f:28:e3:e0:91:51:a4:37: 
    35         51:d9:32:ac:3d:cc:17:73:e6:be:f3:4c:d9:77:8e:f1:25:85: 
    36         ed:7c 
     29        58:3d:38:b1:c0:41:f7:59:16:4f:ca:97:29:9c:8d:d8:46:79: 
     30        9c:11:6a:b3:a4:44:5e:d2:3e:75:d3:9a:66:de:d5:b6:26:87: 
     31        60:c5:c0:99:c4:56:fe:40:b0:f1:88:12:f9:49:65:fa:66:69: 
     32        03:0a:56:51:4f:64:47:f0:39:75:b8:88:0c:34:5b:c6:5c:f8: 
     33        04:90:9e:32:09:0e:fc:ec:54:df:5c:e6:be:aa:9a:db:75:32: 
     34        19:73:e1:b5:a4:ee:a3:c0:c6:da:e4:ab:e5:70:e4:e8:69:c9: 
     35        e6:c6:f4:58:1d:d4:82:c4:61:ed:5e:2b:c9:69:12:b4:89:82: 
     36        48:66 
    3737-----BEGIN CERTIFICATE----- 
    38 MIICBDCCAW2gAwIBAgIBNjANBgkqhkiG9w0BAQQFADAvMQwwCgYDVQQKEwNOREcx 
    39 DTALBgNVBAsTBEJBREMxEDAOBgNVBAMTB1Rlc3QgQ0EwHhcNMDcxMjEyMTM1MjE2 
    40 WhcNMDgxMjExMTM1MjE2WjBKMRowGAYDVQQKExFOREcgU2VjdXJpdHkgVGVzdDEP 
    41 MA0GA1UECxMGU2l0ZSBBMRswGQYDVQQDExJBdHRyaWJ1dGVBdXRob3JpdHkwgZ8w 
    42 DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKe1/6FTEUpfH8pjctfL9Fhz/KqF8gsz 
    43 yH3lzXif9Z1KqHysrdXGRS7mC6OUSAIdp8jYCM1klmol8obtm5xiZFyddsJfWo8g 
    44 Ypr5OWVshZ2xrnL8gX8OjYCg8wmdM0nZTUgF89Bds7lJ3j0699OLgKV2Tz3zvZEi 
    45 7M+YsgNwXJ2BAgMBAAGjFTATMBEGCWCGSAGG+EIBAQQEAwIE8DANBgkqhkiG9w0B 
    46 AQQFAAOBgQCePSXVXBO46o/1inn8PatfUTtIeOulPjQ/SO6MrUpOth33wQsh3kbq 
    47 1HYOA5XaR+xK9BC4dF0sfUsZqMCoxKyBXjqkZOPJK9YDd8y7apmFkP742i8pN6us 
    48 p7NfmSpSVD2nzRunLyjj4JFRpDdR2TKsPcwXc+a+80zZd47xJYXtfA== 
     38MIICBTCCAW6gAwIBAgICAP0wDQYJKoZIhvcNAQEEBQAwLzEMMAoGA1UEChMDTkRH 
     39MQ0wCwYDVQQLEwRCQURDMRAwDgYDVQQDEwdUZXN0IENBMB4XDTA4MTIxNTE2MzUy 
     40NFoXDTEzMTIxNDE2MzUyNFowSjEaMBgGA1UEChMRTkRHIFNlY3VyaXR5IFRlc3Qx 
     41DzANBgNVBAsTBlNpdGUgQTEbMBkGA1UEAxMSQXR0cmlidXRlQXV0aG9yaXR5MIGf 
     42MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCntf+hUxFKXx/KY3LXy/RYc/yqhfIL 
     43M8h95c14n/WdSqh8rK3VxkUu5gujlEgCHafI2AjNZJZqJfKG7ZucYmRcnXbCX1qP 
     44IGKa+TllbIWdsa5y/IF/Do2AoPMJnTNJ2U1IBfPQXbO5Sd49OvfTi4Cldk89872R 
     45IuzPmLIDcFydgQIDAQABoxUwEzARBglghkgBhvhCAQEEBAMCBPAwDQYJKoZIhvcN 
     46AQEEBQADgYEAWD04scBB91kWT8qXKZyN2EZ5nBFqs6REXtI+ddOaZt7VtiaHYMXA 
     47mcRW/kCw8YgS+Ull+mZpAwpWUU9kR/A5dbiIDDRbxlz4BJCeMgkO/OxU31zmvqqa 
     4823UyGXPhtaTuo8DG2uSr5XDk6GnJ5sb0WB3UgsRh7V4ryWkStImCSGY= 
    4949-----END CERTIFICATE----- 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/x509/test_x509.py

    r4404 r4654  
    1212__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1313__revision__ = '$Id:test_x509.py 4335 2008-10-14 12:44:22Z pjkersha $' 
     14import logging 
     15logging.basicConfig(level=logging.DEBUG) 
     16log = logging.getLogger(__name__) 
    1417 
    1518import unittest 
     
    1720import sys 
    1821import getpass 
    19 import traceback 
     22from StringIO import StringIO 
    2023 
    2124from ConfigParser import SafeConfigParser 
    2225from ndg.security.common.X509 import X509CertRead, X509CertParse, X500DN, \ 
    23     X509Stack, X509StackError, SelfSignedCert, CertIssuerNotFound 
     26    X509Stack, X509StackEmptyError, SelfSignedCert, X509CertIssuerNotFound 
    2427 
    2528from os.path import expandvars as xpdVars 
     
    5154    def test1X509CertRead(self): 
    5255        'test1X509CertRead: read in a cert from file' 
    53         print self.test1X509CertRead.__doc__ 
     56        print(self.test1X509CertRead.__doc__) 
    5457        self.x509Cert = \ 
    5558            X509CertRead(xpdVars(self.cfg['test1X509CertRead']['certfile'])) 
    56         assert(self.x509Cert) 
     59        self.assert_(self.x509Cert) 
    5760 
    5861    def test2X509CertAsPEM(self): 
    5962        'test2X509CertAsPEM: display as a PEM format string' 
    6063        self.test1X509CertRead() 
    61         print self.test2X509CertAsPEM.__doc__ 
     64        print(self.test2X509CertAsPEM.__doc__) 
    6265        self.pemString = self.x509Cert.asPEM() 
    63         print self.pemString 
     66        print(self.pemString) 
    6467 
    6568 
     
    6770        'test3X509CertParse: parse from a PEM format string' 
    6871        self.test2X509CertAsPEM() 
    69         print self.test3X509CertParse.__doc__ 
    70         assert(X509CertParse(self.pemString)) 
     72        print(self.test3X509CertParse.__doc__) 
     73        self.assert_(X509CertParse(self.pemString)) 
    7174 
    7275 
     
    7477        'test4GetDN: extract distinguished name' 
    7578        self.test1X509CertRead() 
    76         print self.test4GetDN.__doc__ 
     79        print(self.test4GetDN.__doc__) 
    7780        self.dn = self.x509Cert.dn 
    78         print self.dn 
     81        print(self.dn) 
    7982         
    8083    def test5DN(self): 
    8184        'test5DN: test X.500 Distinguished Name attributes' 
    82         print self.test5DN.__doc__ 
     85        print(self.test5DN.__doc__) 
    8386        self.test4GetDN() 
    8487        for item in self.dn.items(): 
    85             print "%s=%s" % item 
     88            print("%s=%s" % item) 
    8689         
    8790    def test6DNCmp(self): 
    8891        '''test6DNCmp: test X.500 Distinguished Name comparison 
    8992        operators''' 
    90         print self.test6DNCmp.__doc__ 
     93        print(self.test6DNCmp.__doc__) 
    9194        self.test4GetDN() 
    9295        testDN = X500DN(dn="/O=a/OU=b/CN=c") 
    9396 
    94         assert(not(testDN == self.dn)) 
    95         assert(testDN != self.dn) 
    96         assert(self.dn == self.dn) 
    97         assert(not(self.dn != self.dn)) 
     97        self.assert_(not(testDN == self.dn)) 
     98        self.assert_(testDN != self.dn) 
     99        self.assert_(self.dn == self.dn) 
     100        self.assert_(not(self.dn != self.dn)) 
    98101             
    99102    def test7X509Stack(self): 
    100103        '''test7X509Stack: test X509Stack functionality''' 
    101         print self.test7X509Stack.__doc__ 
     104        print(self.test7X509Stack.__doc__) 
    102105        self.test1X509CertRead() 
    103106        stack = X509Stack() 
    104         assert(len(stack)==0) 
    105         assert(stack.push(self.x509Cert)) 
    106         assert(len(stack)==1) 
    107         print "stack[0] = %s" % stack[0] 
     107        self.assert_(len(stack)==0) 
     108        self.assert_(stack.push(self.x509Cert)) 
     109        self.assert_(len(stack)==1) 
     110        print("stack[0] = %s" % stack[0]) 
    108111        for i in stack: 
    109             print "stack iterator i = %s" % i 
    110         print "stack.pop() = %s" % stack.pop() 
    111         assert(len(stack)==0) 
     112            print("stack iterator i = %s" % i) 
     113        print("stack.pop() = %s" % stack.pop()) 
     114        self.assert_(len(stack)==0) 
    112115             
    113116    def test8X509StackVerifyCertChain(self): 
    114117        '''test8X509StackVerifyCertChain: testVerifyCertChain method''' 
    115         print self.test8X509StackVerifyCertChain.__doc__ 
     118        print(self.test8X509StackVerifyCertChain.__doc__) 
    116119        self.test1X509CertRead() 
    117         proxyCert=X509CertRead(xpdVars(\ 
     120        proxyCert=X509CertRead(xpdVars( 
    118121                   self.cfg['test8X509StackVerifyCertChain']['proxycertfile'])) 
    119122 
     
    126129        caStack.push(caCert) 
    127130         
    128         print "Verification of external cert with external CA stack..." 
     131        print("Verification of external cert with external CA stack...") 
    129132        stack1.verifyCertChain(x509Cert2Verify=proxyCert,  
    130133                               caX509Stack=caStack) 
    131134         
    132         print "Verification of stack content using CA stack..." 
     135        print("Verification of stack content using CA stack...") 
    133136        stack1.push(proxyCert) 
    134137        stack1.verifyCertChain(caX509Stack=caStack) 
    135138         
    136         print "Verification of stack alone..." 
     139        print("Verification of stack alone...") 
    137140        stack1.push(caCert) 
    138141        stack1.verifyCertChain() 
    139142         
    140         print "Reject self-signed cert. ..." 
     143        print("Reject self-signed cert. ...") 
    141144        stack2 = X509Stack() 
    142145        try: 
    143146            stack2.verifyCertChain() 
    144             raise Exception, "Empty stack error expected" 
    145         except X509StackError: 
     147            self.fail("Empty stack error expected") 
     148        except X509StackEmptyError: 
    146149            pass 
    147150 
     
    149152        try: 
    150153            stack2.verifyCertChain() 
    151             raise Exception, "Reject of self-signed cert. expected" 
     154            self.fail("Reject of self-signed cert. expected") 
    152155        except SelfSignedCert: 
    153156            pass 
    154157         
    155         print "Accept self-signed cert. ..." 
     158        print("Accept self-signed cert. ...") 
    156159        stack2.verifyCertChain(rejectSelfSignedCert=False) 
    157160         
    158         assert(stack2.pop()) 
    159         print "Test no cert. issuer found ..." 
     161        self.assert_(stack2.pop()) 
     162        print("Test no cert. issuer found ...") 
    160163        stack2.push(proxyCert) 
    161164        try: 
    162165            stack2.verifyCertChain() 
    163             raise Exception, "No cert. issuer error expected" 
    164         except CertIssuerNotFound: 
     166            self.fail("No cert. issuer error expected") 
     167        except X509CertIssuerNotFound: 
    165168            pass 
    166169         
    167         print "Test no cert. issuer found again with incomplete chain ..." 
     170        print("Test no cert. issuer found again with incomplete chain ...") 
    168171        stack2.push(self.x509Cert) 
    169172        try: 
    170173            stack2.verifyCertChain() 
    171             raise Exception, "No cert. issuer error expected" 
    172         except CertIssuerNotFound: 
     174            self.fail("No cert. issuer error expected") 
     175        except X509CertIssuerNotFound: 
    173176            pass 
     177 
     178    def test9ExpiryTime(self): 
     179        self.test1X509CertRead() 
    174180         
    175  
    176 class X509TestSuite(unittest.TestSuite): 
    177     def __init__(self): 
    178         map = map(X509TestCase, 
    179                   ( 
    180                     "test1X509CertRead", 
    181                     "test2X509CertAsPEM", 
    182                     "test3X509CertParse", 
    183                     "test4GetDN", 
    184                     "test5DN", 
    185                     "test6DNCmp", 
    186                     "test7X509Stack", 
    187                     "test8X509StackVerifyCertChain" 
    188                   )) 
    189         unittest.TestSuite.__init__(self, map) 
    190   
     181        # Set ridiculous bounds for expiry warning to ensure a warning message 
     182        # is output 
     183        try: 
     184            saveStderr = sys.stderr 
     185            sys.stderr = StringIO() 
     186            self.assert_(self.x509Cert.isValidTime( 
     187                                                nDaysBeforeExpiryLimit=36500),  
     188                                                "Certificate has expired") 
     189            msg = sys.stderr.getvalue() 
     190            if not msg: 
     191                self.fail("No warning message was set") 
     192            else: 
     193                print("PASSED - Got warning message from X509Cert." 
     194                      "isValidTime: %s" % msg) 
     195        finally: 
     196            sys.stderr = saveStderr 
    191197                                        
    192198if __name__ == "__main__": 
Note: See TracChangeset for help on using the changeset viewer.