demo/secure_element/resources/generation_scripts/secure_element_common.py

1 
2 
3 from __future__ import print_function
4 
5 import sys
6 import os
7 import binascii
8 
9 try:
10  import cryptography
11  from cryptography import x509
12 except:
13  sys.stdout.write("\n\n\n*** You must install the python package 'cryptography' first. Run the command:\n\n" + \
14  " pip install cryptography\n\n" + \
15  "More details here: https://pypi.org/project/cryptography\n\n\n")
16 import pytz
17 from cryptography.hazmat.primitives import serialization
18 from cryptography.hazmat.primitives import hashes
19 from cryptography.hazmat.primitives.asymmetric import ec
20 from cryptography.hazmat import backends
21 
22 crypto_be = backends.default_backend()
23 
24 
25 CREDENTIAL_BASE_PATH = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'credentials'))
26 CREDENTIAL_PATH = lambda filename : os.path.join(CREDENTIAL_BASE_PATH, filename).replace('\\', '/')
27 
28 SOURCE_BASE_PATH = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..', 'cert_templates'))
29 SOURCE_PATH = lambda filename : os.path.join(SOURCE_BASE_PATH, filename).replace('\\', '/')
30 
31 
32 ROOT_CA_FILENAME_BASE = 'root-ca'
33 ROOT_CA_KEY_FILENAME = ROOT_CA_FILENAME_BASE + '.key'
34 ROOT_CA_CERT_FILENAME = ROOT_CA_FILENAME_BASE + '.crt'
35 
36 SIGNER_CA_FILENAME_BASE = 'signer-ca'
37 SIGNER_CA_KEY_FILENAME = SIGNER_CA_FILENAME_BASE + '.key'
38 SIGNER_CA_CSR_FILENAME = SIGNER_CA_FILENAME_BASE + '.csr'
39 SIGNER_CA_CERT_FILENAME = SIGNER_CA_FILENAME_BASE + '.crt'
40 SIGNER_CA_VER_CERT_FILENAME = SIGNER_CA_FILENAME_BASE + '-verification.crt'
41 SIGNER_CA_C_FILENAME = 'cert_def_1_signer.c'
42 
43 KIT_INFO_FILENAME = 'kit-info.json'
44 
45 DEVICE_FILENAME_BASE = 'device'
46 DEVICE_CSR_FILENAME = DEVICE_FILENAME_BASE + '.csr'
47 DEVICE_CSR_C_FILENAME = 'cert_def_3_device_csr.c'
48 
49 DEVICE_CERT_FILENAME = DEVICE_FILENAME_BASE + '.crt'
50 DEVICE_CERT_C_FILENAME = 'cert_def_2_device.c'
51 
52 SERVER_FILENAME_BASE = 'test-server'
53 SERVER_KEY_FILENAME = SERVER_FILENAME_BASE + '.key'
54 SERVER_CSR_FILENAME = SERVER_FILENAME_BASE + '.csr'
55 SERVER_CERT_FILENAME = SERVER_FILENAME_BASE + '.crt'
56 SERVER_CERT_CHAIN_FILENAME = SERVER_FILENAME_BASE + '-chain.crt'
57 
58 
59 
60 
61 def load_or_create_key(filename, verbose=True):
62  file_path = CREDENTIAL_PATH(filename)
63 
64  try:
65  os.makedirs(os.path.dirname(file_path))
66  except:
67  pass
68 
69  # Create or load a root CA key pair
70  priv_key = None
71  if os.path.isfile(file_path):
72  # Load existing key
73  with open(file_path, 'rb') as f:
74  if verbose:
75  print(' Loading from ' + f.name)
76  priv_key = serialization.load_pem_private_key(
77  data=f.read(),
78  password=None,
79  backend=crypto_be)
80  if priv_key == None:
81  # No private key loaded, generate new one
82  if verbose:
83  print(' No key file found, generating new key')
84  priv_key = ec.generate_private_key(ec.SECP256R1(), crypto_be)
85  # Save private key to file
86  with open(file_path, 'wb') as f:
87  if verbose:
88  print(' Saving to ' + f.name)
89  pem_key = priv_key.private_bytes(
90  encoding=serialization.Encoding.PEM,
91  format=serialization.PrivateFormat.PKCS8,
92  encryption_algorithm=serialization.NoEncryption())
93  f.write(pem_key)
94  return priv_key
95 
96 
97 def random_cert_sn(size):
98  """Create a positive, non-trimmable serial number for X.509 certificates"""
99  raw_sn = bytearray(os.urandom(size))
100  raw_sn[0] = raw_sn[0] & 0x7F # Force MSB bit to 0 to ensure positive integer
101  raw_sn[0] = raw_sn[0] | 0x40 # Force next bit to 1 to ensure the integer won't be trimmed in ASN.1 DER encoding
102 
103  result = 0
104  for i in range(len(raw_sn)):
105  result = result * 256 + int(raw_sn[len(raw_sn) - i - 1])
106 
107  return result
108 
109 
110 def read_pem_cert(cert_path):
111  with open(cert_path, 'rb') as f:
112  print(' Loading from ' + f.name)
113  return x509.load_pem_x509_certificate(f.read(), crypto_be)
114 
115 def pub_key_to_bytes(pub_key):
116  # Get the public key as X and Y integers concatenated
117  pub_nums = pub_key.public_numbers()
118  pubkey = bytearray(binascii.unhexlify('{:064x}'.format(pub_nums.x)))
119  pubkey.extend(binascii.unhexlify('{:064x}'.format(pub_nums.y)))
120  return pubkey
121