source: TI12-security/trunk/python/NDG/AttCert.py @ 1142

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/NDG/AttCert.py@1142
Revision 1142, 27.1 KB checked in by pjkersha, 14 years ago (diff)

NDG/AttAuthority.py: use new AttCert? class vars for mapped/original provenance flags

NDG/AttCert.py:

  • Fixed bug in setValidityTime - code to apply not before time offset was incorrectly indented so that it wasn't

applied.

  • Added class vars for mapped/original provenance flags
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1"""NDG Attribute Certificate (Authentication -or Access- Token)
2
3NERC Data Grid Project
4
5P J Kershaw 05/04/05
6
7Copyright (C) 2005 CCLRC & NERC
8
9This software may be distributed under the terms of the Q Public License,
10version 1.0 or later."""
11
12reposID = '$Id$'
13
14import types
15import os
16import re
17
18# XML Parsing
19import cElementTree as ElementTree
20
21# Time module for use with validity times
22from time import strftime
23from time import strptime
24from datetime import datetime
25from datetime import timedelta
26
27# XML signature module based on xmlsec and libxml2
28from XMLSecDoc import *
29
30from X509 import X500DN
31from X509 import X500DNError
32
33
34class AttCertError(Exception):
35   
36    """Exception handling for NDG Attribute Certificate class."""
37   
38    def __init__(self, msg):
39        self.__msg = msg
40         
41    def __str__(self):
42        return self.__msg
43   
44
45class AttCert(dict, XMLSecDoc):
46
47    """NDG Attribute Certificate (Authentication or Access Token)."""
48
49    # Attribute Certificate file version
50    __version = "1.0"
51
52    # Provenance of certificate may be original or mapped from another
53    # certificate
54    mappedProvenance = 'mapped'
55    origProvenance = 'original'
56    __provenance = (origProvenance, mappedProvenance)
57
58
59    # Nb. pass XMLSecDoc keyword arguments in xmlSecDocKeys dictionary
60    def __init__(self, filePath=None, lifeTime=-1, **xmlSecDocKeys):
61
62        """Initialisation - Attribute Certificate file path may be specified.
63        Also, holder and issuer details and signing authority key and
64        certificate."""
65
66        # Base class initialisation
67        dict.__init__(self)
68        XMLSecDoc.__init__(self, **xmlSecDocKeys)
69
70
71        if filePath is not None:
72            if not isinstance(filePath, basestring):
73                raise AttCertError("Input file path must be a valid string")
74           
75            self.filePath = filePath
76
77
78        # Data dictionary version of xml
79        #
80        # Nb. RoleSet is an empty list - it will be filled role dictionary
81        # items [{'role': {'name': '<Name>'}}, ... ]
82        self.__dat = {
83           
84            "version":            AttCert.__version,
85            "holder":             '',
86            "issuer":             '',
87            "issuerName":         '',
88            "issuerSerialNumber": 0,
89            "validity":           {"notBefore": '', "notAfter": ''},
90            "attributes":         {"roleSet": []},
91            "provenance":         ''
92        }
93
94        # Holder and issuer X500DN objects - instanciated in read method
95        self.__issuerDN = None
96        self.__holderDN = None
97
98
99        # Check for input certificate life time interval - if not set default
100        # to one day
101        if lifeTime is -1:
102            self.__lifeTime = 28800 # 8 hours
103        else:
104            self.__lifeTime = lifeTime
105       
106        self.__dtNotBefore = None
107        self.__dtNotAfter = None
108
109       
110    def __repr__(self):
111        """Override default behaviour to return internal dictionary content"""
112        return str(self.__dat)
113
114               
115    def __delitem__(self, key):
116        "Attribute Certificate keys cannot be removed"
117       
118        raise AttCertError('Keys cannot be deleted from ' + \
119                           self.__class__.__name__)
120
121
122    def __getitem__(self, key):
123        self.__class__.__name__ + """ behaves as data dictionary of Attribute
124        Certificate properties
125
126        Nb. also possible to apply keys belonging validity and attributes
127        sub dictionaries
128        """
129       
130        # Check input key
131        if self.__dat.has_key(key):
132
133            # key recognised
134            return self.__dat[key]               
135
136        elif self.__dat['validity'].has_key(key):
137
138            # Allow indexing via validity keys - a shorthand way of referencing
139            # for convenience
140            return self.__dat['validity'][key]
141
142        elif self.__dat['attributes'].has_key(key):
143
144            # Allow indexing via attirbutes keys - a shorthand way of
145            # referencing for convenience
146            return self.__dat['attributes'][key]
147
148        else:
149            # key not recognised as a short or long name version
150            raise AttCertError('Key "%s" not recognised for %s' % \
151                               (key, self.__class__.__name__))
152
153
154    def __setitem__(self, key, item):       
155        self.__class__.__name__ + """ behaves as data dictionary of Attribute
156        Certificate properties
157
158        Nb. also possible to apply keys belonging validity and attributes
159        sub dictionaries
160        """
161
162        # Check input key
163        if self.__dat.has_key(key):
164
165            # key recognised - check if setting provenance
166            if key is "provenance" and not self.isValidProvenance(item):
167                raise AttCertError("Provenance must be set to \"" + \
168                            "\" or \"".join(AttCert.__provenance) + "\"")
169           
170            self.__dat[key] = item
171
172        elif self.__dat['attributes'].has_key(key):
173
174            # Allow indexing via acInfo keys - a shorthand way of referencing
175            # for convenience
176            return self.__dat['attributes'][key]
177
178        elif self.__dat['validity'].has_key(key):
179               
180            # Prevent setting of notBefore/notAfter - restrict to method
181            # setValidityTime
182            raise AttCertError(\
183                "Use setValidityTime method to set notBefore/notAfter times")
184           
185        else:
186            # key not recognised as a short or long name version
187            raise AttCertError('Key "%s" not recognised for %s' % \
188                               (key, self.__class__.__name__))
189       
190
191    def __eq__(self, attCert):
192        """Return true if all elements are the same"""
193       
194        try:
195            return min([self.__dat[key] == attCert[key] \
196                       for key in self.__dat.keys()])
197        except:
198            return False
199       
200
201    def __nonzero__(self):
202        """Ensure if <attCertInstance> test yields True"""
203        return True
204   
205   
206    def clear(self):
207        raise AttCertError("Data cannot be cleared from " + \
208                           self.__class__.__name__)
209
210   
211    def copy(self):
212
213        import copy
214        return copy.copy(self)
215
216   
217    def keys(self):
218        return self.__dat.keys()
219
220    def items(self):
221        return self.__dat.items()
222
223    def values(self):
224        return self.__dat.values()
225
226    def has_key(self, key):
227        return self.__dat.has_key(key)
228
229    # 'in' operator
230    def __contains__(self, key):
231        return key in self.__dat
232
233
234    def getExptdVersion(self):
235        """Return the Attribute Certificate XML expected version."""
236        return AttCert.__version
237
238
239    #
240    # Get/Set methods
241    #
242    # Nb. it's also possible to access the data dictionary parameters via
243    # __setitem__ and __getitem__ standard dictionary methods
244    #
245    def setVersion(self, version):
246        """Set the version number to be written to file."""       
247        self.__dat['version'] = version
248   
249    def getVersion(self):
250        """Get version number as set in file."""
251        return self.__dat['version']
252   
253    def setHolder(self, holder):
254        """Set holder's Distinguished Name string."""
255        self.__dat['holder'] = holder
256   
257    def getHolder(self):
258        """Get holder's Distinguished Name string."""
259        return self.__dat['holder']
260
261    def getHolderDN(self):
262         """Get the holder's Distinguished Name as an X500DN instance"""
263         return self.__holderDN
264   
265    def setIssuer(self, issuer):
266        """Set issuer's Distinguished Name."""
267        self.__dat['issuer'] = issuer
268   
269    def getIssuer(self):
270        """Get the issuer's Distinguished Name string"""
271        return self.__dat['issuer']
272
273    def getIssuerDN(self):
274         """Get the issuer's Distinguished Name as an X500DN instance"""
275         return self.__issuerDN
276       
277    def setIssuerName(self, issuerName):
278        """Set the name of the issuer"""
279        self.__dat['issuerName'] = issuerName
280   
281    def getIssuerName(self):
282        """Get the name of the issuer"""
283        return self.__dat['issuerName']
284   
285    def setIssuerSerialNumber(self, serialNumber):
286        """Set the issuer serial number"""
287        self.__dat['issuerSerialNumber'] = serialNumber
288   
289    def getIssuerSerialNumber(self):
290        """Get the issuer serial number"""
291        return self.__dat['issuerSerialNumber']
292
293
294    # Nb. no setValidityNotBefore/setValidityNotAfter methods - use
295    # setValidityTime instead.
296   
297    def getValidityNotBefore(self, asDatetime=False):
298        """Get the validity Not Before date/time string
299
300        Set asDatetime to True to return as a datetime type
301        Nb. time may not have been set - if so it will be set to None"""
302        if asDatetime is True:
303            return self.__dtNotBefore
304        else:
305            return self.__dat['validity']['notBefore']
306
307
308    def getValidityNotAfter(self, asDatetime=False):
309        """Get the validity Not After date/time string
310
311        Set asDatetime to True to return as a datetime type
312        Nb. time may not have been set - if so it will be set to None"""
313        if asDatetime is True:
314            return self.__dtNotAfter
315        else:
316            return self.__dat['validity']['notAfter']
317
318   
319    def getRoleSet(self):
320        """Get the roleSet as a list of role dictionaries."""
321        return self.__dat['attributes']['roleSet']
322
323
324    def getRoles(self):
325        """Return roles as a list"""
326        try:
327            return [i.values()[0].values()[0] \
328                    for i in self.__dat['attributes']['roleSet']]
329        except:
330            return []
331
332       
333    def setProvenance(self, provenance):
334        """Set the provenance for the certificate: 'original' or 'mapped'."""
335
336        if not self.isValidProvenance(provenance):
337            raise AttCertError("Provenance must be set to \"" + \
338                               "\" or \"".join(AttCert.__provenance) + "\"")
339       
340        self.__dat['provenance'] = provenance
341
342   
343    def getProvenance(self):
344        """Get the provenance for the certificate."""
345        return self.__dat['provenance']
346   
347
348    def isValidProvenance(self, provenance=None):
349        """Check provenance is set correctly - to 'original'/'mapped'.
350
351        If no provenance argument is provided, test against the setting in
352        the current instance.
353        """
354       
355        if not provenance:
356            provenance = self.__dat['provenance']
357
358        return provenance in AttCert.__provenance
359       
360
361    def isOriginal(self):
362        """Check for original provenance."""
363        return self.__dat['provenance'] == self.__class__.origProvenance
364
365
366    def isMapped(self):
367        """Check for mapped provenance."""
368        return self.__dat['provenance'] == self.__class__.mappedProvenance
369
370
371    def addRoles(self, roleName):
372        """Add new roles to the roleSet in attributes."""
373
374        if isinstance(roleName, basestring):
375            roleName = [roleName]
376           
377        self.__dat['attributes']['roleSet'].extend(\
378                                [{'role': {'name': i}} for i in roleName])
379
380
381    def parse(self, xmlTxt, rtnRootElem=False):
382
383        """Parse an Attribute Certificate content contained in string input
384
385        xmlTxt:     Attribute Certificate XML content as string"""
386       
387        rootElem = ElementTree.XML(xmlTxt)
388
389        # Call generic ElementTree parser
390        self.__parse(rootElem)
391
392
393        # Call base class parser method to initialise libxml2 objects for
394        # signature validation
395        try:
396            XMLSecDoc.parse(self, xmlTxt)
397
398        except Exception, e:
399            raise AttCertError("Attribute Certificate: %s" % e)
400
401        if rtnRootElem:
402            return rootElem
403
404       
405    def read(self, filePath=None):
406
407        """Read Attribute Certificate
408
409        filePath:   file to be read, if omitted __filePath member variable is
410                    used instead"""
411
412        if filePath:
413            if not isinstance(filePath, basestring):
414                raise AttCertError("Input file path must be a string.")
415
416            self.filePath = filePath
417        else:
418            filePath = self.filePath
419
420
421        try:   
422            tree = ElementTree.parse(filePath)
423            rootElem = tree.getroot()
424        except Exception, e:
425            raise AttCertError("Attribute Certificate: %s" % e)
426       
427        # Call generic ElementTree parser
428        self.__parse(rootElem)
429
430
431        # Call base class read method to initialise libxml2 objects for
432        # signature validation
433        try:
434            XMLSecDoc.read(self)
435
436        except Exception, e:
437            raise AttCertError("Attribute Certificate: %s" % e)
438
439
440
441       
442    def __parse(self, rootElem):
443
444        """Private XML parsing method accepts a ElementTree.Element type
445        as input
446
447        rootElem:       ElementTree.Element type
448        """
449       
450        # Extract from acInfo tag
451        acInfoElem = rootElem.find("acInfo")
452       
453        if not acInfoElem:
454            raise AttCertError("<acInfo> tag not found in \"%s\"" % \
455                               self.filePath)
456
457
458        # Copy all acInfo tags into dictionary
459        for elem in acInfoElem:
460       
461            if not self.__dat.has_key(elem.tag):
462                raise AttCertError(self.filePath + "\": <" + \
463                                   elem.tag + "> not recognised.")
464
465            # Make sure not to copy validity and attributes tags - handle
466            # these separately below
467            if not elem.getchildren():
468                self.__dat[elem.tag] = elem.text
469
470        # Convert issuer and holder into X500DN instances
471        try:
472            self.__issuerDN = X500DN(dn=self.__dat['issuer'])
473
474        except X500DNError, x500dnErr:
475            raise AttCertError("Issuer DN: %s" % x500dnErr)
476
477
478        try:
479            self.__holderDN = X500DN(dn=self.__dat['holder'])
480
481        except X500DNError, x500dnErr:
482            raise AttCertError("Holder DN: %s" % x500dnErr)
483       
484                                 
485        # Extract validity and attributes subsets
486        self.__dat['validity']['notBefore'] = \
487                                rootElem.findtext("acInfo/validity/notBefore")
488       
489        if self.__dat['validity']['notBefore'] is None:
490            raise AttCertError("<notBefore> tag not found in \"%s\"" % \
491                               self.filePath)
492
493        # Update datetime object equivalent
494        self.__dtNotBefore = self.timeStr2datetime(\
495                                        self.__dat['validity']['notBefore'])
496
497       
498        self.__dat['validity']['notAfter'] = \
499                                rootElem.findtext("acInfo/validity/notAfter")
500       
501        if self.__dat['validity']['notAfter'] is None:
502            raise AttCertError("<notAfter> tag not found in \"%s\"" %
503                               self.filePath)
504
505
506        # Update datetime object equivalent
507        self.__dtNotAfter = self.timeStr2datetime(\
508                                        self.__dat['validity']['notAfter'])
509
510
511        # set up role list
512        roleElem = acInfoElem.findall("attributes/roleSet/role/name")
513        if roleElem is None:
514            raise AttCertError("<role> tag not found in \"%s\"" % \
515                               self.filePath)
516       
517        self.__dat['attributes']['roleSet'] = \
518                                [{'role': {'name': i.text}} for i in roleElem]
519                   
520       
521        if not self.isValidVersion():           
522            raise AttCertError('Attribute Certificate version is ' + \
523                               self.__dat['version'] + ' but version ' + \
524                               AttCert.__version + ' expected')
525
526
527
528
529    def createXML(self):
530
531        """Create XML for Attribute Token from current data settings and
532        return as a string.  The XML created is MINUS the digital signature.
533        To obtain the signed version, run the sign method and pass the attCert
534        object reference into str()
535
536        Implementation of virtual method defined in XMLSecDoc base class"""
537
538        # Nb.
539        # * this method is used by AttCert.read()
540        # * Signing by Attribute Authority is separate - see AttCert.sign()
541       
542
543        # Check for valid provenance
544        if not self.isValidProvenance():
545            raise AttCertError("Provenance must be set to \"" + \
546                               "\" or \"".join(AttCert.__provenance) + "\"")
547
548       
549        # Create string of all XML content       
550        xmlTxt = \
551"""<attributeCertificate>
552    <acInfo>
553        <version>""" + self.__dat['version'] + """</version>
554        <holder>""" + self.__dat['holder'] + """</holder>
555        <issuer>""" + self.__dat['issuer'] + """</issuer>
556        <issuerName>""" + self.__dat['issuerName'] + """</issuerName>
557        <issuerSerialNumber>""" + str(self.__dat['issuerSerialNumber']) +\
558            """</issuerSerialNumber>
559        <validity>
560            <notBefore>""" + self.__dat['validity']['notBefore'] + \
561            """</notBefore>
562            <notAfter>""" + self.__dat['validity']['notAfter'] + \
563            """</notAfter>
564        </validity>
565        <attributes>
566            <roleSet>
567                """ + \
568        "".join(["""<role>
569                    <name>""" + i['role']['name'] + """</name>
570                </role>
571            """ for i in self.__dat['attributes']['roleSet']]) +\
572            """</roleSet>
573        </attributes>
574        <provenance>""" + self.__dat['provenance'] + """</provenance>
575    </acInfo>
576</attributeCertificate>"""
577
578
579        # Return XML file content as a string
580        return xmlTxt
581
582
583
584
585    def setValidityTime(self,
586                        dtNotBefore=None, 
587                        dtNotAfter=None, 
588                        lifeTime=None,
589                        notBeforeOffset=None):
590
591        """Set the notBefore and notAfter times which determine the window for
592        which the Attribute Certificate is valid
593
594        Nb. use UTC time.  lifeTime and notBeforeOffset are in seconds
595        """
596
597        if dtNotBefore is not None:
598            if not isinstance(dtNotBefore, datetime):
599                raise AttCertError(\
600                                "Input not before time must be datetime type")
601           
602            self.__dtNotBefore = dtNotBefore
603           
604        else:
605            # Use current UTC +/- offset
606            self.__dtNotBefore = datetime.utcnow()
607           
608        if notBeforeOffset is not None:
609            self.__dtNotBefore += timedelta(seconds=notBeforeOffset)
610           
611
612
613        if dtNotAfter is not None:
614            if not isinstance(dtNotAfter, datetime):
615                raise AttCertError(\
616                                "Input not after time must be datetime type")
617
618            # Use input Not After time to calculate a new lifetime setting
619            dtDeltaLifeTime = dtNotAfter - self.__dtNotBefore
620            if dtDeltaLifeTime < timedelta(0):
621                raise AttCertError("Input Not After time is invalid %s" % \
622                                   str(dtNotAfter))
623
624            self.__lifeTime = dtDeltaLifeTime.days*86400 + \
625                              dtDeltaLifeTime.seconds
626
627            self.__dtNotAfter = dtNotAfter
628           
629        else:
630            # Check for input certificate life time interval
631            if lifeTime is not None:
632                self.__lifeTime = lifeTime
633               
634            try:
635                # Make a time delta object from the lifetime expressed in
636                # seconds
637                dtDeltaLifeTime = timedelta(seconds=self.__lifeTime)
638            except Exception, e:
639                raise AttCertError("Invalid Certificate lifetime set %.3f" % \
640                                   self.__lifeTime)
641           
642            # Add certificate lifetime to calculate not after time
643            self.__dtNotAfter = self.__dtNotBefore + dtDeltaLifeTime
644
645       
646        self.__dat['validity']['notBefore'] = \
647                                    self.datetime2timeStr(self.__dtNotBefore)
648       
649        self.__dat['validity']['notAfter'] = \
650                                    self.datetime2timeStr(self.__dtNotAfter)
651
652
653
654
655    def datetime2timeStr(self, dtVal):
656
657        """Convert a datetime object to a notBefore/notAfter time string"""
658
659        if not isinstance(dtVal, datetime):
660            raise AttCertError(\
661                        "Invalid datetime object for conversion to string")
662       
663        # Convert from 1-12 to 0-11 month format used in XML file
664        #lDateTime = list(dtVal.utctimetuple()[0:6])
665
666        #lDateTime[1] -= 1
667
668        # Format as a single string with no commas or brackets
669        #return ''.join(re.findall('[0-9 ]', str(lDateTime)))
670
671        # Use 1-12 format
672        # P J Kershaw 09/06/05
673        return dtVal.strftime("%Y %m %d %H %M %S")
674
675   
676
677    def timeStr2datetime(self, sTime):
678
679        """Convert a notBefore/notAfter time string to a datetime object"""
680
681        # Convert from 0-11 to 1-12 month format used by datetime()
682        try:
683            #lTime = [int(i) for i in sTime.split()]
684            lTime = strptime(sTime, "%Y %m %d %H %M %S")
685           
686            # Use 1-12 format
687            # P J Kershaw 09/05/05
688            #lTime[1] += 1
689       
690            return datetime(lTime[0], lTime[1], lTime[2],
691                            lTime[3], lTime[4], lTime[5])
692        except Exception, e:
693            raise AttCertError(\
694                "Error converting time string into datetime object: %s" % e)
695       
696
697
698
699    def isValidTime(self, raiseExcep=False):
700        """Check Attribute Certificate for expiry.  Set raiseExcep to True
701        to raise an exception with a message indicating the nature of the
702        time error"""
703
704        if not isinstance(self.__dtNotBefore, datetime):
705            raise AttCertError("Not Before datetime is not set")
706
707        if not isinstance(self.__dtNotAfter, datetime):
708            raise AttCertError("Not After datetime is not set")
709       
710        dtNow = datetime.utcnow()
711       
712        # Testing only
713        #
714        # P J Kershaw 02/03/06
715        #notBefore = self.__dtNotBefore
716        #notAfter = self.__dtNotAfter
717        #print "Valid Time? = %d" % (dtNow > notBefore and dtNow < notAfter)
718        if raiseExcep:
719            if dtNow < self.__dtNotBefore:
720                raise AttCertError, "Current time %s " % \
721                           dtNow.strftime("%d/%m/%Y %H:%M:%S") + \
722                           "is before Attribute Certificate's " + \
723                           "not before time of %s" % \
724                           self.__dtNotBefore.strftime("%d/%m/%Y %H:%M:%S")
725           
726            if dtNow > self.__dtNotAfter:
727                raise AttCertError, "Current time %s " % \
728                           dtNow.strftime("%d/%m/%Y %H:%M:%S") + \
729                           "is after Attribute Certificate's " + \
730                           "expiry time of %s" % \
731                           self.__dtNotBefore.strftime("%d/%m/%Y %H:%M:%S")               
732           
733            return True       
734        else:
735            return dtNow > self.__dtNotBefore and dtNow < self.__dtNotAfter
736
737
738       
739       
740    def isValidVersion(self):
741
742        """Check Attribute Certificate XML file version"""
743        return self.__dat['version'] == AttCert.__version
744
745
746
747
748    def isValid(self,
749                raiseExcep=False,
750                chkTime=True,
751                chkVersion=True,
752                chkProvenance=True,
753                chkSig=True,
754                **xmlSecDocKeys):
755
756        """Check Attribute Certificate is valid:
757
758        - Time validity is OK
759        - XML file version is OK
760        - valid provenance setting
761        - Signature is valid.
762
763        chkTime:                set to True to do time validity check (default
764                                is True)
765
766        chkVersion:             set to True to Attribute Certificate file
767                                version (default is True)
768
769        chkProvenance:          set to True to check provenance value is valid
770                                (default is True)
771
772        chkSig:                 set to True to check digital signature - for
773                                this certFilePathList must contain the root
774                                certificate of the X.509 certificate used to
775                                sign the AttCert.  Alternatively,
776                                certFilePathList can be set via __init__
777                                (default chkSig value is True)
778                               
779        raiseExcep:             set to true to raise an exception if invalid
780                                instead of returning False.  Default is to set
781                                this flag to False.
782
783        Also accepts keyword arguments corresponding to XMLSecDoc.isValidSig:
784       
785        xmlTxt:                 string buffer containing the text from the XML
786                                file to be checked.  If omitted, the
787                                filePath argument is used instead.
788
789        filePath:               file path to XML file to be checked.  This
790                                argument is used if no xmlTxt was provided.
791                                If filePath itself is omitted the file set
792                                by self.__filePath is read instead.
793
794        certFilePathList:       list of files paths must contain certificate
795                                of trusted authority used to validate the
796                                signature.  If set, it is copied into
797                                self.__certFilePathList.  If omitted
798                                self.__certFilePathList is used unchanged.                             
799        """
800
801        # Carry out checks in turn - Specific exception error messages are
802        # raised if flag is set
803        if chkTime and not self.isValidTime(raiseExcep=raiseExcep):
804            return False
805
806       
807        if chkVersion and not self.isValidVersion():
808            if raiseExcep:
809                raise AttCertError('Attribute Certificate version is ' + \
810                                   self.__dat['version'] + ' but version ' + \
811                                   AttCert.__version + ' expected')
812           
813            return False
814
815
816        if chkProvenance and not self.isValidProvenance():
817            if raiseExcep:
818                raise AttCertError(\
819                    "Attribute Certificate Provenance must be set to \"" + \
820                    "\" or \"".join(AttCert.__provenance) + "\"")
821               
822            return False
823
824
825        # Handle exception from XMLSecDocc.isValidSig() regardless of
826        # raiseExcep flag setting
827        try:           
828            if chkSig and not self.isValidSig(**xmlSecDocKeys):
829                if raiseExcep:
830                    raise AttCertError(\
831                                "Attribute Certificate signature is invalid")
832               
833                return False
834       
835        except Exception, e:
836            raise AttCertError(str(e))
837       
838
839        # All tests passed
840        return True
841
842
843
844#_____________________________________________________________________________
845# Alternative AttCert constructors
846#
847def AttCertRead(filePath):
848    """Create a new attribute certificate read in from a file"""
849   
850    attCert = AttCert(filePath)
851    attCert.read()
852   
853    return attCert
854
855
856
857
858def AttCertParse(attCertTxt):
859    """Create a new attribute certificate from string of file content"""
860   
861    attCert = AttCert()
862    attCert.parse(attCertTxt)
863   
864    return attCert
Note: See TracBrowser for help on using the repository browser.