Changeset 1947 for TI12-security


Ignore:
Timestamp:
03/01/07 17:17:49 (13 years ago)
Author:
pjkersha
Message:

python/ndg.security.test/ndg/security/test/XMLSecDoc/xmlSecDocTest.py and
python/ndg.security.common/ndg/security/common/XMLSec.py: cont'd refactoring to use M2Crypto based XML
signature.

Location:
TI12-security/trunk/python
Files:
2 edited

Legend:

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

    r1946 r1947  
    11"""NDG XML Security - Encryption and Digital Signature 
    22 
    3 Wraps pyXMLSec package 
    4  
    53Nerc Data Grid Project 
    64 
    75P J Kershaw 05/04/05 
    86 
    9 Copyright (C) 2006 CCLRC & NERC 
     7P J Kershaw 03/01/07: Re-write to use M2Crypto, ZSI and DOM instead of  
     8pyXMLSec 
    109 
    1110This software may be distributed under the terms of the Q Public License, 
     
    3029# associated note 
    3130from xml.dom.ext.reader.PyExpat import Reader 
     31 
     32# Digest and signature/verify 
     33from sha import sha 
     34from M2Crypto import X509, BIO, RSA 
     35import base64 
     36 
     37# Canonicalization 
     38from ZSI.wstools.c14n import Canonicalize 
     39from xml.dom import Node 
     40from xml.xpath.Context import Context 
     41from xml import xpath 
     42 
     43from ZSI.wstools.Namespaces import DSIG 
    3244 
    3345 
     
    14811493                        fdel=__delFilePath, 
    14821494                        doc="File Path for XML document to apply security to") 
    1483  
    1484  
    1485     #_________________________________________________________________________ 
    1486     def __setCertFilePathList(self, filePath): 
     1495     
     1496     
     1497    def __getDocNode(self): 
     1498        """Get file path for file to be signed/encrypted.""" 
     1499        return self.__docNode 
     1500 
     1501 
     1502    def __delDocNode(self): 
     1503        """Prevent file path being deleted.""" 
     1504        raise AttributeError, "\"docNode\" cannot be deleted" 
     1505  
     1506   
     1507    # Publish attribute as read/write 
     1508    docNode = property(fget=__getDocNode, 
     1509                       fdel=__delDocNode, 
     1510                       doc="DOM document node for XML") 
     1511 
     1512    #_________________________________________________________________________ 
     1513    def __setCertdocNodeList(self, filePath): 
    14871514        """File path for certificate used to sign document /  
    14881515        list of certificates used to check the signature of a document""" 
     
    16271654             inclX509SubjName=True, 
    16281655             inclX509IssSerial=True, 
    1629              rtnAsString=False): 
     1656             rtnAsString=False, 
     1657             **c14nKw): 
    16301658        """Sign XML document using an X.509 certificate private key 
    16311659 
     
    16571685            self.parse(xmlTxt) 
    16581686 
    1659              
     1687        if self.__docNode is None: 
     1688            XMLSecDocError, "XML to be signed has not been read in or parsed." 
     1689                
    16601690        # Set private key file 
    16611691        if signingKeyFilePath is not None: 
     
    16661696        if certFilePathList is not None: 
    16671697            self.__setCertFilePathList(certFilePathList) 
    1668              
    1669         # Return as required 
    1670         if rtnAsString: 
    1671             return self.asString() 
    1672          
    1673          
    1674         # Add X.509 cert as binary security token 
    1675         x509Cert = X509.load_cert(self.__certFilePathList[0]) 
    1676          
    1677         x509CertPat = re.compile(\ 
    1678             '-----BEGIN CERTIFICATE-----\n?(.*?)\n?-----END CERTIFICATE-----', 
    1679             re.S) 
    1680         x509CertStr = x509CertPat.findall(x509Cert.as_pem())[0] 
    1681  
    1682         soapWriter._header.setNamespaceAttribute('ds', DSIG.BASE) 
    1683         soapWriter._header.setNamespaceAttribute('ec', DSIG.C14N_EXCL) 
    1684          
    1685          
    1686         # Change value and encoding types to suite WebSphere 
    1687 #        binSecTokElem.node.setAttribute('ValueType', "wsse:X509v3") 
    1688         valueType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509" 
    1689         binSecTokElem.node.setAttribute('ValueType', valueType) 
    1690 #        binSecTokElem.node.setAttribute('EncodingType', "wsse:Base64Binary") 
    1691         encodingType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" 
    1692         binSecTokElem.node.setAttribute('EncodingType', encodingType) 
    1693          
    1694         # Add ID so that the binary token can be included in the signature 
    1695         binSecTokElem.node.setAttribute('wsu:Id', "binaryToken") 
    1696  
    1697         binSecTokElem.createAppendTextNode(x509CertStr) 
     1698 
     1699        self.__docNode.setNamespaceAttribute('ds', DSIG.BASE) 
     1700        self.__docNode.setNamespaceAttribute('ec', DSIG.C14N_EXCL) 
    16981701 
    16991702         
    17001703        # Signature 
    1701         signatureElem = wsseElem.createAppendElement(DSIG.BASE, 'Signature') 
     1704        signatureElem = self.__docNode.createAppendElement(DSIG.BASE,  
     1705                                                           'Signature') 
    17021706        signatureElem.setNamespaceAttribute('ds', DSIG.BASE) 
    17031707         
     
    17131717        c14nMethodElem.node.setAttribute('Algorithm', DSIG.C14N_EXCL) 
    17141718        c14nInclNamespacesElem = c14nMethodElem.createAppendElement(\ 
    1715                         DSIG.C14N_EXCL, 
    1716                                                 'InclusiveNamespaces') 
     1719                                                    DSIG.C14N_EXCL, 
     1720                                                    'InclusiveNamespaces') 
    17171721        c14nInclNamespacesElem.node.setAttribute('PrefixList',  
    17181722            ' '.join(signedInfoC14nKw['unsuppressedPrefixes'])) 
     
    17211725        sigMethodElem = signedInfoElem.createAppendElement(DSIG.BASE, 
    17221726                                                    'SignatureMethod') 
    1723         #sigMethodElem.node.setAttribute('Algorithm', DSIG.DIGEST_SHA1) 
    17241727        sigMethodElem.node.setAttribute('Algorithm', DSIG.SIG_RSA_SHA1) 
    17251728         
     
    17411744            'ds':     DSIG.BASE,  
    17421745        } 
    1743         ctxt = Context(docNode, processorNss=processorNss) 
    1744         idNodes = xpath.Evaluate('//*[@wsu:Id]',  
    1745                                  contextNode=docNode,  
    1746                                  context=ctxt) 
     1746        ctxt = Context(self.__docNode, processorNss=processorNss) 
    17471747         
    17481748        # 1) Reference Generation 
    17491749        # 
    17501750        # Find references 
    1751         c14nKw = {} 
    1752         c14nKw['unsuppressedPrefixes'] = ['xmlns', 'xsi', 'xsd', 'SOAP-ENV', 'wsu', 'wsse', 'ns1'] 
    1753         for idNode in idNodes: 
    1754              
    1755             # Set URI attribute to point to reference to be signed 
    1756             #uri = u"#" + idNode.getAttribute('wsu:Id') 
    1757             uri = u"#" + idNode.attributes[(_WSU.UTILITY, 'Id')].value 
    1758              
    1759             # Canonicalize reference 
    1760             c14nRef = Canonicalize(idNode, **c14nKw) 
    1761              
    1762             # Calculate digest for reference and base 64 encode 
    1763             # 
    1764             # Nb. encodestring adds a trailing newline char 
    1765             digestValue = base64.encodestring(sha(c14nRef).digest()).strip() 
    1766  
    1767  
    1768             # Add a new reference element to SignedInfo 
    1769             refElem = signedInfoElem.createAppendElement(DSIG.BASE,  
    1770                                                          'Reference') 
    1771             refElem.node.setAttribute('URI', uri) 
    1772              
    1773             # Use ds:Transforms or wsse:TransformationParameters? 
    1774             transformsElem = refElem.createAppendElement(DSIG.BASE,  
    1775                                                         'Transforms') 
    1776             transformElem = transformsElem.createAppendElement(DSIG.BASE,  
    1777                                                                'Transform') 
    1778             transformElem.node.setAttribute('Algorithm', DSIG.C14N_EXCL) 
    1779  
    1780             inclNamespacesElem = transformElem.createAppendElement(\ 
    1781                             DSIG.C14N_EXCL, 
    1782                                                        'InclusiveNamespaces') 
    1783             inclNamespacesElem.node.setAttribute('PrefixList', 
    1784                 ' '.join(c14nKw['unsuppressedPrefixes'])) 
    1785              
    1786             # Digest Method  
    1787             digestMethodElem = refElem.createAppendElement(DSIG.BASE,  
    1788                                                            'DigestMethod') 
    1789             digestMethodElem.node.setAttribute('Algorithm', DSIG.DIGEST_SHA1) 
    1790              
    1791             # Digest Value 
    1792             digestValueElem = refElem.createAppendElement(DSIG.BASE,  
    1793                                                           'DigestValue') 
    1794             digestValueElem.createAppendTextNode(digestValue) 
     1751        if not c14nKw: 
     1752            c14nKw['unsuppressedPrefixes'] = ['xmlns', 'ns1'] 
     1753         
     1754        # Canonicalize reference 
     1755        c14nRef = Canonicalize(idNode, **c14nKw) 
     1756         
     1757        # Calculate digest for reference and base 64 encode 
     1758        # 
     1759        # Nb. encodestring adds a trailing newline char 
     1760        digestValue = base64.encodestring(sha(c14nRef).digest()).strip() 
     1761 
     1762 
     1763        # Add a new reference element to SignedInfo 
     1764        refElem = signedInfoElem.createAppendElement(DSIG.BASE, 'Reference') 
     1765         
     1766        # Use ds:Transforms or wsse:TransformationParameters? 
     1767        transformsElem = refElem.createAppendElement(DSIG.BASE,  
     1768                                                    'Transforms') 
     1769        transformElem = transformsElem.createAppendElement(DSIG.BASE,  
     1770                                                           'Transform') 
     1771        transformElem.node.setAttribute('Algorithm', DSIG.C14N_EXCL) 
     1772 
     1773        inclNamespacesElem = transformElem.createAppendElement(\ 
     1774                                                   DSIG.C14N_EXCL, 
     1775                                                   'InclusiveNamespaces') 
     1776        inclNamespacesElem.node.setAttribute('PrefixList', 
     1777                                    ' '.join(c14nKw['unsuppressedPrefixes'])) 
     1778         
     1779        # Digest Method  
     1780        digestMethodElem = refElem.createAppendElement(DSIG.BASE,  
     1781                                                       'DigestMethod') 
     1782        digestMethodElem.node.setAttribute('Algorithm', DSIG.DIGEST_SHA1) 
     1783         
     1784        # Digest Value 
     1785        digestValueElem = refElem.createAppendElement(DSIG.BASE,  
     1786                                                      'DigestValue') 
     1787        digestValueElem.createAppendTextNode(digestValue) 
    17951788 
    17961789    
     
    18451838        print "Signature Generated" 
    18461839        print str(soapWriter) 
     1840         
     1841        if inclX509Cert: 
     1842            # Add X.509 cert 
     1843            x509Cert = X509.load_cert(self.__certFilePathList[0]) 
     1844             
     1845            x509CertPat = re.compile(\ 
     1846            '-----BEGIN CERTIFICATE-----\n?(.*?)\n?-----END CERTIFICATE-----', 
     1847            re.S) 
     1848            x509CertStr = x509CertPat.findall(x509Cert.as_pem())[0] 
     1849                 
     1850            x509CertElem.createAppendTextNode(x509CertStr) 
     1851             
     1852        # Return as required 
     1853        if rtnAsString: 
     1854            return self.asString() 
    18471855 
    18481856 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/XMLSecDoc/xmlSecDocTest.py

    r1945 r1947  
    7474             
    7575        try: 
     76            certFilePathList = self.cfg['test2Sign']['certfile'] 
     77            signingKeyFilePath = self.cfg['test2Sign']['keyfile'] 
    7678            self.xmlSecDoc.sign() 
    7779        except: 
     
    8284             
    8385        try: 
    84             self.xmlSecDoc.filePath = self.cfg['test3Write'].get('filePath') 
     86            self.xmlSecDoc.filePath = self.cfg['test3Write']['filePath'] 
    8587            self.xmlSecDoc.write() 
    8688        except: 
Note: See TracChangeset for help on using the changeset viewer.