def parse(self, b): p = ASN1Parser(b) #Get the tbsCertificate tbsCertificateP = p.getChild(0) #Is the optional version field present? #This determines which index the key is at if tbsCertificateP.value[0]==0xA0: subjectPublicKeyInfoIndex = 6 validityIndex = 4 else: subjectPublicKeyInfoIndex = 5 validityIndex = 3 #Get the subjectPublicKeyInfo spkiP = tbsCertificateP.getChild(subjectPublicKeyInfoIndex) #Parse the notAfter time validityP = tbsCertificateP.getChild(validityIndex) notAfterP = validityP.getChild(1) if notAfterP.type == 0x17: # UTCTime self.notAfter = Time.parseASN1UTCTime(notAfterP.value) elif notAfterP.type == 0x18: # GeneralizedTime self.notAfter = Time.parseASN1GeneralizedTime(notAfterP.value) else: raise SyntaxError() # Get the hash values self.cert_sha256 = Digest.SHA256(b) self.key_sha256 = Digest.SHA256(spkiP.getTotalBytes()) # Check if this is a TACK certificate: #Get the tbsCertificate versionP = tbsCertificateP.getChild(0) if versionP.type != 0xA0: # i.e. tag of [0], version return # X.509 version field not present versionPP = versionP.getTagged() if versionPP.value != bytearray([0x02]): return # X.509 version field does not equal v3 # Find extensions element x = 0 while 1: certFieldP = tbsCertificateP.getChild(x) if not certFieldP: raise SyntaxError("X.509 extensions not present") if certFieldP.type == 0xA3: # i.e. tag of [3], extensions break x += 1 self.preExtBytes = b[versionP.offset : certFieldP.offset] self.extBytes = bytearray() # Iterate through extensions x = 0 certFieldPP = certFieldP.getTagged() while 1: extFieldP = certFieldPP.getChild(x) if not extFieldP: break # Check the extnID and parse out TACK if present extnIDP = extFieldP.getChild(0) if extnIDP.value == TlsCertificate.OID_TACK: if self.tackExt: raise SyntaxError("More than one TACK Extension") # OK! We found a TACK, parse it.. self.tackExt = TackExtension(extFieldP.getChild(1).value) else: # Collect all non-TACK extensions: self.extBytes += b[extFieldP.offset :\ extFieldP.offset + extFieldP.getTotalLength()] x += 1 # Finish copying the tail of the certificate self.postExtBytes = b[certFieldP.offset + certFieldP.getTotalLength():]
def __init__(self, data=None): if data is None: return #self.key_sha256 = bytearray(32) #self.cert_sha256 = bytearray(32) self.notAfter = 0 # Below values are populated for TACK certs self.tackExt = None # Below values hold cert contents excluding TACK stuff self.preExtBytes = None self.extBytes = None self.postExtBytes = None p = ASN1Parser(data) #Get the tbsCertificate tbsCertificateP = p.getChild(0) #Is the optional version field present? #This determines which index the key is at if tbsCertificateP.value[0] == 0xA0: subjectPublicKeyInfoIndex = 6 validityIndex = 4 else: subjectPublicKeyInfoIndex = 5 validityIndex = 3 #Get the subjectPublicKeyInfo spkiP = tbsCertificateP.getChild(subjectPublicKeyInfoIndex) #Parse the notAfter time validityP = tbsCertificateP.getChild(validityIndex) notAfterP = validityP.getChild(1) if notAfterP.type == 0x17: # UTCTime self.notAfter = Time.parseASN1UTCTime(notAfterP.value) elif notAfterP.type == 0x18: # GeneralizedTime self.notAfter = Time.parseASN1GeneralizedTime(notAfterP.value) else: raise SyntaxError() # Get the hash values self.cert_sha256 = Digest.SHA256(data) self.key_sha256 = Digest.SHA256(spkiP.getTotalBytes()) # Check if this is a TACK certificate: #Get the tbsCertificate versionP = tbsCertificateP.getChild(0) if versionP.type != 0xA0: # i.e. tag of [0], version return # X.509 version field not present versionPP = versionP.getTagged() if versionPP.value != bytearray([0x02]): return # X.509 version field does not equal v3 # Find extensions element x = 0 while 1: certFieldP = tbsCertificateP.getChild(x) if not certFieldP: raise SyntaxError("X.509 extensions not present") if certFieldP.type == 0xA3: # i.e. tag of [3], extensions break x += 1 self.preExtBytes = data[versionP.offset:certFieldP.offset] self.extBytes = bytearray() # Iterate through extensions x = 0 certFieldPP = certFieldP.getTagged() while 1: extFieldP = certFieldPP.getChild(x) if not extFieldP: break # Check the extnID and parse out TACK if present extnIDP = extFieldP.getChild(0) if extnIDP.value == TlsCertificate.OID_TACK: if self.tackExt: raise SyntaxError("More than one TACK Extension") # OK! We found a TACK, parse it.. self.tackExt = TackExtension(extFieldP.getChild(1).value) else: # Collect all non-TACK extensions: self.extBytes += data[extFieldP.offset :\ extFieldP.offset + extFieldP.getTotalLength()] x += 1 # Finish copying the tail of the certificate self.postExtBytes = data[certFieldP.offset + certFieldP.getTotalLength():]