Ignore:
Timestamp:
20/08/08 14:03:20 (11 years ago)
Author:
cbyrom
Message:

General refactoring and updating of code, including:

Removal of refC14nKw and singnedInfoC14nKw keywords in wsssecurity session manager config
(the refC14nInclNS and signedInfoC14nInclNS keywords are sufficient);
Creation of new DOM signature handler class, dom.py, based on the wsSecurity
class;
Abstraction of common code between dom.py and etree.py into new parent
class, BaseSignatureHandler?.py.
Fixing and extending use of properties in the SignatureHandler? code.
Fixing a few bugs with the original SignatureHandler? code.
Updating of test cases to new code/code structure.

File:
1 edited

Legend:

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

    r4081 r4129  
    1010License, version 1.0 or later.""" 
    1111__contact__ = "P.J.Kershaw@rl.ac.uk" 
    12 __revision__ = '$Id: wsSecurity.py 3790 2008-04-17 12:46:30Z pjkersha $' 
    13  
     12__revision__ = '$Id:  $' 
     13 
     14from BaseSignatureHandler import _WSU, OASIS, BaseSignatureHandler 
    1415import re 
    1516 
     
    4142 
    4243import ZSI 
    43 from ZSI.wstools.Namespaces import DSIG, ENCRYPTION, WSU, WSA200403, \ 
     44from ZSI.wstools.Namespaces import DSIG, WSA200403, \ 
    4445                                   SOAP, SCHEMA # last included for xsi 
    45                                     
    46 from ZSI.wstools.Namespaces import WSU as _WSU 
    47 from ZSI.wstools.Namespaces import OASIS as _OASIS 
    48                                    
     46 
    4947from ZSI.TC import ElementDeclaration,TypeDefinition 
    5048from ZSI.generate.pyclass import pyclass_type 
     
    7371log = logging.getLogger(__name__) 
    7472 
    75  
    76 class _ENCRYPTION(ENCRYPTION): 
    77     '''Derived from ENCRYPTION class to add in extra 'tripledes-cbc' - is this 
    78     any different to 'des-cbc'?  ENCRYPTION class implies that it is the same 
    79     because it's assigned to 'BLOCK_3DES' ??''' 
    80     BLOCK_TRIPLEDES = "http://www.w3.org/2001/04/xmlenc#tripledes-cbc" 
    81  
    82 class WSU(_WSU): 
    83     '''Try different utility namespace for use with WebSphere''' 
    84     #UTILITY = "http://schemas.xmlsoap.org/ws/2003/06/utility" 
    85     UTILITY = \ 
    86 "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
    87  
    88 class OASIS(_OASIS): 
    89     # wss4j 1.5.3 
    90     WSSE11 = \ 
    91     "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" 
    92     # wss4j 1.5.1 
    93     #WSSE11 = "http://docs.oasis-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity-secext-1.1.xsd" 
    94         
    95 def getElements(node, nameList): 
    96     '''DOM Helper function for getting child elements from a given node''' 
    97     # Avoid sub-string matches 
    98     nameList = isinstance(nameList, basestring) and [nameList] or nameList 
    99     return [n for n in node.childNodes if str(n.localName) in nameList] 
    100  
    101  
    102 def getChildNodes(node, nodeList=None): 
    103     if nodeList is None: 
    104         nodeList = [node]  
    105     return _getChildNodes(node, nodeList) 
    106             
    107 def _getChildNodes(node, nodeList): 
    108  
    109     if node.attributes is not None: 
    110         nodeList += node.attributes.values()  
    111     nodeList += node.childNodes 
    112     for childNode in node.childNodes: 
    113         _getChildNodes(childNode, nodeList) 
    114     return nodeList 
    115  
    116  
    117 class WSSecurityError(Exception): 
    118     """For WS-Security generic exceptions not covered by other exception 
    119     classes in this module""" 
    120  
    121 class InvalidCertChain(WSSecurityError):     
    122     """Raised from SignatureHandler.verify if the certificate submitted to 
    123     verify a signature is not from a known CA""" 
    124      
    125 class VerifyError(WSSecurityError): 
    126     """Raised from SignatureHandler.verify if an error occurs in the signature 
    127     verification""" 
    128  
    129 class NoSignatureFound(WSSecurityError):  
    130     """Incoming message to be verified was not signed""" 
    131      
    132 class TimestampError(WSSecurityError): 
    133     """Raised from SignatureHandler._verifyTimestamp if there is a problem with 
    134     the created or expiry times in an input message Timestamp""" 
    135      
    136 class InvalidSignature(WSSecurityError): 
    137     """Raised from verify method for an invalid signature""" 
    138  
    139 class SignatureError(WSSecurityError): 
    140     """Flag if an error occurs during signature generation""" 
    141          
    142 class SignatureHandler(object): 
     73class SignatureHandler(BaseSignatureHandler): 
    14374    """Class to handle signature and verification of signature with  
    14475    WS-Security 
    145      
    146     @cvar binSecTokValType: supported ValueTypes for BinarySecurityToken 
    147     element in WSSE header 
    148     @type binSecTokValType: dict 
    149      
    150     @ivar addTimestamp: set to true to add a timestamp to outbound messages 
    151     @type addTimestamp: bool  
    152  
    153     @ivar applySignatureConfirmation: for servers - set this flag to enable the  
    154     signature value of a request to be recorded and included with a  
    155     SignatureConfirmation element in the response. 
    156     @type applySignatureConfirmation: bool 
    157      
    158     @param b64EncSignatureValue: base 64 encoded signature value for the last  
    159     message verified 
    160     @type b64EncSignatureValue: string/None""" 
    161  
    162      
    163     binSecTokValType = { 
    164         "X509PKIPathv1": OASIS.X509TOKEN.X509PKIPathv1, 
    165         "X509":          OASIS.X509TOKEN.X509, 
    166         "X509v3":        OASIS.X509TOKEN.X509+"v3" 
    167     } 
    168  
    169     binSecTokEncType = \ 
     76    """ 
     77 
     78    _binSecTokEncType = \ 
    17079"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" 
    17180 
     
    17483    { 
    17584        'ds':       DSIG.BASE,  
    176         'wsu':      WSU.UTILITY,  
     85        'wsu':      _WSU.UTILITY,  
    17786        'wsse':     OASIS.WSSE,  
    17887        'SOAP-ENV': SOAP.ENV  
    179 #        'soapenv':  SOAP.ENV 
    18088    } 
    18189 
    182  
    183     #_________________________________________________________________________ 
    184     def __init__(self, cfgFilePath=None, cfgFileSection='DEFAULT', 
    185                  cfgClass=WSSecurityConfig, **kw): 
    186         ''' 
    187         @reqBinSecTokValType: set the ValueType for the BinarySecurityToken 
    188         added to the WSSE header for a signed message.  See  
    189         __setReqBinSecTokValType method and binSecTokValType class variable 
    190         for options.  binSecTokValType determines whether signingCert or 
    191         signingCertChain attributes will be used.         
    192         @type binSecTokValType: string 
    193          
    194         @param verifyingCert: X.509 certificate used by verify method to 
    195         verify a message.  This argument can be omitted if the message to 
    196         be verified contains the X.509 certificate in the  
    197         BinarySecurityToken element.  In this case, the cert read from the 
    198         message will be assigned to the verifyingCert attribute. 
    199         @type verifyingCert: M2Crypto.X509.X509 /  
    200         ndg.security.common.X509.X509Cert 
    201          
    202         @param verifyingCertFilePath: alternative input to the above, pass  
    203         the file path to the certificate stored in a file 
    204         @type verifyingCertFilePath: string 
    205          
    206         @param signingCert: certificate associated with private key used to 
    207         sign a message.  The sign method will add this to the  
    208         BinarySecurityToken element of the WSSE header.  binSecTokValType 
    209         attribute must be set to 'X509' or 'X509v3' ValueTyep.  As an  
    210         alternative, use signingCertChain - see below... 
    211         @type signingCert: M2Crypto.X509.X509 /  
    212         ndg.security.common.X509.X509Cert 
    213          
    214         @param signingCertFilePath: alternative input to the above, pass  
    215         the file path to the certificate stored in a file 
    216         @type signingCertFilePath: string 
    217          
    218         @param signingCertChain: pass a list of certificates constituting a  
    219         chain of trust from the certificate used to verifying the signature  
    220         backward to the CA cert.  The CA cert need not be included.  To use  
    221         this option, reqBinSecTokValType must be set to the 'X509PKIPathv1' 
    222         ValueType 
    223         @type signingCertChain: list or tuple  
    224          
    225         @param signingPriKey: private key used to be sign method to sign 
    226         message 
    227         @type signingPriKey: M2Crypto.RSA. 
    228          
    229         @param signingPriKeyFilePath: equivalent to the above but pass  
    230         private key from PEM file 
    231         @type signingPriKeyFilePath: string 
    232          
    233         @param signingPriKeyPwd: password protecting private key.  Set / 
    234         default to None if there is no password. 
    235         @type signingPriKeyPwd: string or None 
    236          
    237         @param caCertDirPath: establish trust for signature verification.  
    238         This is a directory containing CA certificates.  These are used to 
    239         verify the certificate used to verify the message signature. 
    240         @type caCertDirPath: string 
    241          
    242         @param caCertFilePathList: same as above except pass in a list of 
    243         file paths instead of a single directory name. 
    244         @type caCertFilePathList: list or tuple 
    245          
    246         @param addTimestamp: set to true to add a timestamp to outbound  
    247         messages 
    248         @type addTimestamp: bool  
    249          
    250         @param : for servers - set this flag to enable the signature value of a 
    251         request to be recorded and included with a SignatureConfirmation  
    252         element in the response. 
    253         @type : bool  
    254          
    255         @param refC14nKw: dictionary of keywords to reference  
    256         Canonicalization.  Use 'inclusive_namespaces' keyword to set  
    257         inclusive_namespaces. 
    258         @type refC14nKw: dict 
    259          
    260         @param signedInfoC14nKw: keywords to Signed Info Canonicalization. 
    261         It uses the same format as refC14nKw above. 
    262         @type signedInfoC14nKw: dict 
    263         ''' 
    264         log.debug("SignatureHandler.__init__ ...") 
    265          
    266         # WSSecurityConfig is the default class for reading config params but 
    267         # alternative derivative class may be passed in instead. 
    268         if not issubclass(cfgClass, WSSecurityConfig): 
    269             raise TypeError("%s is not a sub-class of WSSecurityConfig" % \ 
    270                             cfgClass) 
    271         self.cfg = cfgClass() 
    272          
    273         # Read parameters from config file if set 
    274         if cfgFilePath: 
    275             log.debug("SignatureHandler.__init__: Processing config file...") 
    276             self.cfg.read(cfgFilePath) 
    277             self.cfg.parse(section=cfgFileSection) 
    278          
    279         # Also update config from keywords set  
    280         log.debug("SignatureHandler.__init__: setting config from keywords...") 
    281         self.cfg.update(kw) 
    282          
    283          
    284         self.__setReqBinSecTokValType(self.cfg['reqBinSecTokValType']) 
    285          
    286         # Set keywords for canonicalization of SignedInfo and reference  
    287         # elements 
    288         # TODO: get rid of refC14nKw and signedInfoC14nKw options 
    289         if len(self.cfg.get('refC14nInclNS', [])): 
    290             self.__setRefC14nKw({'inclusive_namespaces': 
    291                                  self.cfg['refC14nInclNS']}) 
    292         else: 
    293             self.__setRefC14nKw(self.cfg['refC14nKw']) 
    294  
    295     
    296         if len(self.cfg.get('signedInfoC14nNS', [])): 
    297             self.__setSignedInfoC14nKw({'inclusive_namespaces': 
    298                                         self.cfg['signedInfoC14nNS']}) 
    299         else: 
    300             self.__setSignedInfoC14nKw(self.cfg['signedInfoC14nKw']) 
    301              
    302  
    303         self.__setVerifyingCert(self.cfg['verifyingCert']) 
    304         self.__setVerifyingCertFilePath(self.cfg['verifyingCertFilePath']) 
    305          
    306         self.__setSigningCert(self.cfg['signingCert']) 
    307         self.__setSigningCertFilePath(self.cfg['signingCertFilePath']) 
    308  
    309         if self.cfg.get('signingCertChain'): 
    310             self.__setSigningCertChain(self.cfg['signingCertChain']) 
    311         else: 
    312             self.__signingCertChain = None    
    313               
    314         # MUST be set before __setSigningPriKeyFilePath / __setSigningPriKey 
    315         # are called 
    316         self.__setSigningPriKeyPwd(self.cfg['signingPriKeyPwd']) 
    317          
    318         if self.cfg.get('signingPriKey'): 
    319             # Don't allow None for private key setting 
    320             self.__setSigningPriKey(self.cfg['signingPriKey']) 
    321              
    322         self.__setSigningPriKeyFilePath(self.cfg['signingPriKeyFilePath']) 
    323          
    324         # CA certificate(s) for verification of X.509 certificate used with 
    325         # signature. 
    326         if self.cfg.get('caCertDirPath'): 
    327             self.caCertDirPath = self.cfg['caCertDirPath'] 
    328              
    329         elif self.cfg.get('caCertFilePathList'): 
    330             self.caCertFilePathList = self.cfg['caCertFilePathList'] 
    331              
    332         self.addTimestamp = self.cfg['addTimestamp'] 
    333         self.applySignatureConfirmation=self.cfg['applySignatureConfirmation'] 
    334         self.b64EncSignatureValue = None 
    335          
    336         log.debug("WSSE Config = %s" % self.cfg) 
    337  
    338                  
    339     #_________________________________________________________________________ 
    340     def __setReqBinSecTokValType(self, value): 
    341         """Set ValueType attribute for BinarySecurityToken used in a request 
    342           
    343         @type value: string 
    344         @param value: name space for BinarySecurityToken ValueType check 
    345         'binSecTokValType' class variable for supported types.  Input can be  
    346         shortened to binSecTokValType keyword if desired. 
    347         """ 
    348          
    349         if value in self.__class__.binSecTokValType: 
    350             self.__reqBinSecTokValType = self.__class__.binSecTokValType[value] 
    351   
    352         elif value in self.__class__.binSecTokValType.values(): 
    353             self.__reqBinSecTokValType = value 
    354         else: 
    355             raise WSSecurityError, \ 
    356                 'Request BinarySecurityToken ValueType "%s" not recognised' %\ 
    357                 value 
    358              
    359          
    360     reqBinSecTokValType = property(fset=__setReqBinSecTokValType, 
    361          doc="ValueType attribute for BinarySecurityToken used in request") 
    362          
    363  
    364     #_________________________________________________________________________ 
    365     def __checkC14nKw(self, kw): 
    366         """Check keywords for canonicalization in signing process - generic 
    367         method for setting keywords for reference element and SignedInfo 
    368         element c14n 
    369          
    370         @type kw: dict 
    371         @param kw: keyword used with ZSI.wstools.Utility.Canonicalization""" 
    372          
    373         # Check for dict/None - Set to None in order to use inclusive  
    374         # canonicalization 
    375         if kw is not None and not isinstance(kw, dict): 
    376             # Otherwise keywords must be a dictionary 
    377             raise AttributeError, \ 
    378                 "Expecting dictionary type for reference c14n keywords" 
    379                  
    380         elif kw.get('inclusive_namespaces') and \ 
    381              not isinstance(kw['inclusive_namespaces'], list) and \ 
    382              not isinstance(kw['inclusive_namespaces'], tuple): 
    383             raise AttributeError, \ 
    384                 'Expecting list or tuple of prefix names for "%s" keyword' % \ 
    385                 'inclusive_namespaces' 
    386          
    387                  
    388     #_________________________________________________________________________ 
    389     def __setRefC14nKw(self, kw): 
    390         """Set keywords for canonicalization of reference elements in the  
    391         signing process""" 
    392         self.__checkC14nKw(kw)                     
    393         self.__refC14nKw = kw 
    394          
    395     refC14nKw = property(fset=__setRefC14nKw, 
    396                          doc="Keywords for c14n of reference elements") 
    397          
    398                  
    399     #_________________________________________________________________________ 
    400     def __setSignedInfoC14nKw(self, kw): 
    401         """Set keywords for canonicalization of SignedInfo element in the  
    402         signing process""" 
    403         self.__checkC14nKw(kw)                     
    404         self.__signedInfoC14nKw = kw 
    405          
    406     signedInfoC14nKw = property(fset=__setSignedInfoC14nKw, 
    407                                 doc="Keywords for c14n of SignedInfo element") 
    408  
    409  
    410     #_________________________________________________________________________ 
    411     def __refC14nIsExcl(self): 
    412         return isinstance(self.__refC14nKw, dict) and \ 
    413                isinstance(self.__refC14nKw.get('inclusive_namespaces'), list) 
    414                 
    415     refC14nIsExcl = property(fget=__refC14nIsExcl, 
    416     doc="Return True/False c14n for reference elements set to exclusive type") 
    417       
    418  
    419     #_________________________________________________________________________ 
    420     def __signedInfoC14nIsExcl(self): 
    421         return isinstance(self.__signedInfoC14nKw, dict) and \ 
    422         isinstance(self.__signedInfoC14nKw.get('inclusive_namespaces'), list) 
    423                 
    424     signedInfoC14nIsExcl = property(fget=__signedInfoC14nIsExcl, 
    425     doc="Return True/False c14n for SignedInfo element set to exclusive type") 
    426      
    427      
    428     #_________________________________________________________________________ 
    429     def __setCert(self, cert): 
    430         """filter and convert input cert to signing verifying cert set  
    431         property methods.  For signingCert, set to None if it is not to be 
    432         included in the SOAP header.  For verifyingCert, set to None if this 
    433         cert can be expected to be retrieved from the SOAP header of the  
    434         message to be verified 
    435          
    436         @type: ndg.security.common.X509.X509Cert / M2Crypto.X509.X509 / 
    437         string or None 
    438         @param cert: X.509 certificate.   
    439          
    440         @rtype ndg.security.common.X509.X509Cert 
    441         @return X.509 certificate object""" 
    442          
    443         if cert is None or isinstance(cert, X509Cert): 
    444             # ndg.security.common.X509.X509Cert type / None 
    445             return cert 
    446              
    447         elif isinstance(cert, X509.X509): 
    448             # M2Crypto.X509.X509 type 
    449             return X509Cert(m2CryptoX509=cert) 
    450              
    451         elif isinstance(cert, basestring): 
    452             return X509CertParse(cert) 
    453          
    454         else: 
    455             raise AttributeError, "X.509 Cert. must be type: " + \ 
    456                 "ndg.security.common.X509.X509Cert, M2Crypto.X509.X509 or " +\ 
    457                 "a base64 encoded string" 
    458  
    459      
    460     #_________________________________________________________________________ 
    461     def __getVerifyingCert(self): 
    462         '''Return X.509 cert object corresponding to cert used to verify the  
    463         signature in the last call to verify 
    464          
    465          * Cert will correspond to one used in the LATEST call to verify, on 
    466          the next call it will be replaced 
    467          * if verify hasn't been called, the cert will be None 
    468          
    469         @rtype: M2Crypto.X509.X509 
    470         @return: certificate object 
    471         ''' 
    472         return self.__verifyingCert 
    473  
    474  
    475     #_________________________________________________________________________ 
    476     def __setVerifyingCert(self, verifyingCert): 
    477         "Set property method for X.509 cert. used to verify a signature" 
    478         self.__verifyingCert = self.__setCert(verifyingCert) 
    479      
    480         # Reset file path as it may no longer apply 
    481         self.__verifyingCertFilePath = None 
    482          
    483     verifyingCert = property(fset=__setVerifyingCert, 
    484                              fget=__getVerifyingCert, 
    485                              doc="Set X.509 Cert. for verifying signature") 
    486  
    487  
    488     #_________________________________________________________________________ 
    489     def __setVerifyingCertFilePath(self, verifyingCertFilePath): 
    490         "Set method for Service X.509 cert. file path property" 
    491          
    492         if isinstance(verifyingCertFilePath, basestring): 
    493             self.__verifyingCert = X509CertRead(verifyingCertFilePath) 
    494              
    495         elif verifyingCertFilePath is not None: 
    496             raise AttributeError, \ 
    497             "Verifying X.509 Cert. file path must be None or a valid string" 
    498          
    499         self.__verifyingCertFilePath = verifyingCertFilePath 
    500          
    501     verifyingCertFilePath = property(fset=__setVerifyingCertFilePath, 
    502                     doc="file path of X.509 Cert. for verifying signature") 
    503  
    504      
    505     #_________________________________________________________________________ 
    506     def __getSigningCert(self): 
    507         '''Return X.509 cert object corresponding to cert used with 
    508         signature 
    509          
    510         @rtype: M2Crypto.X509.X509 
    511         @return: certificate object 
    512         ''' 
    513         return self.__signingCert 
    514  
    515  
    516     #_________________________________________________________________________ 
    517     def __setSigningCert(self, signingCert): 
    518         "Set property method for X.509 cert. to be included with signature" 
    519         self.__signingCert = self.__setCert(signingCert) 
    520      
    521         # Reset file path as it may no longer apply 
    522         self.__signingCertFilePath = None 
    523          
    524     signingCert = property(fget=__getSigningCert, 
    525                            fset=__setSigningCert, 
    526                            doc="X.509 Cert. to include signature") 
    527  
    528   
    529     #_________________________________________________________________________ 
    530     def __setSigningCertFilePath(self, signingCertFilePath): 
    531         "Set signature X.509 cert property method" 
    532          
    533         if isinstance(signingCertFilePath, basestring): 
    534             self.__signingCert = X509CertRead(signingCertFilePath) 
    535              
    536         elif signingCertFilePath is not None: 
    537             raise AttributeError, \ 
    538                 "Signature X.509 cert. file path must be a valid string" 
    539          
    540         self.__signingCertFilePath = signingCertFilePath 
    541          
    542          
    543     signingCertFilePath = property(fset=__setSigningCertFilePath, 
    544                    doc="File path X.509 cert. to include with signed message") 
    545  
    546      
    547     #_________________________________________________________________________ 
    548     def __setSigningCertChain(self, signingCertChain): 
    549         '''Signature set-up with "X509PKIPathv1" BinarySecurityToken  
    550         ValueType.  Use an X.509 Stack to store certificates that make up a  
    551         chain of trust to certificate used to verify a signature 
    552          
    553         @type signingCertChain: list or tuple of M2Crypto.X509.X509Cert or 
    554         ndg.security.common.X509.X509Cert types. 
    555         @param signingCertChain: list of certificate objects making up the 
    556         chain of trust.  The last certificate is the one associated with the 
    557         private key used to sign the message.''' 
    558          
    559         if not isinstance(signingCertChain, list) and \ 
    560            not isinstance(signingCertChain, tuple): 
    561             raise WSSecurityError, \ 
    562                         'Expecting a list or tuple for "signingCertChain"' 
    563          
    564         self.__signingCertChain = X509Stack() 
    565              
    566         for cert in signingCertChain: 
    567             self.__signingCertChain.push(cert) 
    568              
    569     signingCertChain = property(fset=__setSigningCertChain, 
    570                doc="Cert.s in chain of trust to cert. used to verify msg.") 
    571  
    572   
    573     #_________________________________________________________________________ 
    574     def __setSigningPriKeyPwd(self, signingPriKeyPwd): 
    575         "Set method for private key file password used to sign message" 
    576         if signingPriKeyPwd is not None and \ 
    577            not isinstance(signingPriKeyPwd, basestring): 
    578             raise AttributeError, \ 
    579                 "Signing private key password must be None or a valid string" 
    580          
    581         self.__signingPriKeyPwd = signingPriKeyPwd 
    582          
    583     signingPriKeyPwd = property(fset=__setSigningPriKeyPwd, 
    584              doc="Password protecting private key file used to sign message") 
    585  
    586   
    587     #_________________________________________________________________________ 
    588     def __setSigningPriKey(self, signingPriKey): 
    589         """Set method for client private key 
    590          
    591         Nb. if input is a string, signingPriKeyPwd will need to be set if 
    592         the key is password protected. 
    593          
    594         @type signingPriKey: M2Crypto.RSA.RSA / string 
    595         @param signingPriKey: private key used to sign message""" 
    596          
    597         if isinstance(signingPriKey, basestring): 
    598             pwdCallback = lambda *ar, **kw: self.__signingPriKeyPwd 
    599             self.__signingPriKey = RSA.load_key_string(signingPriKey, 
    600                                                        callback=pwdCallback) 
    601  
    602         elif isinstance(signingPriKey, RSA.RSA): 
    603             self.__signingPriKey = signingPriKey  
    604                     
    605         else: 
    606             raise AttributeError, "Signing private key must be a valid " + \ 
    607                                   "M2Crypto.RSA.RSA type or a string" 
    608                  
    609     signingPriKey = property(fset=__setSigningPriKey, 
    610                              doc="Private key used to sign outbound message") 
    611  
    612   
    613     #_________________________________________________________________________ 
    614     def __setSigningPriKeyFilePath(self, signingPriKeyFilePath): 
    615         """Set method for client private key file path 
    616          
    617         signingPriKeyPwd MUST be set prior to a call to this method""" 
    618         if isinstance(signingPriKeyFilePath, basestring):                            
    619             try: 
    620                 # Read Private key to sign with     
    621                 priKeyFile = BIO.File(open(signingPriKeyFilePath))  
    622                 pwdCallback = lambda *ar, **kw: self.__signingPriKeyPwd                                            
    623                 self.__signingPriKey = RSA.load_key_bio(priKeyFile,  
    624                                                         callback=pwdCallback)            
    625             except Exception, e: 
    626                 raise AttributeError, \ 
    627                                 "Setting private key for signature: %s" % e 
    628          
    629         elif signingPriKeyFilePath is not None: 
    630             raise AttributeError, \ 
    631                         "Private key file path must be a valid string or None" 
    632          
    633         self.__signingPriKeyFilePath = signingPriKeyFilePath 
    634          
    635     signingPriKeyFilePath = property(fset=__setSigningPriKeyFilePath, 
    636                       doc="File path for private key used to sign message") 
    637  
    638     def __caCertIsSet(self): 
    639         '''Check for CA certificate set (X.509 Stack has been created)''' 
    640         return hasattr(self, '_SignatureHandler__caX509Stack') 
    641      
    642     caCertIsSet = property(fget=__caCertIsSet, 
    643            doc='Check for CA certificate set (X.509 Stack has been created)') 
    644      
    645     #_________________________________________________________________________ 
    646     def __appendCAX509Stack(self, caCertList): 
    647         '''Store CA certificates in an X.509 Stack 
    648          
    649         @param caCertList: list or tuple 
    650         @type caCertList: M2Crypto.X509.X509 certificate objects''' 
    651          
    652         if not self.caCertIsSet: 
    653             self.__caX509Stack = X509Stack() 
    654              
    655         for cert in caCertList: 
    656             self.__caX509Stack.push(cert) 
    657  
    658  
    659     #_________________________________________________________________________ 
    660     def __setCAX509StackFromDir(self, caCertDir): 
    661         '''Read CA certificates from directory and add them to the X.509 
    662         stack 
    663          
    664         @param caCertDir: string 
    665         @type caCertDir: directory from which to read CA certificate files''' 
    666          
    667         # Mimic OpenSSL -CApath option which expects directory of CA files 
    668         # of form <Hash cert subject name>.0 
    669         reg = re.compile('\d+\.0') 
    670         try: 
    671             caCertList = [X509CertRead(caFile) \ 
    672                           for caFile in os.listdir(caCertDir) \ 
    673                           if reg.match(caFile)] 
    674         except Exception, e: 
    675             raise WSSecurityError, \ 
    676                 'Loading CA certificate "%s" from CA directory: %s' % \ 
    677                                                         (caFile, str(e)) 
    678                      
    679         # Add to stack 
    680         self.__appendCAX509Stack(caCertList) 
    681          
    682     caCertDirPath = property(fset=__setCAX509StackFromDir, 
    683                       doc="Dir. containing CA cert.s used for verification") 
    684  
    685  
    686     #_________________________________________________________________________ 
    687     def __setCAX509StackFromCertFileList(self, caCertFilePathList): 
    688         '''Read CA certificates from file and add them to the X.509 
    689         stack 
    690          
    691         @type caCertFilePathList: list or tuple 
    692         @param caCertFilePathList: list of file paths for CA certificates to 
    693         be used to verify certificate used to sign message''' 
    694          
    695         if not isinstance(caCertFilePathList, list) and \ 
    696            not isinstance(caCertFilePathList, tuple): 
    697             raise WSSecurityError, \ 
    698                         'Expecting a list or tuple for "caCertFilePathList"' 
    699  
    700         # Mimic OpenSSL -CApath option which expects directory of CA files 
    701         # of form <Hash cert subject name>.0 
    702         try: 
    703             caCertList = [X509CertRead(caFile) \ 
    704                           for caFile in caCertFilePathList] 
    705         except Exception, e: 
    706             raise WSSecurityError, \ 
    707                     'Loading CA certificate "%s" from file list: %s' % \ 
    708                                                         (caFile, str(e)) 
    709                      
    710         # Add to stack 
    711         self.__appendCAX509Stack(caCertList) 
    712          
    713     caCertFilePathList = property(fset=__setCAX509StackFromCertFileList, 
    714                       doc="List of CA cert. files used for verification") 
    71590                 
    71691 
     
    733108         
    734109        # Add ID so that the element can be included in the signature 
    735         sigConfirmElem.set('{%s}Id' % WSU.UTILITY, "signatureConfirmation") 
     110        sigConfirmElem.set('{%s}Id' % _WSU.UTILITY, "signatureConfirmation") 
    736111 
    737112        # Add ID so that the element can be included in the signature 
     
    758133        ''' 
    759134        # Nb. wsu ns declaration is in the SOAP header elem 
    760         timestampElem = ElementTree.Element("{%s}%s"%(WSU.UTILITY,'Timestamp')) 
     135        timestampElem = ElementTree.Element("{%s}%s"%(_WSU.UTILITY,'Timestamp')) 
    761136        wsseElem.append(timestampElem) 
    762137         
    763138        # Add ID so that the timestamp element can be included in the signature 
    764         timestampElem.set('{%s}Id' % WSU.UTILITY, "timestamp") 
     139        timestampElem.set('{%s}Id' % _WSU.UTILITY, "timestamp") 
    765140         
    766141        # Value type can be any be any one of those supported via  
    767142        # binSecTokValType 
    768         createdElem = ElementTree.Element("{%s}%s" % (WSU.UTILITY,'Created')) 
     143        createdElem = ElementTree.Element("{%s}%s" % (_WSU.UTILITY,'Created')) 
    769144        timestampElem.append(createdElem) 
    770145         
     
    773148         
    774149        dtExpiryTime = dtCreatedTime + timedelta(seconds=elapsedSec) 
    775         expiresElem = ElementTree.Element("{%s}%s" % (WSU.UTILITY, 'Expires')) 
     150        expiresElem = ElementTree.Element("{%s}%s" % (_WSU.UTILITY, 'Expires')) 
    776151        timestampElem.append(expiresElem) 
    777152         
     
    872247        # Add X.509 cert as binary security token 
    873248        # TODO: sub encodestring with b64encode? 
    874         if self.__reqBinSecTokValType==self.binSecTokValType['X509PKIPathv1']: 
    875             binSecTokVal = base64.encodestring(self.__signingCertChain.asDER()) 
     249        if self.reqBinSecTokValType==self.binSecTokValType['X509PKIPathv1']: 
     250            binSecTokVal = base64.encodestring(self.signingCertChain.asDER()) 
    876251        else: 
    877252            # Assume X.509 / X.509 vers 3 
    878             binSecTokVal = base64.encodestring(self.__signingCert.asDER()) 
     253            binSecTokVal = base64.encodestring(self.signingCert.asDER()) 
    879254 
    880255        self._soapEnvElem = soapWriter.dom._elem 
     
    887262        soapHdrElem.set("xmlns:%s" % 'wsse', OASIS.WSSE) 
    888263        soapHdrElem.set("xmlns:%s" % 'wsse11', OASIS.WSSE11) 
    889 #        soapHdrElem.set("xmlns:%s" % 'wsu', WSU.UTILITY) 
    890         self._soapEnvElem.set("xmlns:%s" % 'wsu', WSU.UTILITY) 
     264#        soapHdrElem.set("xmlns:%s" % 'wsu', _WSU.UTILITY) 
     265        self._soapEnvElem.set("xmlns:%s" % 'wsu', _WSU.UTILITY) 
    891266        soapHdrElem.set("xmlns:%s" % 'ds', DSIG.BASE) 
    892267         
    893         try: 
    894             refC14nPfxSet = len(self.__refC14nKw['inclusive_namespaces']) > 0 
    895         except KeyError: 
    896             refC14nPfxSet = False 
    897  
    898         try: 
    899             signedInfoC14nPfxSet = \ 
    900                 len(self.__signedInfoC14nKw['inclusive_namespaces']) > 0 
    901         except KeyError: 
    902             signedInfoC14nPfxSet = False 
    903                  
    904         if refC14nPfxSet: 
     268        refC14nPfxSet = False 
     269        if isinstance(self.refC14nKw.get('inclusive_namespaces'), list) and \ 
     270            len(self.refC14nKw['inclusive_namespaces']) > 0: 
     271            refC14nPfxSet = True  
     272 
     273        signedInfoC14nPfxSet = False 
     274        if isinstance(self.signedInfoC14nKw.get('inclusive_namespaces'), list) and \ 
     275            len(self.signedInfoC14nKw['inclusive_namespaces']) > 0: 
     276            signedInfoC14nPfxSet = True 
     277                 
     278        if refC14nPfxSet or signedInfoC14nPfxSet: 
    905279            soapHdrElem.set("xmlns:%s" % 'ec', DSIG.C14N_EXCL) 
    906280             
     
    929303        # Value type can be any be any one of those supported via  
    930304        # binSecTokValType 
    931         binSecTokElem.set('ValueType', self.__reqBinSecTokValType) 
    932         binSecTokElem.set('EncodingType', SignatureHandler.binSecTokEncType) 
     305        binSecTokElem.set('ValueType', self.reqBinSecTokValType) 
     306        binSecTokElem.set('EncodingType', self._binSecTokEncType) 
    933307         
    934308        # Add ID so that the binary token can be included in the signature 
    935         binSecTokElem.set('{%s}Id' % WSU.UTILITY, "binaryToken") 
     309        binSecTokElem.set('{%s}Id' % _WSU.UTILITY, "binaryToken") 
    936310         
    937311        binSecTokElem.text = binSecTokVal 
     
    971345            c14nMethodElem.append(c14nInclNamespacesElem) 
    972346             
    973             pfxList = ' '.join(self.__signedInfoC14nKw['inclusive_namespaces']) 
     347            pfxList = ' '.join(self.signedInfoC14nKw['inclusive_namespaces']) 
    974348            c14nInclNamespacesElem.set('PrefixList', pfxList) 
    975349 
     
    1001375         
    1002376        # Add Reference to body so that it can be included in the signature 
    1003         #soapBodyElem.set('xmlns:wsu', WSU.UTILITY) - results in duplicate xmlns declarations 
    1004         soapBodyElem.set('{%s}Id' % WSU.UTILITY, 'body') 
     377        #soapBodyElem.set('xmlns:wsu', _WSU.UTILITY) - results in duplicate xmlns declarations 
     378        soapBodyElem.set('{%s}Id' % _WSU.UTILITY, 'body') 
    1005379 
    1006380 
     
    1019393             
    1020394            # Set URI attribute to point to reference to be signed 
    1021             uri = '#' + refElem.get('{%s}%s' % (WSU.UTILITY, 'Id')) 
     395            uri = '#' + refElem.get('{%s}%s' % (_WSU.UTILITY, 'Id')) 
    1022396             
    1023397            # Canonicalize reference 
    1024 #            refC14n = self.canonicalize(subset=refElem, 
    1025 #                                        exclusive=self.refC14nIsExcl, 
    1026 #                                        **self.__refC14nKw) 
    1027398            refC14n = soapWriter.dom.canonicalize(subset=refElem, 
    1028399                                                  exclusive=self.refC14nIsExcl, 
    1029                                                   **self.__refC14nKw) 
     400                                                  **self.refC14nKw) 
    1030401            log.debug('Canonicalisation for URI "%s": %s', uri, refC14n) 
    1031402             
     
    1057428                                                       refC14nAlg, 
    1058429                                                       'InclusiveNamespaces') 
    1059                 refPfxList = ' '.join(self.__refC14nKw['inclusive_namespaces']) 
     430                refPfxList = ' '.join(self.refC14nKw['inclusive_namespaces']) 
    1060431                inclNamespacesElem.set('PrefixList', refPfxList) 
    1061432             
     
    1078449        c14nSignedInfo = soapWriter.dom.canonicalize(subset=signedInfoElem, 
    1079450                                           exclusive=self.signedInfoC14nIsExcl, 
    1080                                            **self.__signedInfoC14nKw) 
     451                                           **self.signedInfoC14nKw) 
    1081452        log.debug('Canonicalisation for <ds:signedInfo>: %s', c14nSignedInfo) 
    1082453         
     
    1085456         
    1086457        # Sign using the private key and base 64 encode the result 
    1087         signatureValue = self.__signingPriKey.sign(signedInfoDigestValue) 
     458        signatureValue = self.signingPriKey.sign(signedInfoDigestValue) 
    1088459         
    1089460        # encodestring puts newline markers at 76 char intervals otherwise no  
     
    1275646             
    1276647            valueType = binSecTokElem.get("ValueType") 
    1277             if valueType in (SignatureHandler.binSecTokValType['X509v3'], 
    1278                              SignatureHandler.binSecTokValType['X509']): 
     648            if valueType in (self.binSecTokValType['X509v3'], 
     649                             self.binSecTokValType['X509']): 
    1279650                # Remove base 64 encoding 
    1280651                derString = base64.decodestring(x509CertTxt) 
     
    1288659 
    1289660            elif valueType == \ 
    1290                 SignatureHandler.binSecTokValType['X509PKIPathv1']: 
     661                self.binSecTokValType['X509PKIPathv1']: 
    1291662                 
    1292663                derString = base64.decodestring(x509CertTxt) 
     
    1295666                # TODO: Check ordering - is the last off the stack the 
    1296667                # one to use to verify the message? 
    1297                 self.__verifyingCert = x509Stack[-1] 
     668                self.verifyingCert = x509Stack[-1] 
    1298669            else: 
    1299670                raise WSSecurityError('BinarySecurityToken ValueType ' \ 
    1300671                    'attribute is not recognised: "%s"' % valueType) 
    1301672 
    1302         if self.__verifyingCert is None: 
     673        if self.verifyingCert is None: 
    1303674            raise VerifyError("No certificate set for verification of the " \ 
    1304675                              "signature") 
    1305676         
    1306677        # Extract RSA public key from the cert 
    1307         rsaPubKey = self.__verifyingCert.pubKey.get_rsa() 
     678        rsaPubKey = self.verifyingCert.pubKey.get_rsa() 
    1308679 
    1309680        # Apply the signature verification 
     
    1319690         
    1320691        # Verify chain of trust  
    1321         x509Stack.verifyCertChain(x509Cert2Verify=self.__verifyingCert, 
     692        x509Stack.verifyCertChain(x509Cert2Verify=self.verifyingCert, 
    1322693                                  caX509Stack=self.__caX509Stack) 
    1323694 
Note: See TracChangeset for help on using the changeset viewer.