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

Merge pull request #1282 from jsha/debug-everything

Add Debug trait for X509 and other types.
parents e5e8fb49 cbfdaa51
Loading
Loading
Loading
Loading
+44 −9
Original line number Diff line number Diff line
@@ -67,12 +67,18 @@ foreign_type_and_impl_send_sync! {
impl fmt::Display for Asn1GeneralizedTimeRef {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            let mem_bio = MemBio::new()?;
            cvt(ffi::ASN1_GENERALIZEDTIME_print(
            let mem_bio = match MemBio::new() {
                Err(_) => return f.write_str("error"),
                Ok(m) => m,
            };
            let print_result = cvt(ffi::ASN1_GENERALIZEDTIME_print(
                mem_bio.as_ptr(),
                self.as_ptr(),
            ))?;
            write!(f, "{}", str::from_utf8_unchecked(mem_bio.get_buf()))
            ));
            match print_result {
                Err(_) => f.write_str("error"),
                Ok(_) => f.write_str(str::from_utf8_unchecked(mem_bio.get_buf())),
            }
        }
    }
}
@@ -207,10 +213,22 @@ impl<'a> PartialOrd<Asn1Time> for &'a Asn1TimeRef {
impl fmt::Display for Asn1TimeRef {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        unsafe {
            let mem_bio = MemBio::new()?;
            cvt(ffi::ASN1_TIME_print(mem_bio.as_ptr(), self.as_ptr()))?;
            write!(f, "{}", str::from_utf8_unchecked(mem_bio.get_buf()))
            let mem_bio = match MemBio::new() {
                Err(_) => return f.write_str("error"),
                Ok(m) => m,
            };
            let print_result = cvt(ffi::ASN1_TIME_print(mem_bio.as_ptr(), self.as_ptr()));
            match print_result {
                Err(_) => f.write_str("error"),
                Ok(_) => f.write_str(str::from_utf8_unchecked(mem_bio.get_buf())),
            }
        }
    }
}

impl fmt::Debug for Asn1TimeRef {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.to_string())
    }
}

@@ -389,6 +407,15 @@ impl Asn1StringRef {
    }
}

impl fmt::Debug for Asn1StringRef {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match self.as_utf8() {
            Ok(openssl_string) => openssl_string.fmt(fmt),
            Err(_) => fmt.write_str("error"),
        }
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::ASN1_INTEGER;
    fn drop = ffi::ASN1_INTEGER_free;
@@ -527,12 +554,20 @@ impl fmt::Display for Asn1ObjectRef {
                self.as_ptr(),
                0,
            );
            let s = str::from_utf8(&buf[..len as usize]).map_err(|_| fmt::Error)?;
            fmt.write_str(s)
            match str::from_utf8(&buf[..len as usize]) {
                Err(_) => fmt.write_str("error"),
                Ok(s) => fmt.write_str(s),
            }
        }
    }
}

impl fmt::Debug for Asn1ObjectRef {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str(self.to_string().as_str())
    }
}

cfg_if! {
    if #[cfg(any(ossl110, libressl273))] {
        use ffi::ASN1_STRING_get0_data;
+20 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_int, c_long};
use std::ffi::CString;
use std::fmt;
use std::mem;
use std::ptr;

@@ -286,6 +287,25 @@ where
    }
}

impl<T> fmt::Debug for PKey<T> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let alg = match self.id() {
            Id::RSA => "RSA",
            Id::HMAC => "HMAC",
            Id::DSA => "DSA",
            Id::DH => "DH",
            Id::EC => "EC",
            #[cfg(ossl111)]
            Id::ED25519 => "Ed25519",
            #[cfg(ossl111)]
            Id::ED448 => "Ed448",
            _ => "unknown",
        };
        fmt.debug_struct("PKey").field("algorithm", &alg).finish()
        // TODO: Print details for each specific type of key
    }
}

impl<T> Clone for PKey<T> {
    fn clone(&self) -> PKey<T> {
        PKeyRef::to_owned(self)
+10 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
use libc::c_int;
use std::borrow::Borrow;
use std::convert::AsRef;
use std::fmt;
use std::iter;
use std::marker::PhantomData;
use std::mem;
@@ -43,6 +44,15 @@ pub struct Stack<T: Stackable>(*mut T::StackType);
unsafe impl<T: Stackable + Send> Send for Stack<T> {}
unsafe impl<T: Stackable + Sync> Sync for Stack<T> {}

impl<T> fmt::Debug for Stack<T>
where
    T: Stackable,
    T::Ref: fmt::Debug,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_list().entries(self).finish()
    }
}
impl<T: Stackable> Drop for Stack<T> {
    fn drop(&mut self) {
        unsafe {
+58 −0
Original line number Diff line number Diff line
@@ -671,6 +671,35 @@ impl Clone for X509 {
    }
}

impl fmt::Debug for X509 {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        let serial = match &self.serial_number().to_bn() {
            Ok(bn) => match bn.to_hex_str() {
                Ok(hex) => hex.to_string(),
                Err(_) => "".to_string(),
            },
            Err(_) => "".to_string(),
        };
        let mut debug_struct = formatter.debug_struct("X509");
        debug_struct.field("serial_number", &serial);
        debug_struct.field("signature_algorithm", &self.signature_algorithm().object());
        debug_struct.field("issuer", &self.issuer_name());
        debug_struct.field("subject", &self.subject_name());
        if let Some(subject_alt_names) = &self.subject_alt_names() {
            debug_struct.field("subject_alt_names", subject_alt_names);
        }
        debug_struct.field("not_before", &self.not_before());
        debug_struct.field("not_after", &self.not_after());

        if let Ok(public_key) = &self.public_key() {
            debug_struct.field("public_key", public_key);
        };
        // TODO: Print extensions once they are supported on the X509 struct.

        debug_struct.finish()
    }
}

impl AsRef<X509Ref> for X509Ref {
    fn as_ref(&self) -> &X509Ref {
        self
@@ -867,6 +896,12 @@ impl X509NameRef {
    }
}

impl fmt::Debug for X509NameRef {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.debug_list().entries(self.entries()).finish()
    }
}

/// A type to destructure and examine an `X509Name`.
pub struct X509NameEntries<'a> {
    name: &'a X509NameRef,
@@ -942,6 +977,12 @@ impl X509NameEntryRef {
    }
}

impl fmt::Debug for X509NameEntryRef {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_fmt(format_args!("{:?} = {:?}", self.object(), self.data()))
    }
}

/// A builder used to construct an `X509Req`.
pub struct X509ReqBuilder(X509Req);

@@ -1298,6 +1339,23 @@ impl GeneralNameRef {
    }
}

impl fmt::Debug for GeneralNameRef {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        if let Some(email) = self.email() {
            formatter.write_str(email)
        } else if let Some(dnsname) = self.dnsname() {
            formatter.write_str(dnsname)
        } else if let Some(uri) = self.uri() {
            formatter.write_str(uri)
        } else if let Some(ipaddress) = self.ipaddress() {
            let result = String::from_utf8_lossy(ipaddress);
            formatter.write_str(&result)
        } else {
            formatter.write_str("(empty)")
        }
    }
}

impl Stackable for GeneralName {
    type StackType = ffi::stack_st_GENERAL_NAME;
}
+13 −0
Original line number Diff line number Diff line
@@ -31,6 +31,19 @@ fn test_cert_loading() {
    assert_eq!(hash_vec, &*fingerprint);
}

#[test]
fn test_debug() {
    let cert = include_bytes!("../../test/cert.pem");
    let cert = X509::from_pem(cert).unwrap();
    let debugged = format!("{:#?}", cert);
    assert!(debugged.contains(r#"serial_number: "8771F7BDEE982FA5""#));
    assert!(debugged.contains(r#"signature_algorithm: sha256WithRSAEncryption"#));
    assert!(debugged.contains(r#"countryName = "AU""#));
    assert!(debugged.contains(r#"stateOrProvinceName = "Some-State""#));
    assert!(debugged.contains(r#"not_before: Aug 14 17:00:03 2016 GMT"#));
    assert!(debugged.contains(r#"not_after: Aug 12 17:00:03 2026 GMT"#));
}

#[test]
fn test_cert_issue_validity() {
    let cert = include_bytes!("../../test/cert.pem");