def verify_sct(chain, sct_tls, log_key_pem): sct = client_pb2.SignedCertificateTimestamp() tls_message.decode(sct_tls, sct) log_key = pem.from_pem(log_key_pem, "PUBLIC KEY")[0] key_info = verify.create_key_info_from_raw_key(log_key) lv = verify.LogVerifier(key_info) print lv.verify_sct(sct, chain)
def verify_sct(chain, sct_tls, log_key_pem): sct = client_pb2.SignedCertificateTimestamp() tls_message.decode(sct_tls, sct) log_key = pem.from_pem(log_key_pem, 'PUBLIC KEY')[0] key_info = verify.create_key_info_from_raw_key(log_key) lv = verify.LogVerifier(key_info) print lv.verify_sct(sct, chain)
def __init__(self, key_info, merkle_verifier=merkle.MerkleVerifier()): """Initialize from KeyInfo protocol buffer and a MerkleVerifier.""" self.__merkle_verifier = merkle_verifier if key_info.type != client_pb2.KeyInfo.ECDSA: raise error.UnsupportedAlgorithmError("Key type %d not supported" % key_info.type) # Will raise a PemError on invalid encoding self.__der, _ = pem.from_pem(key_info.pem_key, LogVerifier.__ECDSA_READ_MARKERS) try: self.__pubkey = ecdsa.VerifyingKey.from_der(self.__der) except ecdsa.der.UnexpectedDER as e: raise error.EncodingError(e)
def from_pem(cls, pem_string, strict_der=True): """Read a single PEM-encoded certificate from a string. Args: pem_string: the certificate string. strict_der: if False, tolerate some non-fatal DER errors. Returns: a Certificate object. Raises: ct.crypto.pem.PemError, ct.crypto.error.ASN1Error: the string does not contain a valid PEM certificate. """ der_cert, _ = pem.from_pem(pem_string, cls.PEM_MARKERS) return cls.from_der(der_cert, strict_der=strict_der)
def __init__(self, key_info): """Creates a verifier that uses a PEM-encoded ECDSA public key. Args: - key_info: KeyInfo protobuf message Raises: - PemError: If the key has an invalid encoding """ if (key_info.type != client_pb2.KeyInfo.ECDSA): raise error.UnsupportedAlgorithmError( "Expected ECDSA key, but got key type %d" % key_info.type) # Will raise a PemError on invalid encoding self.__der, _ = pem.from_pem(key_info.pem_key, self.__READ_MARKERS) try: self.__key = ecdsa.VerifyingKey.from_der(self.__der) except ecdsa.der.UnexpectedDER as e: raise error.EncodingError(e)
def __init__(self, key_info): """Creates a verifier that uses a PEM-encoded RSA public key. Args: - key_info: KeyInfo protobuf message Raises: - PemError: If the key has an invalid encoding """ if (key_info.type != client_pb2.KeyInfo.RSA): raise error.UnsupportedAlgorithmError( "Expected RSA key, but got key type %d" % key_info.type) # Will raise a PemError on invalid encoding self.__der, _ = pem.from_pem(key_info.pem_key, self.__READ_MARKERS) try: self.__key = Crypto.PublicKey.RSA.importKey(self.__der) except (ValueError, IndexError, TypeError) as e: raise error.EncodingError(e)
def getIssuersFromAIA(cert): tbs = cert.getComponentByName('tbsCertificate') extensions = tbs.getComponentByName('extensions') or [] allIssuers = [] for extension in extensions: oid = extension.getComponentByName('extnID') if oid != id_pe_authorityInfoAccess: continue print extension.prettyPrint() value, rest = decoder.decode(extension.getComponentByName('extnValue'), asn1Spec=univ.OctetString()) assert rest == "" aia, rest = decoder.decode(value, asn1Spec=AuthorityInfoAccessSyntax()) assert rest == "" print aia.prettyPrint() for ad in aia: oid = ad.getComponentByName('accessMethod') if oid != id_ad_caIssuers: continue print ad.prettyPrint() loc = ad.getComponentByName('accessLocation').\ getComponentByName('uniformResourceIdentifier') print type(loc), loc certHandle = urlopen(str(loc)) # RFC 5280 says this should either be 'application/pkix-cert' or # 'application/pkcs7-mime' (in which case the result should be a # "certs-only" PCKS#7 response, as specified in RFC 2797). Of # course, we see other values, so just try both formats. print certHandle.info().gettype() issuer = certHandle.read() # Have we got an (incorrect, but let's fix it) PEM encoded cert? if issuer.startswith('-----'): try: (issuer, _) = from_pem(issuer, ['CERTIFICATE']) except PemError as e: print "PEM decode failed:", e print "For cert:", issuer # Is it a certificate? try: cert, rest = decoder.decode(issuer, asn1Spec=certType) assert rest == "" allIssuers.append(cert) continue except PyAsn1Error as e: # On failure, try the next thing print "Cert decode failed:", e pass # If not, it had better be PKCS#7 "certs-only" try: pkcs7, rest = decoder.decode(issuer, asn1Spec=rfc2315.ContentInfo()) assert rest == "" assert pkcs7.getComponentByName( 'contentType') == rfc2315.signedData signedData = decoder.decode( pkcs7.getComponentByName('content'), asn1Spec=rfc2315.SignedData()) except PyAsn1Error as e: # Give up print "PKCS#7 decode also failed:", e print "Skipping issuer URL:", loc continue for signedDatum in signedData: # FIXME: why does this happen? Example is at # http://crt.usertrust.com/AddTrustExternalCARoot.p7c. if signedDatum == '': print "** Skipping strange Any('') in PKCS7 **" continue certs = signedDatum.getComponentByName('certificates') for c in certs: cert = c.getComponentByName('certificate') allIssuers.append(cert) return allIssuers
def getIssuersFromAIA(cert): tbs = cert.getComponentByName('tbsCertificate') extensions = tbs.getComponentByName('extensions') or [] allIssuers = [] for extension in extensions: oid = extension.getComponentByName('extnID') if oid != id_pe_authorityInfoAccess: continue print extension.prettyPrint() value, rest = decoder.decode(extension.getComponentByName('extnValue'), asn1Spec=univ.OctetString()) assert rest == "" aia, rest = decoder.decode(value, asn1Spec=AuthorityInfoAccessSyntax()) assert rest == "" print aia.prettyPrint() for ad in aia: oid = ad.getComponentByName('accessMethod') if oid != id_ad_caIssuers: continue print ad.prettyPrint() loc = ad.getComponentByName('accessLocation').\ getComponentByName('uniformResourceIdentifier') print type(loc), loc certHandle = urlopen(str(loc)) # RFC 5280 says this should either be 'application/pkix-cert' or # 'application/pkcs7-mime' (in which case the result should be a # "certs-only" PCKS#7 response, as specified in RFC 2797). Of # course, we see other values, so just try both formats. print certHandle.info().gettype() issuer = certHandle.read() # Have we got an (incorrect, but let's fix it) PEM encoded cert? if issuer.startswith('-----'): try: (issuer, _) = from_pem(issuer, ['CERTIFICATE']) except PemError as e: print "PEM decode failed:", e print "For cert:", issuer # Is it a certificate? try: cert, rest = decoder.decode(issuer, asn1Spec=certType) assert rest == "" allIssuers.append(cert) continue except PyAsn1Error as e: # On failure, try the next thing print "Cert decode failed:", e pass # If not, it had better be PKCS#7 "certs-only" try: pkcs7, rest = decoder.decode(issuer, asn1Spec=rfc2315.ContentInfo()) assert rest == "" assert pkcs7.getComponentByName('contentType') == rfc2315.signedData signedData = decoder.decode(pkcs7.getComponentByName('content'), asn1Spec=rfc2315.SignedData()) except PyAsn1Error as e: # Give up print "PKCS#7 decode also failed:", e print "Skipping issuer URL:", loc continue for signedDatum in signedData: # FIXME: why does this happen? Example is at # http://crt.usertrust.com/AddTrustExternalCARoot.p7c. if signedDatum == '': print "** Skipping strange Any('') in PKCS7 **" continue certs = signedDatum.getComponentByName('certificates') for c in certs: cert = c.getComponentByName('certificate') allIssuers.append(cert) return allIssuers
'3uMziiLOl/fHTDM0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J\n' '5APC2em4JlvR8EEEFMoA==\n' '-----END PUBLIC KEY-----\n') logurl = 'http://ct.googleapis.com/pilot'; logdns = 'pilot.ct.googleapis.com' response = urllib2.urlopen('%s/ct/v1/get-entries?start=%s&end=%s' % (logurl, index, index)) j = response.read() j = json.loads(j) leaf_input = j['entries'][0]['leaf_input'] logging.info('leaf = %s', leaf_input) leaf = base64.b64decode(leaf_input) leaf_hash = hashlib.sha256(chr(0) + leaf).digest() keyinfo = verify.create_key_info_from_raw_key(pem.from_pem(keypem, 'PUBLIC KEY')[0]) log_verifier = verify.LogVerifier(keyinfo) lookup = CTDNSLookup(logdns, log_verifier) sth = lookup.GetSTH() logging.info('sth = %s', sth) logging.info('hash = %s', base64.b64encode(leaf_hash)) verifier = merkle.MerkleVerifier() index = int(index) audit_path = [] prev = None apl = verifier.audit_path_length(index, sth.tree_size) for level in range(0, apl): h = lookup.GetEntry(level, index, sth.tree_size) logging.info('hash = %s', base64.b64encode(h))
def test_from_pem(self): self.assertEqual((self.BLOB, self.MARKER), pem.from_pem(self.PEM_BLOB, (self.MARKER,))) # from_pem will also take a plain string for the marker self.assertEqual((self.BLOB, self.MARKER), pem.from_pem(self.PEM_BLOB, self.MARKER))
'5APC2em4JlvR8EEEFMoA==\n' '-----END PUBLIC KEY-----\n') logurl = 'http://ct.googleapis.com/pilot' logdns = 'pilot.ct.googleapis.com' response = urllib2.urlopen('%s/ct/v1/get-entries?start=%s&end=%s' % (logurl, index, index)) j = response.read() j = json.loads(j) leaf_input = j['entries'][0]['leaf_input'] logging.info('leaf = %s', leaf_input) leaf = base64.b64decode(leaf_input) leaf_hash = hashlib.sha256(chr(0) + leaf).digest() keyinfo = verify.create_key_info_from_raw_key( pem.from_pem(keypem, 'PUBLIC KEY')[0]) log_verifier = verify.LogVerifier(keyinfo) lookup = CTDNSLookup(logdns, log_verifier) sth = lookup.GetSTH() logging.info('sth = %s', sth) logging.info('hash = %s', base64.b64encode(leaf_hash)) verifier = merkle.MerkleVerifier() index = int(index) audit_path = [] prev = None apl = verifier.audit_path_length(index, sth.tree_size) for level in range(0, apl): h = lookup.GetEntry(level, index, sth.tree_size) logging.info('hash = %s', base64.b64encode(h))
def test_from_pem(self): self.assertEqual((self.BLOB, self.MARKER), pem.from_pem(self.PEM_BLOB, (self.MARKER, ))) # from_pem will also take a plain string for the marker self.assertEqual((self.BLOB, self.MARKER), pem.from_pem(self.PEM_BLOB, self.MARKER))
def test_from_pem(self): self.assertEqual((self.BLOB, self.MARKER), pem.from_pem(self.PEM_BLOB, (self.MARKER,)))