15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import asn1 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import hashlib 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This file implements very minimal certificate and OCSP generation. It's 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# designed to test revocation checking. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def RandomNumber(length_in_bytes): 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''RandomNumber returns a random number of length 8*|length_in_bytes| bits''' 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rand = os.urandom(length_in_bytes) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 0 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for x in rand: 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n <<= 8 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n |= ord(x) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return n 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ModExp(n, e, p): 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''ModExp returns n^e mod p''' 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r = 1 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while e != 0: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if e & 1: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r = (r*n) % p 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) e >>= 1 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = (n*n) % p 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return r 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# PKCS1v15_SHA256_PREFIX is the ASN.1 prefix for a SHA256 signature. 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPKCS1v15_SHA256_PREFIX = '3031300d060960864801650304020105000420'.decode('hex') 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RSA(object): 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, modulus, e, d): 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.m = modulus 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.e = e 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.d = d 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.modlen = 0 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m = modulus 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while m != 0: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.modlen += 1 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m >>= 8 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Sign(self, message): 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci digest = hashlib.sha256(message).digest() 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci prefix = PKCS1v15_SHA256_PREFIX 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) em = ['\xff'] * (self.modlen - 1 - len(prefix) - len(digest)) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) em[0] = '\x00' 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) em[1] = '\x01' 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) em += "\x00" + prefix + digest 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 0 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for x in em: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n <<= 8 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n |= ord(x) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = ModExp(n, self.d, self.m) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out = [] 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while s != 0: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.append(s & 0xff) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s >>= 8 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.reverse() 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '\x00' * (self.modlen - len(out)) + asn1.ToBytes(out) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ToDER(self): 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return asn1.ToDER(asn1.SEQUENCE([self.m, self.e])) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Name(cn = None, c = None, o = None): 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names = asn1.SEQUENCE([]) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if cn is not None: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names.children.append( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SET([ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMMON_NAME, cn, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if c is not None: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names.children.append( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SET([ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COUNTRY, c, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if o is not None: 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names.children.append( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SET([ 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ORGANIZATION, o, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return names 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The private key and root certificate name are hard coded here: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This is the private key 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)KEY = RSA(0x00a71998f2930bfe73d031a87f133d2f378eeeeed52a77e44d0fc9ff6f07ff32cbf3da999de4ed65832afcb0807f98787506539d258a0ce3c2c77967653099a9034a9b115a876c39a8c4e4ed4acd0c64095946fb39eeeb47a0704dbb018acf48c3a1c4b895fc409fb4a340a986b1afc45519ab9eca47c30185c771c64aa5ecf07d, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x6f6665f70cb2a9a28acbc5aa0cd374cfb49f49e371a542de0a86aa4a0554cc87f7e71113edf399021ca875aaffbafaf8aee268c3b15ded2c84fb9a4375bbc6011d841e57833bc6f998d25daf6fa7f166b233e3e54a4bae7a5aaaba21431324967d5ff3e1d4f413827994262115ca54396e7068d0afa7af787a5782bc7040e6d3) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# And the same thing in PEM format 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)KEY_PEM = '''-----BEGIN RSA PRIVATE KEY----- 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MIICXAIBAAKBgQCnGZjykwv+c9AxqH8TPS83ju7u1Sp35E0Pyf9vB/8yy/PamZ3k 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)7WWDKvywgH+YeHUGU50ligzjwsd5Z2UwmakDSpsRWodsOajE5O1KzQxkCVlG+znu 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)60egcE27AYrPSMOhxLiV/ECftKNAqYaxr8RVGaueykfDAYXHccZKpezwfQIBAwKB 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gG9mZfcMsqmiisvFqgzTdM+0n0njcaVC3gqGqkoFVMyH9+cRE+3zmQIcqHWq/7r6 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)+K7iaMOxXe0shPuaQ3W7xgEdhB5XgzvG+ZjSXa9vp/FmsjPj5UpLrnpaqrohQxMk 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ln1f8+HU9BOCeZQmIRXKVDlucGjQr6eveHpXgrxwQObTAkEA2wBAfuduw5G0/VfN 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Wx66D5fbPccfYFqLM5LuTimLmNqzK2gIKXckB2sm44gJZ6wVlumaB1CSNug2LNYx 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)3cAjUwJBAMNUo1hbI8ugqqwI9kpxv9+2Heea4BlnXbS6tYF8pvkHMoliuxNbXmmB 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)u4zNB5iZ6V0ZZ4nvtUNo2cGr/h/Lcu8CQQCSACr/RPSCYSNTj948vya1D+d+hL+V 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)kbIiYfQ0G7Jl5yIc8AVw+hgE8hntBVuacrkPRmaviwwkms7IjsvpKsI3AkEAgjhs 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)5ZIX3RXHHVtO3EvVP86+mmdAEO+TzdHOVlMZ+1ohsOx8t5I+8QEnszNaZbvw6Lua 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)W/UjgkXmgR1UFTJMnwJBAKErmAw21/g3SST0a4wlyaGT/MbXL8Ouwnb5IOKQVe55 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CZdeVeSh6cJ4hAcQKfr2s1JaZTJFIBPGKAif5HqpydA= 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-----END RSA PRIVATE KEY----- 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)''' 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Root certificate CN 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ISSUER_CN = "Testing CA" 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# All certificates are issued under this policy OID, in the Google arc: 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CERT_POLICY_OID = asn1.OID([1, 3, 6, 1, 4, 1, 11129, 2, 4, 1]) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# These result in the following root certificate: 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# -----BEGIN CERTIFICATE----- 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# MIIB0TCCATqgAwIBAgIBATANBgkqhkiG9w0BAQUFADAVMRMwEQYDVQQDEwpUZXN0aW5nIENBMB4X 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# DTEwMDEwMTA2MDAwMFoXDTMyMTIwMTA2MDAwMFowFTETMBEGA1UEAxMKVGVzdGluZyBDQTCBnTAN 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# BgkqhkiG9w0BAQEFAAOBiwAwgYcCgYEApxmY8pML/nPQMah/Ez0vN47u7tUqd+RND8n/bwf/Msvz 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2pmd5O1lgyr8sIB/mHh1BlOdJYoM48LHeWdlMJmpA0qbEVqHbDmoxOTtSs0MZAlZRvs57utHoHBN 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# uwGKz0jDocS4lfxAn7SjQKmGsa/EVRmrnspHwwGFx3HGSqXs8H0CAQOjMzAxMBIGA1UdEwEB/wQI 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# MAYBAf8CAQAwGwYDVR0gAQEABBEwDzANBgsrBgEEAdZ5AgHODzANBgkqhkiG9w0BAQUFAAOBgQA/ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# STb40A6D+93jMfLGQzXc997IsaJZdoPt7tYa8PqGJBL62EiTj+erd/H5pDZx/2/bcpOG4m9J56yg 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# wOohbllw2TM+oeEd8syzV6X+1SIPnGI56JRrm3UXcHYx1Rq5loM9WKAiz/WmIWmskljsEQ7+542p 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# q0pkHjs8nuXovSkUYA== 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# -----END CERTIFICATE----- 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If you update any of the above, you can generate a new root with the 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# following line: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# print DERToPEM(MakeCertificate(ISSUER_CN, ISSUER_CN, 1, KEY, KEY, None)) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Various OIDs 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AIA_OCSP = asn1.OID([1, 3, 6, 1, 5, 5, 7, 48, 1]) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AUTHORITY_INFORMATION_ACCESS = asn1.OID([1, 3, 6, 1, 5, 5, 7, 1, 1]) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASIC_CONSTRAINTS = asn1.OID([2, 5, 29, 19]) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CERT_POLICIES = asn1.OID([2, 5, 29, 32]) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMMON_NAME = asn1.OID([2, 5, 4, 3]) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COUNTRY = asn1.OID([2, 5, 4, 6]) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HASH_SHA1 = asn1.OID([1, 3, 14, 3, 2, 26]) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OCSP_TYPE_BASIC = asn1.OID([1, 3, 6, 1, 5, 5, 7, 48, 1, 1]) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ORGANIZATION = asn1.OID([2, 5, 4, 10]) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PUBLIC_KEY_RSA = asn1.OID([1, 2, 840, 113549, 1, 1, 1]) 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciSHA256_WITH_RSA_ENCRYPTION = asn1.OID([1, 2, 840, 113549, 1, 1, 11]) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def MakeCertificate( 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) issuer_cn, subject_cn, serial, pubkey, privkey, ocsp_url = None): 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''MakeCertificate returns a DER encoded certificate, signed by privkey.''' 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions = asn1.SEQUENCE([]) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Default subject name fields 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = "XX" 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) o = "Testing Org" 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if issuer_cn == subject_cn: 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Root certificate. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = None 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) o = None 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions.children.append( 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basic_constraints, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) True, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.OCTETSTRING(asn1.ToDER(asn1.SEQUENCE([ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) True, # IsCA 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, # Path len 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]))), 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ])) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ocsp_url is not None: 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions.children.append( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AUTHORITY_INFORMATION_ACCESS, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) False, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.OCTETSTRING(asn1.ToDER(asn1.SEQUENCE([ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AIA_OCSP, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.Raw(asn1.TagAndLength(0x86, len(ocsp_url)) + ocsp_url), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]))), 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ])) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions.children.append( 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_POLICIES, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) False, 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.OCTETSTRING(asn1.ToDER(asn1.SEQUENCE([ 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ # PolicyInformation 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_POLICY_OID, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]))), 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tbsCert = asn1.ToDER(asn1.SEQUENCE([ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.Explicit(0, 2), # Version 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serial, 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci asn1.SEQUENCE([SHA256_WITH_RSA_ENCRYPTION, None]), # SignatureAlgorithm 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Name(cn = issuer_cn), # Issuer 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ # Validity 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.UTCTime("100101060000Z"), # NotBefore 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.UTCTime("321201060000Z"), # NotAfter 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Name(cn = subject_cn, c = c, o = o), # Subject 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ # SubjectPublicKeyInfo 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ # Algorithm 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUBLIC_KEY_RSA, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) None, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.BitString(asn1.ToDER(pubkey)), 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.Explicit(3, extensions), 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ])) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return asn1.ToDER(asn1.SEQUENCE([ 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.Raw(tbsCert), 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SHA256_WITH_RSA_ENCRYPTION, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) None, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.BitString(privkey.Sign(tbsCert)), 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ])) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def MakeOCSPResponse(issuer_cn, issuer_key, serial, ocsp_state): 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # https://tools.ietf.org/html/rfc2560 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) issuer_name_hash = asn1.OCTETSTRING( 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hashlib.sha1(asn1.ToDER(Name(cn = issuer_cn))).digest()) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) issuer_key_hash = asn1.OCTETSTRING( 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hashlib.sha1(asn1.ToDER(issuer_key)).digest()) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_status = None 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ocsp_state == OCSP_STATE_REVOKED: 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_status = asn1.Explicit(1, asn1.GeneralizedTime("20100101060000Z")) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif ocsp_state == OCSP_STATE_UNKNOWN: 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 2, 0)) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif ocsp_state == OCSP_STATE_GOOD: 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_status = asn1.Raw(asn1.TagAndLength(0x80 | 0, 0)) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ValueError('Bad OCSP state: ' + str(ocsp_state)) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basic_resp_data_der = asn1.ToDER(asn1.SEQUENCE([ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.Explicit(2, issuer_key_hash), 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.GeneralizedTime("20100101060000Z"), # producedAt 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ # SingleResponse 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ # CertID 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ # hashAlgorithm 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HASH_SHA1, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) None, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) issuer_name_hash, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) issuer_key_hash, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serial, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_status, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.GeneralizedTime("20100101060000Z"), # thisUpdate 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.Explicit(0, asn1.GeneralizedTime("20300101060000Z")), # nextUpdate 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ])) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basic_resp = asn1.SEQUENCE([ 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.Raw(basic_resp_data_der), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.SEQUENCE([ 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SHA256_WITH_RSA_ENCRYPTION, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) None, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]), 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.BitString(issuer_key.Sign(basic_resp_data_der)), 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resp = asn1.SEQUENCE([ 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.ENUMERATED(0), 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.Explicit(0, asn1.SEQUENCE([ 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OCSP_TYPE_BASIC, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asn1.OCTETSTRING(asn1.ToDER(basic_resp)), 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ])) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ]) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return asn1.ToDER(resp) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def DERToPEM(der): 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pem = '-----BEGIN CERTIFICATE-----\n' 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pem += der.encode('base64') 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pem += '-----END CERTIFICATE-----\n' 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pem 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OCSP_STATE_GOOD = 1 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OCSP_STATE_REVOKED = 2 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OCSP_STATE_INVALID = 3 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OCSP_STATE_UNAUTHORIZED = 4 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OCSP_STATE_UNKNOWN = 5 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# unauthorizedDER is an OCSPResponse with a status of 6: 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# SEQUENCE { ENUM(6) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unauthorizedDER = '30030a0106'.decode('hex') 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def GenerateCertKeyAndOCSP(subject = "127.0.0.1", 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ocsp_url = "http://127.0.0.1", 326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ocsp_state = OCSP_STATE_GOOD, 327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) serial = 0): 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '''GenerateCertKeyAndOCSP returns a (cert_and_key_pem, ocsp_der) where: 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cert_and_key_pem contains a certificate and private key in PEM format 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) with the given subject common name and OCSP URL. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ocsp_der contains a DER encoded OCSP response or None if ocsp_url is 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) None''' 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if serial == 0: 335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) serial = RandomNumber(16) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_der = MakeCertificate(ISSUER_CN, bytes(subject), serial, KEY, KEY, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes(ocsp_url)) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_pem = DERToPEM(cert_der) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ocsp_der = None 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ocsp_url is not None: 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ocsp_state == OCSP_STATE_UNAUTHORIZED: 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ocsp_der = unauthorizedDER 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif ocsp_state == OCSP_STATE_INVALID: 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ocsp_der = '3' 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ocsp_der = MakeOCSPResponse(ISSUER_CN, KEY, serial, ocsp_state) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (cert_pem + KEY_PEM, ocsp_der) 350