Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Certificate: useful APIs #9300

Merged
merged 15 commits into from
Jul 26, 2023
61 changes: 60 additions & 1 deletion src/rust/cryptography-x509/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,21 @@

use crate::common;
use crate::extensions;
use crate::extensions::Extensions;
use crate::extensions::{Extension, Extensions};
use crate::name;
use crate::name::NameReadable;

#[derive(Debug, PartialEq)]
pub enum CertificateError {
DuplicateExtension(asn1::ObjectIdentifier),
Malformed(asn1::ParseError),
}

impl From<asn1::ParseError> for CertificateError {
fn from(value: asn1::ParseError) -> Self {
CertificateError::Malformed(value)
}
}

#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Eq, Clone)]
pub struct Certificate<'a> {
Expand All @@ -14,6 +27,52 @@ pub struct Certificate<'a> {
pub signature: asn1::BitString<'a>,
}

impl Certificate<'_> {
/// Returns the certificate's issuer.
pub fn issuer(&self) -> &NameReadable<'_> {
self.tbs_cert.issuer.unwrap_read()
}

/// Returns the certificate's subject.
pub fn subject(&self) -> &NameReadable<'_> {
self.tbs_cert.subject.unwrap_read()
}

/// Returns whether the certificate is "self-issued", whether its
/// issuer and subject are the same.
pub fn is_self_issued(&self) -> bool {
self.issuer() == self.subject()
}

/// Returns an iterable container over the certificate's extension, or
/// an error if the extension set contains a duplicate extension.
pub fn extensions(&self) -> Result<Extensions<'_>, CertificateError> {
self.tbs_cert
.extensions()
.map_err(CertificateError::DuplicateExtension)
woodruffw marked this conversation as resolved.
Show resolved Hide resolved
}

/// Returns whether the given extension (by OID) is critical, or
/// false if the extension is not present.
pub fn extension_is_critical(&self, oid: &asn1::ObjectIdentifier) -> bool {
woodruffw marked this conversation as resolved.
Show resolved Hide resolved
match self.extensions() {
Ok(exts) => exts
.get_extension(oid)
.map(|ext| ext.critical)
.unwrap_or(false),
Err(_) => false,
}
}

/// Returns a specific extension by OID.
pub fn extension(
&self,
oid: &asn1::ObjectIdentifier,
) -> Result<Option<Extension<'_>>, CertificateError> {
Ok(self.extensions()?.get_extension(oid))
}
woodruffw marked this conversation as resolved.
Show resolved Hide resolved
}

#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Eq, Clone)]
pub struct TbsCertificate<'a> {
#[explicit(0)]
Expand Down
Loading