Merge pull request #1282 from jsha/debug-everything
Add Debug trait for X509 and other types.
This commit is contained in:
commit
f042c21f93
|
|
@ -67,12 +67,18 @@ foreign_type_and_impl_send_sync! {
|
||||||
impl fmt::Display for Asn1GeneralizedTimeRef {
|
impl fmt::Display for Asn1GeneralizedTimeRef {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mem_bio = MemBio::new()?;
|
let mem_bio = match MemBio::new() {
|
||||||
cvt(ffi::ASN1_GENERALIZEDTIME_print(
|
Err(_) => return f.write_str("error"),
|
||||||
|
Ok(m) => m,
|
||||||
|
};
|
||||||
|
let print_result = cvt(ffi::ASN1_GENERALIZEDTIME_print(
|
||||||
mem_bio.as_ptr(),
|
mem_bio.as_ptr(),
|
||||||
self.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,12 +213,24 @@ impl<'a> PartialOrd<Asn1Time> for &'a Asn1TimeRef {
|
||||||
impl fmt::Display for Asn1TimeRef {
|
impl fmt::Display for Asn1TimeRef {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mem_bio = MemBio::new()?;
|
let mem_bio = match MemBio::new() {
|
||||||
cvt(ffi::ASN1_TIME_print(mem_bio.as_ptr(), self.as_ptr()))?;
|
Err(_) => return f.write_str("error"),
|
||||||
write!(f, "{}", str::from_utf8_unchecked(mem_bio.get_buf()))
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Asn1Time {
|
impl Asn1Time {
|
||||||
fn new() -> Result<Asn1Time, ErrorStack> {
|
fn new() -> Result<Asn1Time, ErrorStack> {
|
||||||
|
|
@ -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! {
|
foreign_type_and_impl_send_sync! {
|
||||||
type CType = ffi::ASN1_INTEGER;
|
type CType = ffi::ASN1_INTEGER;
|
||||||
fn drop = ffi::ASN1_INTEGER_free;
|
fn drop = ffi::ASN1_INTEGER_free;
|
||||||
|
|
@ -527,11 +554,19 @@ impl fmt::Display for Asn1ObjectRef {
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
let s = str::from_utf8(&buf[..len as usize]).map_err(|_| fmt::Error)?;
|
match str::from_utf8(&buf[..len as usize]) {
|
||||||
fmt.write_str(s)
|
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! {
|
cfg_if! {
|
||||||
if #[cfg(any(ossl110, libressl273))] {
|
if #[cfg(any(ossl110, libressl273))] {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ use ffi;
|
||||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||||
use libc::{c_int, c_long};
|
use libc::{c_int, c_long};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
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> {
|
impl<T> Clone for PKey<T> {
|
||||||
fn clone(&self) -> PKey<T> {
|
fn clone(&self) -> PKey<T> {
|
||||||
PKeyRef::to_owned(self)
|
PKeyRef::to_owned(self)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use foreign_types::{ForeignType, ForeignTypeRef, Opaque};
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::convert::AsRef;
|
use std::convert::AsRef;
|
||||||
|
use std::fmt;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
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 + Send> Send for Stack<T> {}
|
||||||
unsafe impl<T: Stackable + Sync> Sync 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> {
|
impl<T: Stackable> Drop for Stack<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
impl AsRef<X509Ref> for X509Ref {
|
||||||
fn as_ref(&self) -> &X509Ref {
|
fn as_ref(&self) -> &X509Ref {
|
||||||
self
|
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`.
|
/// A type to destructure and examine an `X509Name`.
|
||||||
pub struct X509NameEntries<'a> {
|
pub struct X509NameEntries<'a> {
|
||||||
name: &'a X509NameRef,
|
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`.
|
/// A builder used to construct an `X509Req`.
|
||||||
pub struct X509ReqBuilder(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 {
|
impl Stackable for GeneralName {
|
||||||
type StackType = ffi::stack_st_GENERAL_NAME;
|
type StackType = ffi::stack_st_GENERAL_NAME;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,19 @@ fn test_cert_loading() {
|
||||||
assert_eq!(hash_vec, &*fingerprint);
|
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]
|
#[test]
|
||||||
fn test_cert_issue_validity() {
|
fn test_cert_issue_validity() {
|
||||||
let cert = include_bytes!("../../test/cert.pem");
|
let cert = include_bytes!("../../test/cert.pem");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue