-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start collection of basic data types
- Loading branch information
Showing
2 changed files
with
330 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
[package] | ||
name = "rustls-pki-types" | ||
version = "0.1.0" | ||
version = "1.0.0-alpha.1" | ||
edition = "2021" | ||
rust-version = "1.60" | ||
license = "MIT OR Apache-2.0" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
[features] | ||
default = ["alloc"] | ||
alloc = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,331 @@ | ||
pub fn add(left: usize, right: usize) -> usize { | ||
left + right | ||
#![no_std] | ||
#![warn(unreachable_pub)] | ||
#![warn(clippy::use_self)] | ||
|
||
#[cfg(feature = "alloc")] | ||
extern crate alloc; | ||
|
||
#[cfg(feature = "alloc")] | ||
use alloc::vec::Vec; | ||
use core::fmt; | ||
use core::ops::Deref; | ||
|
||
/// A DER-encoded X.509 private key, in one of several formats | ||
/// | ||
/// See variant inner types for more detailed information. | ||
#[non_exhaustive] | ||
#[derive(Debug, PartialEq)] | ||
pub enum PrivateKeyDer<'a> { | ||
Pkcs1(PrivatePkcs1KeyDer<'a>), | ||
Sec1(PrivateSec1KeyDer<'a>), | ||
Pkcs8(PrivatePkcs8KeyDer<'a>), | ||
} | ||
|
||
impl<'a> PrivateKeyDer<'a> { | ||
pub fn secret_der(&self) -> &[u8] { | ||
match self { | ||
PrivateKeyDer::Pkcs1(key) => key.secret_pkcs1_der(), | ||
PrivateKeyDer::Sec1(key) => key.secret_sec1_der(), | ||
PrivateKeyDer::Pkcs8(key) => key.secret_pkcs8_der(), | ||
} | ||
} | ||
} | ||
|
||
/// A DER-encoded plaintext RSA private key; as specified in PKCS#1/RFC 3447 | ||
/// | ||
/// A common format for storing private keys is | ||
/// [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). | ||
/// PEM blocks for RSA (PKCS#1) private keys are commonly stored in files with a `.pem` or `.key` | ||
/// suffix, and look like this: | ||
/// | ||
/// ```txt | ||
/// -----BEGIN RSA PRIVATE KEY----- | ||
/// <base64-encoded certificate content> | ||
/// -----END RSA PRIVATE KEY----- | ||
/// ``` | ||
/// | ||
/// The [`rustls-pemfile`](https://docs.rs/rustls-pemfile/latest/rustls_pemfile/) crate can be used | ||
/// to parse PEM files. The [`rcgen`](https://docs.rs/rcgen/latest/rcgen/) crate can be used to | ||
/// generate certificates and private keys. | ||
#[derive(PartialEq)] | ||
pub struct PrivatePkcs1KeyDer<'a>(Der<'a>); | ||
|
||
impl PrivatePkcs1KeyDer<'_> { | ||
pub fn secret_pkcs1_der(&self) -> &[u8] { | ||
self.0.as_ref() | ||
} | ||
} | ||
|
||
impl<'a> From<&'a [u8]> for PrivatePkcs1KeyDer<'a> { | ||
fn from(slice: &'a [u8]) -> Self { | ||
Self(Der(DerInner::Borrowed(slice))) | ||
} | ||
} | ||
|
||
#[cfg(feature = "alloc")] | ||
impl<'a> From<Vec<u8>> for PrivatePkcs1KeyDer<'a> { | ||
fn from(vec: Vec<u8>) -> Self { | ||
Self(Der(DerInner::Owned(vec))) | ||
} | ||
} | ||
|
||
impl fmt::Debug for PrivatePkcs1KeyDer<'_> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.debug_tuple("PrivatePkcs1KeyDer") | ||
.field(&"[secret key elided]") | ||
.finish() | ||
} | ||
} | ||
|
||
/// A Sec1-encoded plaintext private key; as specified in RFC 5915 | ||
/// | ||
/// A common format for storing private keys is | ||
/// [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). | ||
/// PEM blocks for Sec1 private keys are commonly stored in files with a `.pem` or `.key` | ||
/// suffix, and look like this: | ||
/// | ||
/// ```txt | ||
/// -----BEGIN EC PRIVATE KEY----- | ||
/// <base64-encoded certificate content> | ||
/// -----END EC PRIVATE KEY----- | ||
/// ``` | ||
/// | ||
/// The [`rustls-pemfile`](https://docs.rs/rustls-pemfile/latest/rustls_pemfile/) crate can be used | ||
/// to parse PEM files. The [`rcgen`](https://docs.rs/rcgen/latest/rcgen/) crate can be used to | ||
/// generate certificates and private keys. | ||
#[derive(PartialEq)] | ||
pub struct PrivateSec1KeyDer<'a>(Der<'a>); | ||
|
||
impl PrivateSec1KeyDer<'_> { | ||
pub fn secret_sec1_der(&self) -> &[u8] { | ||
self.0.as_ref() | ||
} | ||
} | ||
|
||
impl<'a> From<&'a [u8]> for PrivateSec1KeyDer<'a> { | ||
fn from(slice: &'a [u8]) -> Self { | ||
Self(Der(DerInner::Borrowed(slice))) | ||
} | ||
} | ||
|
||
#[cfg(feature = "alloc")] | ||
impl<'a> From<Vec<u8>> for PrivateSec1KeyDer<'a> { | ||
fn from(vec: Vec<u8>) -> Self { | ||
Self(Der(DerInner::Owned(vec))) | ||
} | ||
} | ||
|
||
impl fmt::Debug for PrivateSec1KeyDer<'_> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.debug_tuple("PrivatePkcs1KeyDer") | ||
.field(&"[secret key elided]") | ||
.finish() | ||
} | ||
} | ||
|
||
/// A DER-encoded plaintext private key; as specified in PKCS#8/RFC 5958 | ||
/// | ||
/// A common format for storing private keys is | ||
/// [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). | ||
/// PEM blocks for PKCS#8 private keys are commonly stored in files with a `.pem` or `.key` | ||
/// suffix, and look like this: | ||
/// | ||
/// ```txt | ||
/// -----BEGIN PRIVATE KEY----- | ||
/// <base64-encoded certificate content> | ||
/// -----END PRIVATE KEY----- | ||
/// ``` | ||
/// | ||
/// The [`rustls-pemfile`](https://docs.rs/rustls-pemfile/latest/rustls_pemfile/) crate can be used | ||
/// to parse PEM files. The [`rcgen`](https://docs.rs/rcgen/latest/rcgen/) crate can be used to | ||
/// generate certificates and private keys. | ||
/// ``` | ||
#[derive(PartialEq)] | ||
pub struct PrivatePkcs8KeyDer<'a>(Der<'a>); | ||
|
||
impl PrivatePkcs8KeyDer<'_> { | ||
pub fn secret_pkcs8_der(&self) -> &[u8] { | ||
self.0.as_ref() | ||
} | ||
} | ||
|
||
impl<'a> From<&'a [u8]> for PrivatePkcs8KeyDer<'a> { | ||
fn from(slice: &'a [u8]) -> Self { | ||
Self(Der(DerInner::Borrowed(slice))) | ||
} | ||
} | ||
|
||
#[cfg(feature = "alloc")] | ||
impl<'a> From<Vec<u8>> for PrivatePkcs8KeyDer<'a> { | ||
fn from(vec: Vec<u8>) -> Self { | ||
Self(Der(DerInner::Owned(vec))) | ||
} | ||
} | ||
|
||
impl fmt::Debug for PrivatePkcs8KeyDer<'_> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.debug_tuple("PrivatePkcs1KeyDer") | ||
.field(&"[secret key elided]") | ||
.finish() | ||
} | ||
} | ||
|
||
/// A trust anchor (a.k.a. root CA), represented as a DER-encoded X.509 certificate | ||
/// | ||
/// Traditionally, certificate verification libraries have represented trust anchors as full X.509 | ||
/// root certificates. However, those certificates contain a lot more data than is needed for | ||
/// verifying certificates. The [`TrustAnchor`] representation allows an application to store | ||
/// just the essential elements of trust anchors. | ||
#[derive(Clone, Debug, PartialEq)] | ||
pub struct TrustAnchor<'a> { | ||
pub subject: Der<'a>, | ||
pub subject_public_key_info: Der<'a>, | ||
pub name_constraints: Option<Der<'a>>, | ||
} | ||
|
||
impl TrustAnchor<'_> { | ||
#[cfg(feature = "alloc")] | ||
pub fn to_owned(&self) -> TrustAnchor<'static> { | ||
use alloc::borrow::ToOwned; | ||
TrustAnchor { | ||
subject: self.subject.as_ref().to_owned().into(), | ||
subject_public_key_info: self.subject_public_key_info.as_ref().to_owned().into(), | ||
name_constraints: self | ||
.name_constraints | ||
.as_ref() | ||
.map(|nc| nc.as_ref().to_owned().into()), | ||
} | ||
} | ||
} | ||
|
||
/// A Certificate Revocation List; as specified in RFC 5280 | ||
#[derive(Debug, PartialEq)] | ||
pub struct CertificateRevocationListDer<'a>(Der<'a>); | ||
|
||
impl AsRef<[u8]> for CertificateRevocationListDer<'_> { | ||
fn as_ref(&self) -> &[u8] { | ||
self.0.as_ref() | ||
} | ||
} | ||
|
||
impl Deref for CertificateRevocationListDer<'_> { | ||
type Target = [u8]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
self.as_ref() | ||
} | ||
} | ||
|
||
impl<'a> From<&'a [u8]> for CertificateRevocationListDer<'a> { | ||
fn from(slice: &'a [u8]) -> Self { | ||
Self(Der::from(slice)) | ||
} | ||
} | ||
|
||
#[cfg(feature = "alloc")] | ||
impl<'a> From<Vec<u8>> for CertificateRevocationListDer<'a> { | ||
fn from(vec: Vec<u8>) -> Self { | ||
Self(Der::from(vec)) | ||
} | ||
} | ||
|
||
/// A DER-encoded X.509 certificate; as specified in RFC 5280 | ||
/// | ||
/// A common format for storing certificates is | ||
/// [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). | ||
/// PEM certificates are commonly stored in files with a `.pem`, `.cer` or `.crt` suffix, and look | ||
/// like this: | ||
/// | ||
/// ```txt | ||
/// -----BEGIN BEGIN EC PRIVATE KEY----- | ||
/// <base64-encoded certificate content> | ||
/// -----END CERTIFICATE----- | ||
/// ``` | ||
/// | ||
/// The [`rustls-pemfile`](https://docs.rs/rustls-pemfile/latest/rustls_pemfile/) crate can be used | ||
/// to parse PEM files. The [`rcgen`](https://docs.rs/rcgen/latest/rcgen/) crate can be used to | ||
/// generate certificates and private keys. | ||
/// ``` | ||
#[derive(Clone, Debug, PartialEq)] | ||
pub struct CertificateDer<'a>(Der<'a>); | ||
|
||
impl AsRef<[u8]> for CertificateDer<'_> { | ||
fn as_ref(&self) -> &[u8] { | ||
self.0.as_ref() | ||
} | ||
} | ||
|
||
impl Deref for CertificateDer<'_> { | ||
type Target = [u8]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
self.as_ref() | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
impl<'a> From<&'a [u8]> for CertificateDer<'a> { | ||
fn from(slice: &'a [u8]) -> Self { | ||
Self(Der::from(slice)) | ||
} | ||
} | ||
|
||
#[cfg(feature = "alloc")] | ||
impl<'a> From<Vec<u8>> for CertificateDer<'a> { | ||
fn from(vec: Vec<u8>) -> Self { | ||
Self(Der::from(vec)) | ||
} | ||
} | ||
|
||
#[derive(Clone, PartialEq)] | ||
pub struct Der<'a>(DerInner<'a>); | ||
|
||
impl<'a> Der<'a> { | ||
// Trait methods cannot be const, so we additionally offer some traditional constructors. | ||
pub const fn from_slice(der: &'a [u8]) -> Self { | ||
Self(DerInner::Borrowed(der)) | ||
} | ||
} | ||
|
||
impl AsRef<[u8]> for Der<'_> { | ||
fn as_ref(&self) -> &[u8] { | ||
match &self.0 { | ||
#[cfg(feature = "alloc")] | ||
DerInner::Owned(vec) => vec.as_ref(), | ||
DerInner::Borrowed(slice) => slice, | ||
} | ||
} | ||
} | ||
|
||
#[test] | ||
fn it_works() { | ||
let result = add(2, 2); | ||
assert_eq!(result, 4); | ||
impl Deref for Der<'_> { | ||
type Target = [u8]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
self.as_ref() | ||
} | ||
} | ||
|
||
impl<'a> From<&'a [u8]> for Der<'a> { | ||
fn from(slice: &'a [u8]) -> Self { | ||
Self(DerInner::Borrowed(slice)) | ||
} | ||
} | ||
|
||
#[cfg(feature = "alloc")] | ||
impl<'a> From<Vec<u8>> for Der<'a> { | ||
fn from(vec: Vec<u8>) -> Self { | ||
Self(DerInner::Owned(vec)) | ||
} | ||
} | ||
|
||
impl fmt::Debug for Der<'_> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.debug_tuple("Der").field(&self.as_ref()).finish() | ||
} | ||
} | ||
|
||
#[derive(Clone, PartialEq)] | ||
enum DerInner<'a> { | ||
#[cfg(feature = "alloc")] | ||
Owned(Vec<u8>), | ||
Borrowed(&'a [u8]), | ||
} |