mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-18 04:28:18 +00:00
feat(core/prodtest): parse algorithm identifier
[no changelog]
This commit is contained in:
parent
a684d6f1ed
commit
be7236076f
@ -21,10 +21,12 @@
|
|||||||
const uint8_t OID_AUTHORITY_KEY_IDENTIFIER[] = {0x06, 0x03, 0x55, 0x1d, 0x23};
|
const uint8_t OID_AUTHORITY_KEY_IDENTIFIER[] = {0x06, 0x03, 0x55, 0x1d, 0x23};
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const uint8_t ECDSA_WITH_SHA256[] = {
|
static const uint8_t ECDSA_P256_WITH_SHA256[] = {
|
||||||
0x30, 0x0a, // a sequence of 10 bytes
|
0x30, 0x13, // a sequence of 19 bytes
|
||||||
|
0x06, 0x07, // an OID of 7 bytes
|
||||||
|
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, // corresponds to ecPublicKey in X.509
|
||||||
0x06, 0x08, // an OID of 8 bytes
|
0x06, 0x08, // an OID of 8 bytes
|
||||||
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
|
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, // corresponds to prime256v1 in X.509
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t OID_COMMON_NAME[] = {
|
static const uint8_t OID_COMMON_NAME[] = {
|
||||||
@ -45,6 +47,19 @@ static const uint8_t SUBJECT_COMMON_NAME[] = {
|
|||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
typedef enum { ALG_ID_ECDSA_P256_WITH_SHA256 } alg_id_t;
|
||||||
|
|
||||||
|
static bool get_algorithm(DER_ITEM* alg, alg_id_t* alg_id) {
|
||||||
|
if (alg->buf.size == sizeof(ECDSA_P256_WITH_SHA256) &&
|
||||||
|
memcmp(alg->buf.data, ECDSA_P256_WITH_SHA256,
|
||||||
|
sizeof(ECDSA_P256_WITH_SHA256)) == 0) {
|
||||||
|
*alg_id = ALG_ID_ECDSA_P256_WITH_SHA256;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool get_cert_extensions(DER_ITEM* tbs_cert, DER_ITEM* extensions) {
|
static bool get_cert_extensions(DER_ITEM* tbs_cert, DER_ITEM* extensions) {
|
||||||
// Find the certificate extensions in the tbsCertificate.
|
// Find the certificate extensions in the tbsCertificate.
|
||||||
DER_ITEM cert_item = {0};
|
DER_ITEM cert_item = {0};
|
||||||
@ -171,10 +186,11 @@ static bool get_common_name(DER_ITEM* name, const uint8_t** common_name,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool verify_signature(const uint8_t* pub_key, size_t pub_key_size,
|
static bool verify_signature(alg_id_t alg_id, const uint8_t* pub_key,
|
||||||
const uint8_t* sig, size_t sig_size,
|
size_t pub_key_size, const uint8_t* sig,
|
||||||
const uint8_t* msg, size_t msg_size) {
|
size_t sig_size, const uint8_t* msg,
|
||||||
// ECDSA (NIST P-256) with SHA-256
|
size_t msg_size) {
|
||||||
|
if (alg_id == ALG_ID_ECDSA_P256_WITH_SHA256) {
|
||||||
if (pub_key_size != 65) {
|
if (pub_key_size != 65) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -192,6 +208,9 @@ static bool verify_signature(const uint8_t* pub_key, size_t pub_key_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_cert_chain(cli_t* cli, const uint8_t* chain, size_t chain_size,
|
bool check_cert_chain(cli_t* cli, const uint8_t* chain, size_t chain_size,
|
||||||
@ -215,6 +234,8 @@ bool check_cert_chain(cli_t* cli, const uint8_t* chain, size_t chain_size,
|
|||||||
const uint8_t* pub_key = NULL;
|
const uint8_t* pub_key = NULL;
|
||||||
size_t pub_key_size = 0;
|
size_t pub_key_size = 0;
|
||||||
|
|
||||||
|
alg_id_t alg_id = 0;
|
||||||
|
|
||||||
BUFFER_READER chain_reader = {0};
|
BUFFER_READER chain_reader = {0};
|
||||||
buffer_reader_init(&chain_reader, chain, chain_size);
|
buffer_reader_init(&chain_reader, chain, chain_size);
|
||||||
int cert_count = 0;
|
int cert_count = 0;
|
||||||
@ -281,17 +302,25 @@ bool check_cert_chain(cli_t* cli, const uint8_t* chain, size_t chain_size,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read the algorithm
|
||||||
|
DER_ITEM alg = {0};
|
||||||
|
if (!der_read_item(&pub_key_info.buf, &alg) ||
|
||||||
|
!get_algorithm(&alg, &alg_id)) {
|
||||||
|
cli_error(cli, CLI_ERROR,
|
||||||
|
"check_device_cert_chain, reading algorithm, cert %d.",
|
||||||
|
cert_count);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Read the public key.
|
// Read the public key.
|
||||||
DER_ITEM pub_key_val = {0};
|
DER_ITEM pub_key_val = {0};
|
||||||
uint8_t unused_bits = 0;
|
uint8_t unused_bits = 0;
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
if (!der_read_item(&pub_key_info.buf, &pub_key_val)) {
|
if (!der_read_item(&pub_key_info.buf, &pub_key_val)) {
|
||||||
cli_error(cli, CLI_ERROR,
|
cli_error(cli, CLI_ERROR,
|
||||||
"check_device_cert_chain, der_read_item 6, cert %d.",
|
"check_device_cert_chain, der_read_item 6, cert %d.",
|
||||||
cert_count);
|
cert_count);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!buffer_get(&pub_key_val.buf, &unused_bits) ||
|
if (!buffer_get(&pub_key_val.buf, &unused_bits) ||
|
||||||
!buffer_ptr(&pub_key_val.buf, &pub_key)) {
|
!buffer_ptr(&pub_key_val.buf, &pub_key)) {
|
||||||
@ -303,7 +332,7 @@ bool check_cert_chain(cli_t* cli, const uint8_t* chain, size_t chain_size,
|
|||||||
pub_key_size = buffer_remaining(&pub_key_val.buf);
|
pub_key_size = buffer_remaining(&pub_key_val.buf);
|
||||||
|
|
||||||
// Verify the previous signature.
|
// Verify the previous signature.
|
||||||
if (!verify_signature(pub_key, pub_key_size, sig, sig_size, message,
|
if (!verify_signature(alg_id, pub_key, pub_key_size, sig, sig_size, message,
|
||||||
message_size)) {
|
message_size)) {
|
||||||
cli_error(cli, CLI_ERROR,
|
cli_error(cli, CLI_ERROR,
|
||||||
"check_device_cert_chain, verify_signature, cert %d.",
|
"check_device_cert_chain, verify_signature, cert %d.",
|
||||||
@ -322,15 +351,11 @@ bool check_cert_chain(cli_t* cli, const uint8_t* chain, size_t chain_size,
|
|||||||
message = tbs_cert.buf.data;
|
message = tbs_cert.buf.data;
|
||||||
message_size = tbs_cert.buf.size;
|
message_size = tbs_cert.buf.size;
|
||||||
|
|
||||||
// Read the signatureAlgorithm and ensure it matches ECDSA_WITH_SHA256.
|
// skip the signatureAlgorithm
|
||||||
DER_ITEM sig_alg = {0};
|
DER_ITEM sig_alg = {0};
|
||||||
if (!der_read_item(&cert.buf, &sig_alg) ||
|
if (!der_read_item(&cert.buf, &sig_alg)) {
|
||||||
sig_alg.buf.size != sizeof(ECDSA_WITH_SHA256) ||
|
|
||||||
memcmp(ECDSA_WITH_SHA256, sig_alg.buf.data,
|
|
||||||
sizeof(ECDSA_WITH_SHA256)) != 0) {
|
|
||||||
cli_error(cli, CLI_ERROR,
|
cli_error(cli, CLI_ERROR,
|
||||||
"check_device_cert_chain, checking signatureAlgorithm, cert "
|
"check_device_cert_chain, der_read_item 7, cert %d.", "%d.",
|
||||||
"%d.",
|
|
||||||
cert_count);
|
cert_count);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user