Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ jobs:
- run: cargo clippy --features ring,pem,x509-parser --all-targets
# rustls-cert-gen require either aws_lc_rs or ring feature
- run: cargo clippy -p rcgen --no-default-features --all-targets
- run: cargo clippy -p rcgen --no-default-features --features pem,x509-parser --all-targets
- name: Ensure backend-free builds have no built-in crypto dependencies
run: "! cargo tree -p rcgen --no-default-features --edges normal,build | grep -E 'ring v|aws-lc'"
Comment thread
jgreeer marked this conversation as resolved.
Outdated
- run: cargo clippy --no-default-features --features ring --all-targets
- run: cargo clippy --no-default-features --features aws_lc_rs,pem,x509-parser --all-targets
- run: cargo clippy --no-default-features --features aws_lc_rs_unstable,pem,x509-parser --all-targets
Expand All @@ -73,6 +76,10 @@ jobs:
run: cargo doc --features ring,pem,x509-parser --document-private-items
env:
RUSTDOCFLAGS: ${{ matrix.toolchain == 'nightly' && '-Dwarnings --cfg=rcgen_docsrs' || '-Dwarnings' }}
- name: cargo doc (provider API without a built-in backend)
run: cargo doc -p rcgen --no-default-features --features pem,x509-parser
env:
RUSTDOCFLAGS: ${{ matrix.toolchain == 'nightly' && '-Dwarnings --cfg=rcgen_docsrs' || '-Dwarnings' }}
- name: cargo doc (aws_lc_rs_unstable)
run: cargo doc --features aws_lc_rs_unstable,pem,x509-parser --document-private-items
env:
Expand Down Expand Up @@ -165,6 +172,8 @@ jobs:
run: cargo test --features x509-parser
- name: Run the tests with aws_lc_rs backend enabled
run: cargo test --no-default-features --features aws_lc_rs,pem
- name: Run the tests with no built-in backend
run: cargo test -p rcgen --no-default-features --features pem,x509-parser
# rustls-cert-gen require either aws_lc_rs or ring feature
- name: Run the tests with no features enabled
run: cargo test -p rcgen --no-default-features
Expand Down
14 changes: 3 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,33 @@ Simple Rust library to generate X.509 certificates.

```Rust
use rcgen::{generate_simple_self_signed, CertifiedKey};
let provider = rcgen::crypto::ring::default_provider();
// Generate a certificate that's valid for "localhost" and "hello.world.example"
let subject_alt_names = vec!["hello.world.example".to_string(),
"localhost".to_string()];

let CertifiedKey { cert, signing_key } = generate_simple_self_signed(subject_alt_names).unwrap();
let CertifiedKey { cert, signing_key } =
generate_simple_self_signed(subject_alt_names, provider).unwrap();
println!("{}", cert.pem());
println!("{}", signing_key.serialize_pem());
```

## Cryptography providers

Rcgen does not select a cryptography provider by default. Ring and AWS-LC are available through
the `ring` and `aws_lc_rs` features, respectively.

Enable a built-in provider explicitly:

```toml
[dependencies]
rcgen = { version = "0.15", features = ["ring"] }
```

Applications pass the selected provider explicitly to APIs that perform cryptographic work. A
custom provider can instead implement the `CryptoProvider` trait without enabling either built-in
backend. The `pem` feature is optional.

## Trying it out with openssl

You can do this:
Expand Down
21 changes: 10 additions & 11 deletions rcgen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rcgen"
version = "0.14.10"
version = "0.15.0"
documentation = "https://docs.rs/rcgen"
description.workspace = true
repository.workspace = true
Expand All @@ -11,12 +11,11 @@ rust-version.workspace = true
keywords.workspace = true

[features]
default = ["crypto", "pem", "ring"]
aws_lc_rs = ["crypto", "dep:aws-lc-rs", "aws-lc-rs/aws-lc-sys", "x509-parser?/verify-aws"]
default = ["pem"]
aws_lc_rs = ["dep:aws-lc-rs", "aws-lc-rs/aws-lc-sys"]
aws_lc_rs_unstable = ["aws_lc_rs"] # For backwards compatibility only
fips = ["crypto", "dep:aws-lc-rs", "aws-lc-rs/fips"]
crypto = []
ring = ["crypto", "dep:ring", "x509-parser?/verify"]
fips = ["dep:aws-lc-rs", "aws-lc-rs/fips"]
ring = ["dep:ring"]

[dependencies]
aws-lc-rs = { workspace = true, optional = true }
Expand All @@ -33,22 +32,22 @@ openssl = { workspace = true }

[[example]]
name = "rsa-irc-openssl"
required-features = ["pem"]
required-features = ["pem", "ring"]

[[example]]
name = "sign-leaf-with-ca"
required-features = ["pem", "x509-parser"]
required-features = ["pem", "ring", "x509-parser"]

[[example]]
name = "sign-leaf-with-pem-files"
required-features = ["pem", "x509-parser"]
required-features = ["pem", "ring", "x509-parser"]

[[example]]
name = "simple"
required-features = ["crypto", "pem"]
required-features = ["pem", "ring"]

[package.metadata.docs.rs]
features = ["aws_lc_rs", "aws_lc_rs_unstable", "crypto", "ring", "x509-parser"]
features = ["aws_lc_rs", "aws_lc_rs_unstable", "ring", "x509-parser"]
rustdoc-args = ["--cfg", "rcgen_docsrs"]

[package.metadata.cargo_check_external_types]
Expand Down
5 changes: 3 additions & 2 deletions rcgen/examples/rsa-irc-openssl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

use rcgen::{date_time_ymd, CertificateParams, DistinguishedName};

let provider = rcgen::crypto::ring::default_provider();
let mut params: CertificateParams = Default::default();
params.not_before = date_time_ymd(2021, 5, 19);
params.not_after = date_time_ymd(4096, 1, 1);
params.distinguished_name = DistinguishedName::new();

let pkey: openssl::pkey::PKey<_> = openssl::rsa::Rsa::generate(2048)?.try_into()?;
let key_pair_pem = String::from_utf8(pkey.private_key_to_pem_pkcs8()?)?;
let key_pair = rcgen::KeyPair::from_pem(&key_pair_pem)?;
let key_pair = rcgen::KeyPair::from_pem(&key_pair_pem, provider)?;

let cert = params.self_signed(&key_pair)?;
let cert = params.self_signed(&key_pair, provider)?;
let pem_serialized = cert.pem();
let pem = pem::parse(&pem_serialized)?;
let der_serialized = pem.contents();
Expand Down
21 changes: 11 additions & 10 deletions rcgen/examples/sign-leaf-with-ca.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use rcgen::DnValue::PrintableString;
use rcgen::{
BasicConstraints, Certificate, CertificateParams, DnType, ExtendedKeyUsagePurpose, IsCa,
Issuer, KeyPair, KeyUsagePurpose,
BasicConstraints, Certificate, CertificateParams, CryptoProvider, DnType,
ExtendedKeyUsagePurpose, IsCa, Issuer, KeyPair, KeyUsagePurpose,
};
use time::{Duration, OffsetDateTime};

/// Example demonstrating signing end-entity certificate with ca
fn main() {
let (ca, issuer) = new_ca();
let end_entity = new_end_entity(&issuer);
let provider = rcgen::crypto::ring::default_provider();
let (ca, issuer) = new_ca(provider);
let end_entity = new_end_entity(&issuer, provider);

let end_entity_pem = end_entity.pem();
println!("directly signed end-entity certificate: {end_entity_pem}");
Expand All @@ -17,7 +18,7 @@ fn main() {
println!("ca certificate: {ca_cert_pem}");
}

fn new_ca() -> (Certificate, Issuer<'static, KeyPair>) {
fn new_ca(provider: &dyn CryptoProvider) -> (Certificate, Issuer<'static, KeyPair>) {
let mut params =
CertificateParams::new(Vec::default()).expect("empty subject alt name can't produce error");
let (yesterday, tomorrow) = validity_period();
Expand All @@ -36,12 +37,12 @@ fn new_ca() -> (Certificate, Issuer<'static, KeyPair>) {
params.not_before = yesterday;
params.not_after = tomorrow;

let key_pair = KeyPair::generate().unwrap();
let cert = params.self_signed(&key_pair).unwrap();
let key_pair = KeyPair::generate(provider).unwrap();
let cert = params.self_signed(&key_pair, provider).unwrap();
(cert, Issuer::new(params, key_pair))
}

fn new_end_entity(issuer: &Issuer<'static, KeyPair>) -> Certificate {
fn new_end_entity(issuer: &Issuer<'static, KeyPair>, provider: &dyn CryptoProvider) -> Certificate {
let name = "entity.other.host";
let mut params = CertificateParams::new(vec![name.into()]).expect("we know the name is valid");
let (yesterday, tomorrow) = validity_period();
Expand All @@ -54,8 +55,8 @@ fn new_end_entity(issuer: &Issuer<'static, KeyPair>) -> Certificate {
params.not_before = yesterday;
params.not_after = tomorrow;

let key_pair = KeyPair::generate().unwrap();
params.signed_by(&key_pair, issuer).unwrap()
let key_pair = KeyPair::generate(provider).unwrap();
params.signed_by(&key_pair, issuer, provider).unwrap()
}

fn validity_period() -> (OffsetDateTime, OffsetDateTime) {
Expand Down
7 changes: 4 additions & 3 deletions rcgen/examples/sign-leaf-with-pem-files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rcgen::{CertificateParams, DnType, ExtendedKeyUsagePurpose, Issuer, KeyPair,
use time::{Duration, OffsetDateTime};

fn main() -> Result<(), Box<dyn Error>> {
let provider = rcgen::crypto::ring::default_provider();
let mut args = std::env::args().skip(1);

let signer_keys_file = PathBuf::from(
Expand All @@ -36,7 +37,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let keys_pem = fs::read_to_string(&signer_keys_file)?;
let cert_pem = fs::read_to_string(&signer_cert_file)?;

let key_pair = KeyPair::from_pem(&keys_pem)?;
let key_pair = KeyPair::from_pem(&keys_pem, provider)?;
let signer = Issuer::from_ca_cert_pem(&cert_pem, key_pair)?;

// Create a new signed server certificate
Expand Down Expand Up @@ -66,8 +67,8 @@ fn main() -> Result<(), Box<dyn Error>> {
params.not_before = yesterday;
params.not_after = tomorrow;

let output_keys = KeyPair::generate()?;
let output_cert = params.signed_by(&output_keys, &signer)?;
let output_keys = KeyPair::generate(provider)?;
let output_cert = params.signed_by(&output_keys, &signer, provider)?;

// Write new certificate
fs::write(&output_keys_file, output_keys.serialize_pem())?;
Expand Down
5 changes: 3 additions & 2 deletions rcgen/examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::fs;
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName, DnType, KeyPair, SanType};

fn main() -> Result<(), Box<dyn std::error::Error>> {
let provider = rcgen::crypto::ring::default_provider();
let mut params: CertificateParams = Default::default();
params.not_before = date_time_ymd(1975, 1, 1);
params.not_after = date_time_ymd(4096, 1, 1);
Expand All @@ -18,8 +19,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
SanType::DnsName("localhost".try_into()?),
];

let key_pair = KeyPair::generate()?;
let cert = params.self_signed(&key_pair)?;
let key_pair = KeyPair::generate(provider)?;
let cert = params.self_signed(&key_pair, provider)?;

let pem_serialized = cert.pem();
let pem = pem::parse(&pem_serialized)?;
Expand Down
Loading
Loading