Skip to content

Commit

Permalink
Convert all structs to Cow (rusticata#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
chifflier authored and baloo committed Mar 7, 2022
1 parent e2d49a8 commit 208e1a7
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 48 deletions.
2 changes: 1 addition & 1 deletion examples/print-cert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn print_x509_extension(oid: &Oid, ext: &X509Extension) {
println!(
" [crit:{} l:{}] {}: ",
ext.critical,
ext.value.len(),
ext.value().len(),
format_oid(oid)
);
match ext.parsed_extension() {
Expand Down
4 changes: 2 additions & 2 deletions examples/print-crl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn print_authority_key_identifier(aki: &AuthorityKeyIdentifier, level: usize) {
if aki.authority_cert_issuer.is_some() {
unimplemented!();
}
if let Some(serial) = aki.authority_cert_serial {
if let Some(serial) = &aki.authority_cert_serial {
let s = format_serial(serial);
println!("{:indent$}serial: {}", "", &s, indent = level);
}
Expand Down Expand Up @@ -65,7 +65,7 @@ fn print_x509_extension(oid: &Oid, ext: &X509Extension, level: usize) {
x => {
print!("{:indent$}{}:", "", format_oid(oid), indent = level);
print!(" Critical={}", ext.critical);
print!(" len={}", ext.value.len());
print!(" len={}", ext.value().len());
println!();
println!(" {:indent$}{:?}", "", x, indent = level);
}
Expand Down
21 changes: 11 additions & 10 deletions src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use der_parser::*;
use nom::{Offset, Parser};
use oid_registry::Oid;
use oid_registry::*;
use std::borrow::Cow;
use std::collections::HashMap;
use time::Duration;

Expand Down Expand Up @@ -321,8 +322,8 @@ pub struct TbsCertificate<'a> {
pub issuer_uid: Option<UniqueIdentifier<'a>>,
pub subject_uid: Option<UniqueIdentifier<'a>>,
extensions: Vec<X509Extension<'a>>,
pub(crate) raw: &'a [u8],
pub(crate) raw_serial: &'a [u8],
pub(crate) raw: Cow<'a, [u8]>,
pub(crate) raw_serial: Cow<'a, [u8]>,
}

impl<'a> TbsCertificate<'a> {
Expand Down Expand Up @@ -543,13 +544,13 @@ impl<'a> TbsCertificate<'a> {
}

/// Get the raw bytes of the certificate serial number
pub fn raw_serial(&self) -> &'a [u8] {
self.raw_serial
pub fn raw_serial(&'a self) -> &'a [u8] {
&self.raw_serial
}

/// Get a formatted string of the certificate serial number, separated by ':'
pub fn raw_serial_as_string(&self) -> String {
format_serial(self.raw_serial)
format_serial(&self.raw_serial)
}
}

Expand All @@ -575,7 +576,7 @@ fn get_extension_unique<'a, 'b>(
impl<'a> AsRef<[u8]> for TbsCertificate<'a> {
#[inline]
fn as_ref(&self) -> &[u8] {
self.raw
&self.raw
}
}

Expand Down Expand Up @@ -624,8 +625,8 @@ impl<'a> FromDer<'a> for TbsCertificate<'a> {
subject_uid,
extensions,

raw: &start_i[..len],
raw_serial: serial.0,
raw: Cow::Borrowed(&start_i[..len]),
raw_serial: Cow::Borrowed(serial.0),
};
Ok((i, tbs))
})(i)
Expand Down Expand Up @@ -685,8 +686,8 @@ impl<'a> Parser<&'a [u8], TbsCertificate<'a>, X509Error> for TbsCertificateParse
subject_uid,
extensions,

raw: &start_i[..len],
raw_serial: serial.0,
raw: Cow::Borrowed(&start_i[..len]),
raw_serial: Cow::Borrowed(serial.0),
};
Ok((i, tbs))
})(input)
Expand Down
9 changes: 5 additions & 4 deletions src/certification_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use der_parser::*;
use nom::Offset;
#[cfg(feature = "verify")]
use oid_registry::*;
use std::borrow::Cow;
use std::collections::HashMap;

/// Certification Signing Request (CSR)
Expand Down Expand Up @@ -67,8 +68,8 @@ impl<'a> X509CertificationRequest<'a> {
// get public key
let key = signature::UnparsedPublicKey::new(verification_alg, spki.subject_public_key.data);
// verify signature
let sig = self.signature_value.data;
key.verify(self.certification_request_info.raw, sig)
let sig = &self.signature_value.data;
key.verify(&self.certification_request_info.raw, &sig)
.or(Err(X509Error::SignatureVerificationError))
}
}
Expand Down Expand Up @@ -119,7 +120,7 @@ pub struct X509CertificationRequestInfo<'a> {
pub subject: X509Name<'a>,
pub subject_pki: SubjectPublicKeyInfo<'a>,
attributes: Vec<X509CriAttribute<'a>>,
pub raw: &'a [u8],
pub raw: Cow<'a, [u8]>,
}

impl<'a> X509CertificationRequestInfo<'a> {
Expand Down Expand Up @@ -180,7 +181,7 @@ impl<'a> FromDer<'a> for X509CertificationRequestInfo<'a> {
subject,
subject_pki,
attributes,
raw: &start_i[..len],
raw: Cow::Borrowed(&start_i[..len]),
};
Ok((i, tbs))
})(i)
Expand Down
5 changes: 3 additions & 2 deletions src/cri_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ use der_parser::oid::Oid;
use nom::combinator::map_res;
use nom::Err;
use oid_registry::*;
use std::borrow::Cow;
use std::collections::HashMap;

/// Attributes for Certification Request
#[derive(Clone, Debug, PartialEq)]
pub struct X509CriAttribute<'a> {
pub oid: Oid<'a>,
pub value: &'a [u8],
pub(crate) value: Cow<'a, [u8]>,
pub(crate) parsed_attribute: ParsedCriAttribute<'a>,
}

Expand All @@ -33,7 +34,7 @@ impl<'a> FromDer<'a> for X509CriAttribute<'a> {
let (i, parsed_attribute) = crate::cri_attributes::parser::parse_attribute(i, &oid)?;
let ext = X509CriAttribute {
oid,
value: &value_start[..value_start.len() - i.len()],
value: Cow::Borrowed(&value_start[..value_start.len() - i.len()]),
parsed_attribute,
};
Ok((i, ext))
Expand Down
15 changes: 8 additions & 7 deletions src/revocation_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use nom::combinator::{all_consuming, complete, map, opt};
use nom::multi::many1;
use nom::Offset;
use oid_registry::*;
use std::borrow::Cow;
use std::collections::HashMap;

/// An X.509 v2 Certificate Revocation List (CRL).
Expand Down Expand Up @@ -159,7 +160,7 @@ pub struct TbsCertList<'a> {
pub next_update: Option<ASN1Time>,
pub revoked_certificates: Vec<RevokedCertificate<'a>>,
extensions: Vec<X509Extension<'a>>,
pub(crate) raw: &'a [u8],
pub(crate) raw: Cow<'a, [u8]>,
}

impl<'a> TbsCertList<'a> {
Expand Down Expand Up @@ -200,7 +201,7 @@ impl<'a> TbsCertList<'a> {

impl<'a> AsRef<[u8]> for TbsCertList<'a> {
fn as_ref(&self) -> &[u8] {
self.raw
&self.raw
}
}

Expand All @@ -225,7 +226,7 @@ impl<'a> FromDer<'a> for TbsCertList<'a> {
next_update,
revoked_certificates: revoked_certificates.unwrap_or_default(),
extensions,
raw: &start_i[..len],
raw: Cow::Borrowed(&start_i[..len]),
};
Ok((i, tbs))
})(i)
Expand All @@ -240,7 +241,7 @@ pub struct RevokedCertificate<'a> {
pub revocation_date: ASN1Time,
/// Additional information about revocation
extensions: Vec<X509Extension<'a>>,
pub(crate) raw_serial: &'a [u8],
pub(crate) raw_serial: Cow<'a, [u8]>,
}

impl<'a> RevokedCertificate<'a> {
Expand Down Expand Up @@ -285,12 +286,12 @@ impl<'a> RevokedCertificate<'a> {

/// Get the raw bytes of the certificate serial number
pub fn raw_serial(&self) -> &[u8] {
self.raw_serial
&self.raw_serial
}

/// Get a formatted string of the certificate serial number, separated by ':'
pub fn raw_serial_as_string(&self) -> String {
format_serial(self.raw_serial)
format_serial(&self.raw_serial)
}

/// Get the code identifying the reason for the revocation, if present
Expand Down Expand Up @@ -331,7 +332,7 @@ impl<'a> FromDer<'a> for RevokedCertificate<'a> {
user_certificate,
revocation_date,
extensions: extensions.unwrap_or_default(),
raw_serial,
raw_serial: Cow::Borrowed(raw_serial),
};
Ok((i, revoked))
})(i)
Expand Down
28 changes: 18 additions & 10 deletions src/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use nom::multi::{many0, many1};
use nom::{Err, Offset};
use oid_registry::*;
use rusticata_macros::newtype_enum;
use std::borrow::Cow;
use std::convert::TryFrom;
use std::fmt;
use std::iter::FromIterator;
Expand Down Expand Up @@ -109,9 +110,9 @@ impl<'a> AttributeTypeAndValue<'a> {
/// Note: the [`TryFrom`] trait is implemented for `&str`, so this is equivalent to `attr.try_into()`.
///
/// Only NumericString, PrintableString, UTF8String and IA5String
/// are considered here. Other string types can be read using `as_slice`.
/// are considered here. Other string types can be read using `as_bytes`.
#[inline]
pub fn as_str(&self) -> Result<&'a str, X509Error> {
pub fn as_str(&'a self) -> Result<&'a str, X509Error> {
self.attr_value.as_str().map_err(|e| e.into())
}

Expand All @@ -121,7 +122,8 @@ impl<'a> AttributeTypeAndValue<'a> {
///
/// Note: the [`TryFrom`] trait is implemented for `&[u8]`, so this is equivalent to `attr.try_into()`.
#[inline]
pub fn as_slice(&self) -> Result<&'a [u8], X509Error> {
#[deprecated(since = "0.10.0", note = "Please use `as_bytes` instead")]
pub fn as_slice(&'a self) -> Result<&'a [u8], X509Error> {
self.attr_value.as_slice().map_err(|e| e.into())
}
}
Expand Down Expand Up @@ -337,7 +339,7 @@ impl<'a> FromDer<'a> for AlgorithmIdentifier<'a> {
#[derive(Clone, Debug, PartialEq)]
pub struct X509Name<'a> {
pub(crate) rdn_seq: Vec<RelativeDistinguishedName<'a>>,
pub(crate) raw: &'a [u8],
pub(crate) raw: Cow<'a, [u8]>,
}

impl<'a> fmt::Display for X509Name<'a> {
Expand All @@ -353,7 +355,10 @@ impl<'a> X509Name<'a> {
/// Builds a new `X509Name` from the provided elements.
#[inline]
pub const fn new(rdn_seq: Vec<RelativeDistinguishedName<'a>>, raw: &'a [u8]) -> Self {
X509Name { rdn_seq, raw }
X509Name {
rdn_seq,
raw: Cow::Borrowed(raw),
}
}

/// Attempt to format the current name, using the given registry to convert OIDs to strings.
Expand All @@ -365,8 +370,8 @@ impl<'a> X509Name<'a> {
}

// Not using the AsRef trait, as that would not give back the full 'a lifetime
pub fn as_raw(&self) -> &'a [u8] {
self.raw
pub fn as_raw(&'a self) -> &'a [u8] {
&self.raw
}

/// Return an iterator over the `RelativeDistinguishedName` components of the name
Expand Down Expand Up @@ -464,7 +469,10 @@ impl<'a> X509Name<'a> {
impl<'a> FromIterator<RelativeDistinguishedName<'a>> for X509Name<'a> {
fn from_iter<T: IntoIterator<Item = RelativeDistinguishedName<'a>>>(iter: T) -> Self {
let rdn_seq = iter.into_iter().collect();
X509Name { rdn_seq, raw: &[] }
X509Name {
rdn_seq,
raw: Cow::Borrowed(&[]),
}
}
}

Expand All @@ -483,7 +491,7 @@ impl<'a> FromDer<'a> for X509Name<'a> {
let len = start_i.offset(i);
let name = X509Name {
rdn_seq,
raw: &start_i[..len],
raw: Cow::Borrowed(&start_i[..len]),
};
Ok((i, name))
})(i)
Expand Down Expand Up @@ -643,7 +651,7 @@ mod tests {
],
},
],
raw: &[], // incorrect, but enough for testing
raw: Cow::Borrowed(&[]), // incorrect, but enough for testing
};
assert_eq!(
name.to_string(),
Expand Down
29 changes: 18 additions & 11 deletions tests/readcert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use ::time::OffsetDateTime;
use der_parser::oid;
use nom::Parser;
use oid_registry::*;
use std::borrow::Cow;
use std::collections::HashMap;
use x509_parser::prelude::*;

Expand Down Expand Up @@ -95,10 +96,10 @@ fn test_x509_parser() {
4, 20, 163, 5, 47, 24, 96, 80, 194, 137, 10, 221, 43, 33, 79, 255, 142, 78,
168, 48, 49, 54,
],
ParsedExtension::SubjectKeyIdentifier(KeyIdentifier(&[
ParsedExtension::SubjectKeyIdentifier(KeyIdentifier(Cow::Borrowed(&[
163, 5, 47, 24, 96, 80, 194, 137, 10, 221, 43, 33, 79, 255, 142, 78, 168,
48, 49, 54,
])),
]))),
),
X509Extension::new(
oid!(2.5.29 .35),
Expand All @@ -108,10 +109,10 @@ fn test_x509_parser() {
255, 142, 78, 168, 48, 49, 54,
],
ParsedExtension::AuthorityKeyIdentifier(AuthorityKeyIdentifier {
key_identifier: Some(KeyIdentifier(&[
key_identifier: Some(KeyIdentifier(Cow::Borrowed(&[
163, 5, 47, 24, 96, 80, 194, 137, 10, 221, 43, 33, 79, 255, 142, 78,
168, 48, 49, 54,
])),
]))),
authority_cert_issuer: None,
authority_cert_serial: None,
}),
Expand Down Expand Up @@ -236,10 +237,10 @@ fn test_crl_parse() {
234, 199, 181, 251, 159, 249, 173, 52,
],
ParsedExtension::AuthorityKeyIdentifier(AuthorityKeyIdentifier {
key_identifier: Some(KeyIdentifier(&[
key_identifier: Some(KeyIdentifier(Cow::Borrowed(&[
190, 18, 1, 204, 170, 234, 17, 128, 218, 46, 173, 178, 234, 199, 181,
251, 159, 249, 173, 52,
])),
]))),
authority_cert_issuer: None,
authority_cert_serial: None,
}),
Expand Down Expand Up @@ -281,10 +282,10 @@ fn test_crl_parse_empty() {
82, 191, 80, 27, 57, 39, 6, 172,
],
ParsedExtension::AuthorityKeyIdentifier(AuthorityKeyIdentifier {
key_identifier: Some(KeyIdentifier(&[
key_identifier: Some(KeyIdentifier(Cow::Borrowed(&[
34, 101, 12, 214, 90, 157, 52, 137, 243, 131, 180, 149, 82, 191, 80,
27, 57, 39, 6, 172,
])),
]))),
authority_cert_issuer: None,
authority_cert_serial: None,
}),
Expand Down Expand Up @@ -333,10 +334,16 @@ fn test_duplicate_authority_info_access() {
.expect("no AIA found");
let mut accessdescs = HashMap::new();
let ca_issuers = vec![
&GeneralName::URI("http://cdp1.pca.dfn.de/dfn-ca-global-g2/pub/cacert/cacert.crt"),
&GeneralName::URI("http://cdp2.pca.dfn.de/dfn-ca-global-g2/pub/cacert/cacert.crt"),
&GeneralName::URI(
"http://cdp1.pca.dfn.de/dfn-ca-global-g2/pub/cacert/cacert.crt".into(),
),
&GeneralName::URI(
"http://cdp2.pca.dfn.de/dfn-ca-global-g2/pub/cacert/cacert.crt".into(),
),
];
let ocsp = vec![&GeneralName::URI("http://ocsp.pca.dfn.de/OCSP-Server/OCSP")];
let ocsp = vec![&GeneralName::URI(
"http://ocsp.pca.dfn.de/OCSP-Server/OCSP".into(),
)];
accessdescs.insert(OID_PKIX_ACCESS_DESCRIPTOR_CA_ISSUERS, ca_issuers);
accessdescs.insert(OID_PKIX_ACCESS_DESCRIPTOR_OCSP, ocsp);
if let ParsedExtension::AuthorityInfoAccess(aia) = extension.parsed_extension() {
Expand Down

0 comments on commit 208e1a7

Please sign in to comment.