rust: bssl-x509: proper serialisation of X.509 certificate serial number

Our internal ASN1_STRING represents serial numbers as sign plus
magnitude instead of twos-complement.

Signed-off-by: Xiangfei Ding <xfding@google.com>
Change-Id: I8c909c455b94dc20958a52482dd87e1d6a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/93587
Reviewed-by: Adam Langley <agl@google.com>
Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Rudolf Polzer <rpolzer@google.com>
diff --git a/rust/bssl-x509/src/certificates.rs b/rust/bssl-x509/src/certificates.rs
index 8e5f81d..ece3a6d 100644
--- a/rust/bssl-x509/src/certificates.rs
+++ b/rust/bssl-x509/src/certificates.rs
@@ -277,32 +277,33 @@
     /// This is a big-endian integer. If the most-significant bit is set then
     /// it is negative. Positive values that would otherwise have the
     /// most-significant bit set are left padded with a zero byte to avoid this.
-    pub fn as_twos_complement_bytes(&self) -> &'a [u8] {
+    pub fn as_twos_complement_bytes(&self) -> Vec<u8> {
         let serial = self.ptr();
         let len = unsafe {
             // Safety:
             // - self witnesses the validity of the X509 handle and, therefore,
             //   this handle to the integer;
             // - ASN1_INTEGER is a subtype of ASN1_STRING.
-            bssl_sys::ASN1_STRING_length(serial)
+            bssl_sys::i2c_ASN1_INTEGER(serial, null_mut())
         };
         let Ok(len) = usize::try_from(len) else {
-            panic!("invalid ASN1_INTEGER")
+            panic!("invalid serial number")
         };
-        let ptr = unsafe {
+        if len == 0 {
+            panic!("invalid serial number")
+        }
+        let mut res = vec![0; len];
+        let len = unsafe {
             // Safety:
             // - self witnesses the validity of the X509 handle and, therefore,
-            //   this handle to the integer;
-            // - ASN1_INTEGER is a subtype of ASN1_STRING.
-            bssl_sys::ASN1_STRING_get0_data(serial)
+            //   this handle to the integer.
+            // - `outp` is non-null.
+            let mut outp = res.as_mut_ptr();
+            bssl_sys::i2c_ASN1_INTEGER(serial, &raw mut outp)
         };
-        unsafe {
-            // Safety:
-            // - `ptr` is non-null;
-            // - `len` is positive and less then isize::MAX;
-            // - the lifetime of `self` outlives that of `ptr`.
-            sanitize_slice(ptr, len).expect("invalid ASN1_INTEGER")
-        }
+        assert!(len > 0);
+        res.truncate(usize::try_from(len).unwrap());
+        res
     }
 }