1# Author: Trevor Perrin 2# See the LICENSE file for legal information regarding use of this file. 3 4"""Class representing an X.509 certificate chain.""" 5 6from .utils import cryptomath 7from .utils.tackwrapper import * 8from .utils.pem import * 9from .x509 import X509 10 11class X509CertChain(object): 12 """This class represents a chain of X.509 certificates. 13 14 @type x509List: list 15 @ivar x509List: A list of L{tlslite.x509.X509} instances, 16 starting with the end-entity certificate and with every 17 subsequent certificate certifying the previous. 18 """ 19 20 def __init__(self, x509List=None): 21 """Create a new X509CertChain. 22 23 @type x509List: list 24 @param x509List: A list of L{tlslite.x509.X509} instances, 25 starting with the end-entity certificate and with every 26 subsequent certificate certifying the previous. 27 """ 28 if x509List: 29 self.x509List = x509List 30 else: 31 self.x509List = [] 32 33 def parsePemList(self, s): 34 """Parse a string containing a sequence of PEM certs. 35 36 Raise a SyntaxError if input is malformed. 37 """ 38 x509List = [] 39 bList = dePemList(s, "CERTIFICATE") 40 for b in bList: 41 x509 = X509() 42 x509.parseBinary(b) 43 x509List.append(x509) 44 self.x509List = x509List 45 46 def getNumCerts(self): 47 """Get the number of certificates in this chain. 48 49 @rtype: int 50 """ 51 return len(self.x509List) 52 53 def getEndEntityPublicKey(self): 54 """Get the public key from the end-entity certificate. 55 56 @rtype: L{tlslite.utils.rsakey.RSAKey} 57 """ 58 if self.getNumCerts() == 0: 59 raise AssertionError() 60 return self.x509List[0].publicKey 61 62 def getFingerprint(self): 63 """Get the hex-encoded fingerprint of the end-entity certificate. 64 65 @rtype: str 66 @return: A hex-encoded fingerprint. 67 """ 68 if self.getNumCerts() == 0: 69 raise AssertionError() 70 return self.x509List[0].getFingerprint() 71 72 def checkTack(self, tack): 73 if self.x509List: 74 tlsCert = TlsCertificate(self.x509List[0].bytes) 75 if tlsCert.matches(tack): 76 return True 77 return False 78 79 def getTackExt(self): 80 """Get the TACK and/or Break Sigs from a TACK Cert in the chain.""" 81 tackExt = None 82 # Search list in backwards order 83 for x509 in self.x509List[::-1]: 84 tlsCert = TlsCertificate(x509.bytes) 85 if tlsCert.tackExt: 86 if tackExt: 87 raise SyntaxError("Multiple TACK Extensions") 88 else: 89 tackExt = tlsCert.tackExt 90 return tackExt 91 92