chore: update partial ssl.rs to rcgen

This commit is contained in:
DecDuck
2025-03-20 16:24:26 +11:00
parent 5313622341
commit 3209bcd01d
6 changed files with 168 additions and 185 deletions

View File

@ -15,6 +15,11 @@ use openssl::{
X509Builder, X509NameBuilder, X509ReqBuilder, X509StoreContext, X509,
},
};
use rcgen::{
Certificate, CertificateParams, DistinguishedName, ExtendedKeyUsagePurpose, Ia5String, IsCa,
KeyPair, KeyUsagePurpose, SanType, SerialNumber,
};
use time::{Duration, OffsetDateTime};
fn create_serial_number() -> Asn1Integer {
let mut serial = BigNum::new().unwrap();
@ -24,60 +29,33 @@ fn create_serial_number() -> Asn1Integer {
#[napi]
pub fn generate_root_ca() -> Result<Vec<String>, Error> {
let nid = Nid::X9_62_PRIME256V1;
let group = EcGroup::from_curve_name(nid).unwrap();
let private_key = EcKey::generate(&group).unwrap();
let mut params = CertificateParams::default();
let mut x509_builder = X509Builder::new().unwrap();
x509_builder.set_version(2).unwrap();
let mut name = DistinguishedName::new();
name.push(rcgen::DnType::CommonName, "Drop Root Server");
name.push(rcgen::DnType::OrganizationName, "Drop");
let serial_number = create_serial_number();
x509_builder.set_serial_number(&serial_number).unwrap();
params.distinguished_name = name;
let mut x509_name = X509NameBuilder::new().unwrap();
x509_name
.append_entry_by_nid(Nid::COMMONNAME, "Drop Root Server")
.unwrap();
x509_name
.append_entry_by_nid(Nid::ORGANIZATIONNAME, "Drop")
.unwrap();
let x509_name_built = x509_name.build();
x509_builder.set_subject_name(&x509_name_built).unwrap();
x509_builder.set_issuer_name(&x509_name_built).unwrap();
let not_before = Asn1Time::days_from_now(0).unwrap();
x509_builder.set_not_before(&not_before).unwrap();
let not_after = Asn1Time::days_from_now(365 * 1000).unwrap();
x509_builder.set_not_after(&not_after).unwrap();
x509_builder
.append_extension(BasicConstraints::new().critical().ca().build().unwrap())
.unwrap();
x509_builder
.append_extension(
KeyUsage::new()
.critical()
.key_cert_sign()
.crl_sign()
.digital_signature()
.build()
.unwrap(),
)
params.not_before = OffsetDateTime::now_utc();
params.not_after = OffsetDateTime::now_utc()
.checked_add(Duration::days(365 * 1000))
.unwrap();
let key_pair = PKey::from_ec_key(private_key).unwrap();
x509_builder.set_pubkey(&key_pair).unwrap();
params.is_ca = IsCa::Ca(rcgen::BasicConstraints::Unconstrained);
x509_builder
.sign(&key_pair, MessageDigest::sha256())
.unwrap();
params.key_usages = vec![
KeyUsagePurpose::CrlSign,
KeyUsagePurpose::KeyCertSign,
KeyUsagePurpose::DigitalSignature,
];
let x509 = x509_builder.build();
let key_pair = KeyPair::generate().map_err(|e| napi::Error::from_reason(e.to_string()))?;
let certificate = CertificateParams::self_signed(params, &key_pair)
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
Ok(vec![
String::from_utf8(x509.to_pem().unwrap()).unwrap(),
String::from_utf8(key_pair.private_key_to_pem_pkcs8().unwrap()).unwrap(),
])
// Returns certificate, then private key
Ok(vec![certificate.pem(), key_pair.serialize_pem()])
}
#[napi]
@ -87,94 +65,31 @@ pub fn generate_client_certificate(
root_ca: String,
root_ca_private: String,
) -> Result<Vec<String>, Error> {
let root_ca_cert = X509::from_pem(root_ca.as_bytes()).unwrap();
let root_ca_key = EcKey::private_key_from_pem(root_ca_private.as_bytes()).unwrap();
let root_ca_key_pair = PKey::from_ec_key(root_ca_key).unwrap();
let root_key_pair =
KeyPair::from_pem(&root_ca_private).map_err(|e| napi::Error::from_reason(e.to_string()))?;
let certificate_params = CertificateParams::from_ca_cert_pem(&root_ca)
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
let root_ca = CertificateParams::self_signed(certificate_params, &root_key_pair)
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
let nid = Nid::X9_62_PRIME256V1;
let group = EcGroup::from_curve_name(nid).unwrap();
let private_key = EcKey::generate(&group).unwrap();
let key_pair = PKey::from_ec_key(private_key).unwrap();
let mut params = CertificateParams::default();
/* Generate req and sign it */
let mut req_builder = X509ReqBuilder::new().unwrap();
req_builder.set_pubkey(&key_pair).unwrap();
let mut name = DistinguishedName::new();
name.push(rcgen::DnType::CommonName, client_id);
name.push(rcgen::DnType::OrganizationName, "Drop");
params.distinguished_name = name;
let mut x509_name = X509NameBuilder::new().unwrap();
x509_name
.append_entry_by_nid(Nid::COMMONNAME, &client_id)
.unwrap();
x509_name
.append_entry_by_nid(Nid::SUBJECT_ALT_NAME, &client_name)
.unwrap();
x509_name
.append_entry_by_nid(Nid::ORGANIZATIONNAME, "Drop")
.unwrap();
let x509_name_built = x509_name.build();
params.key_usages = vec![
KeyUsagePurpose::DigitalSignature,
KeyUsagePurpose::DataEncipherment,
];
req_builder.set_subject_name(&x509_name_built).unwrap();
req_builder
.sign(&key_pair, MessageDigest::sha256())
.unwrap();
let req = req_builder.build();
let key_pair = KeyPair::generate().map_err(|e| napi::Error::from_reason(e.to_string()))?;
let certificate = CertificateParams::signed_by(params, &key_pair, &root_ca, &root_key_pair)
.map_err(|e| napi::Error::from_reason(e.to_string()))?;
/* Generate certificate from req and sign it using CA */
let mut x509_builder = X509Builder::new().unwrap();
x509_builder.set_version(2).unwrap();
x509_builder.set_pubkey(&key_pair).unwrap();
let serial_number = create_serial_number();
x509_builder.set_serial_number(&serial_number).unwrap();
x509_builder.set_subject_name(req.subject_name()).unwrap();
x509_builder
.set_issuer_name(root_ca_cert.issuer_name())
.unwrap();
let not_before = Asn1Time::days_from_now(0).unwrap();
x509_builder.set_not_before(&not_before).unwrap();
let not_after = Asn1Time::days_from_now(365 * 100).unwrap();
x509_builder.set_not_after(&not_after).unwrap();
x509_builder
.append_extension(BasicConstraints::new().build().unwrap())
.unwrap();
x509_builder
.append_extension(
KeyUsage::new()
.critical()
.non_repudiation()
.digital_signature()
.data_encipherment()
.build()
.unwrap(),
)
.unwrap();
let subject_key_identifier = SubjectKeyIdentifier::new()
.build(&x509_builder.x509v3_context(Some(&root_ca_cert), None))
.unwrap();
x509_builder
.append_extension(subject_key_identifier)
.unwrap();
let auth_key_identifier = AuthorityKeyIdentifier::new()
.keyid(false)
.issuer(false)
.build(&x509_builder.x509v3_context(Some(&root_ca_cert), None))
.unwrap();
x509_builder.append_extension(auth_key_identifier).unwrap();
x509_builder
.sign(&root_ca_key_pair, MessageDigest::sha256())
.unwrap();
let x509 = x509_builder.build();
Ok(vec![
String::from_utf8(x509.to_pem().unwrap()).unwrap(),
String::from_utf8(key_pair.private_key_to_pem_pkcs8().unwrap()).unwrap(),
])
// Returns certificate, then private key
Ok(vec![certificate.pem(), key_pair.serialize_pem()])
}
#[napi]