blob: c9d793ff6ef8c8c69c289f63ea6b86d06d0b23f2 [file] [log] [blame]
#!/usr/bin/env bash
#
# Copyright (c) 2021 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Script that can be used to generate CHIP device attestation certificates
# for testing purposes.
# The script expects the path to the chip-cert tool binary as an input argument.
#
# Usage example when the script is run from the CHIP SDK root directory:
# ./credentials/test/gen-test-attestation-certs.sh ./out/debug/standalone/chip-cert
#
# The result will be stored in:
# credentials/test/attestation
# If the intention is to re-generate a new set of attestation certificates that
# replace the already present ones then it is recommended to remove current certificates:
# rm credentials/test/attestation/*
#
# Second example also generates C-Style file with those certificates/keys to be use by the SDK tests:
# ./credentials/test/gen-test-attestation-certs.sh ./out/debug/standalone/chip-cert src/credentials/tests/CHIPAttCert_test_vectors
#
# In addision to the DER/PEM files this command also generates the following C-Style files:
# src/credentials/tests/CHIPAttCert_test_vectors.cpp
# src/credentials/tests/CHIPAttCert_test_vectors.h
#
set -e
here=${0%/*}
dest_dir="$here/attestation"
rm -rf "$dest_dir"
mkdir -p "$dest_dir"
if [ $# == 1 ]; then
chip_cert_tool=$1
elif [ $# == 2 ]; then
chip_cert_tool=$1
output_cstyle_file=$2
else
echo "Error: Please specify one or two input arguments, where first argument is the path to the chip-cert tool binary"
exit
fi
cert_valid_from="2021-06-28 14:23:43"
cert_lifetime=4294967295
# Set #1:
# - PAA Subject includes VID
# - PAI Subject includes PID
{
vid=FFF1
pid=8000
dac_ids=(0000 0001 0002 0003 0004 0005 0006 0007)
paa_key_file="$dest_dir/Chip-Test-PAA-$vid-Key"
paa_cert_file="$dest_dir/Chip-Test-PAA-$vid-Cert"
"$chip_cert_tool" gen-att-cert --type a --subject-cn "Matter Test PAA" --subject-vid "$vid" --valid-from "$cert_valid_from" --lifetime "$cert_lifetime" --out-key "$paa_key_file".pem --out "$paa_cert_file".pem
pai_key_file="$dest_dir/Chip-Test-PAI-$vid-$pid-Key"
pai_cert_file="$dest_dir/Chip-Test-PAI-$vid-$pid-Cert"
"$chip_cert_tool" gen-att-cert --type i --subject-cn "Matter Test PAI" --subject-vid "$vid" --subject-pid "$pid" --valid-from "$cert_valid_from" --lifetime "$cert_lifetime" --ca-key "$paa_key_file".pem --ca-cert "$paa_cert_file".pem --out-key "$pai_key_file".pem --out "$pai_cert_file".pem
for dac in "${dac_ids[@]}"; do
dac_key_file="$dest_dir/Chip-Test-DAC-$vid-$pid-$dac-Key"
dac_cert_file="$dest_dir/Chip-Test-DAC-$vid-$pid-$dac-Cert"
"$chip_cert_tool" gen-att-cert --type d --subject-cn "Matter Test DAC $dac" --subject-vid "$vid" --subject-pid "$pid" --valid-from "$cert_valid_from" --lifetime "$cert_lifetime" --ca-key "$pai_key_file".pem --ca-cert "$pai_cert_file".pem --out-key "$dac_key_file".pem --out "$dac_cert_file".pem
done
}
# Set #2:
# - PAA Subject doesn't include VID
# - PAI Subject includes PID
{
vid=FFF2
pid=8001
dac_ids=(0008 0009 000A 000B 000C 000D 000E 000F)
paa_key_file="$dest_dir/Chip-Test-PAA-NoVID-Key"
paa_cert_file="$dest_dir/Chip-Test-PAA-NoVID-Cert"
"$chip_cert_tool" gen-att-cert --type a --subject-cn "Matter Test PAA" --valid-from "$cert_valid_from" --lifetime "$cert_lifetime" --out-key "$paa_key_file".pem --out "$paa_cert_file".pem
pai_key_file="$dest_dir/Chip-Test-PAI-$vid-$pid-Key"
pai_cert_file="$dest_dir/Chip-Test-PAI-$vid-$pid-Cert"
"$chip_cert_tool" gen-att-cert --type i --subject-cn "Matter Test PAI" --subject-vid "$vid" --subject-pid "$pid" --valid-from "$cert_valid_from" --lifetime "$cert_lifetime" --ca-key "$paa_key_file".pem --ca-cert "$paa_cert_file".pem --out-key "$pai_key_file".pem --out "$pai_cert_file".pem
for dac in "${dac_ids[@]}"; do
dac_key_file="$dest_dir/Chip-Test-DAC-$vid-$pid-$dac-Key"
dac_cert_file="$dest_dir/Chip-Test-DAC-$vid-$pid-$dac-Cert"
"$chip_cert_tool" gen-att-cert --type d --subject-cn "Matter Test DAC $dac" --subject-vid "$vid" --subject-pid "$pid" --valid-from "$cert_valid_from" --lifetime "$cert_lifetime" --ca-key "$pai_key_file".pem --ca-cert "$pai_cert_file".pem --out-key "$dac_key_file".pem --out "$dac_cert_file".pem
done
}
# Set #3:
# - PAA Subject doesn't include VID (the same PAA from Set #2 is used)
# - PAI Subject doesn't include PID
{
pid=8002
dac_ids=(0010 0011 0012 0013 0014 0015 0016 0017)
pai_key_file="$dest_dir/Chip-Test-PAI-$vid-NoPID-Key"
pai_cert_file="$dest_dir/Chip-Test-PAI-$vid-NoPID-Cert"
"$chip_cert_tool" gen-att-cert --type i --subject-cn "Matter Test PAI" --subject-vid "$vid" --valid-from "$cert_valid_from" --lifetime "$cert_lifetime" --ca-key "$paa_key_file".pem --ca-cert "$paa_cert_file".pem --out-key "$pai_key_file".pem --out "$pai_cert_file".pem
for dac in "${dac_ids[@]}"; do
dac_key_file="$dest_dir/Chip-Test-DAC-$vid-$pid-$dac-Key"
dac_cert_file="$dest_dir/Chip-Test-DAC-$vid-$pid-$dac-Cert"
"$chip_cert_tool" gen-att-cert --type d --subject-cn "Matter Test DAC $dac" --subject-vid "$vid" --subject-pid "$pid" --valid-from "$cert_valid_from" --lifetime "$cert_lifetime" --ca-key "$pai_key_file".pem --ca-cert "$pai_cert_file".pem --out-key "$dac_key_file".pem --out "$dac_cert_file".pem
done
}
# In addision to PEM format also create certificates in DER form.
for cert_file_pem in "$dest_dir"/*Cert.pem; do
cert_file_der="${cert_file_pem/.pem/.der}"
"$chip_cert_tool" convert-cert "$cert_file_pem" "$cert_file_der" --x509-der
done
# In addision to PEM format also create private key in DER form.
for key_file_pem in "$dest_dir"/*Key.pem; do
key_file_der="${key_file_pem/.pem/.der}"
"$chip_cert_tool" convert-key "$key_file_pem" "$key_file_der" --x509-der
done
# Print generated certificate, keys, and parameters in C-Style to use in the SDK if the output file is provided.
if [ ! -z "$output_cstyle_file" ]; then
copyright_note='/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'
cpp_includes='
#include <lib/support/CodeUtils.h>
#include <lib/support/Span.h>
'
header_includes='
#pragma once
'
namespaces_open='
namespace chip {
namespace TestCerts {
'
namespaces_close='
} // namespace TestCerts
} // namespace chip
'
printf "$copyright_note" >"$output_cstyle_file".cpp
printf "$copyright_note" >"$output_cstyle_file".h
printf "$cpp_includes" >>"$output_cstyle_file".cpp
printf "$header_includes" >>"$output_cstyle_file".h
printf "$namespaces_open\n" >>"$output_cstyle_file".cpp
printf "$namespaces_open\n" >>"$output_cstyle_file".h
for cert_file_pem in credentials/test/attestation/*Cert.pem; do
params_prefix="${cert_file_pem/*Chip-Test/sTestCert}"
params_prefix="${params_prefix//-/_}"
params_prefix="${params_prefix/_Cert.pem/}"
cert_file_der="${cert_file_pem/.pem/.der}"
key_file_pem="${cert_file_pem/Cert.pem/Key.pem}"
{
printf "// \${chip_root}/$cert_file_pem\n\n"
printf "constexpr uint8_t ${params_prefix}_Cert_Array[] = {\n"
less -f "$cert_file_der" | od -t x1 -An | sed 's/\</0x/g' | sed 's/\>/,/g' | sed 's/^/ /g'
printf "};\n\n"
printf "extern const ByteSpan ${params_prefix}_Cert = ByteSpan(${params_prefix}_Cert_Array);\n\n"
printf "constexpr uint8_t ${params_prefix}_SKID_Array[] = {\n"
openssl x509 -text -noout -in "$cert_file_pem" | sed '0,/X509v3 Subject Key Identifier:/d' | sed '2,$d' | sed 's/:/ /g' | sed 's/\</0x/g' | sed 's/\>/,/g' | sed "s/^[ \t]*/ /"
printf "};\n\n"
printf "extern const ByteSpan ${params_prefix}_SKID = ByteSpan(${params_prefix}_SKID_Array);\n\n"
printf "// \${chip_root}/$key_file_pem\n\n"
printf "constexpr uint8_t ${params_prefix}_PublicKey_Array[] = {\n"
openssl ec -text -noout -in "$key_file_pem" | sed '0,/pub:$/d' | sed '/ASN1 OID:/,$d' | sed 's/:/ /g' | sed 's/\</0x/g' | sed 's/\>/,/g' | sed "s/^[ \t]*/ /" | sed 's/ *$//'
printf "};\n\n"
printf "extern const ByteSpan ${params_prefix}_PublicKey = ByteSpan(${params_prefix}_PublicKey_Array);\n\n"
printf "constexpr uint8_t ${params_prefix}_PrivateKey_Array[] = {\n"
openssl ec -text -noout -in "$key_file_pem" | sed '0,/priv:$/d' | sed '/pub:/,$d' | sed 's/:/ /g' | sed 's/\</0x/g' | sed 's/\>/,/g' | sed "s/^[ \t]*/ /" | sed 's/ *$//'
printf "};\n\n"
printf "extern const ByteSpan ${params_prefix}_PrivateKey = ByteSpan(${params_prefix}_PrivateKey_Array);\n\n"
} >>"$output_cstyle_file".cpp
{
printf "extern const ByteSpan ${params_prefix}_Cert;\n"
printf "extern const ByteSpan ${params_prefix}_SKID;\n"
printf "extern const ByteSpan ${params_prefix}_PublicKey;\n"
printf "extern const ByteSpan ${params_prefix}_PrivateKey;\n\n"
} >>"$output_cstyle_file".h
done
printf "$namespaces_close" >>"$output_cstyle_file".cpp
printf "$namespaces_close" >>"$output_cstyle_file".h
fi