File: sign-leaf-with-ca.rs

package info (click to toggle)
rust-rcgen 0.14.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 440 kB
  • sloc: makefile: 2
file content (65 lines) | stat: -rw-r--r-- 2,297 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use rcgen::{
	BasicConstraints, Certificate, CertificateParams, DnType, DnValue::PrintableString,
	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 end_entity_pem = end_entity.pem();
	println!("directly signed end-entity certificate: {end_entity_pem}");

	let ca_cert_pem = ca.pem();
	println!("ca certificate: {ca_cert_pem}");
}

fn new_ca() -> (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();
	params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
	params.distinguished_name.push(
		DnType::CountryName,
		PrintableString("BR".try_into().unwrap()),
	);
	params
		.distinguished_name
		.push(DnType::OrganizationName, "Crab widgits SE");
	params.key_usages.push(KeyUsagePurpose::DigitalSignature);
	params.key_usages.push(KeyUsagePurpose::KeyCertSign);
	params.key_usages.push(KeyUsagePurpose::CrlSign);

	params.not_before = yesterday;
	params.not_after = tomorrow;

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

fn new_end_entity(issuer: &Issuer<'static, KeyPair>) -> 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();
	params.distinguished_name.push(DnType::CommonName, name);
	params.use_authority_key_identifier_extension = true;
	params.key_usages.push(KeyUsagePurpose::DigitalSignature);
	params
		.extended_key_usages
		.push(ExtendedKeyUsagePurpose::ServerAuth);
	params.not_before = yesterday;
	params.not_after = tomorrow;

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

fn validity_period() -> (OffsetDateTime, OffsetDateTime) {
	let day = Duration::new(86400, 0);
	let yesterday = OffsetDateTime::now_utc().checked_sub(day).unwrap();
	let tomorrow = OffsetDateTime::now_utc().checked_add(day).unwrap();
	(yesterday, tomorrow)
}