Skip to content

Commit

Permalink
add certificate signing request
Browse files Browse the repository at this point in the history
  • Loading branch information
Tudyx committed Feb 15, 2024
1 parent e0da4ce commit 8def505
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ categories = ["network-programming", "cryptography"]

[dependencies]
base64 = { version = "0.21", default-features = false, features = ["alloc"] }
pki-types = { package = "rustls-pki-types", version = "1" }
pki-types = { package = "rustls-pki-types", version = "1.3" }

[dev-dependencies]
bencher = "0.1.5"
Expand Down
29 changes: 26 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
//! match item.unwrap() {
//! Item::X509Certificate(cert) => println!("certificate {:?}", cert),
//! Item::Crl(crl) => println!("certificate revocation list: {:?}", crl),
//! Item::Csr(csr) => println!("certificate signing request: {:?}", csr),
//! Item::Pkcs1Key(key) => println!("rsa pkcs1 key {:?}", key),
//! Item::Pkcs8Key(key) => println!("pkcs8 key {:?}", key),
//! Item::Sec1Key(key) => println!("sec1 ec key {:?}", key),
Expand Down Expand Up @@ -67,8 +68,8 @@ pub use pemfile::{read_one_from_slice, Error, Item};
use pki_types::PrivateKeyDer;
#[cfg(feature = "std")]
use pki_types::{
CertificateDer, CertificateRevocationListDer, PrivatePkcs1KeyDer, PrivatePkcs8KeyDer,
PrivateSec1KeyDer,
CertificateDer, CertificateRevocationListDer, CertificateSigningRequestDer, PrivatePkcs1KeyDer,
PrivatePkcs8KeyDer, PrivateSec1KeyDer,
};

#[cfg(feature = "std")]
Expand Down Expand Up @@ -103,7 +104,29 @@ pub fn private_key(rd: &mut dyn io::BufRead) -> Result<Option<PrivateKeyDer<'sta
Item::Pkcs1Key(key) => return Ok(Some(key.into())),
Item::Pkcs8Key(key) => return Ok(Some(key.into())),
Item::Sec1Key(key) => return Ok(Some(key.into())),
Item::X509Certificate(_) | Item::Crl(_) => continue,
Item::X509Certificate(_) | Item::Crl(_) | Item::Csr(_) => continue,
}
}

Ok(None)
}

/// Return the first certificate signing request (CSR) found in `rd`.
///
/// Yields the first PEM section describing a certificate signing request, or an error if a
/// problem occurs while trying to read PEM sections.
#[cfg(feature = "std")]
pub fn csr(
rd: &mut dyn io::BufRead,
) -> Result<Option<CertificateSigningRequestDer<'static>>, io::Error> {
for result in iter::from_fn(move || read_one(rd).transpose()) {
match result? {
Item::Csr(csr) => return Ok(Some(csr)),
Item::Pkcs1Key(_)
| Item::Pkcs8Key(_)
| Item::Sec1Key(_)
| Item::X509Certificate(_)
| Item::Crl(_) => continue,
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/pemfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use core::ops::ControlFlow;
use std::io::{self, ErrorKind};

use pki_types::{
CertificateDer, CertificateRevocationListDer, PrivatePkcs1KeyDer, PrivatePkcs8KeyDer,
PrivateSec1KeyDer,
CertificateDer, CertificateRevocationListDer, CertificateSigningRequestDer, PrivatePkcs1KeyDer,
PrivatePkcs8KeyDer, PrivateSec1KeyDer,
};

/// The contents of a single recognised block in a PEM file.
Expand Down Expand Up @@ -41,6 +41,11 @@ pub enum Item {
///
/// Appears as "X509 CRL" in PEM files.
Crl(CertificateRevocationListDer<'static>),

/// A Certificate Signing Request; as specified in RFC 2986
///
/// Appears as "CERTIFICATE REQUEST" in PEM files.
Csr(CertificateSigningRequestDer<'static>),
}

/// Errors that may arise when parsing the contents of a PEM file
Expand Down Expand Up @@ -195,6 +200,7 @@ fn read_one_impl(
b"PRIVATE KEY" => Some(Item::Pkcs8Key(der.into())),
b"EC PRIVATE KEY" => Some(Item::Sec1Key(der.into())),
b"X509 CRL" => Some(Item::Crl(der.into())),
b"CERTIFICATE REQUEST" => Some(Item::Csr(der.into())),
_ => {
*section = None;
b64buf.clear();
Expand Down
18 changes: 18 additions & 0 deletions tests/data/csr.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIC+zCCAeMCAQAwfDELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRQwEgYD
VQQHDAtTYW4gQW50b25pbzEdMBsGA1UECgwURXhhbXBsZSBPcmdhbml6YXRpb24x
EjAQBgNVBAsMCU1hcmtldGluZzEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwJw0BcbuqZyiABlmSYTi1tcr8DB0D
NcTtzsYe7tlyIKd3mEs+u6Pi3rEQGvOw5eo6CmWII2qmVOqJ2f6gjl2lZJ5DUE6B
I+NNE73zfFMrttUtI8X4ChnE4rrGqqUsSvYz1YVU0KiJ/00YMjEY5XlJYYa9FgfZ
sUrhj4aCFdXS6CU9jueRr+udEBElDcgTS9+pB+LFhVfUMTdxnJ3BcT4ZDDqODH3/
5RAgq03dhRpkkaVIg2uVKTBDoM3hs8T1zIxLM7hItaZzMv4uHdfI8y+BdHrePT33
BoTlocvTEZEqqXEdw2kUd4PDgyUTjFE3b9OeLk0Ju5GRvuCW3UcS5gFvAgMBAAGg
OjA4BgkqhkiG9w0BCQ4xKzApMCcGA1UdEQQgMB6CC2V4YW1wbGUuY29tgg9mb28u
ZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBACWsgxPw13QUpoCJOqvp8B1A
EfsxRJITSROmukV3ZQycPT76Y3GVrM9sGjO8p13J/CVw2KcWc9xmgHF0MdvPNhnW
OB6Y07hVpNnJVHb1KglOkNkTy6sVDtnZHg2klqGSyzIbwZ9R3JG8HtRdkceIrm3D
gdiZyLcf1VDCCUGaskEi2CsggCQQJNyGi+8BSQ8MPKm/m0KrSchGQ157eWCCjopz
f5GQe2UGOg5T7g8+S4GdECMwkMlTGUwlAM6LuOG/NZqP528PCAYQv0eOYdSwALQT
GwTyU4AZ9y1uBFuaFxABew9GbDEtNY/XHTF8308edUwGBk6jfD+UuTeEwRZGs9E=
-----END CERTIFICATE REQUEST-----
18 changes: 18 additions & 0 deletions tests/data/zen.pem
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,22 @@ vTwHyadGSMK4CWtrn9fCAgSLw6NX74D7Cx1IaS8vstMjpeUqOS0dk5ThiW47HceB
DTko7rV5N+RGH2nW1ynLoZKCJQqqZcLilFMyKPui3jifJnQlMFi54jGVgg/D6UQn
7dA7wb2ux/1hSiaarp+mi7ncVOyByz6/WQP8mfc=
-----END X509 CRL-----
-----BEGIN CERTIFICATE REQUEST-----
MIIC+zCCAeMCAQAwfDELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRQwEgYD
VQQHDAtTYW4gQW50b25pbzEdMBsGA1UECgwURXhhbXBsZSBPcmdhbml6YXRpb24x
EjAQBgNVBAsMCU1hcmtldGluZzEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwJw0BcbuqZyiABlmSYTi1tcr8DB0D
NcTtzsYe7tlyIKd3mEs+u6Pi3rEQGvOw5eo6CmWII2qmVOqJ2f6gjl2lZJ5DUE6B
I+NNE73zfFMrttUtI8X4ChnE4rrGqqUsSvYz1YVU0KiJ/00YMjEY5XlJYYa9FgfZ
sUrhj4aCFdXS6CU9jueRr+udEBElDcgTS9+pB+LFhVfUMTdxnJ3BcT4ZDDqODH3/
5RAgq03dhRpkkaVIg2uVKTBDoM3hs8T1zIxLM7hItaZzMv4uHdfI8y+BdHrePT33
BoTlocvTEZEqqXEdw2kUd4PDgyUTjFE3b9OeLk0Ju5GRvuCW3UcS5gFvAgMBAAGg
OjA4BgkqhkiG9w0BCQ4xKzApMCcGA1UdEQQgMB6CC2V4YW1wbGUuY29tgg9mb28u
ZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBACWsgxPw13QUpoCJOqvp8B1A
EfsxRJITSROmukV3ZQycPT76Y3GVrM9sGjO8p13J/CVw2KcWc9xmgHF0MdvPNhnW
OB6Y07hVpNnJVHb1KglOkNkTy6sVDtnZHg2klqGSyzIbwZ9R3JG8HtRdkceIrm3D
gdiZyLcf1VDCCUGaskEi2CsggCQQJNyGi+8BSQ8MPKm/m0KrSchGQ157eWCCjopz
f5GQe2UGOg5T7g8+S4GdECMwkMlTGUwlAM6LuOG/NZqP528PCAYQv0eOYdSwALQT
GwTyU4AZ9y1uBFuaFxABew9GbDEtNY/XHTF8308edUwGBk6jfD+UuTeEwRZGs9E=
-----END CERTIFICATE REQUEST-----
... that's all folks!
14 changes: 13 additions & 1 deletion tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ fn private_key() {
assert!(rustls_pemfile::private_key(&mut reader).unwrap().is_none());
}

#[test]
fn test_csr() {
let data = include_bytes!("data/csr.pem");
let mut reader = BufReader::new(&data[..]);
rustls_pemfile::csr(&mut reader).unwrap().unwrap();

let data = include_bytes!("data/certificate.chain.pem");
let mut reader = BufReader::new(&data[..]);
assert!(rustls_pemfile::private_key(&mut reader).unwrap().is_none());
}

#[test]
fn test_certs() {
let data = include_bytes!("data/certificate.chain.pem");
Expand Down Expand Up @@ -139,7 +150,7 @@ fn parse_in_order() {
let items = rustls_pemfile::read_all(&mut reader)
.collect::<Result<Vec<_>, _>>()
.unwrap();
assert_eq!(items.len(), 9);
assert_eq!(items.len(), 10);
assert!(matches!(items[0], rustls_pemfile::Item::X509Certificate(_)));
assert!(matches!(items[1], rustls_pemfile::Item::X509Certificate(_)));
assert!(matches!(items[2], rustls_pemfile::Item::X509Certificate(_)));
Expand All @@ -149,6 +160,7 @@ fn parse_in_order() {
assert!(matches!(items[6], rustls_pemfile::Item::Pkcs1Key(_)));
assert!(matches!(items[7], rustls_pemfile::Item::Pkcs8Key(_)));
assert!(matches!(items[8], rustls_pemfile::Item::Crl(_)));
assert!(matches!(items[9], rustls_pemfile::Item::Csr(_)));
}

#[test]
Expand Down

0 comments on commit 8def505

Please sign in to comment.