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>
diff --git a/rust/bssl-crypto/src/ed25519.rs b/rust/bssl-crypto/src/ed25519.rs
index 73c90fb..6be0508 100644
--- a/rust/bssl-crypto/src/ed25519.rs
+++ b/rust/bssl-crypto/src/ed25519.rs
@@ -161,32 +161,23 @@
// 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))
@@ -269,6 +260,14 @@
}
#[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
let pk = test_helpers::decode_hex(