Add from/to SubjectPublicKeyInfo conversion to ed25519.

And run `cargo fmt`.

Change-Id: Iff0ad50ffc8fb02454b22b82050c605620a201f8
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/76647
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/rust/bssl-crypto/src/ed25519.rs b/rust/bssl-crypto/src/ed25519.rs
index 6644aa2..73c90fb 100644
--- a/rust/bssl-crypto/src/ed25519.rs
+++ b/rust/bssl-crypto/src/ed25519.rs
@@ -34,7 +34,10 @@
 //! assert!(public_key.verify(signed_message, &sig).is_ok());
 //! ```
 
-use crate::{FfiMutSlice, FfiSlice, InvalidSignatureError};
+use crate::{
+    cbb_to_buffer, parse_with_cbs, scoped, with_output_array, Buffer, FfiMutSlice, FfiSlice,
+    InvalidSignatureError,
+};
 
 /// The length in bytes of an Ed25519 public key.
 pub const PUBLIC_KEY_LEN: usize = bssl_sys::ED25519_PUBLIC_KEY_LEN as usize;
@@ -149,6 +152,66 @@
         &self.0
     }
 
+    /// Parse a public key in SubjectPublicKeyInfo format.
+    pub fn from_der_subject_public_key_info(spki: &[u8]) -> Option<Self> {
+        let mut pkey = scoped::EvpPkey::from_ptr(parse_with_cbs(
+            spki,
+            // Safety: `pkey` is a non-null result from `EVP_parse_public_key` here.
+            |pkey| unsafe { bssl_sys::EVP_PKEY_free(pkey) },
+            // 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 {
+            return None;
+        }
+
+        // When the out buffer is not null, the raw public key is written into it.
+        // Safety: the arguments are valid.
+        let raw_pkey: [u8; PUBLIC_KEY_LEN] = unsafe {
+            with_output_array(|out, _| {
+                assert_eq!(
+                    1,
+                    bssl_sys::EVP_PKEY_get_raw_public_key(pkey.as_ffi_ptr(), out, &mut out_len)
+                );
+            })
+        };
+        Some(PublicKey(raw_pkey))
+    }
+
+    /// Serialize this key in SubjectPublicKeyInfo format.
+    pub fn to_der_subject_public_key_info(&self) -> Buffer {
+        // Safety: this only copies from the `self.0` buffer.
+        let mut pkey = scoped::EvpPkey::from_ptr(unsafe {
+            bssl_sys::EVP_PKEY_new_raw_public_key(
+                bssl_sys::EVP_PKEY_ED25519,
+                /*unused=*/ core::ptr::null_mut(),
+                self.0.as_ffi_ptr(),
+                PUBLIC_KEY_LEN,
+            )
+        });
+        assert!(!pkey.as_ffi_ptr().is_null());
+
+        cbb_to_buffer(PUBLIC_KEY_LEN + 32, |cbb| unsafe {
+            // The arguments are valid so this will only fail if out of memory,
+            // which this crate doesn't handle.
+            assert_eq!(1, bssl_sys::EVP_marshal_public_key(cbb, pkey.as_ffi_ptr()));
+        })
+    }
+
     /// Verifies that `signature` is a valid signature, by this key, of `msg`.
     pub fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), InvalidSignatureError> {
         let ret = unsafe {
@@ -183,6 +246,29 @@
     }
 
     #[test]
+    fn der_subject_public_key_info() {
+        let priv_key = PrivateKey::generate();
+        let msg = [0u8; 0];
+        let sig = priv_key.sign(&msg);
+
+        let pub_key = priv_key.to_public();
+        assert!(pub_key.verify(&msg, &sig).is_ok());
+
+        let pub_key_der = pub_key.to_der_subject_public_key_info();
+        let pub_key_from_der =
+            PublicKey::from_der_subject_public_key_info(pub_key_der.as_ref()).unwrap();
+        assert_eq!(pub_key.as_bytes(), pub_key_from_der.as_bytes());
+        assert!(pub_key_from_der.verify(&msg, &sig).is_ok());
+
+        assert!(PublicKey::from_der_subject_public_key_info(
+            &pub_key_from_der.as_bytes()[0..PUBLIC_KEY_LEN / 2]
+        )
+        .is_none());
+
+        assert!(PublicKey::from_der_subject_public_key_info(b"").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(
diff --git a/rust/bssl-crypto/src/hkdf.rs b/rust/bssl-crypto/src/hkdf.rs
index 24343ae..968e644 100644
--- a/rust/bssl-crypto/src/hkdf.rs
+++ b/rust/bssl-crypto/src/hkdf.rs
@@ -184,9 +184,7 @@
     evp_md: *const bssl_sys::EVP_MD,
 }
 
-#[allow(clippy::let_unit_value,
-        clippy::unwrap_used,
-)]
+#[allow(clippy::let_unit_value, clippy::unwrap_used)]
 impl Prk {
     /// Creates a Prk from bytes.
     pub fn new<MD: digest::Algorithm>(prk_bytes: &[u8]) -> Option<Self> {
@@ -210,10 +208,11 @@
 
     /// Returns the bytes of the pseudorandom key.
     pub fn as_bytes(&self) -> &[u8] {
-        self.prk.get(..self.len)
-        // unwrap:`self.len` must be less than the length of `self.prk` thus
-        // this is always in bounds.
-        .unwrap()
+        self.prk
+            .get(..self.len)
+            // unwrap:`self.len` must be less than the length of `self.prk` thus
+            // this is always in bounds.
+            .unwrap()
     }
 
     /// Derive key material for the given info parameter. Attempting
diff --git a/rust/bssl-crypto/src/hpke.rs b/rust/bssl-crypto/src/hpke.rs
index 2259140..12010ac 100644
--- a/rust/bssl-crypto/src/hpke.rs
+++ b/rust/bssl-crypto/src/hpke.rs
@@ -95,7 +95,6 @@
         }
     }
 
-
     fn from_rfc_id(n: u16) -> Option<Kem> {
         match n {
             n if n == Kem::P256HkdfSha256 as u16 => Some(Self::P256HkdfSha256),