Changeset 6399


Ignore:
Timestamp:
25/01/10 16:19:17 (9 years ago)
Author:
pjkersha
Message:

Working client side

Location:
TI12-security/trunk/WSSecurity/ndg/wssecurity
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/WSSecurity/ndg/wssecurity/common/signaturehandler/__init__.py

    r6396 r6399  
    111111        className=('',), 
    112112        reqBinarySecurityTokValType=(OASIS.X509TOKEN.X509,), 
    113         verifyingCert=(None,), 
     113        verifyingCert=(None, ''), 
    114114        verifyingCertFilePath=(None, ''), 
    115         signingCert=(None,), 
     115        signingCert=(None, ''), 
    116116        signingCertFilePath=(None, ''),  
    117117        signingCertChain=([],), 
    118         signingPriKey=(None,), 
     118        signingPriKey=(None, ''), 
    119119        signingPriKeyFilePath=(None, ''),  
    120120        signingPriKeyPwd=(None, ''), 
     
    471471                           doc="X.509 Certificate to include signature") 
    472472 
    473   
     473    def _getSigningCertFilePath(self): 
     474        "Get signature X.509 certificate property method" 
     475        return self.__signingCertFilePath 
     476     
    474477    def _setSigningCertFilePath(self, signingCertFilePath): 
    475478        "Set signature X.509 certificate property method" 
     
    484487        self.__signingCertFilePath = signingCertFilePath 
    485488         
    486     signingCertFilePath = property(fset=_setSigningCertFilePath, 
     489    signingCertFilePath = property(fget=_getSigningCertFilePath, 
     490                                   fset=_setSigningCertFilePath, 
    487491                                   doc="File path X.509 cert. to include with " 
    488492                                       "signed message") 
     
    498502        chain of trust.  The last certificate is the one associated with the 
    499503        private key used to sign the message.''' 
     504        self.__signingCertChain = X509Stack() 
     505         
    500506        for cert in signingCertChain: 
    501             self.__signingCertChain.push(cert) 
     507            if cert: 
     508                self.__signingCertChain.push(cert) 
    502509             
    503510    def _getSigningCertChain(self): 
     
    506513    signingCertChain = property(fset=_setSigningCertChain, 
    507514                                fget=_getSigningCertChain, 
    508                                 doc="Cert.s in chain of trust to cert. used " 
    509                                     "to verify msg.") 
     515                                doc="Certificates in the chain of trust to " 
     516                                    "verify the certificate provided in an " 
     517                                    "incoming message.") 
    510518 
    511519    def _setSigningPriKeyPwd(self, signingPriKeyPwd): 
    512520        "Set method for private key file password used to sign message" 
    513         if signingPriKeyPwd is not None and \ 
    514            not isinstance(signingPriKeyPwd, basestring): 
     521        if (signingPriKeyPwd is not None and  
     522            not isinstance(signingPriKeyPwd, basestring)): 
    515523            raise AttributeError("Signing private key password must be None " 
    516524                                 "or a valid string") 
     
    534542        @type signingPriKey: M2Crypto.RSA.RSA / string / None 
    535543        @param signingPriKey: private key used to sign message""" 
    536          
    537         if isinstance(signingPriKey, basestring): 
     544        if not signingPriKey: 
     545            self.__signingPriKey = None 
     546             
     547        elif isinstance(signingPriKey, basestring): 
    538548            pwdCallback = lambda *ar, **kw: self.__signingPriKeyPwd 
    539549            self.__signingPriKey = RSA.load_key_string(signingPriKey, 
     
    542552            self.__signingPriKey = signingPriKey 
    543553             
    544         elif signingPriKey is None: 
    545             self.__signingPriKey = None         
    546554        else: 
    547555            raise TypeError("Signing private key must be a valid " 
     
    602610        @type caCertDir: directory from which to read CA certificate files''' 
    603611         
    604         if caCertDir is None: 
     612        if not caCertDir: 
    605613            return 
    606614         
  • TI12-security/trunk/WSSecurity/ndg/wssecurity/common/signaturehandler/foursuite.py

    r6396 r6399  
    1414import os 
    1515import re 
     16import traceback 
    1617from cStringIO import StringIO 
    1718 
     
    5758    WS-Security 
    5859    """ 
     60    # Namespaces for XPath searches 
     61    PROCESSOR_NSS = { 
     62        'ds':     DSIG.BASE,  
     63        'wsu':    _WSU.UTILITY,  
     64        'wsse':   OASIS.WSSE,  
     65        'soapenv':SOAP.ENV  
     66    } 
     67     
    5968    _refC14nPfxSet = lambda self: len(self.refC14nKw.get( 
    6069                            BaseSignatureHandler.ZSI_C14N_KEYWORD_NAME, [])) > 0 
     
    7180                                        "for signature of signed info " 
    7281                                        "elements") 
     82 
     83    def sign(self, soapWriter): 
     84        '''Sign the message body and binary security token of a SOAP message 
     85         
     86        @type soapWriter: ZSI.writer.SoapWriter 
     87        @param soapWriter: ZSI object to write SOAP message 
     88        ''' 
     89 
     90        # Add X.509 cert as binary security token 
     91        if self.reqBinarySecurityTokValType == \ 
     92           self.BINARY_SECURITY_TOK_VAL_TYPE['X509PKIPathv1']: 
     93            if self.signingCertChain is None: 
     94                msg = 'SignatureHandler signingCertChain attribute is not set' 
     95                log.error(msg) 
     96                raise AttributeError(msg) 
     97             
     98            binSecTokVal = base64.encodestring(self.signingCertChain.asDER()) 
     99        else: 
     100            # Assume X.509 / X.509 vers 3 
     101            if self.signingCert is None: 
     102                msg = 'SignatureHandler signingCert attribute is not set' 
     103                log.error(msg) 
     104                raise AttributeError(msg) 
     105             
     106            binSecTokVal = base64.encodestring(self.signingCert.asDER()) 
     107 
     108        soapWriter._header.setNamespaceAttribute('wsse', OASIS.WSSE) 
     109        soapWriter._header.setNamespaceAttribute('wsse11', OASIS.WSSE11) 
     110        soapWriter._header.setNamespaceAttribute('wsu', _WSU.UTILITY) 
     111        soapWriter._header.setNamespaceAttribute('ds', DSIG.BASE) 
     112         
     113        # Flag if inclusive namespace prefixes are set for the signature or 
     114        # reference elements 
     115        if self.refC14nPfxSet or self.signedInfoC14nPfxSet: 
     116           soapWriter._header.setNamespaceAttribute('ec', DSIG.C14N_EXCL) 
     117         
     118        # Check <wsse:security> isn't already present in header 
     119        wsseElems = soapWriter._header.evaluate('//wsse:security',  
     120                                    processorNss=SignatureHandler.PROCESSOR_NSS) 
     121        if len(wsseElems) > 1: 
     122            raise SignatureError('wsse:Security element is already present') 
     123 
     124        # Add WSSE element 
     125        wsseElem = soapWriter._header.createAppendElement(OASIS.WSSE,  
     126                                                          'Security') 
     127        wsseElem.setNamespaceAttribute('wsse', OASIS.WSSE) 
     128         
     129        # Flag to recipient - they MUST parse and check this signature  
     130        wsseElem.setAttributeNS(SOAP.ENV, 'mustUnderstand', "1") 
     131         
     132        # Binary Security Token element will contain the X.509 cert  
     133        # corresponding to the private key used to sing the message 
     134        binSecTokElem = wsseElem.createAppendElement(OASIS.WSSE,  
     135                                                     'BinarySecurityToken') 
     136         
     137        # Value type can be any be any one of those supported via  
     138        # BINARY_SECURITY_TOK_VAL_TYPE 
     139        binSecTokElem.setAttributeNS(None,  
     140                                     'ValueType',  
     141                                     self.reqBinarySecurityTokValType) 
     142 
     143        binSecTokElem.setAttributeNS(None,  
     144                                     'EncodingType', 
     145                                     self.BINARY_SECURITY_TOK_ENCODING_TYPE) 
     146         
     147        # Add ID so that the binary token can be included in the signature 
     148        binSecTokElem.setAttributeNS(_WSU.UTILITY, 'Id', "binaryToken") 
     149 
     150        binSecTokElem.createAppendTextNode(binSecTokVal) 
     151 
     152        # Timestamp 
     153        if self.addTimestamp: 
     154            self._addTimeStamp(wsseElem) 
     155             
     156        # Signature Confirmation 
     157        if self.applySignatureConfirmation:  
     158            self._applySignatureConfirmation(wsseElem) 
     159         
     160        # Signature 
     161        signatureElem = wsseElem.createAppendElement(DSIG.BASE, 'Signature') 
     162        signatureElem.setNamespaceAttribute('ds', DSIG.BASE) 
     163         
     164        # Signature - Signed Info 
     165        signedInfoElem = signatureElem.createAppendElement(DSIG.BASE,  
     166                                                           'SignedInfo') 
     167         
     168        # Signed Info - Canonicalization method 
     169        c14nMethodElem = signedInfoElem.createAppendElement(DSIG.BASE, 
     170                                                    'CanonicalizationMethod') 
     171         
     172        # Set based on 'signedInfoIsExcl' property 
     173        c14nAlgOpt = (DSIG.C14N, DSIG.C14N_EXCL) 
     174        signedInfoC14nAlg = c14nAlgOpt[int(self.signedInfoC14nIsExcl)] 
     175         
     176        c14nMethodElem.setAttributeNS(None, 'Algorithm', signedInfoC14nAlg) 
     177         
     178        if self.signedInfoC14nPfxSet: 
     179            c14nInclNamespacesElem = c14nMethodElem.createAppendElement( 
     180                                                    signedInfoC14nAlg, 
     181                                                    'InclusiveNamespaces') 
     182            inclNsPfx = ' '.join(self.signedInfoC14nKw[ 
     183                                        SignatureHandler.ZSI_C14N_KEYWORD_NAME]) 
     184            c14nInclNamespacesElem.setAttributeNS(None, 'PrefixList', inclNsPfx) 
     185         
     186        # Signed Info - Signature method 
     187        sigMethodElem = signedInfoElem.createAppendElement(DSIG.BASE, 
     188                                                           'SignatureMethod') 
     189        sigMethodElem.setAttributeNS(None, 'Algorithm', DSIG.SIG_RSA_SHA1) 
     190         
     191        # Signature - Signature value 
     192        signatureValueElem = signatureElem.createAppendElement(DSIG.BASE,  
     193                                                             'SignatureValue') 
     194         
     195        # Key Info 
     196        KeyInfoElem = signatureElem.createAppendElement(DSIG.BASE, 'KeyInfo') 
     197        secTokRefElem = KeyInfoElem.createAppendElement(OASIS.WSSE,  
     198                                                  'SecurityTokenReference') 
     199         
     200        # Reference back to the binary token included earlier 
     201        wsseRefElem = secTokRefElem.createAppendElement(OASIS.WSSE,  
     202                                                        'Reference') 
     203        wsseRefElem.setAttributeNS(None, 'URI', "#binaryToken") 
     204         
     205        # Add Reference to body so that it can be included in the signature 
     206        soapWriter.body.setAttributeNS(_WSU.UTILITY, 'Id', "body") 
     207 
     208        refElems = soapWriter.body.evaluate('//*[@wsu:Id]',  
     209                                    processorNss=SignatureHandler.PROCESSOR_NSS) 
     210         
     211        # Set based on 'signedInfoIsExcl' property 
     212        refC14nAlg = c14nAlgOpt[int(self.refC14nIsExcl)] 
     213         
     214        # 1) Reference Generation 
     215        # 
     216        # Find references 
     217        for refElem in refElems: 
     218             
     219            refID = refElem.getAttributeValue(_WSU.UTILITY, 'Id') 
     220             
     221            # Set URI attribute to point to reference to be signed 
     222            uri = u"#" + refID 
     223             
     224            # Canonicalize reference 
     225            # 
     226            # ndg.wssecurity.common.utils.zsi.DomletteElementProxy's C14N method 
     227            # wraps 4Suite-XML CanonicalPrint 
     228            unsuppressedPrefixes = self.refC14nKw.get( 
     229                                    SignatureHandler.ZSI_C14N_KEYWORD_NAME, []) 
     230             
     231            refC14n = refElem.canonicalize(algorithm=refC14nAlg,  
     232                                    unsuppressedPrefixes=unsuppressedPrefixes) 
     233 
     234            # Calculate digest for reference and base 64 encode 
     235            # 
     236            # Nb. encodestring adds a trailing newline char 
     237            digestValue = base64.encodestring(sha(refC14n).digest()).strip() 
     238 
     239 
     240            # Add a new reference element to SignedInfo 
     241            refElem = signedInfoElem.createAppendElement(DSIG.BASE,  
     242                                                         'Reference') 
     243            refElem.setAttributeNS(None, 'URI', uri) 
     244             
     245            # Use ds:Transforms or wsse:TransformationParameters? 
     246            transformsElem = refElem.createAppendElement(DSIG.BASE,  
     247                                                         'Transforms') 
     248            transformElem = transformsElem.createAppendElement(DSIG.BASE,  
     249                                                               'Transform') 
     250 
     251            # Set Canonicalization algorithm type 
     252            transformElem.setAttributeNS(None, 'Algorithm', refC14nAlg) 
     253            if self.refC14nPfxSet: 
     254                # Exclusive C14N requires inclusive namespace elements 
     255                inclNamespacesElem = transformElem.createAppendElement( 
     256                                                       refC14nAlg, 
     257                                                       'InclusiveNamespaces') 
     258                refInclNsPfx = ' '.join(self.refC14nKw[ 
     259                                        SignatureHandler.ZSI_C14N_KEYWORD_NAME]) 
     260                inclNamespacesElem.setAttributeNS(None, 'PrefixList',  
     261                                                  refInclNsPfx) 
     262             
     263            # Digest Method  
     264            digestMethodElem = refElem.createAppendElement(DSIG.BASE,  
     265                                                           'DigestMethod') 
     266            digestMethodElem.setAttributeNS(None, 'Algorithm', DSIG.DIGEST_SHA1) 
     267             
     268            # Digest Value 
     269            digestValueElem = refElem.createAppendElement(DSIG.BASE,  
     270                                                          'DigestValue') 
     271            digestValueElem.createAppendTextNode(digestValue) 
     272 
     273        # 2) Signature Generation 
     274        #         
     275        # Canonicalize the signedInfo node 
     276        try: 
     277            signedInfoElem = soapWriter.body.evaluate('//ds:SignedInfo', 
     278                                processorNss=SignatureHandler.PROCESSOR_NSS)[0] 
     279        except TypeError, e: 
     280            log.error("Error locating SignedInfo element for signature") 
     281            raise  
     282         
     283        unsuppressedPrefixes = self.refC14nKw.get( 
     284                                    SignatureHandler.ZSI_C14N_KEYWORD_NAME, []) 
     285 
     286        # ndg.wssecurity.common.utils.zsi.DomletteElementProxy's C14N method 
     287        # wraps 4Suite-XML CanonicalPrint 
     288        c14nSignedInfo = signedInfoElem.canonicalize( 
     289                                    algorithm=signedInfoC14nAlg, 
     290                                    unsuppressedPrefixes=unsuppressedPrefixes) 
     291        # Calculate digest of SignedInfo 
     292        signedInfoDigestValue = sha(c14nSignedInfo).digest() 
     293         
     294        # Sign using the private key and base 64 encode the result 
     295        signatureValue = self.signingPriKey.sign(signedInfoDigestValue) 
     296        b64EncSignatureValue = base64.encodestring(signatureValue).strip() 
     297 
     298        # Add to <SignatureValue> 
     299        signatureValueElem.createAppendTextNode(b64EncSignatureValue) 
     300 
     301        log.info("Signature generation complete") 
     302 
     303    def verify(self, parsedSOAP, raiseNoSignatureFound=True): 
     304        """Verify signature 
     305         
     306        @type parsedSOAP: ZSI.parse.ParsedSoap 
     307        @param parsedSOAP: object contain parsed SOAP message received from 
     308        sender""" 
     309 
     310        signatureElem = parsedSOAP.dom.xpath('//ds:Signature',  
     311                                    explicitNss=SignatureHandler.PROCESSOR_NSS) 
     312        nSignatureElem = len(signatureElem) 
     313        if nSignatureElem > 1: 
     314            raise VerifyError('Multiple <ds:Signature/> elements found') 
     315         
     316        elif nSignatureElem < 1: 
     317            # Message wasn't signed 
     318            msg = "Input message wasn't signed!" 
     319            if raiseNoSignatureFound: 
     320                raise NoSignatureFound(msg) 
     321            else:  
     322                log.warning(msg) 
     323                return 
     324             
     325        signatureElem = signatureElem[0] 
     326         
     327        # Two stage process: reference validation followed by signature  
     328        # validation  
     329         
     330        # 1) Reference Validation 
     331         
     332        # Check for canonicalization set via ds:CanonicalizationMethod - 
     333        # Use this later as a back up in case no Canonicalization was set in  
     334        # the transforms elements 
     335        try: 
     336            c14nMethodElem = parsedSOAP.dom.xpath('//ds:CanonicalizationMethod', 
     337                                explicitNss=SignatureHandler.PROCESSOR_NSS)[0] 
     338        except TypeError: 
     339            log.error("XPath query error locating " 
     340                      "<ds:CanonicalizationMethod/>: %s" %  
     341                      traceback.format_exc()) 
     342            raise 
     343         
     344        refElems = parsedSOAP.dom.xpath('//ds:Reference', 
     345                                    explicitNss=SignatureHandler.PROCESSOR_NSS) 
     346 
     347        for refElem in refElems: 
     348            # Get the URI for the reference 
     349            refURI = refElem.getAttributeNS(None, 'URI') 
     350             
     351            try: 
     352                transformsElem = getElements(refElem, "Transforms")[0] 
     353                transformElems = getElements(transformsElem, "Transform") 
     354     
     355                refAlgorithm = transformElems[0].getAttributeNS(None, 
     356                                                                'Algorithm') 
     357            except Exception, e: 
     358                raise VerifyError('failed to get transform algorithm for ' 
     359                                  '<ds:Reference URI="%s">' %  
     360                                  (refURI, e)) 
    73361                 
    74  
     362            # Add extra keyword for Exclusive canonicalization method 
     363            refC14nKw = {} 
     364            if self.refC14nIsExcl: 
     365                try: 
     366                    # Check for no inclusive namespaces set 
     367                    inclusiveNS = getElements(transformElems[0],  
     368                                              "InclusiveNamespaces")                    
     369                    if len(inclusiveNS) > 0: 
     370                        pfxListAttElem = inclusiveNS[0].getAttributeNodeNS(None,  
     371                                                                'PrefixList') 
     372                             
     373                        refC14nKw['inclusivePrefixes'] = \ 
     374                                                pfxListAttElem.value.split() 
     375                    else: 
     376                        refC14nKw['inclusivePrefixes'] = None 
     377                except Exception, e: 
     378                    raise VerifyError('failed to handle transform (%s) in ' 
     379                                      '<ds:Reference URI="%s">: %s' % \ 
     380                                      (transformElems[0], refURI, e)) 
     381         
     382            # Canonicalize the reference data and calculate the digest 
     383            if refURI[0] != "#": 
     384                raise VerifyError("Expecting # identifier for Reference URI " 
     385                                  "\"%s\"" % refURI) 
     386                     
     387            # XPath reference 
     388            uriXPath = '//*[@wsu:Id="%s"]' % refURI[1:] 
     389            uriElem = parsedSOAP.dom.xpath(uriXPath, 
     390                                explicitNss=SignatureHandler.PROCESSOR_NSS)[0] 
     391 
     392            f = StringIO() 
     393            CanonicalPrint(uriElem, stream=f, exclusive=self.refC14nIsExcl, 
     394                           **refC14nKw) 
     395            refC14n = f.getvalue() 
     396            digestValue = base64.encodestring(sha(refC14n).digest()).strip() 
     397             
     398            # Extract the digest value that was stored             
     399            digestNode = getElements(refElem, "DigestValue")[0] 
     400            nodeDigestValue = str(digestNode.childNodes[0].nodeValue).strip()    
     401             
     402            # Reference validates if the two digest values are the same 
     403            if digestValue != nodeDigestValue: 
     404                raise InvalidSignature('Digest Values do not match for URI: ' 
     405                                       '"%s"' % refURI) 
     406             
     407            log.debug("Verified canonicalization for element %s" % refURI[1:]) 
     408                 
     409        # 2) Signature Validation 
     410        signedInfoElem = parsedSOAP.dom.xpath('//ds:SignedInfo', 
     411                                explicitNss=SignatureHandler.PROCESSOR_NSS)[0] 
     412 
     413        # Get algorithm used for canonicalization of the SignedInfo  
     414        # element.  Nb. This is NOT necessarily the same as that used to 
     415        # canonicalize the reference elements checked above! 
     416        signedInfoC14nAlg = c14nMethodElem.getAttributeNS(None, "Algorithm") 
     417        signedInfoC14nKw = {} 
     418        if self.signedInfoC14nIsExcl: 
     419            try: 
     420                # Check for inclusive namespaces 
     421                inclusiveNsElem = getElements(c14nMethodElem, 
     422                                              "InclusiveNamespaces") 
     423                if len(inclusiveNsElem) > 0:                     
     424                    pfxListAttElem = inclusiveNsElem[0].getAttributeNodeNS(None, 
     425                                                                 'PrefixList') 
     426                    signedInfoC14nKw['inclusivePrefixes' 
     427                                     ] = pfxListAttElem.value.split() 
     428                else: 
     429                    signedInfoC14nKw['inclusivePrefixes'] = None 
     430            except Exception, e: 
     431                raise VerifyError('failed to handle exclusive ' 
     432                                  'canonicalisation for SignedInfo: %s' % e) 
     433 
     434        # Canonicalize the SignedInfo node and take digest 
     435        f = StringIO() 
     436        CanonicalPrint(signedInfoElem, 
     437                       stream=f, 
     438                       exclusive=self.signedInfoC14nIsExcl,  
     439                       **signedInfoC14nKw)        
     440        c14nSignedInfo = f.getvalue()   
     441                        
     442        signedInfoDigestValue = sha(c14nSignedInfo).digest() 
     443         
     444        # Get the signature value in order to check against the digest just 
     445        # calculated 
     446        try: 
     447            signatureValueElem = parsedSOAP.dom.xpath('//ds:SignatureValue', 
     448                                explicitNss=SignatureHandler.PROCESSOR_NSS)[0] 
     449        except: 
     450            raise WSSecurityError("No signature value found: %s" %  
     451                                  traceback.format_exc()) 
     452             
     453        # Remove base 64 encoding 
     454        b64EncSignatureValue = signatureValueElem.childNodes[0].nodeValue 
     455        signatureValue = base64.decodestring(b64EncSignatureValue) 
     456 
     457        # Cache Signature Value here so that a response can include it. 
     458        # 
     459        # Nb. If the sign method is called from a separate SignatureHandler 
     460        # object then the signature value must be passed from THIS object to 
     461        # the other SignatureHandler otherwise signature confirmation will 
     462        # fail 
     463        if self.applySignatureConfirmation: 
     464            # re-encode string to avoid possible problems with interpretation  
     465            # of line breaks 
     466            self.b64EncSignatureValue = b64EncSignatureValue 
     467        else: 
     468            self.b64EncSignatureValue = None 
     469          
     470        # Look for X.509 Cert in wsse:BinarySecurityToken node 
     471        try: 
     472            binSecTokElem = parsedSOAP.dom.xpath('//wsse:BinarySecurityToken', 
     473                                explicitNss=SignatureHandler.PROCESSOR_NSS)[0] 
     474        except: 
     475            # Signature may not have included the Binary Security Token in  
     476            # which case the verifying cert will need to have been set  
     477            # elsewhere 
     478            log.info("No Binary Security Token found in WS-Security header") 
     479            binSecTokElem = None 
     480         
     481        if binSecTokElem: 
     482            try: 
     483                x509CertTxt=str(binSecTokElem.childNodes[0].nodeValue) 
     484                 
     485                valueType = binSecTokElem.getAttributeNS(None, "ValueType") 
     486                tokValTypes = ( 
     487                    self.__class__.BINARY_SECURITY_TOK_VAL_TYPE['X509v3'], 
     488                    self.__class__.BINARY_SECURITY_TOK_VAL_TYPE['X509']) 
     489                 
     490                if valueType in tokValTypes: 
     491                    # Remove base 64 encoding 
     492                    derString = base64.decodestring(x509CertTxt) 
     493                    self.verifyingCert = X509Cert.Parse(derString,  
     494                                                    format=X509Cert.formatDER) 
     495                    x509Stack = X509Stack() 
     496 
     497                elif valueType == self.__class__.BINARY_SECURITY_TOK_VAL_TYPE[ 
     498                                                            'X509PKIPathv1']: 
     499                     
     500                    derString = base64.decodestring(x509CertTxt) 
     501                    x509Stack = X509StackParseFromDER(derString) 
     502                     
     503                    # TODO: Check ordering - is the last off the stack the 
     504                    # one to use to verify the message? 
     505                    self.verifyingCert = x509Stack[-1] 
     506                else: 
     507                    raise WSSecurityError("BinarySecurityToken ValueType " 
     508                                          'attribute is not recognised: "%s"' % 
     509                                          valueType) 
     510                                
     511            except Exception: 
     512                raise VerifyError("Error extracting BinarySecurityToken " 
     513                                  "from WSSE header: %s" %  
     514                                  traceback.format_exc()) 
     515 
     516        if self.verifyingCert is None: 
     517            raise VerifyError("No certificate set for verification of the " 
     518                              "signature") 
     519         
     520        # Extract RSA public key from the cert 
     521        rsaPubKey = self.verifyingCert.pubKey.get_rsa() 
     522 
     523        # Apply the signature verification 
     524        try: 
     525            verify = rsaPubKey.verify(signedInfoDigestValue, signatureValue) 
     526        except RSA.RSAError, e: 
     527            raise VerifyError("Error in Signature: " % e) 
     528         
     529        if not verify: 
     530            raise InvalidSignature("Invalid signature") 
     531         
     532        # Verify chain of trust  
     533        x509Stack.verifyCertChain(x509Cert2Verify=self.verifyingCert, 
     534                                  caX509Stack=self._caX509Stack) 
     535         
     536        self._verifyTimeStamp(parsedSOAP,  
     537                              SignatureHandler.PROCESSOR_NSS, 
     538                              timestampClockSkew=self.timestampClockSkew, 
     539                              timestampMustBeSet=self.timestampMustBeSet, 
     540                              createdElemMustBeSet=self.createdElemMustBeSet, 
     541                              expiresElemMustBeSet=self.expiresElemMustBeSet)  
     542        log.info("Signature OK")         
     543                
    75544    def _applySignatureConfirmation(self, wsseElem): 
    76545        '''Add SignatureConfirmation element - as specified in WS-Security 1.1 
     
    230699                                     "time %s is before the current time %s." % 
    231700                                     (dtExpiry, dtNow)) 
    232  
    233     def sign(self, soapWriter): 
    234         '''Sign the message body and binary security token of a SOAP message 
    235          
    236         @type soapWriter: ZSI.writer.SoapWriter 
    237         @param soapWriter: ZSI object to write SOAP message 
    238         ''' 
    239          
    240         # Namespaces for XPath searches 
    241         processorNss = \ 
    242         { 
    243             'ds':     DSIG.BASE,  
    244             'wsu':    _WSU.UTILITY,  
    245             'wsse':   OASIS.WSSE,  
    246             'soapenv':"http://schemas.xmlsoap.org/soap/envelope/"  
    247         } 
    248  
    249         # Add X.509 cert as binary security token 
    250         if self.reqBinarySecurityTokValType == \ 
    251            self.BINARY_SECURITY_TOK_VAL_TYPE['X509PKIPathv1']: 
    252             if self.signingCertChain is None: 
    253                 msg = 'SignatureHandler signingCertChain attribute is not set' 
    254                 log.error(msg) 
    255                 raise AttributeError(msg) 
    256              
    257             binSecTokVal = base64.encodestring(self.signingCertChain.asDER()) 
    258         else: 
    259             # Assume X.509 / X.509 vers 3 
    260             if self.signingCert is None: 
    261                 msg = 'SignatureHandler signingCert attribute is not set' 
    262                 log.error(msg) 
    263                 raise AttributeError(msg) 
    264              
    265             binSecTokVal = base64.encodestring(self.signingCert.asDER()) 
    266  
    267         soapWriter._header.setNamespaceAttribute('wsse', OASIS.WSSE) 
    268         soapWriter._header.setNamespaceAttribute('wsse11', OASIS.WSSE11) 
    269         soapWriter._header.setNamespaceAttribute('wsu', _WSU.UTILITY) 
    270         soapWriter._header.setNamespaceAttribute('ds', DSIG.BASE) 
    271          
    272         # Flag if inclusive namespace prefixes are set for the signature or 
    273         # reference elements 
    274         if self.refC14nPfxSet or self.signedInfoC14nPfxSet: 
    275            soapWriter._header.setNamespaceAttribute('ec', DSIG.C14N_EXCL) 
    276          
    277         # Check <wsse:security> isn't already present in header 
    278         wsseElems = soapWriter._header.evaluate('//wsse:security',  
    279                                                 processorNss=processorNss) 
    280         if len(wsseElems) > 1: 
    281             raise SignatureError('wsse:Security element is already present') 
    282  
    283         # Add WSSE element 
    284         wsseElem = soapWriter._header.createAppendElement(OASIS.WSSE,  
    285                                                           'Security') 
    286         wsseElem.setNamespaceAttribute('wsse', OASIS.WSSE) 
    287          
    288         # Flag to recipient - they MUST parse and check this signature  
    289         wsseElem.setAttributeNS(SOAP.ENV, 'mustUnderstand', "1") 
    290          
    291         # Binary Security Token element will contain the X.509 cert  
    292         # corresponding to the private key used to sing the message 
    293         binSecTokElem = wsseElem.createAppendElement(OASIS.WSSE,  
    294                                                      'BinarySecurityToken') 
    295          
    296         # Value type can be any be any one of those supported via  
    297         # BINARY_SECURITY_TOK_VAL_TYPE 
    298         binSecTokElem.setAttributeNS(None,  
    299                                      'ValueType',  
    300                                      self.reqBinarySecurityTokValType) 
    301  
    302         binSecTokElem.setAttributeNS(None,  
    303                                      'EncodingType', 
    304                                      self.BINARY_SECURITY_TOK_ENCODING_TYPE) 
    305          
    306         # Add ID so that the binary token can be included in the signature 
    307         binSecTokElem.setAttributeNS(_WSU.UTILITY, 'Id', "binaryToken") 
    308  
    309         binSecTokElem.createAppendTextNode(binSecTokVal) 
    310  
    311         # Timestamp 
    312         if self.addTimestamp: 
    313             self._addTimeStamp(wsseElem) 
    314              
    315         # Signature Confirmation 
    316         if self.applySignatureConfirmation:  
    317             self._applySignatureConfirmation(wsseElem) 
    318          
    319         # Signature 
    320         signatureElem = wsseElem.createAppendElement(DSIG.BASE, 'Signature') 
    321         signatureElem.setNamespaceAttribute('ds', DSIG.BASE) 
    322          
    323         # Signature - Signed Info 
    324         signedInfoElem = signatureElem.createAppendElement(DSIG.BASE,  
    325                                                            'SignedInfo') 
    326          
    327         # Signed Info - Canonicalization method 
    328         c14nMethodElem = signedInfoElem.createAppendElement(DSIG.BASE, 
    329                                                     'CanonicalizationMethod') 
    330          
    331         # Set based on 'signedInfoIsExcl' property 
    332         c14nAlgOpt = (DSIG.C14N, DSIG.C14N_EXCL) 
    333         signedInfoC14nAlg = c14nAlgOpt[int(self.signedInfoC14nIsExcl)] 
    334          
    335         c14nMethodElem.setAttributeNS(None, 'Algorithm', signedInfoC14nAlg) 
    336          
    337         if self.signedInfoC14nPfxSet: 
    338             c14nInclNamespacesElem = c14nMethodElem.createAppendElement( 
    339                                                     signedInfoC14nAlg, 
    340                                                     'InclusiveNamespaces') 
    341             inclNsPfx = ' '.join(self.signedInfoC14nKw['inclusive_namespaces']) 
    342             c14nInclNamespacesElem.setAttributeNS(None,'PrefixList',inclNsPfx) 
    343          
    344         # Signed Info - Signature method 
    345         sigMethodElem = signedInfoElem.createAppendElement(DSIG.BASE, 
    346                                                            'SignatureMethod') 
    347         sigMethodElem.setAttributeNS(None, 'Algorithm', DSIG.SIG_RSA_SHA1) 
    348          
    349         # Signature - Signature value 
    350         signatureValueElem = signatureElem.createAppendElement(DSIG.BASE,  
    351                                                              'SignatureValue') 
    352          
    353         # Key Info 
    354         KeyInfoElem = signatureElem.createAppendElement(DSIG.BASE, 'KeyInfo') 
    355         secTokRefElem = KeyInfoElem.createAppendElement(OASIS.WSSE,  
    356                                                   'SecurityTokenReference') 
    357          
    358         # Reference back to the binary token included earlier 
    359         wsseRefElem = secTokRefElem.createAppendElement(OASIS.WSSE,  
    360                                                         'Reference') 
    361         wsseRefElem.setAttributeNS(None, 'URI', "#binaryToken") 
    362          
    363         # Add Reference to body so that it can be included in the signature 
    364         soapWriter.body.setAttributeNS(_WSU.UTILITY, 'Id', "body") 
    365  
    366         refElems = soapWriter.body.evaluate('//*[@wsu:Id]',  
    367                                             processorNss=processorNss) 
    368          
    369         # Set based on 'signedInfoIsExcl' property 
    370         refC14nAlg = c14nAlgOpt[int(self.refC14nIsExcl)] 
    371          
    372         # 1) Reference Generation 
    373         # 
    374         # Find references 
    375         for refElem in refElems: 
    376              
    377             refID = refElem.getAttributeValue(_WSU.UTILITY, 'Id') 
    378              
    379             # Set URI attribute to point to reference to be signed 
    380             uri = u"#" + refID 
    381              
    382             # Canonicalize reference 
    383             inclusiveNsKWs = self.createUnsupressedPrefixKW(self.refC14nKw) 
    384             refC14n = refElem.canonicalize(algorithm=refC14nAlg,  
    385                                            **inclusiveNsKWs) 
    386  
    387             # Calculate digest for reference and base 64 encode 
    388             # 
    389             # Nb. encodestring adds a trailing newline char 
    390             digestValue = base64.encodestring(sha(refC14n).digest()).strip() 
    391  
    392  
    393             # Add a new reference element to SignedInfo 
    394             refElem = signedInfoElem.createAppendElement(DSIG.BASE,  
    395                                                          'Reference') 
    396             refElem.setAttributeNS(None, 'URI', uri) 
    397              
    398             # Use ds:Transforms or wsse:TransformationParameters? 
    399             transformsElem = refElem.createAppendElement(DSIG.BASE,  
    400                                                          'Transforms') 
    401             transformElem = transformsElem.createAppendElement(DSIG.BASE,  
    402                                                                'Transform') 
    403  
    404             # Set Canonicalization algorithm type 
    405             transformElem.setAttributeNS(None, 'Algorithm', refC14nAlg) 
    406             if self.refC14nPfxSet: 
    407                 # Exclusive C14N requires inclusive namespace elements 
    408                 inclNamespacesElem = transformElem.createAppendElement( 
    409                                                                                    refC14nAlg, 
    410                                                        'InclusiveNamespaces') 
    411                 refInclNsPfx = ' '.join(self.refC14nKw['inclusive_namespaces']) 
    412                 inclNamespacesElem.setAttributeNS(None, 'PrefixList',  
    413                                                   refInclNsPfx) 
    414              
    415             # Digest Method  
    416             digestMethodElem = refElem.createAppendElement(DSIG.BASE,  
    417                                                            'DigestMethod') 
    418             digestMethodElem.setAttributeNS(None, 'Algorithm',DSIG.DIGEST_SHA1) 
    419              
    420             # Digest Value 
    421             digestValueElem = refElem.createAppendElement(DSIG.BASE,  
    422                                                           'DigestValue') 
    423             digestValueElem.createAppendTextNode(digestValue) 
    424  
    425     
    426         # 2) Signature Generation 
    427         #         
    428         # Canonicalize the signedInfo node 
    429         signedInfoInclusiveNsKWs = self.createUnsupressedPrefixKW( 
    430                                                         self.signedInfoC14nKw) 
    431         try: 
    432             signedInfoElem = soapWriter.body.evaluate('//ds:SignedInfo', 
    433                                                   processorNss=processorNss)[0] 
    434         except TypeError, e: 
    435             log.error("Error locating SignedInfo element for signature") 
    436             raise  
    437          
    438         c14nSignedInfo=signedInfoElem.canonicalize(algorithm=signedInfoC14nAlg, 
    439                                                    **signedInfoInclusiveNsKWs) 
    440         # Calculate digest of SignedInfo 
    441         signedInfoDigestValue = sha(c14nSignedInfo).digest() 
    442          
    443         # Sign using the private key and base 64 encode the result 
    444         signatureValue = self.signingPriKey.sign(signedInfoDigestValue) 
    445         b64EncSignatureValue = base64.encodestring(signatureValue).strip() 
    446  
    447         # Add to <SignatureValue> 
    448         signatureValueElem.createAppendTextNode(b64EncSignatureValue) 
    449  
    450         log.info("Signature generation complete") 
    451  
    452  
    453     def createUnsupressedPrefixKW(self, dictToConvert): 
    454         """ 
    455         Convert a dictionary to use keys with names, 'inclusive_namespaces' in 
    456         place of keys with names 'unsupressedPrefixes' 
    457         NB, this is required for the ZSI canonicalize method 
    458         @type dictToConvert: dict 
    459         @param dictToConvert: dictionary to convert 
    460         @rtype: dict 
    461         @return: dictionary with corrected keys 
    462         """ 
    463         nsList = [] 
    464         newDict = dictToConvert.copy() 
    465         if isinstance(newDict, dict) and \ 
    466             isinstance(newDict.get('inclusive_namespaces'), list): 
    467             nsList = newDict.get('inclusive_namespaces') 
    468             newDict.pop('inclusive_namespaces') 
    469  
    470         newDict['unsuppressedPrefixes'] = nsList 
    471         return newDict 
    472  
    473     def verify(self, parsedSOAP, raiseNoSignatureFound=True): 
    474         """Verify signature 
    475          
    476         @type parsedSOAP: ZSI.parse.ParsedSoap 
    477         @param parsedSOAP: object contain parsed SOAP message received from 
    478         sender""" 
    479  
    480         processorNss = { 
    481             'ds':     DSIG.BASE,  
    482             'wsu':    _WSU.UTILITY,  
    483             'wsse':   OASIS.WSSE,  
    484             'soapenv':SOAP.ENV  
    485         } 
    486         signatureElem = parsedSOAP.dom.xpath('//ds:Signature',  
    487                                              explicitNss=processorNss) 
    488         if len(signatureElem) > 1: 
    489             raise VerifyError('Multiple <ds:Signature/> elements found') 
    490          
    491         try: 
    492             signatureElem = signatureElem[0] 
    493         except IndexError: 
    494             # Message wasn't signed 
    495             msg = "Input message wasn't signed!" 
    496             if raiseNoSignatureFound: 
    497                 raise NoSignatureFound(msg) 
    498             else:  
    499                 log.warning(msg) 
    500                 return 
    501          
    502         # Two stage process: reference validation followed by signature  
    503         # validation  
    504          
    505         # 1) Reference Validation 
    506          
    507         # Check for canonicalization set via ds:CanonicalizationMethod - 
    508         # Use this later as a back up in case no Canonicalization was set in  
    509         # the transforms elements 
    510         try: 
    511             c14nMethodElem=parsedSOAP.dom.xpath('//ds:CanonicalizationMethod', 
    512                                                 explicitNss=processorNss)[0] 
    513         except TypeError, e: 
    514             log.error("XPath query error locating " 
    515                       "<ds:CanonicalizationMethod/>: %s" % e) 
    516             raise 
    517          
    518         refElems = parsedSOAP.dom.xpath('//ds:Reference', 
    519                                         explicitNss=processorNss) 
    520  
    521         for refElem in refElems: 
    522             # Get the URI for the reference 
    523             refURI = refElem.getAttributeNS(None, 'URI') 
    524              
    525             try: 
    526                 transformsElem = getElements(refElem, "Transforms")[0] 
    527                 transformElems = getElements(transformsElem, "Transform") 
    528      
    529                 refAlgorithm = transformElems[0].getAttributeNS(None, 
    530                                                                 'Algorithm') 
    531             except Exception, e: 
    532                 raise VerifyError('failed to get transform algorithm for ' 
    533                                   '<ds:Reference URI="%s">' %  
    534                                   (refURI, e)) 
    535                  
    536             # Add extra keyword for Exclusive canonicalization method 
    537             refC14nKw = {} 
    538             refC14nIsExcl = refAlgorithm == DSIG.C14N_EXCL 
    539             if refC14nIsExcl: 
    540                 try: 
    541                     # Check for no inclusive namespaces set 
    542                     inclusiveNS = getElements(transformElems[0],  
    543                                               "InclusiveNamespaces")                    
    544                     if len(inclusiveNS) > 0: 
    545                         pfxListAttElem=inclusiveNS[0].getAttributeNodeNS(None,  
    546                                                                 'PrefixList') 
    547                              
    548                         refC14nKw['inclusivePrefixes'] = \ 
    549                                                 pfxListAttElem.value.split() 
    550                     else: 
    551                         refC14nKw['inclusivePrefixes'] = None 
    552                 except Exception, e: 
    553                     raise VerifyError('failed to handle transform (%s) in ' 
    554                                       '<ds:Reference URI="%s">: %s' % \ 
    555                                       (transformElems[0], refURI, e)) 
    556          
    557             # Canonicalize the reference data and calculate the digest 
    558             if refURI[0] != "#": 
    559                 raise VerifyError("Expecting # identifier for Reference URI " 
    560                                   "\"%s\"" % refURI) 
    561                      
    562             # XPath reference 
    563             uriXPath = '//*[@wsu:Id="%s"]' % refURI[1:] 
    564             uriElem = parsedSOAP.dom.xpath(uriXPath, 
    565                                            explicitNss=processorNss)[0] 
    566  
    567             f = StringIO() 
    568             CanonicalPrint(uriElem, stream=f, exclusive=refC14nIsExcl, 
    569                            **refC14nKw) 
    570             refC14n = f.getvalue() 
    571             digestValue = base64.encodestring(sha(refC14n).digest()).strip() 
    572              
    573             # Extract the digest value that was stored             
    574             digestNode = getElements(refElem, "DigestValue")[0] 
    575             nodeDigestValue = str(digestNode.childNodes[0].nodeValue).strip()    
    576              
    577             # Reference validates if the two digest values are the same 
    578             if digestValue != nodeDigestValue: 
    579                 raise InvalidSignature('Digest Values do not match for URI: ' 
    580                                        '"%s"' % refURI) 
    581              
    582             log.debug("Verified canonicalization for element %s" % refURI[1:]) 
    583                  
    584         # 2) Signature Validation 
    585         signedInfoElem = parsedSOAP.dom.xpath('//ds:SignedInfo', 
    586                                               explicitNss=processorNss)[0] 
    587  
    588         # Get algorithm used for canonicalization of the SignedInfo  
    589         # element.  Nb. This is NOT necessarily the same as that used to 
    590         # canonicalize the reference elements checked above! 
    591         signedInfoC14nAlg = c14nMethodElem.getAttributeNS(None, "Algorithm") 
    592         signedInfoC14nKw = {} 
    593         signedInfoC14nIsExcl = signedInfoC14nAlg == DSIG.C14N_EXCL 
    594         if signedInfoC14nIsExcl: 
    595             try: 
    596                 # Check for inclusive namespaces 
    597                 inclusiveNsElem = getElements(c14nMethodElem, 
    598                                               "InclusiveNamespaces") 
    599                 if len(inclusiveNsElem) > 0:                     
    600                     pfxListAttElem=inclusiveNsElem[0].getAttributeNodeNS(None, 
    601                                                                  'PrefixList') 
    602                     signedInfoC14nKw['inclusivePrefixes'] = \ 
    603                                                 pfxListAttElem.value.split() 
    604                 else: 
    605                     signedInfoC14nKw['inclusivePrefixes'] = None 
    606             except Exception, e: 
    607                 raise VerifyError('failed to handle exclusive ' 
    608                                   'canonicalisation for SignedInfo: %s' % e) 
    609  
    610         # Canonicalize the SignedInfo node and take digest 
    611         f = StringIO() 
    612         CanonicalPrint(signedInfoElem, 
    613                        stream=f, 
    614                        exclusive=signedInfoC14nIsExcl,  
    615                        **signedInfoC14nKw)        
    616         c14nSignedInfo = f.getvalue()   
    617                         
    618         signedInfoDigestValue = sha(c14nSignedInfo).digest() 
    619          
    620         # Get the signature value in order to check against the digest just 
    621         # calculated 
    622         signatureValueElem = parsedSOAP.dom.xpath('//ds:SignatureValue', 
    623                                                   explicitNss=processorNss)[0] 
    624  
    625         # Remove base 64 encoding 
    626         b64EncSignatureValue = signatureValueElem.childNodes[0].nodeValue 
    627         signatureValue = base64.decodestring(b64EncSignatureValue) 
    628  
    629         # Cache Signature Value here so that a response can include it. 
    630         # 
    631         # Nb. If the sign method is called from a separate SignatureHandler 
    632         # object then the signature value must be passed from THIS object to 
    633         # the other SignatureHandler otherwise signature confirmation will 
    634         # fail 
    635         if self.applySignatureConfirmation: 
    636             # re-encode string to avoid possible problems with interpretation  
    637             # of line breaks 
    638             self.b64EncSignatureValue = b64EncSignatureValue 
    639         else: 
    640             self.b64EncSignatureValue = None 
    641           
    642         # Look for X.509 Cert in wsse:BinarySecurityToken node 
    643         try: 
    644             binSecTokElem = parsedSOAP.dom.xpath('//wsse:BinarySecurityToken', 
    645                                                  explicitNss=processorNss)[0] 
    646         except: 
    647             # Signature may not have included the Binary Security Token in  
    648             # which case the verifying cert will need to have been set  
    649             # elsewhere 
    650             log.info("No Binary Security Token found in WS-Security header") 
    651             binSecTokElem = None 
    652          
    653         if binSecTokElem: 
    654             try: 
    655                 x509CertTxt=str(binSecTokElem.childNodes[0].nodeValue) 
    656                  
    657                 valueType = binSecTokElem.getAttributeNS(None, "ValueType") 
    658                 if valueType in (self.__class__.BINARY_SECURITY_TOK_VAL_TYPE['X509v3'], 
    659                                  self.__class__.BINARY_SECURITY_TOK_VAL_TYPE['X509']): 
    660                     # Remove base 64 encoding 
    661                     derString = base64.decodestring(x509CertTxt) 
    662                     self.verifyingCert = X509Cert.Parse(derString,  
    663                                                     format=X509Cert.formatDER) 
    664                     x509Stack = X509Stack() 
    665  
    666                 elif valueType == \ 
    667                     self.__class__.BINARY_SECURITY_TOK_VAL_TYPE['X509PKIPathv1']: 
    668                      
    669                     derString = base64.decodestring(x509CertTxt) 
    670                     x509Stack = X509StackParseFromDER(derString) 
    671                      
    672                     # TODO: Check ordering - is the last off the stack the 
    673                     # one to use to verify the message? 
    674                     self.verifyingCert = x509Stack[-1] 
    675                 else: 
    676                     raise WSSecurityError("BinarySecurityToken ValueType " 
    677                                           'attribute is not recognised: "%s"' % 
    678                                           valueType) 
    679                                 
    680             except Exception, e: 
    681                 raise VerifyError("Error extracting BinarySecurityToken " 
    682                                   "from WSSE header: %s" % e) 
    683  
    684         if self.verifyingCert is None: 
    685             raise VerifyError("No certificate set for verification of the " 
    686                               "signature") 
    687          
    688         # Extract RSA public key from the cert 
    689         rsaPubKey = self.verifyingCert.pubKey.get_rsa() 
    690  
    691         # Apply the signature verification 
    692         try: 
    693             verify = rsaPubKey.verify(signedInfoDigestValue, signatureValue) 
    694         except RSA.RSAError, e: 
    695             raise VerifyError("Error in Signature: " % e) 
    696          
    697         if not verify: 
    698             raise InvalidSignature("Invalid signature") 
    699          
    700         # Verify chain of trust  
    701         x509Stack.verifyCertChain(x509Cert2Verify=self.verifyingCert, 
    702                                   caX509Stack=self._caX509Stack) 
    703          
    704         self._verifyTimeStamp(parsedSOAP,  
    705                               processorNss, 
    706                               timestampClockSkew=self.timestampClockSkew, 
    707                               timestampMustBeSet=self.timestampMustBeSet, 
    708                               createdElemMustBeSet=self.createdElemMustBeSet, 
    709                               expiresElemMustBeSet=self.expiresElemMustBeSet)  
    710         log.info("Signature OK")         
  • TI12-security/trunk/WSSecurity/ndg/wssecurity/test/unit/signaturehandler/foursuite/server/echoServer.py

    r5291 r6399  
    1515from EchoService_services_server import EchoService as _EchoService 
    1616 
    17 from ndg.security.common.wssecurity.signaturehandler.dom import SignatureHandler 
     17from ndg.wssecurity.common.signaturehandler import SignatureHandlerFactory 
    1818 
    1919from os.path import expandvars as xpdVars 
     
    118118    # Create the Inherited version of the server 
    119119    echo = EchoService() 
    120     echo.signatureHandler = SignatureHandler(cfg=wsseCfgFilePath) 
     120    echo.signatureHandler = SignatureHandlerFactory.fromConfigFile( 
     121                                                                wsseCfgFilePath) 
    121122 
    122123    serviceContainer.setNode(echo, url=path) 
  • TI12-security/trunk/WSSecurity/ndg/wssecurity/test/unit/signaturehandler/foursuite/server/wssecurity.cfg

    r5560 r6399  
    99# BSD - See LICENCE file for details 
    1010# 
    11 # TODO: Refactor option names - put into inbound and outbound sections / apply 
    12 # namespace prefixes to better categorise 
    1311[DEFAULT] 
     12className = ndg.wssecurity.common.signaturehandler.foursuite.SignatureHandler 
    1413 
    1514# 
Note: See TracChangeset for help on using the changeset viewer.