rust: bssl-tls: Expose bytes behind CRYPTO_BUFFER wrappers

This allows the Certificate type to share the content with a custom
certificate verifier in the future.

Signed-off-by: Xiangfei Ding <xfding@google.com>
Change-Id: I158c09df8db19f350b5df2adef1e55546a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/92468
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Rudolf Polzer <rpolzer@google.com>
diff --git a/rust/bssl-tls/src/macros.rs b/rust/bssl-tls/src/macros.rs
index 61dd30e..c1258ec 100644
--- a/rust/bssl-tls/src/macros.rs
+++ b/rust/bssl-tls/src/macros.rs
@@ -77,6 +77,35 @@
             }
         }
 
+        impl ::core::ops::Deref for $name {
+            type Target = [u8];
+            fn deref(&self) -> &Self::Target {
+                let (data, len) = unsafe {
+                    // Safety: `self` witnesses the validity of the underlying handle.
+                    (
+                        ::bssl_sys::CRYPTO_BUFFER_data(self.ptr()),
+                        ::bssl_sys::CRYPTO_BUFFER_len(self.ptr()),
+                    )
+                };
+                if data.is_null() || len == 0 || len > isize::MAX as usize {
+                    &[]
+                } else {
+                    unsafe {
+                        // Safety:
+                        // - `data` is 1-size and 1-align and `len` is valid by BoringSSL invariant.
+                        // - `len` is sanitised to be within bound.
+                        ::core::slice::from_raw_parts(data, len)
+                    }
+                }
+            }
+        }
+
+        impl ::core::convert::AsRef<[u8]> for $name {
+            fn as_ref(&self) -> &[u8] {
+                &self
+            }
+        }
+
         impl $name {
             /// **NOTE: we do not sanitise or validate the input bytes.**
             #[inline(always)]