9 from __future__
import print_function
14 from secure_element_common
import *
15 from secure_element_device
import secure_element_device
16 from cert2certdef
import gen_cert_def_c_device
17 from pyasn1.compat.integer
import from_bytes
20 ''' ******************************************************************************************* ''' 21 def create_device_cert():
22 print(
'\nOpening connection to Device')
23 with secure_element_device()
as device:
24 _create_device_cert(device)
27 ''' ******************************************************************************************* ''' 28 def _create_device_cert(device):
29 print(
'\nInitializing Device')
30 device_info = device.init()
31 print(
' MAC Address: %s' % device_info.mac)
32 print(
' ATECC608A SN: %s' % device_info.se.serial_number)
33 print(
' ATECC608A Public Key:')
36 public_key = binascii.hexlify(device_info.se.public_key)
37 int_size = len(public_key) / 2
38 print(
' X: %s' % public_key[:int_size])
39 print(
' Y: %s' % public_key[int_size:])
42 print(
'\nLoading signer CA key')
43 if not os.path.isfile(CREDENTIAL_PATH(SIGNER_CA_KEY_FILENAME)):
44 raise Exception(
'Failed to find signer CA key file, ' + SIGNER_CA_KEY_FILENAME +
'. Have you run the script: ca_create_signer.py first?')
46 with open(CREDENTIAL_PATH(SIGNER_CA_KEY_FILENAME),
'rb')
as f:
47 print(
' Loading from ' + f.name)
48 signer_ca_priv_key = serialization.load_pem_private_key(
53 print(
'\nLoading signer CA certificate')
54 if not os.path.isfile(CREDENTIAL_PATH(SIGNER_CA_CERT_FILENAME)):
55 raise Exception(
'Failed to find signer CA certificate file, ' + SIGNER_CA_CERT_FILENAME +
'. Have you run the script: ca_create_signer.py first?')
57 with open(CREDENTIAL_PATH(SIGNER_CA_CERT_FILENAME),
'rb')
as f:
58 print(
' Loading from ' + f.name)
59 signer_ca_cert = x509.load_pem_x509_certificate(f.read(), crypto_be)
62 print(
'\nRequesting device CSR')
63 resp = device.gen_csr()
64 device_csr = x509.load_der_x509_csr(str(resp.csr), crypto_be)
65 if not device_csr.is_signature_valid:
66 raise Exception(
'Device CSR has invalid signature.')
68 with open(CREDENTIAL_PATH(DEVICE_CSR_FILENAME),
'wb')
as f:
69 print(
' Saving to ' + f.name)
70 f.write(device_csr.public_bytes(encoding=serialization.Encoding.PEM))
72 print(
'\nGenerating device certificate from CSR')
74 builder = x509.CertificateBuilder()
75 builder = builder.issuer_name(signer_ca_cert.subject)
76 builder = builder.not_valid_before(datetime.datetime.now(tz=pytz.utc).replace(minute=0,second=0))
77 builder = builder.not_valid_after(datetime.datetime(3000, 12, 31, 23, 59, 59))
78 builder = builder.subject_name(device_csr.subject)
79 builder = builder.public_key(device_csr.public_key())
81 builder = builder.serial_number(device_cert_sn(16, builder))
83 for extension
in device_csr.extensions:
84 builder = builder.add_extension(extension.value, extension.critical)
86 builder = builder.add_extension(
87 x509.SubjectKeyIdentifier.from_public_key(builder._public_key),
89 issuer_ski = signer_ca_cert.extensions.get_extension_for_class(x509.SubjectKeyIdentifier)
90 builder = builder.add_extension(
91 x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier(issuer_ski),
95 device_cert = builder.sign(
96 private_key=signer_ca_priv_key,
97 algorithm=hashes.SHA256(),
101 with open(CREDENTIAL_PATH(DEVICE_CERT_FILENAME),
'wb')
as f:
102 print(
' Saving to ' + f.name)
103 f.write(device_cert.public_bytes(encoding=serialization.Encoding.PEM))
105 print(
'Generating ' + DEVICE_CERT_C_FILENAME)
106 with open(SOURCE_PATH(DEVICE_CERT_C_FILENAME),
'wb')
as f:
107 cert_def_2_device = gen_cert_def_c_device(CREDENTIAL_PATH(DEVICE_CERT_FILENAME))
108 f.write(cert_def_2_device)
115 ''' ******************************************************************************************* 116 The cert_def_2_device.c has: 118 .sn_source = SNSRC_PUB_KEY_HASH, 120 In atcacert_def.h, SNSRC_PUB_KEY_HASH = Cert serial number is the SHA256(Subject public key + Encoded dates) 122 def device_cert_sn(size, builder):
123 pubkey = pub_key_to_bytes(builder._public_key)
127 enc_dates = bytearray(b
'\x00'*3)
128 enc_dates[0] = (enc_dates[0] & 0x07) | ((((builder._not_valid_before.year - 2000) & 0x1F) << 3) & 0xFF)
129 enc_dates[0] = (enc_dates[0] & 0xF8) | ((((builder._not_valid_before.month) & 0x0F) >> 1) & 0xFF)
130 enc_dates[1] = (enc_dates[1] & 0x7F) | ((((builder._not_valid_before.month) & 0x0F) << 7) & 0xFF)
131 enc_dates[1] = (enc_dates[1] & 0x83) | (((builder._not_valid_before.day & 0x1F) << 2) & 0xFF)
132 enc_dates[1] = (enc_dates[1] & 0xFC) | (((builder._not_valid_before.hour & 0x1F) >> 3) & 0xFF)
133 enc_dates[2] = (enc_dates[2] & 0x1F) | (((builder._not_valid_before.hour & 0x1F) << 5) & 0xFF)
134 enc_dates[2] = (enc_dates[2] & 0xE0) | ((expire_years & 0x1F) & 0xFF)
135 enc_dates = bytes(enc_dates)
138 digest = hashes.Hash(hashes.SHA256(), backend=crypto_be)
139 digest.update(str(pubkey))
140 digest.update(enc_dates)
141 raw_sn = bytearray(digest.finalize()[:size])
142 raw_sn[0] = raw_sn[0] & 0x7F
143 raw_sn[0] = raw_sn[0] | 0x40
145 return from_bytes(raw_sn, signed=
False)
152 ''' ******************************************************************************************* ''' 153 if __name__ ==
'__main__':
154 parser = optparse.OptionParser(description=
'Uses secure element to generate device certificate and provisions device. NOTE: The device must be connected and programmed with the app running to use this script')
155 options, _ = parser.parse_args()
159 except Exception
as e:
160 traceback.print_exc()