demo/secure_element/resources/generation_scripts/create_signer_cert.py

1 from __future__ import print_function
2 import datetime
3 import traceback
4 import optparse
5 
6 from secure_element_common import *
7 from cert2certdef import gen_cert_def_c_signer
8 
9 
10 
11 ''' ******************************************************************************************* '''
12 def create_signer_cert():
13  print('\nLoading signer CA CSR')
14  if not os.path.isfile(CREDENTIAL_PATH(SIGNER_CA_CSR_FILENAME)):
15  generate_signer_csr()
16 
17  with open(CREDENTIAL_PATH(SIGNER_CA_CSR_FILENAME), 'rb') as f:
18  print(' Loading from ' + f.name)
19  signer_ca_csr = x509.load_pem_x509_csr(f.read(), crypto_be)
20 
21  if not signer_ca_csr.is_signature_valid:
22  raise RuntimeError('Signer CA CSR has invalid signature.')
23 
24  print('\nLoading root CA key')
25  if not os.path.isfile(CREDENTIAL_PATH(ROOT_CA_KEY_FILENAME)):
26  raise Exception('Failed to find root CA key file, ' + ROOT_CA_KEY_FILENAME + '. Have you run the script: ca_create_root.py first?')
27 
28  with open(CREDENTIAL_PATH(ROOT_CA_KEY_FILENAME), 'rb') as f:
29  print(' Loading from ' + f.name)
30  root_ca_priv_key = serialization.load_pem_private_key(
31  data=f.read(),
32  password=None,
33  backend=crypto_be)
34 
35  print('\nLoading root CA certificate')
36  if not os.path.isfile(CREDENTIAL_PATH(ROOT_CA_CERT_FILENAME)):
37  raise Exception('Failed to find root CA certificate file, ' + ROOT_CA_CERT_FILENAME + '. Have you run the script: ca_create_root.py first?')
38 
39  with open(CREDENTIAL_PATH(ROOT_CA_CERT_FILENAME), 'rb') as f:
40  print(' Loading from ' + f.name)
41  root_ca_cert = x509.load_pem_x509_certificate(f.read(), crypto_be)
42 
43  # Create signer CA certificate
44  print('\nGenerating signer CA certificate from CSR')
45  builder = x509.CertificateBuilder()
46  builder = builder.serial_number(random_cert_sn(16))
47  builder = builder.issuer_name(root_ca_cert.subject)
48  builder = builder.not_valid_before(datetime.datetime.now(tz=pytz.utc))
49  builder = builder.not_valid_after(builder._not_valid_before.replace(year=builder._not_valid_before.year + 10))
50  builder = builder.subject_name(signer_ca_csr.subject)
51  builder = builder.public_key(signer_ca_csr.public_key())
52  builder = add_signer_extensions(
53  builder=builder,
54  authority_cert=root_ca_cert)
55  # Sign signer certificate with root
56  signer_ca_cert = builder.sign(
57  private_key=root_ca_priv_key,
58  algorithm=hashes.SHA256(),
59  backend=crypto_be)
60 
61  # Write signer CA certificate to file
62  with open(CREDENTIAL_PATH(SIGNER_CA_CERT_FILENAME), 'wb') as f:
63  print(' Saving to ' + f.name)
64  f.write(signer_ca_cert.public_bytes(encoding=serialization.Encoding.PEM))
65 
66  print('Generating ' + SIGNER_CA_C_FILENAME)
67  with open(SOURCE_PATH(SIGNER_CA_C_FILENAME), 'wb') as f:
68  f.write(gen_cert_def_c_signer(CREDENTIAL_PATH(SIGNER_CA_CERT_FILENAME)))
69 
70 
71  print('\nDone')
72 
73 
74 ''' ******************************************************************************************* '''
75 def generate_signer_csr():
76  # Load or create a signer CA key pair
77  print('\nLoading signer CA key')
78  signer_ca_priv_key = load_or_create_key(SIGNER_CA_KEY_FILENAME)
79 
80  print('\nGenerating signer CA CSR')
81  builder = x509.CertificateSigningRequestBuilder()
82  builder = builder.subject_name(x509.Name([
83  x509.NameAttribute(x509.oid.NameOID.ORGANIZATION_NAME, u'Example Inc'),
84  x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, u'Example Signer FFFF')]))
85  builder = add_signer_extensions(
86  builder=builder,
87  public_key=signer_ca_priv_key.public_key())
88  signer_ca_csr = builder.sign(
89  private_key=signer_ca_priv_key,
90  algorithm=hashes.SHA256(),
91  backend=crypto_be)
92 
93  # Save CSR
94  with open(CREDENTIAL_PATH(SIGNER_CA_CSR_FILENAME), 'wb') as f:
95  print(' Saving to ' + f.name)
96  f.write(signer_ca_csr.public_bytes(encoding=serialization.Encoding.PEM))
97 
98 
99 
100 ''' ******************************************************************************************* '''
101 def add_signer_extensions(builder, public_key=None, authority_cert=None):
102  if public_key == None:
103  public_key = builder._public_key # Public key not specified, assume its in the builder (cert builder)
104 
105  builder = builder.add_extension(
106  x509.BasicConstraints(ca=True, path_length=0),
107  critical=True)
108 
109  builder = builder.add_extension(
110  x509.KeyUsage(
111  digital_signature=True,
112  content_commitment=False,
113  key_encipherment=False,
114  data_encipherment=False,
115  key_agreement=False,
116  key_cert_sign=True,
117  crl_sign=True,
118  encipher_only=False,
119  decipher_only=False),
120  critical=True)
121 
122  builder = builder.add_extension(
123  x509.SubjectKeyIdentifier.from_public_key(public_key),
124  critical=False)
125  subj_key_id_ext = builder._extensions[-1] # Save newly created subj key id extension
126 
127  if authority_cert:
128  # We have an authority certificate, use its subject key id
129  builder = builder.add_extension(
130  x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
131  authority_cert.extensions.get_extension_for_class(x509.SubjectKeyIdentifier)),
132  critical=False)
133  else:
134  # No authority cert, assume this is a CSR and just use its own subject key id
135  builder = builder.add_extension(
136  x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(subj_key_id_ext),
137  critical=False)
138 
139  return builder
140 
141 
142 
143 
144 ''' ******************************************************************************************* '''
145 if __name__ == '__main__':
146  parser = optparse.OptionParser(description='Generates a certificate to sign the device certificate')
147  args = parser.parse_args()
148 
149  try:
150  create_signer_cert()
151  except Exception as e:
152  traceback.print_exc()
153  print(e)
154 
155