Changeset 4336


Ignore:
Timestamp:
14/10/08 16:21:31 (11 years ago)
Author:
pjkersha
Message:

Fixes for BADC Data Browser integration tests:

  • ndg.security.common.X509.X500DN: fix for DNs where field content contains commas - X509_Name.as_text is not safe for this use X509_Name.str
  • ndg.security.common.m2CryptoSSLUtility: use ndg.security.common.X509.X500DN for accurate comparison of DNs in HostCheck? class peer cert checking.
Location:
TI12-security/trunk/python
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/X509.py

    r4156 r4336  
    539539 
    540540 
    541 #_____________________________________________________________________________ 
    542541def X509StackParseFromDER(derString): 
    543542    """Make a new stack from a DER string 
     
    550549 
    551550 
    552 #_____________________________________________________________________________ 
    553551class X500DNError(Exception): 
    554552    """Exception handling for NDG X.500 DN class.""" 
    555553 
    556554 
    557 #_____________________________________________________________________________ 
    558555# For use with parseSeparator method: 
    559556import re 
     
    566563    # name equivalents 
    567564    # * private * 
    568     __shortNameLUT = {  'commonName':               'CN', 
    569                         'organisationalUnitName':   'OU', 
    570                         'organisation':             'O', 
    571                         'countryName':              'C', 
    572                         'emailAddress':             'EMAILADDRESS', 
    573                         'localityName':             'L', 
    574                         'stateOrProvinceName':      'ST', 
    575                         'streetAddress':            'STREET', 
    576                         'domainComponent':          'DC', 
    577                         'userid':                   'UID'} 
    578  
    579      
    580     def __init__(self, 
    581                  dn=None, 
    582                  m2CryptoX509Name=None, 
    583                  separator=None): 
     565    __shortNameLUT = { 
     566        'commonName':               'CN', 
     567        'organisationalUnitName':   'OU', 
     568        'organisation':             'O', 
     569        'countryName':              'C', 
     570        'emailAddress':             'EMAILADDRESS', 
     571        'localityName':             'L', 
     572        'stateOrProvinceName':      'ST', 
     573        'streetAddress':            'STREET', 
     574        'domainComponent':              'DC', 
     575        'userid':                       'UID' 
     576    } 
     577 
     578     
     579    def __init__(self, dn=None, m2CryptoX509Name=None, separator=None): 
    584580 
    585581        """Create a new X500 Distinguished Name 
    586582 
    587         m2CryptoX509Name:   initialise using using an M2Crypto.X509.X509_Name 
    588         dn:                 initialise using a distinguished name string 
    589         separator:          separator used to delimit dn fields - usually 
    590                             '/' or ','.  If dn is input and separator is 
    591                             omitted the separator character will be 
    592                             automatically parsed from the dn string. 
    593                             """ 
     583        @type m2CryptoX509Name: M2Crypto.X509.X509_Name 
     584        @param m2CryptoX509Name:   initialise using using an  
     585        M2Crypto.X509.X509_Name 
     586        @type dn: basestring 
     587        @param dn: initialise using a distinguished name string 
     588        @type separator: basestring 
     589        @param: separator: separator used to delimit dn fields - usually '/'  
     590        or ','.  If dn is input and separator is omitted the separator  
     591        character will be automatically parsed from the dn string. 
     592        """ 
     593         
    594594        # Private key data 
    595         self.__dat = {  'CN':           '', 
    596                         'OU':           '', 
    597                         'O':            '', 
    598                         'C':            '', 
    599                         'EMAILADDRESS': '', 
    600                         'L':            '', 
    601                         'ST':           '', 
    602                         'STREET':       '', 
    603                         'DC':           '', 
    604                         'UID':          ''} 
     595        self.__dat = {}.fromkeys(X500DN.__shortNameLUT.values(), '') 
    605596     
    606597        dict.__init__(self) 
     
    618609 
    619610            self.__separator = separator 
    620  
    621611             
    622612        if m2CryptoX509Name is not None: 
    623613            # the argument is an x509 dn in m2crypto format 
    624             # 
    625             # Hack required here because M2Crypto doesn't 
    626             # correctly separate emailAddress fields e.g. 
    627             # 
    628             # C=SG, ST=Singapore, O=BMTAP Pte Ltd,  
    629             # OU=Environmental Development,  
    630             # CN=www.bmtap.com.sg/emailAddress=sjamsul.lakau@bmtasia.com.sg 
    631             #                    ^ 
    632             # - The slash is left in place 
    633             # 
    634             # TODO: re-check this for future M2Crypto releases 
    635             dnTxt = ', '.join(m2CryptoX509Name.as_text().split('/'))             
    636             # End hack 
    637              
    638             self.deserialise(dnTxt) 
     614            self.deserialise(str(m2CryptoX509Name)) 
    639615             
    640616        elif dn is not None: 
     
    647623            self.deserialise(dn) 
    648624 
    649  
    650625    def __repr__(self): 
    651626        """Override default behaviour to return internal dictionary content""" 
    652627        return self.serialise() 
    653  
    654628 
    655629    def __str__(self): 
     
    657631        serialised format.""" 
    658632        return self.serialise() 
    659  
    660633         
    661634    def __eq__(self, x500dn): 
     
    666639 
    667640        return self.__dat.items() == x500dn.items() 
    668  
    669          
     641    
    670642    def __ne__(self, x500dn): 
    671643        """Return true if the all the fields of the two DNs are equal""" 
     
    675647 
    676648        return self.__dat.items() != x500dn.items() 
    677  
    678      
     649   
    679650    def __delitem__(self, key): 
    680651        """Prevent keys from being deleted.""" 
    681652        raise X500DNError('Keys cannot be deleted from the X500DN') 
    682  
    683653 
    684654    def __getitem__(self, key): 
     
    699669        else: 
    700670            # key not recognised as a short or long name version 
    701             raise X500DNError('Key "' + key + '" not recognised for X500DN') 
    702  
     671            raise KeyError('Key "' + key + '" not recognised for X500DN') 
    703672 
    704673    def __setitem__(self, key, item): 
     
    719688        else: 
    720689            # key not recognised as a short or long name version 
    721             raise X500DNError('Key "' + key + '" not recognised for X500DN') 
    722  
     690            raise KeyError('Key "' + key + '" not recognised for X500DN') 
    723691 
    724692    def clear(self): 
    725         raise X500DNError("Data cannot be cleared from " + self.__class__.__name__) 
    726  
    727      
     693        raise X500DNError("Data cannot be cleared from X500DN") 
     694 
    728695    def copy(self): 
    729696 
     
    731698        return copy.copy(self) 
    732699 
    733      
    734700    def keys(self): 
    735701        return self.__dat.keys() 
    736702 
    737  
    738703    def items(self): 
    739704        return self.__dat.items() 
    740705 
    741  
    742706    def values(self): 
    743707        return self.__dat.values() 
    744  
    745708 
    746709    def has_key(self, key): 
     
    751714        return key in self.__tags 
    752715 
    753  
    754     def get(self, kw): 
    755         return self.__dat.get(kw) 
    756  
    757      
     716    def get(self, *arg): 
     717        return self.__dat.get(*arg) 
     718   
    758719    def serialise(self, separator=None): 
    759720        """Combine fields in Distinguished Name into a single string.""" 
     
    781742                if isinstance(val, tuple): 
    782743                    dnList += [separator.join(["%s=%s" % (key, valSub) \ 
    783                                             for valSub in val])] 
     744                                               for valSub in val])] 
    784745                else: 
    785746                    dnList += ["%s=%s" % (key, val)] 
     
    837798            for key, val in parsedDN.items(): 
    838799                if key not in self.__dat and key not in self.__shortNameLUT: 
    839                     raise X500DNError, \ 
    840                         "Invalid field \"%s\" in input DN string" % key 
     800                    raise X500DNError('Invalid field "%s" in input DN string' % 
     801                                      key) 
    841802 
    842803                self.__dat[key] = val 
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/m2CryptoSSLUtility.py

    r4145 r4336  
    1818from M2Crypto.httpslib import HTTPSConnection as _HTTPSConnection 
    1919 
    20 from ndg.security.common.X509 import X509Cert, X509Stack 
     20from ndg.security.common.X509 import X509Cert, X509Stack, X500DN 
    2121 
    2222class InvalidCertSignature(SSL.Checker.SSLVerificationError): 
     
    4646        where the hostname is not fully qualified.   
    4747 
    48         *param acceptedDNs: a list of acceptable DNs.  This enables validation where the expected DN is 
    49         where against a limited list of certs. 
     48        *param acceptedDNs: a list of acceptable DNs.  This enables validation  
     49        where the expected DN is where against a limited list of certs. 
    5050         
    5151        @type peerCertCN: string 
     
    8181        """ 
    8282        if peerCert is None: 
    83             raise SSL.Checker.NoCertificate(\ 
    84                                         'SSL Peer did not return certificate') 
     83            raise SSL.Checker.NoCertificate('SSL Peer did not return ' 
     84                                            'certificate') 
    8585 
    8686        peerCertDN = '/'+peerCert.get_subject().as_text().replace(', ', '/') 
     
    9393                raise e 
    9494 
    95         # At least one match should be found in the list 
    96         if self.acceptedDNs and \ 
    97            not len([dn for dn in self.acceptedDNs if peerCertDN==dn]): 
    98             raise InvalidCertDN, \ 
    99             'Peer cert DN "%s" doesn\'t match verification list' % peerCertDN 
     95        # At least one match should be found in the list - first convert to 
     96        # NDG X500DN type to allow per field matching for DN comparison 
     97        peerCertX500DN = X500DN(dn=peerCertDN) 
     98         
     99        if self.acceptedDNs: 
     100           matchFound = False 
     101           for dn in self.acceptedDNs: 
     102               x500dn = X500DN(dn=dn) 
     103               if x500dn == peerCertX500DN: 
     104                   matchFound = True 
     105                   break 
     106                
     107           if not matchFound: 
     108               raise InvalidCertDN('Peer cert DN "%s" doesn\'t match ' 
     109                                   'verification list' % peerCertDN) 
    100110 
    101111        if len(self.__caCertStack) > 0: 
     
    104114                           x509Cert2Verify=X509Cert(m2CryptoX509=peerCert)) 
    105115            except Exception, e: 
    106                 raise InvalidCertSignature( 
    107                 "Peer certificate verification against CA cert failed: %s" % e) 
     116                raise InvalidCertSignature("Peer certificate verification " 
     117                                           "against CA cert failed: %s" % e) 
    108118               
    109119        # They match - drop the exception and return all OK instead           
     
    207217 
    208218        self.sock = SSL.Connection(self.ssl_ctx) 
    209         self.sock.set_post_connection_check_callback( 
    210                                                  self._postConnectionCheck) 
     219        self.sock.set_post_connection_check_callback(self._postConnectionCheck) 
    211220 
    212221        self.sock.set_socket_read_timeout(self.readTimeout) 
  • TI12-security/trunk/python/ndg.security.test/setup.py

    r4143 r4336  
    5151                                  'Makefile', 
    5252                                  'README'], 
    53     'ndg.security.test.sessionCookie': ['test.crt', 
    54                                         'test.key', 
    55                                         'README'], 
    5653    'ndg.security.test.sessionMgr': ['*.xml',  
    5754                                     '*.cfg',  
Note: See TracChangeset for help on using the changeset viewer.