Improve self-signed certificates (#207)

Adds support for:
- A hierarchical SubjectName field.
- Certificate extensions.
This commit is contained in:
str4d
2021-01-12 04:49:15 +13:00
committed by GitHub
parent 90bc878b21
commit 24b035008c
4 changed files with 27 additions and 10 deletions
+20 -6
View File
@@ -49,6 +49,7 @@ use sha2::{Digest, Sha256};
use std::convert::TryFrom;
use std::fmt;
use std::ops::DerefMut;
use x509::{der::Oid, RelativeDistinguishedName};
use x509_parser::{parse_x509_certificate, x509::SubjectPublicKeyInfo};
use zeroize::Zeroizing;
@@ -337,19 +338,21 @@ impl<'a> TryFrom<&'a [u8]> for Certificate {
impl Certificate {
/// Creates a new self-signed certificate for the given key. Writes the resulting
/// certificate to the slot before returning it.
pub fn generate_self_signed(
///
/// `extensions` is optional; if empty, no extensions will be included. Due to the
/// need for an `O: Oid` type parameter, users who do not have any extensions should
/// use the workaround `let extensions: &[x509::Extension<'_, &[u64]>] = &[];`.
pub fn generate_self_signed<O: Oid>(
yubikey: &mut YubiKey,
key: SlotId,
serial: impl Into<Serial>,
not_after: Option<DateTime<Utc>>,
subject: String,
subject: &[RelativeDistinguishedName<'_>],
subject_pki: PublicKeyInfo,
extensions: &[x509::Extension<'_, O>],
) -> Result<Self, Error> {
let serial = serial.into();
// Issuer and subject are the same in self-signed certificates
let issuer = subject.clone();
let mut tbs_cert = Buffer::new(Vec::with_capacity(CB_OBJ_MAX));
let signature_algorithm = match subject_pki.algorithm() {
@@ -361,11 +364,13 @@ impl Certificate {
x509::write::tbs_certificate(
&serial.to_bytes(),
&signature_algorithm,
&issuer,
// Issuer and subject are the same in self-signed certificates.
&subject,
Utc::now(),
not_after,
&subject,
&subject_pki,
&extensions,
),
tbs_cert.deref_mut(),
)
@@ -425,6 +430,15 @@ impl Certificate {
)
.expect("can serialize to Vec");
let (issuer, subject) = parse_x509_certificate(&data)
.map(|(_, cert)| {
(
cert.tbs_certificate.issuer.to_string(),
cert.tbs_certificate.subject.to_string(),
)
})
.expect("We just serialized this correctly");
let cert = Certificate {
serial,
issuer,