rust: Give options to serialise curve names Bug: 487901642 Signed-off-by: Xiangfei Ding <xfding@google.com> Change-Id: I4042ae48973a83c8d0493e83b1745afc6a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/90187 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/rust/bssl-crypto/src/ec.rs b/rust/bssl-crypto/src/ec.rs index 52b59f1..5c982c0 100644 --- a/rust/bssl-crypto/src/ec.rs +++ b/rust/bssl-crypto/src/ec.rs
@@ -387,7 +387,9 @@ } } - /// Parses an ECPrivateKey structure (from RFC 5915). + /// Parses an ECPrivateKey structure from [RFC 5915]. + /// + /// [RFC 5915]: <https://datatracker.ietf.org/doc/html/rfc5915> pub fn from_der_ec_private_key(group: Group, der: &[u8]) -> Option<Self> { let key = parse_with_cbs( der, @@ -401,19 +403,39 @@ Some(Self(key)) } - /// Serializes this private key as an ECPrivateKey structure from RFC 5915. + /// Parses an ECPrivateKey structure from [RFC 5915], whose curve is specified by + /// the `ECParameters`. + /// + /// Unless the curve group is one of the variants of [`Group`], this method returns [`None`]. + /// + /// [RFC 5915]: <https://datatracker.ietf.org/doc/html/rfc5915> + pub fn from_der_ec_private_key_with_curve_names(der: &[u8]) -> Option<Self> { + let key = parse_with_cbs( + der, + // Safety: in this context, `key` is the non-null result of + // `EC_KEY_parse_private_key`. + |key| unsafe { bssl_sys::EC_KEY_free(key) }, + // Safety: `cbs` is valid per `parse_with_cbs`. + |cbs| unsafe { bssl_sys::EC_KEY_parse_private_key(cbs, null()) }, + )?; + let key = Self(key); + if key.get_group().is_none() { + None + } else { + Some(key) + } + } + + /// Serializes this private key as an ECPrivateKey structure from [RFC 5915]. + /// + /// This method also **serialise** known curve names as `ECParameters`. + /// + /// [RFC 5915]: <https://datatracker.ietf.org/doc/html/rfc5915> pub fn to_der_ec_private_key(&self) -> Buffer { cbb_to_buffer(64, |cbb| unsafe { // Safety: the `EC_KEY` is always valid so `EC_KEY_marshal_private_key` // should only fail if out of memory, which this crate doesn't handle. - assert_eq!( - 1, - bssl_sys::EC_KEY_marshal_private_key( - cbb, - self.0, - bssl_sys::EC_PKEY_NO_PARAMETERS as u32 - ) - ); + assert_eq!(1, bssl_sys::EC_KEY_marshal_private_key(cbb, self.0, 0)); }) } @@ -720,12 +742,13 @@ ); } - fn test_key_format<Serialize, Parse>(serialize_func: Serialize, parse_func: Parse) + fn test_key_format<Serialize, Parse>(group: Group, serialize_func: Serialize, parse_func: Parse) where Serialize: FnOnce(&Key) -> Buffer, Parse: Fn(&[u8]) -> Option<Key>, { - let key = Key::generate(Group::P256); + let key = Key::generate(group); + assert_eq!(key.get_group().unwrap(), group); let vec = serialize_func(&key).as_ref().to_vec(); let key2 = parse_func(vec.as_slice()).unwrap(); @@ -733,6 +756,7 @@ key.to_x962_uncompressed().as_ref(), key2.to_x962_uncompressed().as_ref() ); + assert_eq!(key.get_group(), key2.get_group()); assert!(parse_func(&vec.as_slice()[0..16]).is_none()); assert!(parse_func(b"").is_none()); @@ -740,25 +764,39 @@ #[test] fn der_ec_private_key() { - test_key_format( - |key| key.to_der_ec_private_key(), - |buf| Key::from_der_ec_private_key(Group::P256, buf), - ); + for group in [Group::P256, Group::P384] { + test_key_format( + group, + |key| key.to_der_ec_private_key(), + |buf| Key::from_der_ec_private_key(group, buf), + ); + test_key_format( + group, + |key| key.to_der_ec_private_key(), + |buf| Key::from_der_ec_private_key_with_curve_names(buf), + ); + } } #[test] fn der_private_key_info() { - test_key_format( - |key| key.to_der_private_key_info(), - |buf| Key::from_der_private_key_info(Group::P256, buf), - ); + for group in [Group::P256, Group::P384] { + test_key_format( + group, + |key| key.to_der_private_key_info(), + |buf| Key::from_der_private_key_info(group, buf), + ); + } } #[test] fn big_endian() { - test_key_format( - |key| key.to_big_endian(), - |buf| Key::from_big_endian(Group::P256, buf), - ); + for group in [Group::P256, Group::P384] { + test_key_format( + group, + |key| key.to_big_endian(), + |buf| Key::from_big_endian(group, buf), + ); + } } }