1
+ #!/usr/bin/env python3
2
+ import argparse
3
+ import pathlib
4
+ from cryptography .x509 import load_pem_x509_certificate
5
+ from cryptography .hazmat .primitives .serialization import Encoding
6
+ import base64
7
+
8
+ def is_file_and_exists (arg ) -> pathlib .Path :
9
+ p = pathlib .Path (arg )
10
+ if p .is_file () and p .exists ():
11
+ return p
12
+ raise argparse .ArgumentTypeError (f"Argument is not a valid file: { arg } ." )
13
+
14
+ def load_cert (cert : pathlib .Path ) -> bytes :
15
+ """Load x509 certificate and convert to ASN.1 DER-TLV."""
16
+ if cert .suffix == ".pem" :
17
+ return load_pem_x509_certificate (cert .read_bytes ()).public_bytes (
18
+ Encoding .DER
19
+ )
20
+ if cert .suffix == ".der" :
21
+ return cert .read_bytes ()
22
+ raise argparse .ArgumentTypeError ("Certificate not in DER nor PEM format." )
23
+
24
+
25
+ if __name__ == "__main__" :
26
+ parser = argparse .ArgumentParser (
27
+ prog = "gen_cert_store.py" ,
28
+ description = "Creates TROPIC01 Device Certificate Store from input certificates and encodes it as base64."
29
+ )
30
+
31
+ parser .add_argument (
32
+ "--store-version" ,
33
+ help = "Certificate store version (from the Certificate Store Header)." ,
34
+ type = int ,
35
+ default = 1
36
+ )
37
+
38
+ parser .add_argument (
39
+ "--certs" ,
40
+ help = "Files with the certificates in PEM or DER format." ,
41
+ type = is_file_and_exists ,
42
+ nargs = "+" ,
43
+ required = True
44
+ )
45
+
46
+ args = parser .parse_args ()
47
+
48
+ cert_store_header = args .store_version .to_bytes (1 , 'big' )
49
+ cert_store_header += len (args .certs ).to_bytes (1 , 'big' )
50
+ cert_store_body = b''
51
+ for c in args .certs :
52
+ cert_der = load_cert (c )
53
+ cert_store_header += len (cert_der ).to_bytes (2 , 'big' )
54
+ cert_store_body += cert_der
55
+
56
+
57
+ output = base64 .b64encode (cert_store_header + cert_store_body )
58
+ print (f"TROPIC01 Device Certificate Store:\n { output } " )
0 commit comments