Changeset 4081 for TI12-security/trunk


Ignore:
Timestamp:
01/08/08 15:29:07 (11 years ago)
Author:
pjkersha
Message:

First working version of an OpenID Provider as opposed to a Relying Party as avail. with AuthKit?. The code is taken from the HTTPServer example in the Python OpenID package and refactored into WSGI middleware.

  • ndg.security.server.wsgi.openid_provider - WSGI middleware package
  • Tests/openid-provider/op: pylons project test harness for the above

TODO: integrate into AuthKit? and Beaker Session Middleware as required.

Location:
TI12-security/trunk/python
Files:
64 added
3 edited

Legend:

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

    r4059 r4081  
    11111111 
    11121112        signatureElems = self._soapEnvElem.findall('.//ds:Signature',  
    1113                                                    namespaces=self._processorNSs)         
     1113                                                namespaces=self._processorNSs)         
    11141114        if len(signatureElems) > 1: 
    11151115            raise VerifyError('Multiple <ds:Signature/> elements found') 
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/xmlsec/etree.py

    r4061 r4081  
    1212__contact__ = "P.J.Kershaw@rl.ac.uk" 
    1313__revision__ = "$Id$" 
     14import logging 
     15log = logging.getLogger(__name__) 
    1416 
    1517import types 
    1618import os 
     19import base64 
     20from StringIO import StringIO 
    1721 
    1822# Digest and signature/verify 
     
    2024from M2Crypto import X509, BIO, RSA 
    2125from ndg.security.common.X509 import X509CertRead, X509Stack 
    22 import base64 
    2326 
    2427from ZSI.wstools.Namespaces import DSIG, XMLNS 
     28from elementtree import ElementC14N, ElementTree 
    2529 
    2630# Check ElementTree Canonicalization keywords to check if Exclusive 
     
    260264        not been parsed.""" 
    261265 
    262         if not self._rootElem: 
    263             return None 
     266        if self._rootElem is None: 
     267            return '' 
    264268         
    265269        if inclXMLhdr: 
     
    292296         
    293297        if stream is None: 
    294             try: 
    295                 stream = open(self._filePath, 'w') 
    296             except IOError, e: 
    297                 raise XMLSecDocError('Reading file: %s' % e) 
    298          
     298            # File object or file path string may be passed to parse 
     299            stream = self._filePath 
     300 
    299301        self._rootETree = ElementC14N.parse(stream) 
    300302        self._rootElem = self._rootETree.getroot() 
     
    303305    def write(self): 
    304306        """Write XML document""" 
    305         try: 
    306             f = open(self._filePath, 'w') 
    307         except IOError, e: 
    308             raise XMLSecDocError('Writing file: %s' % e) 
    309          
    310         # Check that namespace scope has been added - this will be the case 
    311         # for a parsed message but not true for a document created in memory. 
    312         # In the latter case a call to build the scope is required 
    313         if hasattr(self._rootETree, '_scope'): 
    314             ElementC14N.write(self._rootETree, f, **kw) 
    315         else: 
    316             ElementC14N.write(ElementC14N.build_scoped_tree(self._rootElem), 
    317                               f, 
    318                               **kw) 
     307#        try: 
     308#            f = open(self._filePath, 'w') 
     309#        except IOError, e: 
     310#            raise XMLSecDocError('Writing file: %s' % e) 
     311         
     312        ElementC14N.write(update_scoped_tree(self._rootETree), self._filePath)#f) 
    319313 
    320314 
     
    323317        info''' 
    324318        f = StringIO() 
    325  
    326         # Check that namespace scope has been added - this will be the case 
    327         # for a parsed message but not true for a document created in memory. 
    328         # In the latter case a call to build the scope is required 
    329         if hasattr(self._rootETree, '_scope'): 
    330             ElementC14N.write(self._rootETree, f, **kw) 
    331         else: 
    332             ElementC14N.write(ElementC14N.build_scoped_tree(self._rootElem), 
    333                               f, 
    334                               **kw) 
    335              
     319        ElementC14N.write(update_scoped_tree(self._rootETree),f,**kw)             
    336320        c14n = f.getvalue() 
    337321 
     
    365349        SignedInfo section of the signature.   
    366350        """ 
    367  
     351        log.debug("XMLSecDoc.applyEnvelopedSignature ...") 
     352         
    368353        if xmlTxt: 
     354            log.debug("Parsing from input string ...") 
    369355            self.parse(xmlTxt) 
    370356 
     
    378364        signedInfoC14nIsExcl = isExclC14n(signedInfoC14nKw) 
    379365        signedInfoC14nHasInclNSs = inclNSsSet(signedInfoC14nKw) 
     366        log.debug("SignedInfo C14N method set to %s ..." % \ 
     367                  (signedInfoC14nIsExcl and 'exclusive' or 'inclusive')) 
    380368         
    381369        refC14nIsExcl = isExclC14n(refC14nKw) 
     
    386374        self._rootElem.set('xmlns:%s' % 'ds', DSIG.BASE) 
    387375        if refC14nIsExcl: 
     376            log.debug("Reference C14N method set to exclusive ...") 
    388377            self._rootElem.set('xmlns:%s' % 'ec', DSIG.C14N_EXCL) 
    389378        else: 
     379            log.debug("Reference C14N method set to inclusive ...") 
    390380            self._rootElem.set('xmlns:%s' % 'ec', DSIG.C14N) 
    391381             
     
    401391        # element 
    402392        refC14n = self.canonicalize(**refC14nKw) 
     393        log.debug("Reference C14N = %s" % refC14n) 
    403394         
    404395        # Calculate digest for reference and base 64 encode 
     
    414405         
    415406        # Signature - Signed Info 
    416         signedInfoElem = ElementTree.SubElement(self._rootElem, 
     407        signedInfoElem = ElementTree.SubElement(signatureElem, 
    417408                                        "{%s}%s" % (DSIG.BASE,'SignedInfo')) 
    418409 
     
    547538        no signature element is found, False to return to caller logging a  
    548539        message""" 
     540         
     541        log.debug("XMLSecDoc.verifyEnvelopedSignature ...") 
    549542        
    550543        if xmlTxt: 
     544            log.debug("Parsing from input string ...") 
    551545            self.parse(xmlTxt) 
    552546                                 
     
    560554            'ec':    DSIG.C14N_EXCL 
    561555        } 
    562         ctx = Context(self._rootElem, processorNss=processorNss) 
    563          
    564  
    565556        signatureElems = self._rootElem.findall('.//ds:Signature',  
    566557                                                namespaces=processorNss) 
     
    611602         
    612603        # Get transforms that were applied 
    613         try: 
    614             transformsElem = refElem.find("Transforms", 
    615                                           namespaces=processorNss) 
    616             transformElems = transformsElem.findall("Transform") 
    617  
    618         except Exception, e: 
    619             raise VerifyError,'failed to get transform algorithm: %s' % str(e) 
    620              
     604        transformElems = refElem.findall("ds:Transforms/ds:Transform", 
     605                                         namespaces=processorNss) 
     606        if transformElems == []: 
     607            raise VerifyError('Failed to find transform elements') 
    621608             
    622609        # Check for enveloped style signature and also check for list of  
     
    648635        # Extract the digest value for the reference  
    649636           
    650         refDigestElem = refElem.find("DigestValue") 
     637        refDigestElem = refElem.find('ds:DigestValue', namespaces=processorNss) 
    651638        if refDigestElem is None: 
    652639            raise VerifyError("Error reading reference digest value") 
     
    662649            raise VerifyError("No <ds:SignedInfo/> element found") 
    663650 
     651        signedInfoElem = signedInfoElems[0] 
     652         
    664653        # Get algorithm used for canonicalization of the SignedInfo  
    665654        # element.  Nb. This is NOT necessarily the same as that used to 
     
    724713        # With the Signature node now removed, the parent node can now be 
    725714        # canonicalized and the digest calculated 
    726         refC14n = Canonicalize(**refC14nKw) 
     715        refC14n = self.canonicalize(**refC14nKw) 
     716        log.debug("Reference C14N = %s" % refC14n) 
    727717        calcRefDigestValue = base64.encodestring(sha(refC14n).digest()).strip() 
    728          
     718                
    729719        # Restore signature node 
    730720        self._rootElem.append(signatureElem) 
    731          
    732721         
    733722        # Reference validates if the newly calculated digest value and the  
     
    741730        #         
    742731        # Extract RSA public key from the cert 
    743         rsaPubKey = x509Cert.get_pubkey().get_rsa() 
     732        rsaPubKey = m2X509Cert.get_pubkey().get_rsa() 
    744733 
    745734        # Compare digest value of the SignedInfo element calculated earlier  
     
    752741        if not verify: 
    753742            raise InvalidSignature("Invalid signature") 
    754          
     743 
    755744        # Verify chain of trust if list cert list is present 
    756745        if self._certFilePathList: 
     
    762751            # Make a stack object for certs to be verified    
    763752            x509Stack = X509Stack() 
    764             x509Stack.push(x509Cert) 
     753            x509Stack.push(m2X509Cert) 
    765754            x509Stack.verifyCertChain(caX509Stack=caX509Stack) 
    766755 
     
    806795        raise NotImplementedError, \ 
    807796                        "Encryption algorithm not implemented in this version" 
     797 
     798def update_scoped_tree(root): 
     799    '''Modification of build_scoped_tree to enable updates to be made on  
     800    existing _scope attribute passed in the input tree.  Nb. the input is  
     801    an ElementTree type and NOT an Element type''' 
     802     
     803    elem = root.getroot() 
     804     
     805    # build scope map - may not have previously been created. 
     806    if not hasattr(root, '_scope'): 
     807        root._scope = {} 
     808         
     809    for e in elem.getiterator(): 
     810        scope = [] 
     811        for k in e.keys(): 
     812            if k.startswith("xmlns:"): 
     813                # move xmlns prefix to scope map 
     814                scope.append((k[6:], e.get(k))) 
     815 
     816        if scope: 
     817            # Append to existing scope if it already exists 
     818            if e in root._scope: 
     819                # Ensure only new items are added 
     820                uniq=[(k,v) for k,v in scope if k not in dict(root._scope[e])] 
     821                root._scope[e] += uniq 
     822            else: 
     823                root._scope[e] = scope 
     824 
     825    # build parent map 
     826    root._parent = dict((c, p) for p in elem.getiterator() for c in p) 
     827 
     828    return root 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/sso/sso/controllers/login.py

    r3994 r4081  
    122122         
    123123        # Cache user attributes in Session Manager 
    124         log.debug("Calling Session Manager getAttCert for user ") 
     124        log.debug("Calling Session Manager getAttCert for Attribute Authority " 
     125                  "[%s]" % self.cfg.aaURI) 
    125126        try: 
    126127            # Make request for attribute certificate 
     
    200201            # Look-up list of Cert DNs for trusted requestors 
    201202            aaClnt = AttAuthorityClient(uri=self.cfg.aaURI, 
    202                             tracefile=self.cfg.tracefile, 
    203                             httpProxyHost=self.cfg.httpProxyHost, 
    204                             noHttpProxyList=self.cfg.noHttpProxyList, 
    205                             **self.cfg.wss) 
     203                                    tracefile=self.cfg.tracefile, 
     204                                    httpProxyHost=self.cfg.httpProxyHost, 
     205                                    noHttpProxyList=self.cfg.noHttpProxyList, 
     206                                    **self.cfg.wss) 
    206207             
    207208            HostInfo = aaClnt.getAllHostsInfo() 
     
    213214             
    214215            hostCheck = HostCheck(acceptedDNs=requestServerDN, 
    215                         caCertFilePathList=self.cfg.sslCACertFilePathList) 
     216                            caCertFilePathList=self.cfg.sslCACertFilePathList) 
    216217             
    217218            testConnection = HTTPSConnection(returnToURLHostname,  
Note: See TracChangeset for help on using the changeset viewer.