Changeset 410


Ignore:
Timestamp:
09/05/05 18:01:22 (15 years ago)
Author:
pjkersha
Message:

AttrAuthority?: removed CredentialsRepository? class and Changed credReposDir
references to attrCertDir.

AttrCert? + xmlSigDoc: imporved error handling and added wrappers to
xmlSigDoc method calls from AttrCert? so that AttrCertError? type
exceptions are raised on error.

X509: new X500DN method parseSeparator attempts to find the separator
character from a DN string.

Location:
security/trunk/python
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • security/trunk/python/NDG.BAK/AttAuthority.py

    r408 r410  
    1717 
    1818 
     19# Create unique names for attribute certificates 
     20import tempfile 
     21import os 
     22 
     23 
    1924# For parsing of Map Configuration file 
    2025import cElementTree as ElementTree 
    2126 
    2227# X509 Certificate handling 
    23 from X509 import X509Cert 
    24 from X509 import X500DN 
    25  
    26 # Attribute Certificate 
    27 from AttrCert import AttrCert 
    28 from AttrCert import AttrCertError 
     28from X509 import * 
     29 
     30# NDG Attribute Certificate 
     31from AttrCert import * 
     32 
     33 
     34 
     35 
     36class AttrAuthorityError(Exception): 
     37 
     38    """Exception handling for NDG Attribute Authority class.""" 
     39     
     40    def __init__(self, msg): 
     41        self.__msg = msg 
     42          
     43    def __str__(self): 
     44        return self.__msg 
     45 
     46 
    2947 
    3048 
     
    4058    # implementation of NDG Security 
    4159     
     60 
     61    # Class variables - string constants for set-up of Attribute Certificate 
     62    # file names 
     63    __attrCertFilePfx = "attrCert-" 
     64    __attrCertFileSfx = ".xml" 
     65 
    4266     
    4367    def __init__(self, propertiesFilePath): 
     
    77101        self.__usrRoleSrvr = None 
    78102        self.__usrRolePort = -1 
    79          
    80          
    81         # Initialize Credentials Repository - used to store attribute 
    82         # certificates 
    83         # 
    84         # Temporarily use current directory to store attribute Certificates 
    85         # 
    86         # P J Kershaw 27/04/05 
    87         self.__credRepos=CredentialsRepository(self.__credReposDir) 
    88103 
    89104 
     
    124139        # Nb. new attribute certificate file path is created from the 
    125140        # Credentials Repository 
    126         attrCert = AttrCert(self.__credRepos.newAttrCertFilePath(), 
     141        attrCert = AttrCert(self.__newAttrCertFilePath(), 
    127142                            signingKeyFilePath=self.__keyFilePath, 
    128143                            signingCertFilePath=self.__certFilePath, 
     
    168183            # trusted data centre 
    169184            if extAttrCertFilePath is None: 
    170                 raise "User \"%s\" is not registered " % attrCert['holder'] +\ 
    171                       "and no external attribute certificate is available " +\ 
    172                       " to make a mapping" 
     185                raise AttrAuthorityError(\ 
     186                    "User \"%s\" is not registered " % attrCert['holder'] + \ 
     187                    "and no external attribute certificate is available " + \ 
     188                    " to make a mapping") 
    173189 
    174190            # Read externally provided certificate (i.e. from a trusted data 
    175191            # centre) 
    176             extAttrCert = AttrCert(extAttrCertFilePath, 
     192            try: 
     193                extAttrCert = AttrCert(extAttrCertFilePath, 
    177194                                   trustedCertFilePath=self.__caCertFilePath) 
    178             extAttrCert.read() 
     195                extAttrCert.read() 
     196                 
     197            except AttrCertError, attrCertErr: 
     198                raise AttrAuthorityError(\ 
     199                "External Attribute Certificate error: " + str(attrCertErr)) 
    179200 
    180201 
     
    182203            # be used to make further mappings 
    183204            if extAttrCert.isMapped(): 
    184                 raise "External Attribute Certificate must have an " + \ 
    185                       "original provenance in order to make further mappings." 
     205                raise AttrAuthorityError(\ 
     206                    "External Attribute Certificate must have an " + \ 
     207                    "original provenance in order to make further mappings.") 
    186208 
    187209 
     
    191213                 
    192214            except AttrCertError, excep: 
    193                 raise "Invalid Remote Attribute Certificate \"%s\": %s" % \ 
    194                     (extAttrCertFilePath, excep)          
     215                raise AttrAuthorityError(\ 
     216                    "Invalid Remote Attribute Certificate \"%s\": %s" % \ 
     217                    (extAttrCertFilePath, excep))         
    195218 
    196219 
     
    198221            # TODO: 
    199222            # P J Kershaw 29/04/05 
    200             pdb.set_trace() 
    201             holderDN = X500DN(dn=extAttrCert['holder']) 
     223            try: 
     224                holderDN = X500DN(dn=extAttrCert['holder']) 
     225                 
     226            except X500DNError, x500dnErr: 
     227                raise AttrAuthorityError(\ 
     228                    "Error creating X500DN for holder: %s" % str(x500dnErr)) 
     229             
    202230            if holderDN != usrDN: 
    203                 raise "User certificate and Attribute Certificate DNs " + \ 
    204                       "don't match: " + usrDN + " and " + holderDN 
     231                raise AttrAuthorityError(\ 
     232                    "User certificate and Attribute Certificate DNs " + \ 
     233                    "don't match: " + str(usrDN) + " and " + str(holderDN)) 
    205234             
    206235   
     
    217246            localRoles = self.mapRoles(extAttrCert['issuerName'], extRoles) 
    218247            if not localRoles: 
    219                 raise "No local roles mapped to the %s roles: %s" % \ 
    220                       (extAttrCert['issuerName'], str(extRoles)) 
     248                raise AttrAuthorityError(\ 
     249                    "No local roles mapped to the %s roles: %s" % \ 
     250                    (extAttrCert['issuerName'], str(extRoles))) 
    221251 
    222252            attrCert.addRoles(localRoles) 
     
    233263 
    234264        # Check the certificate is valid 
    235         if not attrCert.isValid(): 
    236             raise "New attribute certificate is invalid: \"%s\"" % \ 
    237                   attrCertFilePath 
     265        try: 
     266            attrCert.isValid(raiseExcep=True) 
     267                 
     268        except AttrCertError, excep: 
     269            raise AttrAuthorityError("New Attribute Certificate \"%s\": %s" %\ 
     270                    (extAttrCertFilePath, excep)) 
    238271 
    239272         
     
    253286        if propertiesFilePath is not None: 
    254287            if not isinstance(propertiesFilePath, basestring): 
    255                 raise "Input Properties file path " + \ 
    256                       "must be a valid string." 
     288                raise AttrAuthorityError("Input Properties file path " + \ 
     289                      "must be a valid string.") 
    257290             
    258291            self.__propertiesFilePath = propertiesFilePath 
     
    273306        self.__attrCertLifeTime = float(properties['attrCertLifeTime']) 
    274307        self.__mapConfigFilePath = properties['mapConfigFile'] 
    275         self.__credReposDir = properties['credReposDir'] 
    276  
    277          
     308        self.__attrCertDir = properties['attrCertDir'] 
     309 
     310        # Check directory path 
     311        try: 
     312            dirList = os.listdir(self.__attrCertDir) 
     313 
     314        except OSError, osError: 
     315            raise AttrAuthorityError(\ 
     316                "Invalid directory path Attribute Certificates store: " + \ 
     317                osError.strerror) 
     318 
     319        
    278320         
    279321         
     
    288330        if mapConfigFilePath is not None: 
    289331            if not isinstance(mapConfigFilePath, basestring): 
    290                 raise "Input Map Configuration file path " + \ 
    291                       "must be a valid string." 
     332                raise AttrAuthorityError(\ 
     333                    "Input Map Configuration file path " + \ 
     334                    "must be a valid string.") 
    292335             
    293336            self.__mapConfigFilePath = mapConfigFilePath 
     
    313356            roleElem = elem.findall('role') 
    314357            if not roleElem: 
    315                 raise "\"role\" tag not found in \"%s\"" % \ 
    316                         self.__mapConfigFilePath 
     358                raise AttrAuthorityError(\ 
     359                    "\"role\" tag not found in \"%s\"" % \ 
     360                    self.__mapConfigFilePath) 
    317361 
    318362            try: 
    319363                trustedHost = elem.attrib.values()[0] 
    320364            except: 
    321                 raise "Error setting trusted host name" 
     365                raise AttrAuthorityError("Error setting trusted host name") 
    322366             
    323367            # Add signatureFile and list of roles 
     
    364408 
    365409 
     410 
    366411    def getRoles(self, usrDN): 
    367412 
     
    389434 
    390435        if not self.__role2Host: 
    391             raise "Roles to host look-up is not set - " + \ 
    392                   "ensure readMapConfig() has been called." 
     436            raise AttrAuthorityError("Roles to host look-up is not set - " + \ 
     437                  "ensure readMapConfig() has been called.") 
    393438        
    394439        if not self.__role2Host.has_key(role): 
     
    408453 
    409454        if not self.__roleMap: 
    410             raise "Roles map is not set - ensure readMapConfig() " + \ 
    411                   "has been called." 
     455            raise AttrAuthorityError(\ 
     456                "Roles map is not set - ensure readMapConfig() " + \ 
     457                "has been called.") 
    412458 
    413459        # Check the host name is a trusted one recorded in the map 
     
    430476 
    431477 
    432 # Create unique names for attribute certificates 
    433 import tempfile 
    434 import os 
    435  
    436 class CredentialsRepository: 
    437  
    438     """Store user credentials (Attribute Certificates) for Attribute 
    439     Authority""" 
    440  
    441     # Class variables - string constants for set-up of Attribute Certificate 
    442     # file names 
    443     __attrCertFilePfx = "attrCert-" 
    444     __attrCertFileSfx = ".xml" 
    445  
    446      
    447     def __init__(self, dirPath): 
    448  
    449         # Check directory path for repository 
    450         try: 
    451             dirList = os.listdir(dirPath) 
    452  
    453         except OSError, osError: 
    454             raise "Invalid input directory path", osError.strerror 
    455          
    456         self.dirPath = dirPath 
    457  
    458  
    459     def newAttrCertFilePath(self): 
     478    def __newAttrCertFilePath(self): 
    460479 
    461480        """Create a new unique attribute certificate file path""" 
    462481         
    463         attrCertFile = tempfile.mkstemp( 
    464                         suffix=CredentialsRepository.__attrCertFileSfx, 
    465                         prefix=CredentialsRepository.__attrCertFilePfx, 
    466                         dir=self.dirPath, 
    467                         text=True) 
     482        attrCertFilePath = tempfile.mkstemp( 
     483                                    suffix=AttrAuthority.__attrCertFileSfx, 
     484                                    prefix=AttrAuthority.__attrCertFilePfx, 
     485                                    dir=self.__attrCertDir, 
     486                                    text=True) 
    468487 
    469488        # The file is opened - close using the file descriptor returned in the 
    470489        # first element of the tuple 
    471         os.close(attrCertFile[0]) 
     490        os.close(attrCertFilePath[0]) 
    472491 
    473492        # The file path is the 2nd element 
    474         return attrCertFile[1] 
     493        return attrCertFilePath[1] 
     494 
  • security/trunk/python/NDG.BAK/AttCert.py

    r407 r410  
    2121 
    2222# XML signature module based on xmlsec and libxml2 
    23 from xmlSigDoc import xmlSigDoc 
     23from xmlSigDoc import * 
    2424 
    2525# XML Parsing 
     
    3131 
    3232from X509 import X500DN 
     33from X509 import X500DNError 
     34 
    3335 
    3436class AttrCertError(Exception): 
    3537     
    36      def __init__(self, value): 
    37          self.value = value 
     38    """Exception handling for NDG Attribute Certificate class.""" 
     39     
     40    def __init__(self, msg): 
     41        self.__msg = msg 
    3842          
    39      def __str__(self): 
    40         return repr(self.value) 
     43    def __str__(self): 
     44        return self.__msg 
    4145     
    4246 
     
    5458 
    5559    # Nb. pass xmlSigDoc keyword arguments in xmlSigDocArgs dictionary 
    56     def __init__(self, 
    57                  filePath=None, 
    58 # Allow setting of these at initialisation?? 
    59 # 
    60 # P J Kershaw 26/04/05 
    61 ##                 holder=None, 
    62 ##                 issuer=None, 
    63                  lifeTime=-1, 
    64                  **xmlSigDocArgs): 
     60    def __init__(self, filePath=None, lifeTime=-1, **xmlSigDocArgs): 
    6561 
    6662        """Initialisation - Attribute Certificate file path may be specified. 
     
    9793        self.__holderDN = None 
    9894 
    99 # Allow setting of these at initialisation?? 
    100 # 
    101 # P J Kershaw 26/04/05 
    102 ##        if holder is not None: 
    103 ## 
    104 ##            if not isinstance(holder, basestring): 
    105 ##                raise "Input holder is %s" % type(holder) + \ 
    106 ##                      ": string type expected" 
    107 ##             
    108 ##            self.__dat['holder'] = holder 
    109 ## 
    110 ## 
    111 ##        if issuer is not None: 
    112 ## 
    113 ##            if not isinstance(issuer, basestring): 
    114 ##                raise "Input issuer is %s" % type(issuer) + \ 
    115 ##                      ": string type expected" 
    116 ## 
    117 ##            self.__dat['issuer'] = issuer 
    118  
    11995 
    12096        # Check for input certificate life time interval - if not set default 
     
    140116        "Attribute Certificate keys cannot be removed" 
    141117         
    142         raise 'Keys cannot be deleted from ' + AttrCert.__name__ 
     118        raise AttrCertError('Keys cannot be deleted from '+AttrCert.__name__) 
    143119 
    144120 
     
    172148        else: 
    173149            # key not recognised as a short or long name version 
    174             raise 'Key "' + key + '" not recognised for ' + AttrCert.__name__ 
     150            raise AttrCertError('Key "' + key + '" not recognised for ' + \ 
     151                                AttrCert.__name__) 
    175152 
    176153 
     
    189166            # key recognised - check if setting provenance 
    190167            if key is "provenance" and not self.isValidProvenance(item): 
    191                 raise "Provenance must be set to \"" + \ 
    192                     "\" or \"".join(AttrCert.__provenance) + "\"" 
     168                raise AttrCertError("Provenance must be set to \"" + \ 
     169                    "\" or \"".join(AttrCert.__provenance) + "\"") 
    193170             
    194171            self.__dat[key] = item 
     
    204181            # Prevent setting of notBefore/notAfter - restrict to method 
    205182            # setValidityTime 
    206             raise "Use setValidityTime method to set notBefore/notAfter times" 
     183            raise AttrCertError(\ 
     184                "Use setValidityTime method to set notBefore/notAfter times") 
    207185             
    208186        else: 
    209187            # key not recognised as a short or long name version 
    210             raise 'Key "' + key + '" not recognised for ' + AttrCert.__name__ 
     188            raise AttrCertError('Key "' + key + '" not recognised for ' + \ 
     189                                AttrCert.__name__) 
    211190         
    212191 
    213192    def clear(self): 
    214         raise "Data cannot be cleared from " + X500DN.__name__ 
     193        raise AttrCertError("Data cannot be cleared from " + X500DN.__name__) 
    215194 
    216195     
     
    326305 
    327306        if not self.isValidProvenance(provenance): 
    328             raise "Provenance must be set to \"" + \ 
    329                 "\" or \"".join(AttrCert.__provenance) + "\"" 
     307            raise AttrCertError("Provenance must be set to \"" + \ 
     308                "\" or \"".join(AttrCert.__provenance) + "\"") 
    330309         
    331310        self.__dat['provenance'] = provenance 
     
    377356        if filePath: 
    378357            if not isinstance(filePath, basestring): 
    379                 raise "Input file path must be a string." 
     358                raise AttrCertError("Input file path must be a string.") 
    380359        else: 
    381360            filePath = self.getFilePath() 
     
    390369         
    391370        if not acInfoElem: 
    392             raise "<acInfo> tag not found in \"" + filePath + "\"" 
     371            raise AttrCertError("<acInfo> tag not found in \""+filePath+"\"") 
    393372 
    394373 
     
    397376         
    398377            if not self.__dat.has_key(elem.tag): 
    399                 raise self.getFilePath() + "\": <" + elem.tag + \ 
    400                       "> not recognised." 
     378                raise AttrCertError(self.getFilePath() + "\": <" + \ 
     379                                    elem.tag + "> not recognised.") 
    401380 
    402381            # Make sure not to copy validity and attributes tags - handle these 
     
    406385 
    407386        # Convert issuer and holder into X500DN instances 
    408         self.__issuerDN = X500DN(dn=self.__dat['issuer']) 
    409         self.__holderDN = X500DN(dn=self.__dat['holder']) 
     387        try: 
     388            self.__issuerDN = X500DN(dn=self.__dat['issuer']) 
     389 
     390        except X500DNError, x500dnErr: 
     391            raise AttrCertError("Issuer DN: %s" % str(x500dnErr)) 
     392 
     393 
     394        try: 
     395            self.__holderDN = X500DN(dn=self.__dat['holder']) 
     396 
     397        except X500DNError, x500dnErr: 
     398            raise AttrCertError("Holder DN: %s" % str(x500dnErr)) 
    410399         
    411400                                  
     
    415404         
    416405        if self.__dat['validity']['notBefore'] is None: 
    417             raise "<notBefore> tag not found in \"%s\"" % filePath 
     406            raise AttrCertError("<notBefore> tag not found in \"%s\"" % \ 
     407                                filePath) 
    418408 
    419409        # Update datetime object equivalent 
     
    426416         
    427417        if self.__dat['validity']['notAfter'] is None: 
    428             raise "<notAfter> tag not found in \"%s\"" % filePath 
     418            raise AttrCertError("<notAfter> tag not found in \"%s\"" % \ 
     419                                filePath) 
    429420 
    430421 
     
    437428        roleElem = acInfoElem.findall("attributes/roleSet/role/name") 
    438429        if roleElem is None: 
    439             raise "<role> tag not found in \"" + filePath + "\"" 
     430            raise AttrCertError("<role> tag not found in \"" + filePath + \ 
     431                                "\"") 
    440432         
    441433        self.__dat['attributes']['roleSet'] = \ 
     
    444436         
    445437        if not self.isValidVersion():            
    446             raise 'Attribute Certificate version is ' + \ 
     438            raise AttrCertError('Attribute Certificate version is ' + \ 
    447439                  self.__dat['version'] + ' but version ' + \ 
    448                   AttrCert.__version + ' expected' 
     440                  AttrCert.__version + ' expected') 
    449441 
    450442 
    451443        # Call base class read method to initialise libxml2 objects for 
    452444        # signature validation 
    453         xmlSigDoc.read(self) 
     445        try: 
     446            xmlSigDoc.read(self) 
     447 
     448        except xmlSigDocError, xmlSigDocErr: 
     449            raise AttrCertError(str(xmlSigDocErr)) 
     450 
     451 
     452 
     453    def write(self, **xmlSigDocKeys): 
     454 
     455        """Write an Attribute Certificate.""" 
     456 
     457        # Method is a wrapper for xmlSigDoc.write to catch exceptions and 
     458        # convert to AttrCertError type 
     459        try: 
     460            xmlSigDoc.write(self, **xmlSigDocKeys) 
     461 
     462        except xmlSigDocError, xmlSigDocErr: 
     463            raise AttrCertError(str(xmlSigDocErr)) 
     464 
     465 
     466 
     467    def sign(self, **xmlSigDocKeys): 
     468 
     469        """Sign an Attribute Certificate.""" 
     470 
     471        # Method is a wrapper for xmlSigDoc.sign to catch exceptions and 
     472        # convert to AttrCertError type 
     473        try: 
     474            xmlSigDoc.sign(self, **xmlSigDocKeys) 
     475 
     476        except xmlSigDocError, xmlSigDocErr: 
     477            raise AttrCertError(str(xmlSigDocErr)) 
    454478 
    455479 
     
    470494        # Check for valid provenance 
    471495        if not self.isValidProvenance(): 
    472             raise "Provenance must be set to \"" + \ 
    473                 "\" or \"".join(AttrCert.__provenance) + "\"" 
     496            raise AttrCertError("Provenance must be set to \"" + \ 
     497                                "\" or \"".join(AttrCert.__provenance) + "\"") 
    474498 
    475499         
     
    520544        if dtNotBefore is not None: 
    521545            if not isinstance(dtNotBefore, datetime): 
    522                 raise "Input not before time must be datetime type" 
     546                raise AttrCertError(\ 
     547                    "Input not before time must be datetime type") 
    523548             
    524549            self.__dtNotBefore = dtNotBefore 
     
    537562            dtDeltaLifeTime = timedelta(0, self.__lifeTime) 
    538563        except: 
    539             raise "Invalid Certificate lifetime set %.3f" % self.__lifeTime 
     564            raise AttrCertError("Invalid Certificate lifetime set %.3f" % \ 
     565                                self.__lifeTime) 
    540566 
    541567         
     
    558584 
    559585        if not isinstance(dtVal, datetime): 
    560             raise "Invalid datetime object for conversion to string" 
     586            raise AttrCertError(\ 
     587                "Invalid datetime object for conversion to string") 
    561588         
    562589        # Convert from 1-12 to 0-11 month format used in XML file 
    563590        lDateTime = list(dtVal.utctimetuple()[0:6]) 
    564         lDateTime[1] -= 1 
     591 
     592        # Use 1-12 format 
     593        # P J Kershaw 09/05/05 
     594        #lDateTime[1] -= 1 
    565595 
    566596        # Format as a single string with no commas or brackets 
     
    577607        try: 
    578608            lTime = [int(i) for i in sTime.split()] 
    579             lTime[1] += 1 
     609             
     610            # Use 1-12 format 
     611            # P J Kershaw 09/05/05 
     612            #lTime[1] += 1 
    580613         
    581614            return datetime(lTime[0], lTime[1], lTime[2], 
    582615                            lTime[3], lTime[4], lTime[5]) 
    583616        except: 
    584             raise "Error converting time string into datetime object" 
     617            raise AttrCertError(\ 
     618                "Error converting time string into datetime object") 
    585619         
    586620 
     
    592626 
    593627        if not isinstance(self.__dtNotBefore, datetime): 
    594             raise "notBefore datetime is not set" 
     628            raise AttrCertError("notBefore datetime is not set") 
    595629 
    596630        if not isinstance(self.__dtNotAfter, datetime): 
    597             raise "notAfter datetime is not set" 
     631            raise AttrCertError("notAfter datetime is not set") 
    598632        
    599633        dtNow = datetime.utcnow() 
     
    611645 
    612646 
    613     def isValid(self, raiseExcep=False): 
     647    def isValid(self, raiseExcep=False, **xmlSigDocKeys): 
    614648 
    615649        """Check Attribute Certificate is valid: 
     
    620654        - Signature is valid. 
    621655 
    622         raiseExcep: set to true to raise an exception if invalid instead 
    623                     of returning False.  Default is to set this flag to False 
     656        raiseExcep:             set to true to raise an exception if invalid 
     657                                instead of returning False.  Default is to set 
     658                                this flag to False. 
     659 
     660        Also accepts keyword arguments corresponding to xmlSigDoc.isValidSig: 
     661         
     662        xmlTxt:                 string buffer containing the text from the XML 
     663                                file to be checked.  If omitted, the 
     664                                filePath argument is used instead. 
     665 
     666        filePath:            file path to XML file to be checked.  This 
     667                                argument is used if no xmlTxt was provided. 
     668                                If filePath itself is omitted the file set 
     669                                by self.__filePath is read instead. 
     670 
     671        trustedCertFilePath:    Certificate of trusted authority used to 
     672                                validate the signature.  If set, it is copied 
     673                                into self.__trustedCertFilePath.  If omitted 
     674                                self.__trustedCertFilePath is used unchanged.                              
    624675        """ 
    625676 
     
    651702 
    652703 
    653         if not self.isValidSig(): 
    654             if raiseExcep: 
    655                 raise AttrCertError(\ 
     704        # Handle exception from xmlSigDoc.isValidSig() regardless of 
     705        # raiseExcep flag setting 
     706        try:             
     707            if not self.isValidSig(**xmlSigDocKeys): 
     708                if raiseExcep: 
     709                    raise AttrCertError(\ 
    656710                                "Attribute Certificate signature is invalid") 
    657              
    658             return False 
    659  
     711                 
     712                return False 
     713         
     714        except xmlSigDocError, xmlSigDocErr: 
     715            raise AttrCertError(str(xmlSigDocErr)) 
     716         
    660717 
    661718        # All tests passed 
  • security/trunk/python/NDG.BAK/X509.py

    r407 r410  
    1 """X509 certificate handling class encapsulates M2Crypto.X509 
     1"""X.509 certificate handling class encapsulates M2Crypto.X509 
    22 
    33Nerc Data Grid Project 
     
    1717 
    1818 
     19 
     20 
     21class X509CertError(Exception): 
     22 
     23    """Exception handling for NDG X.509 Certificate handling class.""" 
     24     
     25    def __init__(self, msg): 
     26        self.msg = msg 
     27          
     28    def __str__(self): 
     29        return self.__msg 
     30 
     31 
     32 
     33 
    1934class X509Cert: 
    2035 
     
    2742 
    2843            if not isinstance(filePath, basestring): 
    29                 raise "Certificate File Path input must be a valid string" 
     44                raise X509CertError(\ 
     45                    "Certificate File Path input must be a valid string") 
    3046             
    3147        self.__filePath = filePath 
     
    3955 
    4056            if not isinstance(filePath, basestring): 
    41                 raise "Certificate File Path input must be a valid string" 
     57                raise X509CertError(\ 
     58                    "Certificate File Path input must be a valid string") 
    4259             
    4360            self.__filePath = filePath 
     
    4663            self.__m2CryptoX509 = M2Crypto.X509.load_cert(self.__filePath) 
    4764        except: 
    48             raise "Error loading certificate \"" + self.__filePath + "\"" 
     65            raise X509CertError(\ 
     66                "Error loading certificate \"" + self.__filePath + "\"") 
    4967 
    5068        # Get distinguished name 
     
    6179        """Get X500 Distinguished Name.""" 
    6280        return self.__dn 
     81 
     82 
     83 
     84 
     85class X500DNError(Exception): 
     86 
     87    """Exception handling for NDG X.500 DN class.""" 
     88     
     89    def __init__(self, msg): 
     90        self.__msg = msg 
     91          
     92    def __str__(self): 
     93        return self.__msg 
    6394 
    6495 
     
    116147        if separator is not None: 
    117148            if not isinstance(separator, basestring): 
    118                 raise "dn Separator must be a valid string" 
     149                raise X500DNError("dn Separator must be a valid string") 
    119150 
    120151            # Check for single character but allow trailing space chars 
    121152            if len(separator.lstrip()) is not 1: 
    122                 raise "dn separator must be a single character" 
     153                raise X500DNError("dn separator must be a single character") 
    123154 
    124155            self.__separator = separator 
     
    168199 
    169200        return self.__dat.items() == x500dn.items() 
     201 
     202 
     203 
     204         
     205    def __cmp__(self, x500dn): 
     206 
     207        """Return true if the all the fields of the two DNs are equal""" 
     208         
     209        if not isinstance(x500dn, X500DN): 
     210            return False 
     211 
     212        return cmp(self.__dat, x500dn.get()) 
    170213     
    171214 
     
    174217    def __delitem__(self, key): 
    175218         
    176         raise 'Keys cannot be deleted from the X500DN' 
     219        raise X500DNError('Keys cannot be deleted from the X500DN') 
    177220 
    178221 
     
    196239        else: 
    197240            # key not recognised as a short or long name version 
    198             raise 'Key "' + key + '" not recognised for X500DN' 
     241            raise X500DNError('Key "' + key + '" not recognised for X500DN') 
    199242 
    200243 
     
    218261        else: 
    219262            # key not recognised as a short or long name version 
    220             raise 'Key "' + key + '" not recognised for X500DN' 
     263            raise X500DNError('Key "' + key + '" not recognised for X500DN') 
    221264 
    222265 
     
    224267 
    225268    def clear(self): 
    226         raise "Data cannot be cleared from " + X500DN.__name__ 
     269        raise X500DNError("Data cannot be cleared from " + X500DN.__name__) 
    227270 
    228271     
     
    250293 
    251294 
     295 
     296    def get(self): 
     297        """Get Distinguished name as a data dictionary.""" 
     298        return self.__dat 
     299 
     300 
     301 
    252302     
    253303    def serialise(self, separator=None): 
     
    257307        if separator: 
    258308            if not isinstance(separator, basestring): 
    259                 raise "Separator must be a valid string" 
     309                raise X500DNError("Separator must be a valid string") 
    260310                 
    261311            self.__separator = separator 
     
    275325        if separator: 
    276326            if not isinstance(separator, basestring): 
    277                 raise "Separator must be a valid string" 
     327                raise X500DNError("Separator must be a valid string") 
    278328 
    279329            self.__separator = separator 
     
    282332        dnFields = dn.split(self.__separator) 
    283333        if len(dnFields) < 2: 
    284             raise "Error parsing DN string: \"%s\"" % dn 
     334            raise X500DNError("Error parsing DN string: \"%s\"" % dn) 
    285335 
    286336         
     
    288338        keyVals = [field.split('=') for field in dnFields] 
    289339 
     340        # Reset existing dictionary values 
     341        self.__dat.fromkeys(self.__dat, '') 
     342         
    290343        # Strip leading and trailing space chars and convert into a dictionary 
    291         self.__dat = dict([(keyVal[0].strip(), keyVal[1].strip()) \ 
    292                            for keyVal in keyVals]) 
     344        self.__dat.update(dict([(keyVal[0].strip(), keyVal[1].strip()) \ 
     345                          for keyVal in keyVals])) 
    293346  
     347 
     348    def parseSeparator(self, dn): 
     349 
     350        """Attempt to parse the separator character from a given input 
     351        DN string.  If not found, return None 
     352 
     353        DNs don't use standard separators e.g. 
     354 
     355        /C=UK/O=eScience/OU=CLRC/L=DL/CN=AN Other 
     356        CN=SUM Oneelse,L=Didcot, O=RAL,OU=SSTD 
     357 
     358        This function isolates and identifies the character.  - In the above, 
     359        '/' and ',' respectively""" 
     360 
     361 
     362        # Make a match string containing all the possible field identifiers 
     363        # with equal sign appended and 'or'ed together.  \W should match the 
     364        # separator which preceeds the field name. \s* allows any whitespace 
     365        # between field name and field separator to be taken into account 
     366        # 
     367        # The resulting match should be a list.  The first character in each 
     368        # element in the list should be the field separator and should be the 
     369        # same 
     370        reMatch = '|'.join(['\W\s*'+i+'=' for i in self.__dat.keys()]) 
     371 
     372        # In the first example above, the resulting match is: 
     373        # ['/C=', '/O=', '/OU=', '/L='] 
     374        # In each element the first character is the separator - check: 
     375        sepList = [i[0:1] for i in reMatch] 
     376        if sepList == sepList.sort(): 
     377            return sepList[0] 
     378        else: 
     379            return None 
  • security/trunk/python/NDG.BAK/xmlSigDoc.py

    r407 r410  
    2424# XML signature module 
    2525import xmlsec 
     26 
     27 
     28 
     29 
     30class xmlSigDocError(Exception): 
     31 
     32    """Exception handling for NDG XML Signature class.""" 
     33     
     34    def __init__(self, msg): 
     35        self.__msg = msg 
     36          
     37    def __str__(self): 
     38        return self.__msg 
     39 
     40 
    2641 
    2742 
     
    5065 
    5166            if not isinstance(filePath, basestring): 
    52                 raise "Input key file path is %s" % type(filePath) + \ 
    53                       ": string type expected" 
     67                raise xmlSigDocError("Input key file path is %s" % \ 
     68                                     type(filePath) + ": string type expected") 
    5469 
    5570            self.__filePath = filePath 
     
    6075 
    6176            if not isinstance(signingKeyFilePath, basestring): 
    62                 raise "Input key file path is %s" % type(issuer) + \ 
    63                       ": string type expected" 
     77                raise xmlSigDocError("Input key file path is %s" % \ 
     78                                     type(issuer) + ": string type expected") 
    6479             
    6580            self.__signingKeyFilePath = signingKeyFilePath 
     
    7085 
    7186            if not isinstance(signingCertFilePath, basestring): 
    72                 raise "Input certificate file path is %s" % type(issuer) + \ 
    73                       ": string type expected" 
     87                raise xmlSigDocError("Input certificate file path is %s" % \ 
     88                                     type(issuer) + ": string type expected") 
    7489 
    7590            self.__signingCertFilePath = signingCertFilePath 
     
    7994 
    8095            if not isinstance(trustedCertFilePath, basestring): 
    81                 raise "Input trusted certificate file path is %s" % \ 
    82                       type(issuer) + ": string type expected" 
     96                raise xmlSigDocError(\ 
     97                    "Input trusted certificate file path is %s" % \ 
     98                    type(issuer) + ": string type expected") 
    8399 
    84100            self.__trustedCertFilePath = trustedCertFilePath 
     
    107123        # Init xmlsec library 
    108124        if xmlsec.init() < 0: 
    109             raise "xmlsec initialization failed." 
     125            raise xmlSigDocError("xmlsec initialization failed.") 
    110126 
    111127         
    112128        # Check loaded library version 
    113129        if xmlsec.checkVersion() != 1: 
    114             raise "xmlsec library version is not compatible.\n" 
     130            raise xmlSigDocError("xmlsec library version is not compatible.") 
    115131 
    116132 
    117133        # Init crypto library 
    118134        if xmlsec.cryptoAppInit(None) < 0: 
    119             raise "Crypto initialization failed." 
     135            raise xmlSigDocError("Crypto initialization failed.") 
    120136 
    121137         
    122138        # Init xmlsec-crypto library 
    123139        if xmlsec.cryptoInit() < 0: 
    124             raise "xmlsec-crypto initialization failed." 
     140            raise xmlSigDocError("xmlsec-crypto initialization failed.") 
    125141 
    126142         
     
    160176        if self.__libxml2Doc is None or \ 
    161177           self.__libxml2Doc.getRootElement() is None: 
    162             raise "Error parsing Attribute Certificate" 
     178            raise xmlSigDocError("Error parsing Attribute Certificate") 
    163179             
    164180        self.__bLibxml2DocFreed = False 
     
    181197        if self.__libxml2Doc is None or \ 
    182198           self.__libxml2Doc.getRootElement() is None: 
    183             raise "Error parsing Attribute Certificate \"%s\"" % \ 
    184                   self.__filePath 
     199            raise xmlSigDocError(\ 
     200                "Error parsing Attribute Certificate \"%s\"" % self.__filePath) 
    185201             
    186202        self.__bLibxml2DocFreed = False 
     
    196212 
    197213        if self.__libxml2Doc is None: 
    198             raise "self.__libxml2ParseDoc() must be called first" 
     214            raise xmlSigDocError(\ 
     215                "self.__libxml2ParseDoc() must be called first") 
    199216         
    200217        if self.__libxml2Ctxt is not None and not self.__bLibxml2CtxtFreed: 
     
    204221        self.__libxml2Ctxt = self.__libxml2Doc.xpathNewContext() 
    205222        if self.__libxml2Ctxt is None: 
    206             raise "Error creating XPath context for \"%s\"" % \ 
    207                   self.__filePath 
     223            raise xmlSigDocError("Error creating XPath context for \"%s\"" % \ 
     224                                  self.__filePath) 
    208225 
    209226        self.__bLibxml2CtxtFreed = False 
     
    224241        self.__dSigCtxt = xmlsec.DSigCtx(keysMngr) 
    225242        if self.__dSigCtxt is None: 
    226             raise "Error creating signature context" 
     243            raise xmlSigDocError("Error creating signature context") 
    227244 
    228245        self.__bDSigCtxtFreed = False 
     
    243260        self.__keysMngr = xmlsec.KeysMngr() 
    244261        if self.__keysMngr is None: 
    245             raise "Failed to create keys manager." 
     262            raise xmlSigDocError("Failed to create keys manager.") 
    246263 
    247264        self.__bkeysMngrFreed = False 
     
    292309 
    293310 
    294     def write(self, filePath=None, bSign=True, xmlTxt=None, **signKeys): 
     311    def write(self, filePath=None, bSign=False, xmlTxt=None, **signKeys): 
    295312 
    296313        """Write XML document applying digital signature 
     
    298315        filePath:               file path for XML output 
    299316                             
    300         bSign:                  flag defaults to True to sign the new 
    301                                 certificate using the private key and 
    302                                 certificate to sign the certificate. 
    303                                 Set to False to NOT sign the document. 
     317        bSign:                  flag defaults to False to NOT sign the 
     318                                document.  Explicitly set to True to sign 
     319                                the new certificate using the private key 
     320                                and certificate. 
    304321 
    305322        xmlTxt:                 string containing formatted xml text for 
     
    322339        if filePath is not None: 
    323340            if not isinstance(filePath, basestring): 
    324                 raise "Input file path must be a valid string." 
     341                raise xmlSigDocError("Input file path must be a valid string") 
    325342             
    326343            self.__filePath = filePath 
     
    357374        """Set file path for file to be signed.""" 
    358375         
    359         try: 
    360             if not isinstance(filePath, basestring): 
    361                 raise 
    362         except: 
    363             raise "File path must be a valid string" 
     376        if filePath is None or not isinstance(filePath, basestring): 
     377             
     378            raise xmlSigDocError("File path must be a valid string") 
    364379         
    365380        self.__filePath = filePath 
     
    373388        Create text for output and return as a string""" 
    374389         
    375         raise "Virtual function: Derived class should implement." 
     390        raise xmlSigDocError(\ 
     391                    "Virtual function: Derived class should implement.") 
    376392 
    377393        return None 
     
    410426        # Attribute Authority server's private key file 
    411427        if signingKeyFilePath is not None: 
    412  
    413             if not isinstance(signingKeyFilePath, basestring): 
    414                 raise "Input key file path is %s" % type(issuer) + \ 
    415                       ": string type expected" 
    416              
    417             self.__signingKeyFilePath = signingKeyFilePath 
     428            self.__signingKeyFilePath = signingKeyFilePath             
    418429 
    419430 
    420431        # Attribute Authority server's RSA certificate file  
    421432        if signingCertFilePath is not None: 
    422  
    423             if not isinstance(signingCertFilePath, basestring): 
    424                 raise "Input certificate file path is %s" % type(issuer) + \ 
    425                       ": string type expected" 
    426  
    427433            self.__signingCertFilePath = signingCertFilePath 
    428434 
    429435 
    430         # Check for read access 
    431         if not os.access(self.__signingKeyFilePath, os.R_OK): 
    432             raise "Private key file \"%s\" not found or no read access" % \ 
    433                 self.__signingKeyFilePath 
    434  
    435  
    436         if not os.access(self.__signingCertFilePath, os.R_OK): 
    437             raise "Certificate file \"%s\" not found or no read access" % \ 
    438                 self.__signingCertFilePath 
     436        # Check files for read access 
     437        try: 
     438            if not os.access(self.__signingKeyFilePath, os.R_OK): 
     439                raise xmlSigDocError(\ 
     440                    "Private key file \"%s\" not found or no read access" % \ 
     441                    self.__signingKeyFilePath) 
     442        except: 
     443            raise xmlSigDocError("Signing Certificate file path is not valid") 
     444 
     445         
     446        try: 
     447            if not os.access(self.__signingCertFilePath, os.R_OK): 
     448                raise xmlSigDocError(\ 
     449                    "Certificate file \"%s\" not found or no read access" % \ 
     450                    self.__signingCertFilePath) 
     451        except: 
     452            raise xmlSigDocError("Private key file path is not a valid") 
    439453 
    440454 
     
    449463                                       None) 
    450464        if sigNode is None: 
    451             raise "Error creating signature template" 
     465            raise xmlSigDocError("Error creating signature template") 
    452466 
    453467         
     
    460474                                       None, None, None) 
    461475        if refNode is None: 
    462             raise "Error adding reference to signature template" 
     476            raise xmlSigDocError( 
     477                "Error adding reference to signature template") 
    463478 
    464479 
    465480        # Add enveloped transform 
    466481        if refNode.addTransform(xmlsec.transformEnvelopedId()) is None: 
    467             raise "Error adding enveloped transform to reference" 
     482            raise xmlSigDocError(\ 
     483                "Error adding enveloped transform to reference") 
    468484 
    469485  
     
    471487        keyInfoNode = sigNode.ensureKeyInfo(None) 
    472488        if keyInfoNode is None: 
    473             raise "Error adding key info" 
     489            raise xmlSigDocError("Error adding key info") 
    474490 
    475491         
    476492        if keyInfoNode.addX509Data() is None: 
    477             raise "Error adding X509Data node" 
     493            raise xmlSigDocError("Error adding X509Data node") 
    478494 
    479495 
     
    489505                                                    None, None) 
    490506        if self.__dSigCtxt.signKey is None: 
    491             raise "Error loading private pem key from \"%s\"" % \ 
    492                   self.__signingKeyFilePath 
     507            raise xmlSigDocError(\ 
     508                "Error loading private pem key from \"%s\"" % \ 
     509                self.__signingKeyFilePath) 
    493510 
    494511 
     
    497514                                       self.__signingCertFilePath, 
    498515                                       xmlsec.KeyDataFormatPem) < 0: 
    499             raise "Error loading pem certificate \"%s\"" % \ 
    500                   self.__signingCertFilePath 
     516            raise xmlSigDocError("Error loading pem certificate \"%s\"" % \ 
     517                                  self.__signingCertFilePath) 
    501518 
    502519 
    503520        # Set key name to the file name 
    504521        if self.__dSigCtxt.signKey.setName(self.__signingKeyFilePath) < 0: 
    505             raise "Error setting key name for key from \"%s\"" % \ 
    506                   self.__signingKeyFilePath 
     522            raise xmlSigDocError(\ 
     523                "Error setting key name for key from \"%s\"" % \ 
     524                  self.__signingKeyFilePath) 
    507525 
    508526 
    509527        # Sign the template 
    510528        if self.__dSigCtxt.sign(sigNode) < 0: 
    511             raise "Signature failed" 
     529            raise xmlSigDocError("Signature failed") 
    512530 
    513531 
     
    527545                                filePath argument is used instead. 
    528546 
    529         filePath:            file path to XML file to be checked.  This 
     547        filePath:               file path to XML file to be checked.  This 
    530548                                argument is used if no xmlTxt was provided. 
    531549                                If filePath itself is omitted the file set 
     
    538556                                """ 
    539557         
    540         #if xmlTxt is None:            
    541         #    xmlTxt = self.createXML() 
    542  
    543558 
    544559        if trustedCertFilePath is not None: 
    545  
    546             if not isinstance(trustedCertFilePath, basestring): 
    547                 raise "Input trusted certificate file path is %s" % \ 
    548                       type(issuer) + ": string type expected" 
    549  
    550560            self.__trustedCertFilePath = trustedCertFilePath 
    551561 
    552  
    553         # Check Certificate for read access 
    554         if not os.access(self.__trustedCertFilePath, os.R_OK): 
    555             raise "Trusted Certificate file \"" + \ 
    556                   self.__trustedCertFilePath + \ 
    557                   "\" not found or no read access" 
    558  
     562         
     563        # Check Certificate file for read access 
     564        try: 
     565            if not os.access(self.__trustedCertFilePath, os.R_OK): 
     566                raise xmlSigDocError("Trusted Certificate file \"" + \ 
     567                      self.__trustedCertFilePath + \ 
     568                      "\" not found or no read access") 
     569        except: 
     570            raise xmlSigDocError("Trusted certificate file path is not valid") 
     571             
    559572 
    560573        # Create and initialize keys manager 
     
    562575 
    563576        if xmlsec.cryptoAppDefaultKeysMngrInit(self.__keysMngr) < 0: 
    564             raise "Failed to initialize keys manager." 
     577            raise xmlSigDocError("Failed to initialize keys manager.") 
    565578 
    566579         
     
    569582                                    xmlsec.KeyDataFormatPem, 
    570583                                    xmlsec.KeyDataTypeTrusted) < 0: 
    571             raise "Error loading pem certificate from \"%s\"" % \ 
    572                   self.__trustedCertFilePath 
    573  
    574  
    575         # If xml text was input update libxml2 doc instance with it's content 
     584            raise xmlSigDocError(\ 
     585                "Error loading pem certificate from \"%s\"" % \ 
     586                self.__trustedCertFilePath) 
     587 
     588 
     589        # If 'xmlTxt' was input update libxml2 doc instance with it's content 
    576590        if xmlTxt is not None: self.__libxml2ParseDoc(xmlTxt) 
    577591         
     
    581595                                   xmlsec.NodeSignature, xmlsec.DSigNs) 
    582596        if dSigNode is None: 
    583             raise "Start node not found in \"%s\"" % self.__filePath 
     597            raise xmlSigDocError(\ 
     598                "Start node not found in \"%s\"" % self.__filePath) 
    584599 
    585600  
     
    590605        # Verify signature 
    591606        if self.__dSigCtxt.verify(dSigNode) < 0: 
    592             raise "Error verifying signature." 
     607            raise xmlSigDocError("Error verifying signature.") 
    593608 
    594609 
  • security/trunk/python/NDG/AttAuthority.py

    r408 r410  
    1717 
    1818 
     19# Create unique names for attribute certificates 
     20import tempfile 
     21import os 
     22 
     23 
    1924# For parsing of Map Configuration file 
    2025import cElementTree as ElementTree 
    2126 
    2227# X509 Certificate handling 
    23 from X509 import X509Cert 
    24 from X509 import X500DN 
    25  
    26 # Attribute Certificate 
    27 from AttrCert import AttrCert 
    28 from AttrCert import AttrCertError 
     28from X509 import * 
     29 
     30# NDG Attribute Certificate 
     31from AttrCert import * 
     32 
     33 
     34 
     35 
     36class AttrAuthorityError(Exception): 
     37 
     38    """Exception handling for NDG Attribute Authority class.""" 
     39     
     40    def __init__(self, msg): 
     41        self.__msg = msg 
     42          
     43    def __str__(self): 
     44        return self.__msg 
     45 
     46 
    2947 
    3048 
     
    4058    # implementation of NDG Security 
    4159     
     60 
     61    # Class variables - string constants for set-up of Attribute Certificate 
     62    # file names 
     63    __attrCertFilePfx = "attrCert-" 
     64    __attrCertFileSfx = ".xml" 
     65 
    4266     
    4367    def __init__(self, propertiesFilePath): 
     
    77101        self.__usrRoleSrvr = None 
    78102        self.__usrRolePort = -1 
    79          
    80          
    81         # Initialize Credentials Repository - used to store attribute 
    82         # certificates 
    83         # 
    84         # Temporarily use current directory to store attribute Certificates 
    85         # 
    86         # P J Kershaw 27/04/05 
    87         self.__credRepos=CredentialsRepository(self.__credReposDir) 
    88103 
    89104 
     
    124139        # Nb. new attribute certificate file path is created from the 
    125140        # Credentials Repository 
    126         attrCert = AttrCert(self.__credRepos.newAttrCertFilePath(), 
     141        attrCert = AttrCert(self.__newAttrCertFilePath(), 
    127142                            signingKeyFilePath=self.__keyFilePath, 
    128143                            signingCertFilePath=self.__certFilePath, 
     
    168183            # trusted data centre 
    169184            if extAttrCertFilePath is None: 
    170                 raise "User \"%s\" is not registered " % attrCert['holder'] +\ 
    171                       "and no external attribute certificate is available " +\ 
    172                       " to make a mapping" 
     185                raise AttrAuthorityError(\ 
     186                    "User \"%s\" is not registered " % attrCert['holder'] + \ 
     187                    "and no external attribute certificate is available " + \ 
     188                    " to make a mapping") 
    173189 
    174190            # Read externally provided certificate (i.e. from a trusted data 
    175191            # centre) 
    176             extAttrCert = AttrCert(extAttrCertFilePath, 
     192            try: 
     193                extAttrCert = AttrCert(extAttrCertFilePath, 
    177194                                   trustedCertFilePath=self.__caCertFilePath) 
    178             extAttrCert.read() 
     195                extAttrCert.read() 
     196                 
     197            except AttrCertError, attrCertErr: 
     198                raise AttrAuthorityError(\ 
     199                "External Attribute Certificate error: " + str(attrCertErr)) 
    179200 
    180201 
     
    182203            # be used to make further mappings 
    183204            if extAttrCert.isMapped(): 
    184                 raise "External Attribute Certificate must have an " + \ 
    185                       "original provenance in order to make further mappings." 
     205                raise AttrAuthorityError(\ 
     206                    "External Attribute Certificate must have an " + \ 
     207                    "original provenance in order to make further mappings.") 
    186208 
    187209 
     
    191213                 
    192214            except AttrCertError, excep: 
    193                 raise "Invalid Remote Attribute Certificate \"%s\": %s" % \ 
    194                     (extAttrCertFilePath, excep)          
     215                raise AttrAuthorityError(\ 
     216                    "Invalid Remote Attribute Certificate \"%s\": %s" % \ 
     217                    (extAttrCertFilePath, excep))         
    195218 
    196219 
     
    198221            # TODO: 
    199222            # P J Kershaw 29/04/05 
    200             pdb.set_trace() 
    201             holderDN = X500DN(dn=extAttrCert['holder']) 
     223            try: 
     224                holderDN = X500DN(dn=extAttrCert['holder']) 
     225                 
     226            except X500DNError, x500dnErr: 
     227                raise AttrAuthorityError(\ 
     228                    "Error creating X500DN for holder: %s" % str(x500dnErr)) 
     229             
    202230            if holderDN != usrDN: 
    203                 raise "User certificate and Attribute Certificate DNs " + \ 
    204                       "don't match: " + usrDN + " and " + holderDN 
     231                raise AttrAuthorityError(\ 
     232                    "User certificate and Attribute Certificate DNs " + \ 
     233                    "don't match: " + str(usrDN) + " and " + str(holderDN)) 
    205234             
    206235   
     
    217246            localRoles = self.mapRoles(extAttrCert['issuerName'], extRoles) 
    218247            if not localRoles: 
    219                 raise "No local roles mapped to the %s roles: %s" % \ 
    220                       (extAttrCert['issuerName'], str(extRoles)) 
     248                raise AttrAuthorityError(\ 
     249                    "No local roles mapped to the %s roles: %s" % \ 
     250                    (extAttrCert['issuerName'], str(extRoles))) 
    221251 
    222252            attrCert.addRoles(localRoles) 
     
    233263 
    234264        # Check the certificate is valid 
    235         if not attrCert.isValid(): 
    236             raise "New attribute certificate is invalid: \"%s\"" % \ 
    237                   attrCertFilePath 
     265        try: 
     266            attrCert.isValid(raiseExcep=True) 
     267                 
     268        except AttrCertError, excep: 
     269            raise AttrAuthorityError("New Attribute Certificate \"%s\": %s" %\ 
     270                    (extAttrCertFilePath, excep)) 
    238271 
    239272         
     
    253286        if propertiesFilePath is not None: 
    254287            if not isinstance(propertiesFilePath, basestring): 
    255                 raise "Input Properties file path " + \ 
    256                       "must be a valid string." 
     288                raise AttrAuthorityError("Input Properties file path " + \ 
     289                      "must be a valid string.") 
    257290             
    258291            self.__propertiesFilePath = propertiesFilePath 
     
    273306        self.__attrCertLifeTime = float(properties['attrCertLifeTime']) 
    274307        self.__mapConfigFilePath = properties['mapConfigFile'] 
    275         self.__credReposDir = properties['credReposDir'] 
    276  
    277          
     308        self.__attrCertDir = properties['attrCertDir'] 
     309 
     310        # Check directory path 
     311        try: 
     312            dirList = os.listdir(self.__attrCertDir) 
     313 
     314        except OSError, osError: 
     315            raise AttrAuthorityError(\ 
     316                "Invalid directory path Attribute Certificates store: " + \ 
     317                osError.strerror) 
     318 
     319        
    278320         
    279321         
     
    288330        if mapConfigFilePath is not None: 
    289331            if not isinstance(mapConfigFilePath, basestring): 
    290                 raise "Input Map Configuration file path " + \ 
    291                       "must be a valid string." 
     332                raise AttrAuthorityError(\ 
     333                    "Input Map Configuration file path " + \ 
     334                    "must be a valid string.") 
    292335             
    293336            self.__mapConfigFilePath = mapConfigFilePath 
     
    313356            roleElem = elem.findall('role') 
    314357            if not roleElem: 
    315                 raise "\"role\" tag not found in \"%s\"" % \ 
    316                         self.__mapConfigFilePath 
     358                raise AttrAuthorityError(\ 
     359                    "\"role\" tag not found in \"%s\"" % \ 
     360                    self.__mapConfigFilePath) 
    317361 
    318362            try: 
    319363                trustedHost = elem.attrib.values()[0] 
    320364            except: 
    321                 raise "Error setting trusted host name" 
     365                raise AttrAuthorityError("Error setting trusted host name") 
    322366             
    323367            # Add signatureFile and list of roles 
     
    364408 
    365409 
     410 
    366411    def getRoles(self, usrDN): 
    367412 
     
    389434 
    390435        if not self.__role2Host: 
    391             raise "Roles to host look-up is not set - " + \ 
    392                   "ensure readMapConfig() has been called." 
     436            raise AttrAuthorityError("Roles to host look-up is not set - " + \ 
     437                  "ensure readMapConfig() has been called.") 
    393438        
    394439        if not self.__role2Host.has_key(role): 
     
    408453 
    409454        if not self.__roleMap: 
    410             raise "Roles map is not set - ensure readMapConfig() " + \ 
    411                   "has been called." 
     455            raise AttrAuthorityError(\ 
     456                "Roles map is not set - ensure readMapConfig() " + \ 
     457                "has been called.") 
    412458 
    413459        # Check the host name is a trusted one recorded in the map 
     
    430476 
    431477 
    432 # Create unique names for attribute certificates 
    433 import tempfile 
    434 import os 
    435  
    436 class CredentialsRepository: 
    437  
    438     """Store user credentials (Attribute Certificates) for Attribute 
    439     Authority""" 
    440  
    441     # Class variables - string constants for set-up of Attribute Certificate 
    442     # file names 
    443     __attrCertFilePfx = "attrCert-" 
    444     __attrCertFileSfx = ".xml" 
    445  
    446      
    447     def __init__(self, dirPath): 
    448  
    449         # Check directory path for repository 
    450         try: 
    451             dirList = os.listdir(dirPath) 
    452  
    453         except OSError, osError: 
    454             raise "Invalid input directory path", osError.strerror 
    455          
    456         self.dirPath = dirPath 
    457  
    458  
    459     def newAttrCertFilePath(self): 
     478    def __newAttrCertFilePath(self): 
    460479 
    461480        """Create a new unique attribute certificate file path""" 
    462481         
    463         attrCertFile = tempfile.mkstemp( 
    464                         suffix=CredentialsRepository.__attrCertFileSfx, 
    465                         prefix=CredentialsRepository.__attrCertFilePfx, 
    466                         dir=self.dirPath, 
    467                         text=True) 
     482        attrCertFilePath = tempfile.mkstemp( 
     483                                    suffix=AttrAuthority.__attrCertFileSfx, 
     484                                    prefix=AttrAuthority.__attrCertFilePfx, 
     485                                    dir=self.__attrCertDir, 
     486                                    text=True) 
    468487 
    469488        # The file is opened - close using the file descriptor returned in the 
    470489        # first element of the tuple 
    471         os.close(attrCertFile[0]) 
     490        os.close(attrCertFilePath[0]) 
    472491 
    473492        # The file path is the 2nd element 
    474         return attrCertFile[1] 
     493        return attrCertFilePath[1] 
     494 
  • security/trunk/python/NDG/AttCert.py

    r407 r410  
    2121 
    2222# XML signature module based on xmlsec and libxml2 
    23 from xmlSigDoc import xmlSigDoc 
     23from xmlSigDoc import * 
    2424 
    2525# XML Parsing 
     
    3131 
    3232from X509 import X500DN 
     33from X509 import X500DNError 
     34 
    3335 
    3436class AttrCertError(Exception): 
    3537     
    36      def __init__(self, value): 
    37          self.value = value 
     38    """Exception handling for NDG Attribute Certificate class.""" 
     39     
     40    def __init__(self, msg): 
     41        self.__msg = msg 
    3842          
    39      def __str__(self): 
    40         return repr(self.value) 
     43    def __str__(self): 
     44        return self.__msg 
    4145     
    4246 
     
    5458 
    5559    # Nb. pass xmlSigDoc keyword arguments in xmlSigDocArgs dictionary 
    56     def __init__(self, 
    57                  filePath=None, 
    58 # Allow setting of these at initialisation?? 
    59 # 
    60 # P J Kershaw 26/04/05 
    61 ##                 holder=None, 
    62 ##                 issuer=None, 
    63                  lifeTime=-1, 
    64                  **xmlSigDocArgs): 
     60    def __init__(self, filePath=None, lifeTime=-1, **xmlSigDocArgs): 
    6561 
    6662        """Initialisation - Attribute Certificate file path may be specified. 
     
    9793        self.__holderDN = None 
    9894 
    99 # Allow setting of these at initialisation?? 
    100 # 
    101 # P J Kershaw 26/04/05 
    102 ##        if holder is not None: 
    103 ## 
    104 ##            if not isinstance(holder, basestring): 
    105 ##                raise "Input holder is %s" % type(holder) + \ 
    106 ##                      ": string type expected" 
    107 ##             
    108 ##            self.__dat['holder'] = holder 
    109 ## 
    110 ## 
    111 ##        if issuer is not None: 
    112 ## 
    113 ##            if not isinstance(issuer, basestring): 
    114 ##                raise "Input issuer is %s" % type(issuer) + \ 
    115 ##                      ": string type expected" 
    116 ## 
    117 ##            self.__dat['issuer'] = issuer 
    118  
    11995 
    12096        # Check for input certificate life time interval - if not set default 
     
    140116        "Attribute Certificate keys cannot be removed" 
    141117         
    142         raise 'Keys cannot be deleted from ' + AttrCert.__name__ 
     118        raise AttrCertError('Keys cannot be deleted from '+AttrCert.__name__) 
    143119 
    144120 
     
    172148        else: 
    173149            # key not recognised as a short or long name version 
    174             raise 'Key "' + key + '" not recognised for ' + AttrCert.__name__ 
     150            raise AttrCertError('Key "' + key + '" not recognised for ' + \ 
     151                                AttrCert.__name__) 
    175152 
    176153 
     
    189166            # key recognised - check if setting provenance 
    190167            if key is "provenance" and not self.isValidProvenance(item): 
    191                 raise "Provenance must be set to \"" + \ 
    192                     "\" or \"".join(AttrCert.__provenance) + "\"" 
     168                raise AttrCertError("Provenance must be set to \"" + \ 
     169                    "\" or \"".join(AttrCert.__provenance) + "\"") 
    193170             
    194171            self.__dat[key] = item 
     
    204181            # Prevent setting of notBefore/notAfter - restrict to method 
    205182            # setValidityTime 
    206             raise "Use setValidityTime method to set notBefore/notAfter times" 
     183            raise AttrCertError(\ 
     184                "Use setValidityTime method to set notBefore/notAfter times") 
    207185             
    208186        else: 
    209187            # key not recognised as a short or long name version 
    210             raise 'Key "' + key + '" not recognised for ' + AttrCert.__name__ 
     188            raise AttrCertError('Key "' + key + '" not recognised for ' + \ 
     189                                AttrCert.__name__) 
    211190         
    212191 
    213192    def clear(self): 
    214         raise "Data cannot be cleared from " + X500DN.__name__ 
     193        raise AttrCertError("Data cannot be cleared from " + X500DN.__name__) 
    215194 
    216195     
     
    326305 
    327306        if not self.isValidProvenance(provenance): 
    328             raise "Provenance must be set to \"" + \ 
    329                 "\" or \"".join(AttrCert.__provenance) + "\"" 
     307            raise AttrCertError("Provenance must be set to \"" + \ 
     308                "\" or \"".join(AttrCert.__provenance) + "\"") 
    330309         
    331310        self.__dat['provenance'] = provenance 
     
    377356        if filePath: 
    378357            if not isinstance(filePath, basestring): 
    379                 raise "Input file path must be a string." 
     358                raise AttrCertError("Input file path must be a string.") 
    380359        else: 
    381360            filePath = self.getFilePath() 
     
    390369         
    391370        if not acInfoElem: 
    392             raise "<acInfo> tag not found in \"" + filePath + "\"" 
     371            raise AttrCertError("<acInfo> tag not found in \""+filePath+"\"") 
    393372 
    394373 
     
    397376         
    398377            if not self.__dat.has_key(elem.tag): 
    399                 raise self.getFilePath() + "\": <" + elem.tag + \ 
    400                       "> not recognised." 
     378                raise AttrCertError(self.getFilePath() + "\": <" + \ 
     379                                    elem.tag + "> not recognised.") 
    401380 
    402381            # Make sure not to copy validity and attributes tags - handle these 
     
    406385 
    407386        # Convert issuer and holder into X500DN instances 
    408         self.__issuerDN = X500DN(dn=self.__dat['issuer']) 
    409         self.__holderDN = X500DN(dn=self.__dat['holder']) 
     387        try: 
     388            self.__issuerDN = X500DN(dn=self.__dat['issuer']) 
     389 
     390        except X500DNError, x500dnErr: 
     391            raise AttrCertError("Issuer DN: %s" % str(x500dnErr)) 
     392 
     393 
     394        try: 
     395            self.__holderDN = X500DN(dn=self.__dat['holder']) 
     396 
     397        except X500DNError, x500dnErr: 
     398            raise AttrCertError("Holder DN: %s" % str(x500dnErr)) 
    410399         
    411400                                  
     
    415404         
    416405        if self.__dat['validity']['notBefore'] is None: 
    417             raise "<notBefore> tag not found in \"%s\"" % filePath 
     406            raise AttrCertError("<notBefore> tag not found in \"%s\"" % \ 
     407                                filePath) 
    418408 
    419409        # Update datetime object equivalent 
     
    426416         
    427417        if self.__dat['validity']['notAfter'] is None: 
    428             raise "<notAfter> tag not found in \"%s\"" % filePath 
     418            raise AttrCertError("<notAfter> tag not found in \"%s\"" % \ 
     419                                filePath) 
    429420 
    430421 
     
    437428        roleElem = acInfoElem.findall("attributes/roleSet/role/name") 
    438429        if roleElem is None: 
    439             raise "<role> tag not found in \"" + filePath + "\"" 
     430            raise AttrCertError("<role> tag not found in \"" + filePath + \ 
     431                                "\"") 
    440432         
    441433        self.__dat['attributes']['roleSet'] = \ 
     
    444436         
    445437        if not self.isValidVersion():            
    446             raise 'Attribute Certificate version is ' + \ 
     438            raise AttrCertError('Attribute Certificate version is ' + \ 
    447439                  self.__dat['version'] + ' but version ' + \ 
    448                   AttrCert.__version + ' expected' 
     440                  AttrCert.__version + ' expected') 
    449441 
    450442 
    451443        # Call base class read method to initialise libxml2 objects for 
    452444        # signature validation 
    453         xmlSigDoc.read(self) 
     445        try: 
     446            xmlSigDoc.read(self) 
     447 
     448        except xmlSigDocError, xmlSigDocErr: 
     449            raise AttrCertError(str(xmlSigDocErr)) 
     450 
     451 
     452 
     453    def write(self, **xmlSigDocKeys): 
     454 
     455        """Write an Attribute Certificate.""" 
     456 
     457        # Method is a wrapper for xmlSigDoc.write to catch exceptions and 
     458        # convert to AttrCertError type 
     459        try: 
     460            xmlSigDoc.write(self, **xmlSigDocKeys) 
     461 
     462        except xmlSigDocError, xmlSigDocErr: 
     463            raise AttrCertError(str(xmlSigDocErr)) 
     464 
     465 
     466 
     467    def sign(self, **xmlSigDocKeys): 
     468 
     469        """Sign an Attribute Certificate.""" 
     470 
     471        # Method is a wrapper for xmlSigDoc.sign to catch exceptions and 
     472        # convert to AttrCertError type 
     473        try: 
     474            xmlSigDoc.sign(self, **xmlSigDocKeys) 
     475 
     476        except xmlSigDocError, xmlSigDocErr: 
     477            raise AttrCertError(str(xmlSigDocErr)) 
    454478 
    455479 
     
    470494        # Check for valid provenance 
    471495        if not self.isValidProvenance(): 
    472             raise "Provenance must be set to \"" + \ 
    473                 "\" or \"".join(AttrCert.__provenance) + "\"" 
     496            raise AttrCertError("Provenance must be set to \"" + \ 
     497                                "\" or \"".join(AttrCert.__provenance) + "\"") 
    474498 
    475499         
     
    520544        if dtNotBefore is not None: 
    521545            if not isinstance(dtNotBefore, datetime): 
    522                 raise "Input not before time must be datetime type" 
     546                raise AttrCertError(\ 
     547                    "Input not before time must be datetime type") 
    523548             
    524549            self.__dtNotBefore = dtNotBefore 
     
    537562            dtDeltaLifeTime = timedelta(0, self.__lifeTime) 
    538563        except: 
    539             raise "Invalid Certificate lifetime set %.3f" % self.__lifeTime 
     564            raise AttrCertError("Invalid Certificate lifetime set %.3f" % \ 
     565                                self.__lifeTime) 
    540566 
    541567         
     
    558584 
    559585        if not isinstance(dtVal, datetime): 
    560             raise "Invalid datetime object for conversion to string" 
     586            raise AttrCertError(\ 
     587                "Invalid datetime object for conversion to string") 
    561588         
    562589        # Convert from 1-12 to 0-11 month format used in XML file 
    563590        lDateTime = list(dtVal.utctimetuple()[0:6]) 
    564         lDateTime[1] -= 1 
     591 
     592        # Use 1-12 format 
     593        # P J Kershaw 09/05/05 
     594        #lDateTime[1] -= 1 
    565595 
    566596        # Format as a single string with no commas or brackets 
     
    577607        try: 
    578608            lTime = [int(i) for i in sTime.split()] 
    579             lTime[1] += 1 
     609             
     610            # Use 1-12 format 
     611            # P J Kershaw 09/05/05 
     612            #lTime[1] += 1 
    580613         
    581614            return datetime(lTime[0], lTime[1], lTime[2], 
    582615                            lTime[3], lTime[4], lTime[5]) 
    583616        except: 
    584             raise "Error converting time string into datetime object" 
     617            raise AttrCertError(\ 
     618                "Error converting time string into datetime object") 
    585619         
    586620 
     
    592626 
    593627        if not isinstance(self.__dtNotBefore, datetime): 
    594             raise "notBefore datetime is not set" 
     628            raise AttrCertError("notBefore datetime is not set") 
    595629 
    596630        if not isinstance(self.__dtNotAfter, datetime): 
    597             raise "notAfter datetime is not set" 
     631            raise AttrCertError("notAfter datetime is not set") 
    598632        
    599633        dtNow = datetime.utcnow() 
     
    611645 
    612646 
    613     def isValid(self, raiseExcep=False): 
     647    def isValid(self, raiseExcep=False, **xmlSigDocKeys): 
    614648 
    615649        """Check Attribute Certificate is valid: 
     
    620654        - Signature is valid. 
    621655 
    622         raiseExcep: set to true to raise an exception if invalid instead 
    623                     of returning False.  Default is to set this flag to False 
     656        raiseExcep:             set to true to raise an exception if invalid 
     657                                instead of returning False.  Default is to set 
     658                                this flag to False. 
     659 
     660        Also accepts keyword arguments corresponding to xmlSigDoc.isValidSig: 
     661         
     662        xmlTxt:                 string buffer containing the text from the XML 
     663                                file to be checked.  If omitted, the 
     664                                filePath argument is used instead. 
     665 
     666        filePath:            file path to XML file to be checked.  This 
     667                                argument is used if no xmlTxt was provided. 
     668                                If filePath itself is omitted the file set 
     669                                by self.__filePath is read instead. 
     670 
     671        trustedCertFilePath:    Certificate of trusted authority used to 
     672                                validate the signature.  If set, it is copied 
     673                                into self.__trustedCertFilePath.  If omitted 
     674                                self.__trustedCertFilePath is used unchanged.                              
    624675        """ 
    625676 
     
    651702 
    652703 
    653         if not self.isValidSig(): 
    654             if raiseExcep: 
    655                 raise AttrCertError(\ 
     704        # Handle exception from xmlSigDoc.isValidSig() regardless of 
     705        # raiseExcep flag setting 
     706        try:             
     707            if not self.isValidSig(**xmlSigDocKeys): 
     708                if raiseExcep: 
     709                    raise AttrCertError(\ 
    656710                                "Attribute Certificate signature is invalid") 
    657              
    658             return False 
    659  
     711                 
     712                return False 
     713         
     714        except xmlSigDocError, xmlSigDocErr: 
     715            raise AttrCertError(str(xmlSigDocErr)) 
     716         
    660717 
    661718        # All tests passed 
  • security/trunk/python/NDG/X509.py

    r407 r410  
    1 """X509 certificate handling class encapsulates M2Crypto.X509 
     1"""X.509 certificate handling class encapsulates M2Crypto.X509 
    22 
    33Nerc Data Grid Project 
     
    1717 
    1818 
     19 
     20 
     21class X509CertError(Exception): 
     22 
     23    """Exception handling for NDG X.509 Certificate handling class.""" 
     24     
     25    def __init__(self, msg): 
     26        self.msg = msg 
     27          
     28    def __str__(self): 
     29        return self.__msg 
     30 
     31 
     32 
     33 
    1934class X509Cert: 
    2035 
     
    2742 
    2843            if not isinstance(filePath, basestring): 
    29                 raise "Certificate File Path input must be a valid string" 
     44                raise X509CertError(\ 
     45                    "Certificate File Path input must be a valid string") 
    3046             
    3147        self.__filePath = filePath 
     
    3955 
    4056            if not isinstance(filePath, basestring): 
    41                 raise "Certificate File Path input must be a valid string" 
     57                raise X509CertError(\ 
     58                    "Certificate File Path input must be a valid string") 
    4259             
    4360            self.__filePath = filePath 
     
    4663            self.__m2CryptoX509 = M2Crypto.X509.load_cert(self.__filePath) 
    4764        except: 
    48             raise "Error loading certificate \"" + self.__filePath + "\"" 
     65            raise X509CertError(\ 
     66                "Error loading certificate \"" + self.__filePath + "\"") 
    4967 
    5068        # Get distinguished name 
     
    6179        """Get X500 Distinguished Name.""" 
    6280        return self.__dn 
     81 
     82 
     83 
     84 
     85class X500DNError(Exception): 
     86 
     87    """Exception handling for NDG X.500 DN class.""" 
     88     
     89    def __init__(self, msg): 
     90        self.__msg = msg 
     91          
     92    def __str__(self): 
     93        return self.__msg 
    6394 
    6495 
     
    116147        if separator is not None: 
    117148            if not isinstance(separator, basestring): 
    118                 raise "dn Separator must be a valid string" 
     149                raise X500DNError("dn Separator must be a valid string") 
    119150 
    120151            # Check for single character but allow trailing space chars 
    121152            if len(separator.lstrip()) is not 1: 
    122                 raise "dn separator must be a single character" 
     153                raise X500DNError("dn separator must be a single character") 
    123154 
    124155            self.__separator = separator 
     
    168199 
    169200        return self.__dat.items() == x500dn.items() 
     201 
     202 
     203 
     204         
     205    def __cmp__(self, x500dn): 
     206 
     207        """Return true if the all the fields of the two DNs are equal""" 
     208         
     209        if not isinstance(x500dn, X500DN): 
     210            return False 
     211 
     212        return cmp(self.__dat, x500dn.get()) 
    170213     
    171214 
     
    174217    def __delitem__(self, key): 
    175218         
    176         raise 'Keys cannot be deleted from the X500DN' 
     219        raise X500DNError('Keys cannot be deleted from the X500DN') 
    177220 
    178221 
     
    196239        else: 
    197240            # key not recognised as a short or long name version 
    198             raise 'Key "' + key + '" not recognised for X500DN' 
     241            raise X500DNError('Key "' + key + '" not recognised for X500DN') 
    199242 
    200243 
     
    218261        else: 
    219262            # key not recognised as a short or long name version 
    220             raise 'Key "' + key + '" not recognised for X500DN' 
     263            raise X500DNError('Key "' + key + '" not recognised for X500DN') 
    221264 
    222265 
     
    224267 
    225268    def clear(self): 
    226         raise "Data cannot be cleared from " + X500DN.__name__ 
     269        raise X500DNError("Data cannot be cleared from " + X500DN.__name__) 
    227270 
    228271     
     
    250293 
    251294 
     295 
     296    def get(self): 
     297        """Get Distinguished name as a data dictionary.""" 
     298        return self.__dat 
     299 
     300 
     301 
    252302     
    253303    def serialise(self, separator=None): 
     
    257307        if separator: 
    258308            if not isinstance(separator, basestring): 
    259                 raise "Separator must be a valid string" 
     309                raise X500DNError("Separator must be a valid string") 
    260310                 
    261311            self.__separator = separator 
     
    275325        if separator: 
    276326            if not isinstance(separator, basestring): 
    277                 raise "Separator must be a valid string" 
     327                raise X500DNError("Separator must be a valid string") 
    278328 
    279329            self.__separator = separator 
     
    282332        dnFields = dn.split(self.__separator) 
    283333        if len(dnFields) < 2: 
    284             raise "Error parsing DN string: \"%s\"" % dn 
     334            raise X500DNError("Error parsing DN string: \"%s\"" % dn) 
    285335 
    286336         
     
    288338        keyVals = [field.split('=') for field in dnFields] 
    289339 
     340        # Reset existing dictionary values 
     341        self.__dat.fromkeys(self.__dat, '') 
     342         
    290343        # Strip leading and trailing space chars and convert into a dictionary 
    291         self.__dat = dict([(keyVal[0].strip(), keyVal[1].strip()) \ 
    292                            for keyVal in keyVals]) 
     344        self.__dat.update(dict([(keyVal[0].strip(), keyVal[1].strip()) \ 
     345                          for keyVal in keyVals])) 
    293346  
     347 
     348    def parseSeparator(self, dn): 
     349 
     350        """Attempt to parse the separator character from a given input 
     351        DN string.  If not found, return None 
     352 
     353        DNs don't use standard separators e.g. 
     354 
     355        /C=UK/O=eScience/OU=CLRC/L=DL/CN=AN Other 
     356        CN=SUM Oneelse,L=Didcot, O=RAL,OU=SSTD 
     357 
     358        This function isolates and identifies the character.  - In the above, 
     359        '/' and ',' respectively""" 
     360 
     361 
     362        # Make a match string containing all the possible field identifiers 
     363        # with equal sign appended and 'or'ed together.  \W should match the 
     364        # separator which preceeds the field name. \s* allows any whitespace 
     365        # between field name and field separator to be taken into account 
     366        # 
     367        # The resulting match should be a list.  The first character in each 
     368        # element in the list should be the field separator and should be the 
     369        # same 
     370        reMatch = '|'.join(['\W\s*'+i+'=' for i in self.__dat.keys()]) 
     371 
     372        # In the first example above, the resulting match is: 
     373        # ['/C=', '/O=', '/OU=', '/L='] 
     374        # In each element the first character is the separator - check: 
     375        sepList = [i[0:1] for i in reMatch] 
     376        if sepList == sepList.sort(): 
     377            return sepList[0] 
     378        else: 
     379            return None 
  • security/trunk/python/NDG/XMLSecDoc.py

    r407 r410  
    2424# XML signature module 
    2525import xmlsec 
     26 
     27 
     28 
     29 
     30class xmlSigDocError(Exception): 
     31 
     32    """Exception handling for NDG XML Signature class.""" 
     33     
     34    def __init__(self, msg): 
     35        self.__msg = msg 
     36          
     37    def __str__(self): 
     38        return self.__msg 
     39 
     40 
    2641 
    2742 
     
    5065 
    5166            if not isinstance(filePath, basestring): 
    52                 raise "Input key file path is %s" % type(filePath) + \ 
    53                       ": string type expected" 
     67                raise xmlSigDocError("Input key file path is %s" % \ 
     68                                     type(filePath) + ": string type expected") 
    5469 
    5570            self.__filePath = filePath 
     
    6075 
    6176            if not isinstance(signingKeyFilePath, basestring): 
    62                 raise "Input key file path is %s" % type(issuer) + \ 
    63                       ": string type expected" 
     77                raise xmlSigDocError("Input key file path is %s" % \ 
     78                                     type(issuer) + ": string type expected") 
    6479             
    6580            self.__signingKeyFilePath = signingKeyFilePath 
     
    7085 
    7186            if not isinstance(signingCertFilePath, basestring): 
    72                 raise "Input certificate file path is %s" % type(issuer) + \ 
    73                       ": string type expected" 
     87                raise xmlSigDocError("Input certificate file path is %s" % \ 
     88                                     type(issuer) + ": string type expected") 
    7489 
    7590            self.__signingCertFilePath = signingCertFilePath 
     
    7994 
    8095            if not isinstance(trustedCertFilePath, basestring): 
    81                 raise "Input trusted certificate file path is %s" % \ 
    82                       type(issuer) + ": string type expected" 
     96                raise xmlSigDocError(\ 
     97                    "Input trusted certificate file path is %s" % \ 
     98                    type(issuer) + ": string type expected") 
    8399 
    84100            self.__trustedCertFilePath = trustedCertFilePath 
     
    107123        # Init xmlsec library 
    108124        if xmlsec.init() < 0: 
    109             raise "xmlsec initialization failed." 
     125            raise xmlSigDocError("xmlsec initialization failed.") 
    110126 
    111127         
    112128        # Check loaded library version 
    113129        if xmlsec.checkVersion() != 1: 
    114             raise "xmlsec library version is not compatible.\n" 
     130            raise xmlSigDocError("xmlsec library version is not compatible.") 
    115131 
    116132 
    117133        # Init crypto library 
    118134        if xmlsec.cryptoAppInit(None) < 0: 
    119             raise "Crypto initialization failed." 
     135            raise xmlSigDocError("Crypto initialization failed.") 
    120136 
    121137         
    122138        # Init xmlsec-crypto library 
    123139        if xmlsec.cryptoInit() < 0: 
    124             raise "xmlsec-crypto initialization failed." 
     140            raise xmlSigDocError("xmlsec-crypto initialization failed.") 
    125141 
    126142         
     
    160176        if self.__libxml2Doc is None or \ 
    161177           self.__libxml2Doc.getRootElement() is None: 
    162             raise "Error parsing Attribute Certificate" 
     178            raise xmlSigDocError("Error parsing Attribute Certificate") 
    163179             
    164180        self.__bLibxml2DocFreed = False 
     
    181197        if self.__libxml2Doc is None or \ 
    182198           self.__libxml2Doc.getRootElement() is None: 
    183             raise "Error parsing Attribute Certificate \"%s\"" % \ 
    184                   self.__filePath 
     199            raise xmlSigDocError(\ 
     200                "Error parsing Attribute Certificate \"%s\"" % self.__filePath) 
    185201             
    186202        self.__bLibxml2DocFreed = False 
     
    196212 
    197213        if self.__libxml2Doc is None: 
    198             raise "self.__libxml2ParseDoc() must be called first" 
     214            raise xmlSigDocError(\ 
     215                "self.__libxml2ParseDoc() must be called first") 
    199216         
    200217        if self.__libxml2Ctxt is not None and not self.__bLibxml2CtxtFreed: 
     
    204221        self.__libxml2Ctxt = self.__libxml2Doc.xpathNewContext() 
    205222        if self.__libxml2Ctxt is None: 
    206             raise "Error creating XPath context for \"%s\"" % \ 
    207                   self.__filePath 
     223            raise xmlSigDocError("Error creating XPath context for \"%s\"" % \ 
     224                                  self.__filePath) 
    208225 
    209226        self.__bLibxml2CtxtFreed = False 
     
    224241        self.__dSigCtxt = xmlsec.DSigCtx(keysMngr) 
    225242        if self.__dSigCtxt is None: 
    226             raise "Error creating signature context" 
     243            raise xmlSigDocError("Error creating signature context") 
    227244 
    228245        self.__bDSigCtxtFreed = False 
     
    243260        self.__keysMngr = xmlsec.KeysMngr() 
    244261        if self.__keysMngr is None: 
    245             raise "Failed to create keys manager." 
     262            raise xmlSigDocError("Failed to create keys manager.") 
    246263 
    247264        self.__bkeysMngrFreed = False 
     
    292309 
    293310 
    294     def write(self, filePath=None, bSign=True, xmlTxt=None, **signKeys): 
     311    def write(self, filePath=None, bSign=False, xmlTxt=None, **signKeys): 
    295312 
    296313        """Write XML document applying digital signature 
     
    298315        filePath:               file path for XML output 
    299316                             
    300         bSign:                  flag defaults to True to sign the new 
    301                                 certificate using the private key and 
    302                                 certificate to sign the certificate. 
    303                                 Set to False to NOT sign the document. 
     317        bSign:                  flag defaults to False to NOT sign the 
     318                                document.  Explicitly set to True to sign 
     319                                the new certificate using the private key 
     320                                and certificate. 
    304321 
    305322        xmlTxt:                 string containing formatted xml text for 
     
    322339        if filePath is not None: 
    323340            if not isinstance(filePath, basestring): 
    324                 raise "Input file path must be a valid string." 
     341                raise xmlSigDocError("Input file path must be a valid string") 
    325342             
    326343            self.__filePath = filePath 
     
    357374        """Set file path for file to be signed.""" 
    358375         
    359         try: 
    360             if not isinstance(filePath, basestring): 
    361                 raise 
    362         except: 
    363             raise "File path must be a valid string" 
     376        if filePath is None or not isinstance(filePath, basestring): 
     377             
     378            raise xmlSigDocError("File path must be a valid string") 
    364379         
    365380        self.__filePath = filePath 
     
    373388        Create text for output and return as a string""" 
    374389         
    375         raise "Virtual function: Derived class should implement." 
     390        raise xmlSigDocError(\ 
     391                    "Virtual function: Derived class should implement.") 
    376392 
    377393        return None 
     
    410426        # Attribute Authority server's private key file 
    411427        if signingKeyFilePath is not None: 
    412  
    413             if not isinstance(signingKeyFilePath, basestring): 
    414                 raise "Input key file path is %s" % type(issuer) + \ 
    415                       ": string type expected" 
    416              
    417             self.__signingKeyFilePath = signingKeyFilePath 
     428            self.__signingKeyFilePath = signingKeyFilePath             
    418429 
    419430 
    420431        # Attribute Authority server's RSA certificate file  
    421432        if signingCertFilePath is not None: 
    422  
    423             if not isinstance(signingCertFilePath, basestring): 
    424                 raise "Input certificate file path is %s" % type(issuer) + \ 
    425                       ": string type expected" 
    426  
    427433            self.__signingCertFilePath = signingCertFilePath 
    428434 
    429435 
    430         # Check for read access 
    431         if not os.access(self.__signingKeyFilePath, os.R_OK): 
    432             raise "Private key file \"%s\" not found or no read access" % \ 
    433                 self.__signingKeyFilePath 
    434  
    435  
    436         if not os.access(self.__signingCertFilePath, os.R_OK): 
    437             raise "Certificate file \"%s\" not found or no read access" % \ 
    438                 self.__signingCertFilePath 
     436        # Check files for read access 
     437        try: 
     438            if not os.access(self.__signingKeyFilePath, os.R_OK): 
     439                raise xmlSigDocError(\ 
     440                    "Private key file \"%s\" not found or no read access" % \ 
     441                    self.__signingKeyFilePath) 
     442        except: 
     443            raise xmlSigDocError("Signing Certificate file path is not valid") 
     444 
     445         
     446        try: 
     447            if not os.access(self.__signingCertFilePath, os.R_OK): 
     448                raise xmlSigDocError(\ 
     449                    "Certificate file \"%s\" not found or no read access" % \ 
     450                    self.__signingCertFilePath) 
     451        except: 
     452            raise xmlSigDocError("Private key file path is not a valid") 
    439453 
    440454 
     
    449463                                       None) 
    450464        if sigNode is None: 
    451             raise "Error creating signature template" 
     465            raise xmlSigDocError("Error creating signature template") 
    452466 
    453467         
     
    460474                                       None, None, None) 
    461475        if refNode is None: 
    462             raise "Error adding reference to signature template" 
     476            raise xmlSigDocError( 
     477                "Error adding reference to signature template") 
    463478 
    464479 
    465480        # Add enveloped transform 
    466481        if refNode.addTransform(xmlsec.transformEnvelopedId()) is None: 
    467             raise "Error adding enveloped transform to reference" 
     482            raise xmlSigDocError(\ 
     483                "Error adding enveloped transform to reference") 
    468484 
    469485  
     
    471487        keyInfoNode = sigNode.ensureKeyInfo(None) 
    472488        if keyInfoNode is None: 
    473             raise "Error adding key info" 
     489            raise xmlSigDocError("Error adding key info") 
    474490 
    475491         
    476492        if keyInfoNode.addX509Data() is None: 
    477             raise "Error adding X509Data node" 
     493            raise xmlSigDocError("Error adding X509Data node") 
    478494 
    479495 
     
    489505                                                    None, None) 
    490506        if self.__dSigCtxt.signKey is None: 
    491             raise "Error loading private pem key from \"%s\"" % \ 
    492                   self.__signingKeyFilePath 
     507            raise xmlSigDocError(\ 
     508                "Error loading private pem key from \"%s\"" % \ 
     509                self.__signingKeyFilePath) 
    493510 
    494511 
     
    497514                                       self.__signingCertFilePath, 
    498515                                       xmlsec.KeyDataFormatPem) < 0: 
    499             raise "Error loading pem certificate \"%s\"" % \ 
    500                   self.__signingCertFilePath 
     516            raise xmlSigDocError("Error loading pem certificate \"%s\"" % \ 
     517                                  self.__signingCertFilePath) 
    501518 
    502519 
    503520        # Set key name to the file name 
    504521        if self.__dSigCtxt.signKey.setName(self.__signingKeyFilePath) < 0: 
    505             raise "Error setting key name for key from \"%s\"" % \ 
    506                   self.__signingKeyFilePath 
     522            raise xmlSigDocError(\ 
     523                "Error setting key name for key from \"%s\"" % \ 
     524                  self.__signingKeyFilePath) 
    507525 
    508526 
    509527        # Sign the template 
    510528        if self.__dSigCtxt.sign(sigNode) < 0: 
    511             raise "Signature failed" 
     529            raise xmlSigDocError("Signature failed") 
    512530 
    513531 
     
    527545                                filePath argument is used instead. 
    528546 
    529         filePath:            file path to XML file to be checked.  This 
     547        filePath:               file path to XML file to be checked.  This 
    530548                                argument is used if no xmlTxt was provided. 
    531549                                If filePath itself is omitted the file set 
     
    538556                                """ 
    539557         
    540         #if xmlTxt is None:            
    541         #    xmlTxt = self.createXML() 
    542  
    543558 
    544559        if trustedCertFilePath is not None: 
    545  
    546             if not isinstance(trustedCertFilePath, basestring): 
    547                 raise "Input trusted certificate file path is %s" % \ 
    548                       type(issuer) + ": string type expected" 
    549  
    550560            self.__trustedCertFilePath = trustedCertFilePath 
    551561 
    552  
    553         # Check Certificate for read access 
    554         if not os.access(self.__trustedCertFilePath, os.R_OK): 
    555             raise "Trusted Certificate file \"" + \ 
    556                   self.__trustedCertFilePath + \ 
    557                   "\" not found or no read access" 
    558  
     562         
     563        # Check Certificate file for read access 
     564        try: 
     565            if not os.access(self.__trustedCertFilePath, os.R_OK): 
     566                raise xmlSigDocError("Trusted Certificate file \"" + \ 
     567                      self.__trustedCertFilePath + \ 
     568                      "\" not found or no read access") 
     569        except: 
     570            raise xmlSigDocError("Trusted certificate file path is not valid") 
     571             
    559572 
    560573        # Create and initialize keys manager 
     
    562575 
    563576        if xmlsec.cryptoAppDefaultKeysMngrInit(self.__keysMngr) < 0: 
    564             raise "Failed to initialize keys manager." 
     577            raise xmlSigDocError("Failed to initialize keys manager.") 
    565578 
    566579         
     
    569582                                    xmlsec.KeyDataFormatPem, 
    570583                                    xmlsec.KeyDataTypeTrusted) < 0: 
    571             raise "Error loading pem certificate from \"%s\"" % \ 
    572                   self.__trustedCertFilePath 
    573  
    574  
    575         # If xml text was input update libxml2 doc instance with it's content 
     584            raise xmlSigDocError(\ 
     585                "Error loading pem certificate from \"%s\"" % \ 
     586                self.__trustedCertFilePath) 
     587 
     588 
     589        # If 'xmlTxt' was input update libxml2 doc instance with it's content 
    576590        if xmlTxt is not None: self.__libxml2ParseDoc(xmlTxt) 
    577591         
     
    581595                                   xmlsec.NodeSignature, xmlsec.DSigNs) 
    582596        if dSigNode is None: 
    583             raise "Start node not found in \"%s\"" % self.__filePath 
     597            raise xmlSigDocError(\ 
     598                "Start node not found in \"%s\"" % self.__filePath) 
    584599 
    585600  
     
    590605        # Verify signature 
    591606        if self.__dSigCtxt.verify(dSigNode) < 0: 
    592             raise "Error verifying signature." 
     607            raise xmlSigDocError("Error verifying signature.") 
    593608 
    594609 
Note: See TracChangeset for help on using the changeset viewer.