Skip to content

Commit

Permalink
Create Certificates via methods on CertificateParams
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Feb 29, 2024
1 parent 9dbc95a commit 80fbb90
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 146 deletions.
4 changes: 2 additions & 2 deletions rcgen/examples/rsa-irc-openssl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
use rcgen::{date_time_ymd, Certificate, CertificateParams, DistinguishedName};
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName};
use std::fmt::Write;
use std::fs;

Expand All @@ -12,7 +12,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let key_pair_pem = String::from_utf8(pkey.private_key_to_pem_pkcs8()?)?;
let key_pair = rcgen::KeyPair::from_pem(&key_pair_pem)?;

let cert = Certificate::generate_self_signed(params, &key_pair)?;
let cert = params.sign_self(&key_pair)?;
let pem_serialized = cert.pem();
let pem = pem::parse(&pem_serialized)?;
let der_serialized = pem.contents();
Expand Down
4 changes: 2 additions & 2 deletions rcgen/examples/rsa-irc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
use rsa::pkcs8::EncodePrivateKey;
use rsa::RsaPrivateKey;

use rcgen::{date_time_ymd, Certificate, CertificateParams, DistinguishedName};
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName};
use std::fmt::Write;
use std::fs;

Expand All @@ -18,7 +18,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let private_key_der = private_key.to_pkcs8_der()?;
let key_pair = rcgen::KeyPair::try_from(private_key_der.as_bytes()).unwrap();

let cert = Certificate::generate_self_signed(params, &key_pair)?;
let cert = params.sign_self(&key_pair)?;
let pem_serialized = cert.pem();
let pem = pem::parse(&pem_serialized)?;
let der_serialized = pem.contents();
Expand Down
4 changes: 2 additions & 2 deletions rcgen/examples/sign-leaf-with-ca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn new_ca() -> Certificate {
params.not_after = tomorrow;

let key_pair = KeyPair::generate().unwrap();
Certificate::generate_self_signed(params, &key_pair).unwrap()
params.sign_self(&key_pair).unwrap()
}

fn new_end_entity() -> Certificate {
Expand All @@ -53,7 +53,7 @@ fn new_end_entity() -> Certificate {
params.not_after = tomorrow;

let key_pair = KeyPair::generate().unwrap();
Certificate::generate_self_signed(params, &key_pair).unwrap()
params.sign_self(&key_pair).unwrap()
}

fn validity_period() -> (OffsetDateTime, OffsetDateTime) {
Expand Down
6 changes: 2 additions & 4 deletions rcgen/examples/simple.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use rcgen::{
date_time_ymd, Certificate, CertificateParams, DistinguishedName, DnType, KeyPair, SanType,
};
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName, DnType, KeyPair, SanType};
use std::fs;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand All @@ -20,7 +18,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
];

let key_pair = KeyPair::generate()?;
let cert = Certificate::generate_self_signed(params, &key_pair)?;
let cert = params.sign_self(&key_pair)?;

let pem_serialized = cert.pem();
let pem = pem::parse(&pem_serialized)?;
Expand Down
110 changes: 52 additions & 58 deletions rcgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ This crate provides a way to generate self signed X.509 certificates.
The most simple way of using this crate is by calling the
[`generate_simple_self_signed`] function.
For more customization abilities, we provide the lower level
[`Certificate::generate_self_signed`] and [`Certificate::generate`] functions.
For more customization abilities, construct a [`CertificateParams`] and
a key pair to call [`CertificateParams::sign()`] or [`CertificateParams::sign_self()`].
*/
#![cfg_attr(
feature = "pem",
Expand Down Expand Up @@ -119,8 +119,7 @@ pub fn generate_simple_self_signed(
subject_alt_names: impl Into<Vec<String>>,
) -> Result<CertifiedKey, Error> {
let key_pair = KeyPair::generate()?;
let cert =
Certificate::generate_self_signed(CertificateParams::new(subject_alt_names)?, &key_pair)?;
let cert = CertificateParams::new(subject_alt_names)?.sign_self(&key_pair)?;
Ok(CertifiedKey { cert, key_pair })
}

Expand Down Expand Up @@ -727,6 +726,48 @@ impl CertificateParams {
..Default::default()
})
}
/// Generate a new certificate from the given parameters, signed by the provided issuer.
///
/// The returned certificate will have its issuer field set to the subject of the
/// provided `issuer`, and the authority key identifier extension will be populated using
/// the subject public key of `issuer`. It will be signed by `issuer_key`.
///
/// Note that no validation of the `issuer` certificate is performed. Rcgen will not require
/// the certificate to be a CA certificate, or have key usage extensions that allow signing.
///
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
/// [`Certificate::pem`].
pub fn sign(
self,
key_pair: &KeyPair,
issuer: &Certificate,
issuer_key: &KeyPair,
) -> Result<Certificate, Error> {
let subject_public_key_info = key_pair.public_key_der();
let der = self.serialize_der_with_signer(
key_pair,
issuer_key,
&issuer.params.distinguished_name,
)?;
Ok(Certificate {
params: self,
subject_public_key_info,
der,
})
}
/// Generates a new self-signed certificate from the given parameters.
///
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
/// [`Certificate::pem`].
pub fn sign_self(self, key_pair: &KeyPair) -> Result<Certificate, Error> {
let subject_public_key_info = key_pair.public_key_der();
let der = self.serialize_der_with_signer(key_pair, key_pair, &self.distinguished_name)?;
Ok(Certificate {
params: self,
subject_public_key_info,
der,
})
}
#[cfg(feature = "x509-parser")]
fn convert_x509_is_ca(
x509: &x509_parser::certificate::X509Certificate<'_>,
Expand Down Expand Up @@ -1602,52 +1643,6 @@ fn write_general_subtrees(writer: DERWriter, tag: u64, general_subtrees: &[Gener
}

impl Certificate {
/// Generates a new self-signed certificate from the given parameters.
///
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
/// [`Certificate::pem`].
pub fn generate_self_signed(
params: CertificateParams,
key_pair: &KeyPair,
) -> Result<Certificate, Error> {
let subject_public_key_info = key_pair.public_key_der();
let der =
params.serialize_der_with_signer(key_pair, key_pair, &params.distinguished_name)?;
Ok(Certificate {
params,
subject_public_key_info,
der,
})
}
/// Generate a new certificate from the given parameters, signed by the provided issuer.
///
/// The returned certificate will have its issuer field set to the subject of the
/// provided `issuer`, and the authority key identifier extension will be populated using
/// the subject public key of `issuer`. It will be signed by `issuer_key`.
///
/// Note that no validation of the `issuer` certificate is performed. Rcgen will not require
/// the certificate to be a CA certificate, or have key usage extensions that allow signing.
///
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
/// [`Certificate::pem`].
pub fn generate(
params: CertificateParams,
key_pair: &KeyPair,
issuer: &Certificate,
issuer_key: &KeyPair,
) -> Result<Certificate, Error> {
let subject_public_key_info = key_pair.public_key_der();
let der = params.serialize_der_with_signer(
key_pair,
issuer_key,
&issuer.params.distinguished_name,
)?;
Ok(Certificate {
params,
subject_public_key_info,
der,
})
}
/// Returns the certificate parameters
pub fn get_params(&self) -> &CertificateParams {
&self.params
Expand Down Expand Up @@ -1883,7 +1878,7 @@ mod tests {

// Make the cert
let key_pair = KeyPair::generate().unwrap();
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
let cert = params.sign_self(&key_pair).unwrap();

// Parse it
let (_rem, cert) = x509_parser::parse_x509_certificate(cert.der()).unwrap();
Expand Down Expand Up @@ -1922,7 +1917,7 @@ mod tests {

// Make the cert
let key_pair = KeyPair::generate().unwrap();
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
let cert = params.sign_self(&key_pair).unwrap();

// Parse it
let (_rem, cert) = x509_parser::parse_x509_certificate(cert.der()).unwrap();
Expand Down Expand Up @@ -1958,7 +1953,7 @@ mod tests {

// Make the cert
let key_pair = KeyPair::generate().unwrap();
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
let cert = params.sign_self(&key_pair).unwrap();

// Parse it
let (_rem, cert) = x509_parser::parse_x509_certificate(cert.der()).unwrap();
Expand All @@ -1985,7 +1980,7 @@ mod tests {

// Make the cert
let key_pair = KeyPair::generate().unwrap();
let cert = Certificate::generate_self_signed(params, &key_pair).unwrap();
let cert = params.sign_self(&key_pair).unwrap();

// Parse it
let (_rem, cert) = x509_parser::parse_x509_certificate(cert.der()).unwrap();
Expand Down Expand Up @@ -2018,7 +2013,7 @@ mod tests {

#[cfg(feature = "pem")]
mod test_pem_serialization {
use crate::{Certificate, CertificateParams, KeyPair};
use crate::{CertificateParams, KeyPair};

#[test]
#[cfg(windows)]
Expand All @@ -2033,8 +2028,7 @@ mod tests {
#[cfg(not(windows))]
fn test_not_windows_line_endings() {
let key_pair = KeyPair::generate().unwrap();
let cert =
Certificate::generate_self_signed(CertificateParams::default(), &key_pair).unwrap();
let cert = CertificateParams::default().sign_self(&key_pair).unwrap();
assert!(!cert.pem().contains('\r'));
}
}
Expand Down Expand Up @@ -2205,7 +2199,7 @@ PITGdT9dgN88nHPCle0B1+OY+OZ5
);

let kp = KeyPair::from_pem(&ca_key).unwrap();
let ca_cert = Certificate::generate_self_signed(params, &kp).unwrap();
let ca_cert = params.sign_self(&kp).unwrap();
assert_eq!(&expected_ski, &ca_cert.get_key_identifier());

let (_remainder, x509) = x509_parser::parse_x509_certificate(ca_cert.der()).unwrap();
Expand Down
Loading

0 comments on commit 80fbb90

Please sign in to comment.