Commit 966cb2ed authored by Rob Shearman's avatar Rob Shearman
Browse files

Add BigNumRef::to_vec_padded

Wire protocols sometimes define a fixed size for fields that may be
derived from a BigNum, so it is useful to be able to obtain a Vec<u8>
that has been padded accordingly.

So add a BN_bn2binpad -sys function and a to_vec_padded wrapper around
this for BigNumRef.
parent bf20ebeb
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ extern "C" {
    pub fn BN_clear_free(bn: *mut BIGNUM);
    pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM;
    pub fn BN_bn2bin(a: *const BIGNUM, to: *mut u8) -> c_int;
    #[cfg(ossl110)]
    pub fn BN_bn2binpad(a: *const BIGNUM, to: *mut u8, tolen: c_int) -> c_int;
    pub fn BN_sub(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
    pub fn BN_add(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
    pub fn BN_mul(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
+31 −0
Original line number Diff line number Diff line
@@ -885,6 +885,37 @@ impl BigNumRef {
        v
    }

    /// Returns a big-endian byte vector representation of the absolute value of `self` padded
    /// to `pad_to` bytes.
    ///
    /// If `pad_to` is less than `self.num_bytes()` then an error is returned.
    ///
    /// `self` can be recreated by using `from_slice`.
    ///
    /// ```
    /// # use openssl::bn::BigNum;
    /// let bn = BigNum::from_u32(0x4543).unwrap();
    ///
    /// let bn_vec = bn.to_vec_padded(4).unwrap();
    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
    ///
    /// let r = bn.to_vec_padded(1);
    /// assert!(r.is_err());
    ///
    /// let bn = -BigNum::from_u32(0x4543).unwrap();
    /// let bn_vec = bn.to_vec_padded(4).unwrap();
    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
    /// ```
    #[cfg(ossl110)]
    pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
        let mut v = Vec::with_capacity(pad_to as usize);
        unsafe {
            cvt(ffi::BN_bn2binpad(self.as_ptr(), v.as_mut_ptr(), pad_to))?;
            v.set_len(pad_to as usize);
        }
        Ok(v)
    }

    /// Returns a decimal string representation of `self`.
    ///
    /// ```