#![doc(html_root_url="https://briansmith.org/rustdoc/")]
#![no_std]
#![allow(
missing_debug_implementations,
)]
#![deny(
unused_qualifications,
)]
#![forbid(
anonymous_parameters,
box_pointers,
fat_ptr_transmutes,
missing_copy_implementations,
missing_docs,
trivial_casts,
trivial_numeric_casts,
unsafe_code,
unstable_features,
unused_extern_crates,
unused_import_braces,
unused_results,
variant_size_differences,
warnings,
)]
#[cfg(any(test, feature = "trust_anchor_util"))]
#[macro_use(format)]
extern crate std;
extern crate ring;
#[cfg(test)]
extern crate base64;
extern crate untrusted;
#[macro_use]
mod der;
mod cert;
mod name;
mod signed_data;
mod calendar;
mod time;
#[cfg(feature = "trust_anchor_util")]
pub mod trust_anchor_util;
mod verify_cert;
pub use name::DNSNameRef;
#[cfg(feature = "std")]
pub use name::DNSName;
pub use signed_data::{
SignatureAlgorithm,
ECDSA_P256_SHA256,
ECDSA_P256_SHA384,
ECDSA_P384_SHA256,
ECDSA_P384_SHA384,
RSA_PKCS1_2048_8192_SHA1,
RSA_PKCS1_2048_8192_SHA256,
RSA_PKCS1_2048_8192_SHA384,
RSA_PKCS1_2048_8192_SHA512,
RSA_PKCS1_3072_8192_SHA384,
RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
};
pub use time::Time;
pub struct EndEntityCert<'a> {
inner: cert::Cert<'a>,
}
impl <'a> EndEntityCert<'a> {
pub fn from(cert_der: untrusted::Input<'a>)
-> Result<EndEntityCert<'a>, Error> {
Ok(EndEntityCert {
inner: cert::parse_cert(cert_der, cert::EndEntityOrCA::EndEntity)?
})
}
pub fn verify_is_valid_tls_server_cert(
&self, supported_sig_algs: &[&SignatureAlgorithm],
&TLSServerTrustAnchors(trust_anchors): &TLSServerTrustAnchors,
intermediate_certs: &[untrusted::Input], time: Time)
-> Result<(), Error> {
verify_cert::build_chain(verify_cert::EKU_SERVER_AUTH,
supported_sig_algs, trust_anchors,
intermediate_certs, &self.inner, time, 0)
}
pub fn verify_is_valid_tls_client_cert(
&self, supported_sig_algs: &[&SignatureAlgorithm],
&TLSClientTrustAnchors(trust_anchors): &TLSClientTrustAnchors,
intermediate_certs: &[untrusted::Input], time: Time)
-> Result<(), Error> {
verify_cert::build_chain(verify_cert::EKU_CLIENT_AUTH,
supported_sig_algs, trust_anchors,
intermediate_certs, &self.inner, time, 0)
}
pub fn verify_is_valid_for_dns_name(&self, dns_name: DNSNameRef)
-> Result<(), Error> {
name::verify_cert_dns_name(&self, dns_name)
}
#[cfg(feature = "std")]
pub fn verify_is_valid_for_at_least_one_dns_name<'names, Names>(
&self, dns_names: Names)
-> Result<std::vec::Vec<DNSNameRef<'names>>, Error>
where Names: Iterator<Item=DNSNameRef<'names>> {
let result: std::vec::Vec<DNSNameRef<'names>> = dns_names
.filter(|n| self.verify_is_valid_for_dns_name(*n).is_ok())
.collect();
if result.is_empty() {
return Err(Error::CertNotValidForName);
}
Ok(result)
}
pub fn verify_signature(&self, signature_alg: &SignatureAlgorithm,
msg: untrusted::Input,
signature: untrusted::Input) -> Result<(), Error> {
signed_data::verify_signature(signature_alg, self.inner.spki, msg,
signature)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Error {
BadDER,
BadDERTime,
CAUsedAsEndEntity,
CertExpired,
CertNotValidForName,
CertNotValidYet,
EndEntityUsedAsCA,
ExtensionValueInvalid,
InvalidCertValidity,
InvalidSignatureForPublicKey,
NameConstraintViolation,
PathLenConstraintViolated,
SignatureAlgorithmMismatch,
RequiredEKUNotFound,
UnknownIssuer,
UnsupportedCertVersion,
UnsupportedCriticalExtension,
UnsupportedSignatureAlgorithmForPublicKey,
UnsupportedSignatureAlgorithm,
}
#[derive(Debug)]
pub struct TrustAnchor<'a> {
pub subject: &'a [u8],
pub spki: &'a [u8],
pub name_constraints: Option<&'a [u8]>
}
#[derive(Debug)]
pub struct TLSServerTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]);
#[derive(Debug)]
pub struct TLSClientTrustAnchors<'a>(pub &'a [TrustAnchor<'a>]);