You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

rcgen

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rcgen - cargo Package Compare versions

Comparing version
0.14.5
to
0.14.6
+82
examples/sign-leaf-with-pem-files.rs
//! Generate a new certificate, and sign it with an existing root or
//! intermediate certificate.
//!
//! Requires four positional command line arguments:
//! * File path to PEM containing signer's key pair
//! * File path to PEM containing signer's certificate
//! * File path for generated PEM containing output key pair
//! * File path for generated PEM containing output certificate
use std::error::Error;
use std::fs;
use std::path::PathBuf;
use rcgen::{CertificateParams, DnType, ExtendedKeyUsagePurpose, Issuer, KeyPair, KeyUsagePurpose};
use time::{Duration, OffsetDateTime};
fn main() -> Result<(), Box<dyn Error>> {
let mut args = std::env::args().skip(1);
let signer_keys_file = PathBuf::from(
args.next()
.ok_or("provide signer's pem keys file as 1st argument")?,
);
let signer_cert_file = PathBuf::from(
args.next()
.ok_or("provide signer's pem certificate file as 2nd argument")?,
);
let output_keys_file =
PathBuf::from(args.next().ok_or("output pem keys file as 3rd argument")?);
let output_cert_file = PathBuf::from(args.next().ok_or("output pem cert file as 4th fourth")?);
// Read existing certificate authority
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 signer = Issuer::from_ca_cert_pem(&cert_pem, key_pair)?;
// Create a new signed server certificate
const DOMAIN: &str = "example.domain";
let sans = vec![DOMAIN.into()];
let mut params = CertificateParams::new(sans)?;
params.distinguished_name.push(DnType::CommonName, DOMAIN);
params.use_authority_key_identifier_extension = true;
params.key_usages.push(KeyUsagePurpose::DigitalSignature);
params
.extended_key_usages
.push(ExtendedKeyUsagePurpose::ServerAuth);
const DAY: Duration = Duration::days(1);
let yesterday = OffsetDateTime::now_utc()
.checked_sub(DAY)
.ok_or("invalid yesterday")?;
let tomorrow = OffsetDateTime::now_utc()
.checked_add(DAY)
.ok_or("invalid tomorrow")?;
params.not_before = yesterday;
params.not_after = tomorrow;
let output_keys = KeyPair::generate()?;
let output_cert = params.signed_by(&output_keys, &signer)?;
// Write new certificate
fs::write(&output_keys_file, output_keys.serialize_pem())?;
fs::write(&output_cert_file, output_cert.pem())?;
println!("Wrote signed leaf certificate:");
println!(" keys: {}", output_keys_file.display());
println!(" cert: {}", output_cert_file.display());
println!();
Ok(())
}
+1
-1
{
"git": {
"sha1": "957a3d80d90bac59123b664808a31727b2a8e767"
"sha1": "5693362c2ecc8ac8315e48caa1facb18c76574db"
},
"path_in_vcs": "rcgen"
}

@@ -81,2 +81,3 @@ # This file is automatically @generated by Cargo.

"aws-lc-sys",
"untrusted 0.7.1",
"zeroize",

@@ -532,3 +533,3 @@ ]

name = "rcgen"
version = "0.14.5"
version = "0.14.6"
dependencies = [

@@ -585,3 +586,3 @@ "aws-lc-rs",

"libc",
"untrusted",
"untrusted 0.9.0",
"windows-sys 0.52.0",

@@ -734,2 +735,8 @@ ]

name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "untrusted"
version = "0.9.0"

@@ -943,2 +950,3 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

"asn1-rs",
"aws-lc-rs",
"data-encoding",

@@ -945,0 +953,0 @@ "der-parser",

@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "rcgen"
version = "0.14.5"
version = "0.14.6"
build = false

@@ -36,3 +36,13 @@ autolib = false

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

@@ -51,2 +61,3 @@ [package.metadata.cargo_check_external_types]

"aws-lc-rs/aws-lc-sys",
"x509-parser?/verify-aws",
]

@@ -56,2 +67,3 @@ aws_lc_rs_unstable = [

"aws-lc-rs/unstable",
"x509-parser?/verify-aws",
]

@@ -72,2 +84,3 @@ crypto = []

"dep:ring",
"x509-parser?/verify",
]

@@ -93,2 +106,10 @@

[[example]]
name = "sign-leaf-with-pem-files"
path = "examples/sign-leaf-with-pem-files.rs"
required-features = [
"pem",
"x509-parser",
]
[[example]]
name = "simple"

@@ -124,3 +145,2 @@ path = "examples/simple.rs"

version = "0.18"
features = ["verify"]
optional = true

@@ -141,1 +161,6 @@

version = "0.10"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ["cfg(rcgen_docsrs)"]
#[cfg(unix)]
fn main() -> Result<(), Box<dyn std::error::Error>> {
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName};
use std::fmt::Write;
use std::fs;
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName};
let mut params: CertificateParams = Default::default();

@@ -8,0 +9,0 @@ params.not_before = date_time_ymd(2021, 5, 19);

@@ -0,4 +1,5 @@

use rcgen::DnValue::PrintableString;
use rcgen::{
BasicConstraints, Certificate, CertificateParams, DnType, DnValue::PrintableString,
ExtendedKeyUsagePurpose, IsCa, Issuer, KeyPair, KeyUsagePurpose,
BasicConstraints, Certificate, CertificateParams, DnType, ExtendedKeyUsagePurpose, IsCa,
Issuer, KeyPair, KeyUsagePurpose,
};

@@ -5,0 +6,0 @@ use time::{Duration, OffsetDateTime};

@@ -1,4 +0,5 @@

use rcgen::{date_time_ymd, CertificateParams, DistinguishedName, DnType, KeyPair, SanType};
use std::fs;
use rcgen::{date_time_ymd, CertificateParams, DistinguishedName, DnType, KeyPair, SanType};
fn main() -> Result<(), Box<dyn std::error::Error>> {

@@ -5,0 +6,0 @@ let mut params: CertificateParams = Default::default();

@@ -5,4 +5,3 @@ #[cfg(feature = "pem")]

use time::OffsetDateTime;
use yasna::DERWriter;
use yasna::Tag;
use yasna::{DERWriter, Tag};

@@ -9,0 +8,0 @@ use crate::key_pair::sign_der;

@@ -13,3 +13,3 @@ use std::hash::Hash;

#[cfg(feature = "x509-parser")]
use crate::{DistinguishedName, SanType};
use crate::{DistinguishedName, ExtendedKeyUsagePurpose, KeyUsagePurpose, SanType};

@@ -79,3 +79,3 @@ /// A public key, extracted from a CSR

impl CertificateSigningRequestParams {
/// Parse a certificate signing request from the ASCII PEM format
/// Parse and verify a certificate signing request from the ASCII PEM format
///

@@ -89,15 +89,20 @@ /// See [`from_der`](Self::from_der) for more details.

/// Parse a certificate signing request from DER-encoded bytes
/// Parse and verify a certificate signing request from DER-encoded bytes
///
/// Currently, this only supports the `Subject Alternative Name` extension.
/// On encountering other extensions, this function will return an error.
/// Currently, this supports the following extensions:
/// - `Subject Alternative Name` (see [`SanType`])
/// - `Key Usage` (see [`KeyUsagePurpose`])
/// - `Extended Key Usage` (see [`ExtendedKeyUsagePurpose`])
///
/// [`rustls_pemfile::csr()`] is often used to obtain a [`CertificateSigningRequestDer`] from
/// On encountering other extensions, this function will return [`Error::UnsupportedExtension`].
/// If the request's signature is invalid, it will return
/// [`Error::InvalidCertificationRequestSignature`].
///
/// The [`PemObject`] trait is often used to obtain a [`CertificateSigningRequestDer`] from
/// PEM input. If you already have a byte slice containing DER, it can trivially be converted
/// into [`CertificateSigningRequestDer`] using the [`Into`] trait.
///
/// [`rustls_pemfile::csr()`]: https://docs.rs/rustls-pemfile/latest/rustls_pemfile/fn.csr.html
/// [`PemObject`]: pki_types::pem::PemObject
#[cfg(feature = "x509-parser")]
pub fn from_der(csr: &CertificateSigningRequestDer<'_>) -> Result<Self, Error> {
use crate::KeyUsagePurpose;
use x509_parser::prelude::FromDer;

@@ -108,3 +113,4 @@

.1;
csr.verify_signature().map_err(|_| Error::RingUnspecified)?;
csr.verify_signature()
.map_err(|_| Error::InvalidCertificationRequestSignature)?;
let alg_oid = csr

@@ -142,33 +148,23 @@ .signature_algorithm

if eku.any {
params.insert_extended_key_usage(crate::ExtendedKeyUsagePurpose::Any);
params.insert_extended_key_usage(ExtendedKeyUsagePurpose::Any);
}
if eku.server_auth {
params.insert_extended_key_usage(
crate::ExtendedKeyUsagePurpose::ServerAuth,
);
params.insert_extended_key_usage(ExtendedKeyUsagePurpose::ServerAuth);
}
if eku.client_auth {
params.insert_extended_key_usage(
crate::ExtendedKeyUsagePurpose::ClientAuth,
);
params.insert_extended_key_usage(ExtendedKeyUsagePurpose::ClientAuth);
}
if eku.code_signing {
params.insert_extended_key_usage(
crate::ExtendedKeyUsagePurpose::CodeSigning,
);
params.insert_extended_key_usage(ExtendedKeyUsagePurpose::CodeSigning);
}
if eku.email_protection {
params.insert_extended_key_usage(
crate::ExtendedKeyUsagePurpose::EmailProtection,
ExtendedKeyUsagePurpose::EmailProtection,
);
}
if eku.time_stamping {
params.insert_extended_key_usage(
crate::ExtendedKeyUsagePurpose::TimeStamping,
);
params.insert_extended_key_usage(ExtendedKeyUsagePurpose::TimeStamping);
}
if eku.ocsp_signing {
params.insert_extended_key_usage(
crate::ExtendedKeyUsagePurpose::OcspSigning,
);
params.insert_extended_key_usage(ExtendedKeyUsagePurpose::OcspSigning);
}

@@ -186,3 +182,2 @@ if !eku.other.is_empty() {

// * is_ca
// * extended_key_usages
// * name_constraints

@@ -220,6 +215,7 @@ // and any other extensions.

mod tests {
use crate::{CertificateParams, ExtendedKeyUsagePurpose, KeyPair, KeyUsagePurpose};
use x509_parser::certification_request::X509CertificationRequest;
use x509_parser::prelude::{FromDer, ParsedExtension};
use crate::{CertificateParams, ExtendedKeyUsagePurpose, KeyPair, KeyUsagePurpose};
#[test]

@@ -226,0 +222,0 @@ fn dont_write_sans_extension_if_no_sans_are_present() {

@@ -13,3 +13,6 @@ use std::fmt;

CouldNotParseKeyPair,
/// The CSR signature is invalid
#[cfg(feature = "x509-parser")]
InvalidCertificationRequestSignature,
#[cfg(feature = "x509-parser")]
/// Invalid subject alternative name type

@@ -66,2 +69,4 @@ InvalidNameType,

#[cfg(feature = "x509-parser")]
InvalidCertificationRequestSignature => write!(f, "Invalid CSR signature")?,
#[cfg(feature = "x509-parser")]
InvalidNameType => write!(f, "Invalid subject alternative name type")?,

@@ -68,0 +73,0 @@ InvalidAsn1String(e) => write!(f, "{e}")?,

#[cfg(feature = "crypto")]
use std::fmt;
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
use aws_lc_rs::unstable::signature::PqdsaKeyPair;
#[cfg(feature = "pem")]

@@ -25,9 +27,8 @@ use pem::Pem;

};
use crate::sign_algo::SignatureAlgorithm;
#[cfg(feature = "crypto")]
use crate::sign_algo::{algo::*, SignAlgo};
use crate::Error;
#[cfg(feature = "pem")]
use crate::ENCODE_CONFIG;
use crate::{sign_algo::SignatureAlgorithm, Error};
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
use aws_lc_rs::unstable::signature::PqdsaKeyPair;

@@ -683,6 +684,4 @@ /// A key pair variant

pub fn from_der(spki_der: &[u8]) -> Result<Self, Error> {
use x509_parser::{
prelude::FromDer,
x509::{AlgorithmIdentifier, SubjectPublicKeyInfo},
};
use x509_parser::prelude::FromDer;
use x509_parser::x509::{AlgorithmIdentifier, SubjectPublicKeyInfo};

@@ -767,8 +766,5 @@ let (rem, spki) =

use super::*;
use crate::ring_like::rand::SystemRandom;
use crate::ring_like::signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING};
use crate::ring_like::{
rand::SystemRandom,
signature::{EcdsaKeyPair, ECDSA_P256_SHA256_FIXED_SIGNING},
};
#[cfg(all(feature = "x509-parser", feature = "pem"))]

@@ -775,0 +771,0 @@ #[test]

@@ -32,3 +32,3 @@ /*!

#![deny(missing_docs)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#![cfg_attr(rcgen_docsrs, feature(doc_cfg))]
#![warn(unreachable_pub)]

@@ -45,14 +45,2 @@

#[cfg(feature = "pem")]
use pem::Pem;
use pki_types::CertificateDer;
use time::{OffsetDateTime, Time};
use yasna::models::ObjectIdentifier;
use yasna::models::{GeneralizedTime, UTCTime};
use yasna::tags::{TAG_BMPSTRING, TAG_TELETEXSTRING, TAG_UNIVERSALSTRING};
use yasna::DERWriter;
use yasna::Tag;
use crate::string::{BmpString, Ia5String, PrintableString, TeletexString, UniversalString};
pub use certificate::{

@@ -70,6 +58,8 @@ date_time_ymd, Attribute, BasicConstraints, Certificate, CertificateParams, CidrSubnet,

pub use key_pair::KeyPair;
pub use key_pair::PublicKeyData;
#[cfg(all(feature = "crypto", feature = "aws_lc_rs"))]
pub use key_pair::RsaKeySize;
pub use key_pair::{SigningKey, SubjectPublicKeyInfo};
pub use key_pair::{PublicKeyData, SigningKey, SubjectPublicKeyInfo};
#[cfg(feature = "pem")]
use pem::Pem;
use pki_types::CertificateDer;
#[cfg(feature = "crypto")]

@@ -79,3 +69,9 @@ use ring_like::digest;

pub use sign_algo::SignatureAlgorithm;
use time::{OffsetDateTime, Time};
use yasna::models::{GeneralizedTime, ObjectIdentifier, UTCTime};
use yasna::tags::{TAG_BMPSTRING, TAG_TELETEXSTRING, TAG_UNIVERSALSTRING};
use yasna::{DERWriter, Tag};
use crate::string::{BmpString, Ia5String, PrintableString, TeletexString, UniversalString};
mod certificate;

@@ -994,6 +990,6 @@ mod crl;

mod test_ip_address_from_octets {
use super::super::ip_addr_from_octets;
use super::super::Error;
use std::net::IpAddr;
use super::super::{ip_addr_from_octets, Error};
#[test]

@@ -1043,6 +1039,8 @@ fn ipv4() {

mod test_san_type_from_general_name {
use crate::SanType;
use std::net::IpAddr;
use x509_parser::extensions::GeneralName;
use crate::SanType;
#[test]

@@ -1049,0 +1047,0 @@ fn with_ipv4() {

use std::fmt;
use std::hash::{Hash, Hasher};
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
use aws_lc_rs::unstable::signature::{
PqdsaSigningAlgorithm, ML_DSA_44_SIGNING, ML_DSA_65_SIGNING, ML_DSA_87_SIGNING,
};
use yasna::models::ObjectIdentifier;
use yasna::DERWriter;
use yasna::Tag;
use yasna::{DERWriter, Tag};

@@ -11,6 +14,2 @@ #[cfg(feature = "crypto")]

use crate::Error;
#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
use aws_lc_rs::unstable::signature::{
PqdsaSigningAlgorithm, ML_DSA_44_SIGNING, ML_DSA_65_SIGNING, ML_DSA_87_SIGNING,
};

@@ -123,6 +122,5 @@ #[cfg(feature = "crypto")]

pub(crate) mod algo {
use super::*;
use crate::oid::*;
use super::*;
/// RSA signing with PKCS#1 1.5 padding and SHA-256 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055)

@@ -129,0 +127,0 @@ pub static PKCS_RSA_SHA256: SignatureAlgorithm = SignatureAlgorithm {

//! ASN.1 string types
use std::{fmt, str::FromStr};
use std::fmt;
use std::str::FromStr;

@@ -581,3 +582,3 @@ use crate::{Error, InvalidAsn1String};

// (https://www.unicode.org/reports/tr19/tr19-9.html#Introduction)
// So any `char` is a valid UTF-32, we just cast it to perform the convertion.
// So any `char` is a valid UTF-32, we just cast it to perform the conversion.
for char in value.chars().map(|char| char as u32) {

@@ -584,0 +585,0 @@ bytes.extend(char.to_be_bytes())

Sorry, the diff of this file is not supported yet