rust: bssl-tls: report RPK in custom certificate verifier In RPK mode, certificate verifier callback is also invoked. Indeed the certificate chain is empty and this renders the callback rather useless. We should expose the peer RPK through the verifier context so that the callback is also meaningful for RPK mode. Signed-off-by: Xiangfei Ding <xfding@google.com> Change-Id: I06e32ecbc6e6cd44c713b9adc42b2ca06a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/97248 Reviewed-by: Rudolf Polzer <rpolzer@google.com>
diff --git a/rust/bssl-tls/src/connection/credentials.rs b/rust/bssl-tls/src/connection/credentials.rs index 1071e35..6be1ef6 100644 --- a/rust/bssl-tls/src/connection/credentials.rs +++ b/rust/bssl-tls/src/connection/credentials.rs
@@ -18,7 +18,10 @@ }; use core::{ ffi::CStr, - ptr::null, // + ptr::{ + NonNull, + null, // + }, // }; use bssl_x509::{ @@ -395,29 +398,14 @@ ty.try_into().ok().and_then(|ty: u8| ty.try_into().ok()) } - /// Get the peer's raw public key as DER-encoded SubjectPublicKeyInfo. + /// Get the peer's raw public key as DER-encoded `SubjectPublicKeyInfo`. pub fn get_peer_raw_public_key(&self) -> Option<Vec<u8>> { let pkey = unsafe { // Safety: // - `self.ptr()` is a valid `SSL` handle. // - `pkey` does not escape the current function frame. - bssl_sys::SSL_get0_peer_rpk(self.ptr()) + NonNull::new(bssl_sys::SSL_get0_peer_rpk(self.ptr()))? }; - if pkey.is_null() { - return None; - } - - let buffer = bssl_crypto::cbb_to_buffer(64, |cbb| { - assert_eq!( - unsafe { - // Safety: - // - `cbb` is a valid pointer to `CBB` provided by `cbb_to_buffer`. - // - `pkey` is a valid pointer to `EVP_PKEY`. - bssl_sys::EVP_marshal_public_key(cbb, pkey) - }, - 1 - ); - }); - Some(buffer.as_ref().to_vec()) + Some(crate::credentials::marshal_evp_into_spki(pkey)) } }
diff --git a/rust/bssl-tls/src/credentials.rs b/rust/bssl-tls/src/credentials.rs index 76aa523..5298574 100644 --- a/rust/bssl-tls/src/credentials.rs +++ b/rust/bssl-tls/src/credentials.rs
@@ -613,6 +613,17 @@ let list = call_slice_getter!(bssl_sys::SSL_get0_signed_cert_timestamp_list, self.ptr())?; (!list.is_empty()).then_some(list) } + + /// Get the Raw Public Key offered by the peer in the `ClientHello`. + pub fn get_peer_raw_public_key(&self) -> Option<Vec<u8>> { + let pkey = unsafe { + // Safety: + // - `self.ptr()` is a valid `SSL` handle. + // - `pkey` does not escape the current function frame. + NonNull::new(bssl_sys::SSL_get0_peer_rpk(self.ptr()))? + }; + Some(marshal_evp_into_spki(pkey)) + } } /// Custom certificate verification callback. @@ -921,5 +932,20 @@ } } +pub(crate) fn marshal_evp_into_spki(pkey: NonNull<bssl_sys::EVP_PKEY>) -> Vec<u8> { + let buffer = bssl_crypto::cbb_to_buffer(64, |cbb| { + assert_eq!( + unsafe { + // Safety: + // - `cbb` is a valid pointer to `CBB` provided by `cbb_to_buffer`. + // - `pkey` is a valid pointer to `EVP_PKEY`. + bssl_sys::EVP_marshal_public_key(cbb, pkey.as_ptr()) + }, + 1 + ); + }); + buffer.as_ref().to_vec() +} + #[cfg(test)] mod tests;
diff --git a/rust/bssl-tls/src/sessions.rs b/rust/bssl-tls/src/sessions.rs index 3026f86..316acb2 100644 --- a/rust/bssl-tls/src/sessions.rs +++ b/rust/bssl-tls/src/sessions.rs
@@ -197,8 +197,6 @@ Ok(res) } - // TODO(@xfding): Implement SSL_SESSION_get0_peer_rpk when needed. - /// Get the signed certificate timestamp list, if any. pub fn get0_signed_cert_timestamp_list(&self) -> Option<&[u8]> { call_slice_getter!( @@ -308,6 +306,17 @@ } } + /// Get the Raw Public Key offered by the peer in the `ClientHello`. + pub fn get_peer_raw_public_key(&self) -> Option<Vec<u8>> { + let pkey = unsafe { + // Safety: + // - `self.ptr()` is a valid `SSL` handle. + // - `pkey` does not escape the current function frame. + NonNull::new(bssl_sys::SSL_SESSION_get0_peer_rpk(self.ptr()))? + }; + Some(crate::credentials::marshal_evp_into_spki(pkey)) + } + /// Check if the session is early data capable. pub fn early_data_capable(&self) -> bool { unsafe {