Skip to content

Commit 4fb3707

Browse files
committed
Attestaion cert script
1 parent 4bc4582 commit 4fb3707

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

scripts/tools/gen_att_certs.py

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2022 Project CHIP Authors
4+
# All rights reserved.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
import argparse
20+
import base64
21+
import json
22+
import logging as log
23+
import os
24+
import subprocess
25+
import sys
26+
from collections import namedtuple
27+
from os.path import exists
28+
29+
CHIP_ROOT = os.path.dirname(os.path.realpath(__file__))[:-len(os.path.join('scripts', 'tools'))]
30+
chip_cert_exe = os.path.join(CHIP_ROOT, 'out', 'host', 'chip-cert')
31+
32+
if not os.path.exists(chip_cert_exe):
33+
print("Error: chip-cert executable not found.Please build chip-cert in connectedhomeip by ninja -C out/host")
34+
35+
def gen_test_certs(vendor_id: int,
36+
product_id: int,
37+
output: str):
38+
"""
39+
Generate Matter certificates according to given Vendor ID and Product ID using the chip-cert executable.
40+
To use own Product Attestation Authority certificate provide paa_cert_path and paa_key_path arguments.
41+
Without providing these arguments a PAA certificate will be get from /credentials/test/attestation directory
42+
in the Matter repository.
43+
44+
Args:
45+
chip_cert_exe (str): path to chip-cert executable
46+
output (str): output path to store a newly generated certificates (CD, DAC, PAI)
47+
vendor_id (int): an identification number specific to Vendor
48+
product_id (int): an identification number specific to Product
49+
device_name (str): human-readable device name
50+
generate_cd (bool, optional): Generate Certificate Declaration and store it in thee output directory. Defaults to False.
51+
paa_cert_path (str, optional): provide PAA certification path. Defaults to None - a path will be set to
52+
/credentials/test/attestation directory.
53+
paa_key_path (str, optional): provide PAA key path. Defaults to None - a path will be set to
54+
/credentials/test/attestation directory.
55+
generate_all_certs: Generate the new DAC and PAI certificates
56+
57+
Returns:
58+
dictionary: ["PAI_CERT": (str)<path to PAI cert .der file>,
59+
"DAC_CERT": (str)<path to DAC cert .der file>,
60+
"DAC_KEY": (str)<path to DAC key .der file>]
61+
"""
62+
63+
CD_PATH = CHIP_ROOT + "/credentials/test/certification-declaration/Chip-Test-CD-Signing-Cert.pem"
64+
CD_KEY_PATH = CHIP_ROOT + "/credentials/test/certification-declaration/Chip-Test-CD-Signing-Key.pem"
65+
PAA_PATH = CHIP_ROOT + "/credentials/test/attestation/Chip-Test-PAA-NoVID-Cert.pem"
66+
PAA_KEY_PATH = CHIP_ROOT + "/credentials/test/attestation/Chip-Test-PAA-NoVID-Key.pem"
67+
68+
attestation_certs = namedtuple("attestation_certs", ["dac_cert", "dac_key", "pai_cert"])
69+
70+
log.info("Generating new Certification Declaration using chip-cert...")
71+
72+
# generate Certification Declaration
73+
cmd = [chip_cert_exe, "gen-cd",
74+
"--key", CD_KEY_PATH,
75+
"--cert", CD_PATH,
76+
"--out", output + "_"+ str(vendor_id) + "_"+ str(product_id) + "/CD.der",
77+
"--format-version", "1",
78+
"--vendor-id", hex(vendor_id),
79+
"--product-id", hex(product_id),
80+
"--device-type-id", "0",
81+
"--certificate-id", "FFFFFFFFFFFFFFFFFFF",
82+
"--security-level", "0",
83+
"--security-info", "0",
84+
"--certification-type", "0",
85+
"--version-number", "0xFFFF",
86+
]
87+
subprocess.run(cmd)
88+
89+
new_certificates = {"PAI_CERT": output + "_"+ str(vendor_id) + "_"+ str(product_id) + "/PAI_cert",
90+
"PAI_KEY": output + "_"+ str(vendor_id) + "_"+ str(product_id)+"/PAI_key",
91+
"DAC_CERT": output + "_"+ str(vendor_id) + "_"+ str(product_id) + "/DAC_cert",
92+
"DAC_KEY": output + "_"+ str(vendor_id)+ "_"+ str(product_id) + "/DAC_key"
93+
}
94+
95+
log.info("Generating new PAI and DAC certificates using chip-cert...")
96+
97+
# generate PAI
98+
cmd = [chip_cert_exe, "gen-att-cert",
99+
"-t", "i",
100+
"-c", "device",
101+
"-V", hex(vendor_id),
102+
"-C", PAA_PATH,
103+
"-K", PAA_KEY_PATH,
104+
"-o", new_certificates["PAI_CERT"] + ".pem",
105+
"-O", new_certificates["PAI_KEY"] + ".pem",
106+
"-l", str(10000),
107+
]
108+
subprocess.run(cmd)
109+
110+
# generate DAC
111+
cmd = [chip_cert_exe, "gen-att-cert",
112+
"-t", "d",
113+
"-c", "device",
114+
"-V", hex(vendor_id),
115+
"-P", hex(product_id),
116+
"-C", new_certificates["PAI_CERT"] + ".pem",
117+
"-K", new_certificates["PAI_KEY"] + ".pem",
118+
"-o", new_certificates["DAC_CERT"] + ".pem",
119+
"-O", new_certificates["DAC_KEY"] + ".pem",
120+
"-l", str(10000),
121+
]
122+
subprocess.run(cmd)
123+
124+
# convert to .der files
125+
for cert_k, cert_v in new_certificates.items():
126+
action_type = "convert-cert" if cert_k.find("CERT") != -1 else "convert-key"
127+
log.info(cert_v + ".der")
128+
cmd = [chip_cert_exe, action_type,
129+
cert_v + ".pem",
130+
cert_v + ".der",
131+
"--x509-der",
132+
]
133+
subprocess.run(cmd)
134+
135+
return attestation_certs(new_certificates["DAC_CERT"] + ".der",
136+
new_certificates["DAC_KEY"] + ".der",
137+
new_certificates["PAI_CERT"] + ".der")
138+
def get_args():
139+
def any_base_int(s): return int(s, 0)
140+
parser = argparse.ArgumentParser(description="ESP32 Attestation generation tool")
141+
parser.add_argument("-o", "--output", type=str, required=False,
142+
help="Output path to store attestation certificates", default="certs/attestation")
143+
parser.add_argument('--vendor-id', type=any_base_int, help="Vendor id")
144+
parser.add_argument('--product-id', type=any_base_int, help="Product id")
145+
return parser.parse_args()
146+
147+
def set_up_out_dirs(args):
148+
os.makedirs(args.output + "_" + str(args.vendor_id) + "_" + str(args.product_id), exist_ok=True)
149+
150+
def main():
151+
args = get_args()
152+
set_up_out_dirs(args)
153+
certs = gen_test_certs(args.vendor_id, args.product_id, args.output)
154+
155+
if __name__ == "__main__":
156+
main()
157+

0 commit comments

Comments
 (0)