Skip to content

Commit 47197c0

Browse files
committed
Attestaion cert script
1 parent 187bb3d commit 47197c0

File tree

2 files changed

+178
-1
lines changed

2 files changed

+178
-1
lines changed

config/esp32/components/chip/factory.cmake

+21-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,27 @@
1414
# limitations under the License.
1515
#
1616

17-
include(${CMAKE_CURRENT_LIST_DIR}/factory_wrapper.cmake)
17+
function(set_default_value VAR DEFAULT_VALUE)
18+
if (NOT DEFINED ${VAR})
19+
set(${VAR} ${DEFAULT_VALUE} CACHE STRING ${VAR})
20+
endif()
21+
endfunction()
22+
23+
function(set_values)
24+
# Set variables with default values if not defined
25+
set_default_value(DEVICE_NAME "My bulb")
26+
set_default_value(VENDOR_NAME "Test-vendor")
27+
set_default_value(DISCRIMINATOR 3841)
28+
set_default_value(PASSCODE 20202020)
29+
set_default_value(VENDOR_ID 0xFFF2)
30+
set_default_value(PRODUCT_ID 0x8001)
31+
set_default_value(HARDWARE_VERSION 1)
32+
set_default_value(HARDWARE_VERSION_STR "Devkit")
33+
set_default_value(DAC_CERT "${CHIP_ROOT}/credentials/test/attestation/Chip-Test-DAC-FFF2-8001-0008-Cert.der")
34+
set_default_value(DAC_KEY "${CHIP_ROOT}/credentials/test/attestation/Chip-Test-DAC-FFF2-8001-0008-Key.der")
35+
set_default_value(PAI_CERT "${CHIP_ROOT}/credentials/test/attestation/Chip-Test-PAI-FFF2-8001-Cert.der")
36+
set_default_value(CERT_DCLRN "${CHIP_ROOT}/credentials/test/certification-declaration/Chip-Test-CD-FFF2-8001.der")
37+
endfunction()
1838

1939
function(generate_build_time_partition fctry_partition esp_secure_cert_partition chip_root)
2040
set(options FLASH_IN_PROJECT)

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)