in key/aziot-key-openssl-engine-shared-test/src/main.rs [194:289]
fn generate_cert(
key_handle: String,
out_file: &std::path::Path,
subject: &str,
kind: &GenerateCertKind,
) -> Result<(), Error> {
let mut engine = load_engine()?;
let mut builder = openssl::x509::X509::builder()?;
builder.set_version(2)?;
let public_key = load_public_key(&mut engine, key_handle.clone())?;
builder.set_pubkey(&public_key)?;
let not_after = openssl::asn1::Asn1Time::days_from_now(match &kind {
GenerateCertKind::Ca => 365,
GenerateCertKind::Client { .. } | GenerateCertKind::Server { .. } => 30,
})?;
builder.set_not_after(std::borrow::Borrow::borrow(¬_after))?;
let not_before = openssl::asn1::Asn1Time::days_from_now(0)?;
builder.set_not_before(std::borrow::Borrow::borrow(¬_before))?;
let mut subject_name = openssl::x509::X509Name::builder()?;
subject_name.append_entry_by_text("CN", subject)?;
let subject_name = subject_name.build();
builder.set_subject_name(&subject_name)?;
match &kind {
GenerateCertKind::Ca => {
builder.set_issuer_name(&subject_name)?;
let ca_extension = openssl::x509::extension::BasicConstraints::new()
.ca()
.build()?;
builder.append_extension(ca_extension)?;
}
GenerateCertKind::Client { ca_cert, .. } | GenerateCertKind::Server { ca_cert, .. } => {
let ca_cert = std::fs::read(ca_cert)?;
let ca_cert = openssl::x509::X509::from_pem(&ca_cert)?;
builder.set_issuer_name(ca_cert.subject_name())?;
match kind {
GenerateCertKind::Ca => unreachable!(),
GenerateCertKind::Client { .. } => {
let client_extension = openssl::x509::extension::ExtendedKeyUsage::new()
.client_auth()
.build()?;
builder.append_extension(client_extension)?;
}
GenerateCertKind::Server { .. } => {
let server_extension = openssl::x509::extension::ExtendedKeyUsage::new()
.server_auth()
.build()?;
builder.append_extension(server_extension)?;
let context = builder.x509v3_context(Some(&ca_cert), None);
let san_extension = openssl::x509::extension::SubjectAlternativeName::new()
.ip("127.0.0.1")
.build(&context)?;
builder.append_extension(san_extension)?;
}
}
}
}
let ca_key_handle = match &kind {
GenerateCertKind::Ca => key_handle,
GenerateCertKind::Client { ca_key_handle, .. }
| GenerateCertKind::Server { ca_key_handle, .. } => ca_key_handle.clone(),
};
let ca_key = load_private_key(&mut engine, ca_key_handle)?;
builder.sign(&ca_key, openssl::hash::MessageDigest::sha256())?;
let cert = builder.build();
let cert = cert.to_pem()?;
let mut out_file = std::fs::File::create(out_file)?;
std::io::Write::write_all(&mut out_file, &cert)?;
match &kind {
GenerateCertKind::Ca => (),
GenerateCertKind::Client { ca_cert, .. } | GenerateCertKind::Server { ca_cert, .. } => {
let ca_cert = std::fs::read(ca_cert)?;
std::io::Write::write_all(&mut out_file, &ca_cert)?;
}
}
std::io::Write::flush(&mut out_file)?;
Ok(())
}