generate.py (3726B)
1 #!/usr/bin/env python 2 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- 3 # vim: set filetype=python 4 5 # This Source Code Form is subject to the terms of the Mozilla Public 6 # License, v. 2.0. If a copy of the MPL was not distributed with this 7 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 9 # This file generates the certspec files for test_cert_version.js. The naming 10 # convention for those files is generally of the form 11 # "<subject-description>_<issuer-description>.pem.certspec". End-entity 12 # certificates are generally called "ee". Intermediates are called 13 # "int". The root CA is called "ca" and self-signed certificates are called 14 # "ss". 15 # In the case that the subject and issuer are the same, the redundant part is 16 # not repeated. 17 # If there is nothing particularly special about a certificate, it has no 18 # description ("nothing particularly special" meaning the certificate is X509v3 19 # and has or does not have the basic constraints extension as expected by where 20 # it is in the hierarchy). Otherwise, the description includes its version and 21 # details about the extension. If the extension is not present, the string 22 # "noBC" is used. If it is present but the cA bit is not asserted, the string 23 # "BC-not-cA" is used. If it is present with the cA bit asserted, the string 24 # "BC-cA" is used. 25 # For example, a v1 intermediate that does not have the extension that was 26 # issued by the root CA has the name "int-v1-noBC_ca.pem.certspec". 27 # A v4 end-entity that does have the extension but does not assert the cA bit 28 # that was issued by the root CA has the name 29 # "ee-v4-BC-not-cA_ca.pem.certspec". 30 # An end-entity issued by a v3 intermediate with the extension that asserts the 31 # cA bit has the name "ee_int-v3-BC-cA.pem.certspec". 32 33 versions = {"v1": 1, "v2": 2, "v3": 3, "v4": 4} 34 35 basicConstraintsTypes = { 36 "noBC": "", 37 "BC-not-cA": "extension:basicConstraints:,", 38 "BC-cA": "extension:basicConstraints:cA,", 39 } 40 41 42 def writeCertspec(issuer, subject, fields): 43 filename = "%s_%s.pem.certspec" % (subject, issuer) 44 if issuer == subject: 45 filename = "%s.pem.certspec" % subject 46 with open(filename, "w") as f: 47 f.write("issuer:%s\n" % issuer) 48 f.write("subject:%s\n" % subject) 49 for field in fields: 50 if len(field) > 0: 51 f.write("%s\n" % field) 52 53 54 keyUsage = "extension:keyUsage:keyCertSign,cRLSign" 55 basicConstraintsCA = "extension:basicConstraints:cA," 56 57 writeCertspec("ca", "ca", [keyUsage, basicConstraintsCA]) 58 59 for versionStr, versionVal in versions.iteritems(): 60 # intermediates 61 versionText = "version:%s" % versionVal 62 for ( 63 basicConstraintsType, 64 basicConstraintsExtension, 65 ) in basicConstraintsTypes.iteritems(): 66 intermediateName = "int-%s-%s" % (versionStr, basicConstraintsType) 67 writeCertspec( 68 "ca", intermediateName, [keyUsage, versionText, basicConstraintsExtension] 69 ) 70 writeCertspec(intermediateName, "ee", []) 71 72 # end-entities 73 versionText = "version:%s" % versionVal 74 for ( 75 basicConstraintsType, 76 basicConstraintsExtension, 77 ) in basicConstraintsTypes.iteritems(): 78 writeCertspec( 79 "ca", 80 "ee-%s-%s" % (versionStr, basicConstraintsType), 81 [versionText, basicConstraintsExtension], 82 ) 83 84 # self-signed certificates 85 versionText = "version:%s" % versionVal 86 for ( 87 basicConstraintsType, 88 basicConstraintsExtension, 89 ) in basicConstraintsTypes.iteritems(): 90 selfSignedName = "ss-%s-%s" % (versionStr, basicConstraintsType) 91 writeCertspec( 92 selfSignedName, selfSignedName, [versionText, basicConstraintsExtension] 93 )