Chromium Code Reviews| Index: net/tools/testserver/minica.py |
| diff --git a/net/tools/testserver/minica.py b/net/tools/testserver/minica.py |
| index 2dd38ef98146e415ffd8ff82f64e44a61f6c9de7..ce1b33d0144e7d3acddbbe047e06a060fa5ce474 100644 |
| --- a/net/tools/testserver/minica.py |
| +++ b/net/tools/testserver/minica.py |
| @@ -166,6 +166,9 @@ OCSP_TYPE_BASIC = asn1.OID([1, 3, 6, 1, 5, 5, 7, 48, 1, 1]) |
| ORGANIZATION = asn1.OID([2, 5, 4, 10]) |
| PUBLIC_KEY_RSA = asn1.OID([1, 2, 840, 113549, 1, 1, 1]) |
| SHA1_WITH_RSA_ENCRYPTION = asn1.OID([1, 2, 840, 113549, 1, 1, 5]) |
| +# SignedCertificateTimestampList (RFC 6962) |
| +SCT_LIST_OCSP = asn1.OID([1, 3, 6, 1, 4, 1, 11129, 2, 4, 5]) |
| + |
|
wtc
2013/12/03 01:18:06
Nit: don't add this blank line.
ekasper
2013/12/03 13:50:51
Done.
|
| def MakeCertificate( |
| @@ -246,7 +249,7 @@ def MakeCertificate( |
| ])) |
| -def MakeOCSPResponse(issuer_cn, issuer_key, serial, ocsp_state): |
| +def MakeOCSPResponse(issuer_cn, issuer_key, serial, ocsp_state, sct_extension): |
| # https://tools.ietf.org/html/rfc2560 |
| issuer_name_hash = asn1.OCTETSTRING( |
| hashlib.sha1(asn1.ToDER(Name(cn = issuer_cn))).digest()) |
| @@ -264,26 +267,38 @@ def MakeOCSPResponse(issuer_cn, issuer_key, serial, ocsp_state): |
| else: |
| raise ValueError('Bad OCSP state: ' + str(ocsp_state)) |
| + single_response_sequence = [ # SingleResponse |
| + asn1.SEQUENCE([ # CertID |
| + asn1.SEQUENCE([ # hashAlgorithm |
| + HASH_SHA1, |
| + None, |
| + ]), |
| + issuer_name_hash, |
| + issuer_key_hash, |
| + serial, |
| + ]), |
| + cert_status, |
| + asn1.GeneralizedTime("20100101060000Z"), # thisUpdate |
| + asn1.Explicit(0, asn1.GeneralizedTime("20300101060000Z")), # nextUpdate |
| + ] |
| + |
| + if sct_extension: |
| + single_extension = asn1.SEQUENCE([ |
| + SCT_LIST_OCSP, # exntID |
| + False, # critical |
| + asn1.OCTETSTRING(asn1.ToDER(asn1.OCTETSTRING(sct_extension))) |
| + ]) |
| + |
| + single_extensions = asn1.SEQUENCE([single_extension]) |
| + single_response_sequence.append(asn1.Explicit(1, single_extensions)) |
| + |
| + single_response = asn1.SEQUENCE(single_response_sequence) |
| + |
| basic_resp_data_der = asn1.ToDER(asn1.SEQUENCE([ |
| asn1.Explicit(2, issuer_key_hash), |
| asn1.GeneralizedTime("20100101060000Z"), # producedAt |
| - asn1.SEQUENCE([ |
| - asn1.SEQUENCE([ # SingleResponse |
| - asn1.SEQUENCE([ # CertID |
| - asn1.SEQUENCE([ # hashAlgorithm |
| - HASH_SHA1, |
| - None, |
| - ]), |
| - issuer_name_hash, |
| - issuer_key_hash, |
| - serial, |
| - ]), |
| - cert_status, |
| - asn1.GeneralizedTime("20100101060000Z"), # thisUpdate |
| - asn1.Explicit(0, asn1.GeneralizedTime("20300101060000Z")), # nextUpdate |
| - ]), |
| - ]), |
| - ])) |
| + asn1.SEQUENCE([single_response]), |
| + ])) |
| basic_resp = asn1.SEQUENCE([ |
| asn1.Raw(basic_resp_data_der), |
| @@ -324,7 +339,8 @@ unauthorizedDER = '30030a0106'.decode('hex') |
| def GenerateCertKeyAndOCSP(subject = "127.0.0.1", |
| ocsp_url = "http://127.0.0.1", |
| ocsp_state = OCSP_STATE_GOOD, |
| - serial = 0): |
| + serial = 0, |
| + sct_extension = None): |
| '''GenerateCertKeyAndOCSP returns a (cert_and_key_pem, ocsp_der) where: |
| * cert_and_key_pem contains a certificate and private key in PEM format |
| with the given subject common name and OCSP URL. |
| @@ -344,6 +360,7 @@ def GenerateCertKeyAndOCSP(subject = "127.0.0.1", |
| elif ocsp_state == OCSP_STATE_INVALID: |
| ocsp_der = '3' |
| else: |
| - ocsp_der = MakeOCSPResponse(ISSUER_CN, KEY, serial, ocsp_state) |
| + ocsp_der = MakeOCSPResponse(ISSUER_CN, KEY, serial, ocsp_state, |
| + sct_extension) |
| return (cert_pem + KEY_PEM, ocsp_der) |