bssl-crypto: Fix Ed25519 SPKI parser to check key types

Otherwise it mistakenly interprets an X25519 SPKI as an Ed25519 key.
Once that is fixed, a number of these error conditions are impossible.

Change-Id: Iffd116252f1f632f8f917c56b1676069686eddbf
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/81587
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
This commit is contained in:
David Benjamin
2025-08-22 16:07:22 -07:00
committed by Boringssl LUCI CQ
parent edb1440439
commit 26e8a8acb9
+17 -18
View File
@@ -161,32 +161,23 @@ impl PublicKey {
// Safety: cbs is valid per `parse_with_cbs`.
|cbs| unsafe { bssl_sys::EVP_parse_public_key(cbs) },
)?);
let mut out_len = 0;
// When the out buffer is null, `out_len` is set to the size of the raw public key.
// Safety: the arguments are valid.
let result = unsafe {
bssl_sys::EVP_PKEY_get_raw_public_key(
pkey.as_ffi_ptr(),
core::ptr::null_mut(),
&mut out_len,
)
};
if result != 1 {
return None;
}
if out_len != PUBLIC_KEY_LEN {
// Safety: `pkey` is a valid `EVP_PKEY`.
if unsafe { bssl_sys::EVP_PKEY_id(pkey.as_ffi_ptr()) } != bssl_sys::EVP_PKEY_ED25519 {
return None;
}
// When the out buffer is not null, the raw public key is written into it.
// Safety: the arguments are valid.
// Safety: `EVP_PKEY_get_raw_public_key` is passed a valid buffer. The
// (always true) assertion ensures the closure always initializes the
// array.
let raw_pkey: [u8; PUBLIC_KEY_LEN] = unsafe {
with_output_array(|out, _| {
with_output_array(|out, mut out_len| {
// If `pkey` is an Ed25519 key, checked above, the raw public
// key must be available, and must be `PUBLIC_KEY_LEN` bytes.
assert_eq!(
1,
bssl_sys::EVP_PKEY_get_raw_public_key(pkey.as_ffi_ptr(), out, &mut out_len)
);
assert_eq!(out_len, PUBLIC_KEY_LEN);
})
};
Some(PublicKey(raw_pkey))
@@ -268,6 +259,14 @@ mod test {
assert!(PublicKey::from_der_subject_public_key_info(b"").is_none());
}
#[test]
fn der_subject_public_key_info_wrong_type() {
// This is an X25519 key, not an Ed25519 key.
let spki = test_helpers::decode_hex_into_vec("302a300506032b656e032100e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c");
// `from_der_subject_public_key_info` should reject it.
assert!(PublicKey::from_der_subject_public_key_info(&spki).is_none());
}
#[test]
fn empty_msg() {
// Test Case 1 from RFC test vectors: https://www.rfc-editor.org/rfc/rfc8032#section-7.1