Unverified Commit 0138f525 authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #1858 from sfackler/asn1-integer-cmp

Add ASN.1 Integer comparison and to_owned
parents 74785856 516f1b52
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -43,8 +43,10 @@ extern "C" {
    pub fn ASN1_TIME_set(from: *mut ASN1_TIME, to: time_t) -> *mut ASN1_TIME;

    pub fn ASN1_INTEGER_free(x: *mut ASN1_INTEGER);
    pub fn ASN1_INTEGER_dup(a: *const ASN1_INTEGER) -> *mut ASN1_INTEGER;
    pub fn ASN1_INTEGER_get(dest: *const ASN1_INTEGER) -> c_long;
    pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int;
    pub fn ASN1_INTEGER_cmp(a: *const ASN1_INTEGER, b: *const ASN1_INTEGER) -> c_int;
    pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER;
    pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM;

+63 −1
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@
use cfg_if::cfg_if;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_char, c_int, c_long, time_t};
#[cfg(ossl102)]
use std::cmp::Ordering;
use std::ffi::CString;
use std::fmt;
@@ -512,6 +511,23 @@ impl Asn1Integer {
    }
}

impl Ord for Asn1Integer {
    fn cmp(&self, other: &Self) -> Ordering {
        Asn1IntegerRef::cmp(self, other)
    }
}
impl PartialOrd for Asn1Integer {
    fn partial_cmp(&self, other: &Asn1Integer) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl Eq for Asn1Integer {}
impl PartialEq for Asn1Integer {
    fn eq(&self, other: &Asn1Integer) -> bool {
        Asn1IntegerRef::eq(self, other)
    }
}

impl Asn1IntegerRef {
    #[allow(missing_docs, clippy::unnecessary_cast)]
    #[deprecated(since = "0.10.6", note = "use to_bn instead")]
@@ -536,6 +552,30 @@ impl Asn1IntegerRef {
    pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> {
        unsafe { cvt(ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) }
    }

    /// Creates a new Asn1Integer with the same value.
    #[corresponds(ASN1_INTEGER_dup)]
    pub fn to_owned(&self) -> Result<Asn1Integer, ErrorStack> {
        unsafe { cvt_p(ffi::ASN1_INTEGER_dup(self.as_ptr())).map(|p| Asn1Integer::from_ptr(p)) }
    }
}

impl Ord for Asn1IntegerRef {
    fn cmp(&self, other: &Self) -> Ordering {
        let res = unsafe { ffi::ASN1_INTEGER_cmp(self.as_ptr(), other.as_ptr()) };
        res.cmp(&0)
    }
}
impl PartialOrd for Asn1IntegerRef {
    fn partial_cmp(&self, other: &Asn1IntegerRef) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl Eq for Asn1IntegerRef {}
impl PartialEq for Asn1IntegerRef {
    fn eq(&self, other: &Asn1IntegerRef) -> bool {
        self.cmp(other) == Ordering::Equal
    }
}

foreign_type_and_impl_send_sync! {
@@ -749,6 +789,28 @@ mod tests {
        assert!(c_ref < a_ref);
    }

    #[test]
    fn integer_to_owned() {
        let a = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap();
        let b = a.to_owned().unwrap();
        assert_eq!(
            a.to_bn().unwrap().to_dec_str().unwrap().to_string(),
            b.to_bn().unwrap().to_dec_str().unwrap().to_string(),
        );
        assert_ne!(a.as_ptr(), b.as_ptr());
    }

    #[test]
    fn integer_cmp() {
        let a = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap();
        let b = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap();
        let c = Asn1Integer::from_bn(&BigNum::from_dec_str("43").unwrap()).unwrap();
        assert!(a == b);
        assert!(a != c);
        assert!(a < c);
        assert!(c > b);
    }

    #[test]
    fn object_from_str() {
        let object = Asn1Object::from_str("2.16.840.1.101.3.4.2.1").unwrap();