Skip to content

Commit b491b28

Browse files
committed
Detach sign_der() from KeyPair
1 parent 67a73a7 commit b491b28

File tree

5 files changed

+67
-74
lines changed

5 files changed

+67
-74
lines changed

rcgen/src/certificate.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ use yasna::{DERWriter, Tag};
1010

1111
use crate::crl::CrlDistributionPoint;
1212
use crate::csr::CertificateSigningRequest;
13-
use crate::key_pair::{serialize_public_key_der, PublicKeyData};
13+
use crate::key_pair::{serialize_public_key_der, sign_der, PublicKeyData};
1414
#[cfg(feature = "crypto")]
1515
use crate::ring_like::digest;
1616
#[cfg(feature = "pem")]
1717
use crate::ENCODE_CONFIG;
1818
use crate::{
1919
oid, write_distinguished_name, write_dt_utc_or_generalized,
2020
write_x509_authority_key_identifier, write_x509_extension, DistinguishedName, Error, Issuer,
21-
KeyIdMethod, KeyPair, KeyUsagePurpose, SanType, SerialNumber,
21+
KeyIdMethod, KeyUsagePurpose, SanType, SerialNumber, SigningKey,
2222
};
2323

2424
/// An issued certificate together with the parameters used to generate it.
@@ -151,7 +151,7 @@ impl CertificateParams {
151151
self,
152152
public_key: &impl PublicKeyData,
153153
issuer: &Certificate,
154-
issuer_key: &KeyPair,
154+
issuer_key: &impl SigningKey,
155155
) -> Result<Certificate, Error> {
156156
let issuer = Issuer {
157157
distinguished_name: &issuer.params.distinguished_name,
@@ -168,7 +168,7 @@ impl CertificateParams {
168168
///
169169
/// The returned [`Certificate`] may be serialized using [`Certificate::der`] and
170170
/// [`Certificate::pem`].
171-
pub fn self_signed(self, key_pair: &KeyPair) -> Result<Certificate, Error> {
171+
pub fn self_signed(self, key_pair: &impl SigningKey) -> Result<Certificate, Error> {
172172
let issuer = Issuer {
173173
distinguished_name: &self.distinguished_name,
174174
key_identifier_method: &self.key_identifier_method,
@@ -531,7 +531,7 @@ impl CertificateParams {
531531
/// same output.
532532
pub fn serialize_request(
533533
&self,
534-
subject_key: &KeyPair,
534+
subject_key: &impl SigningKey,
535535
) -> Result<CertificateSigningRequest, Error> {
536536
self.serialize_request_with_attributes(subject_key, Vec::new())
537537
}
@@ -549,7 +549,7 @@ impl CertificateParams {
549549
/// [RFC 2986]: <https://datatracker.ietf.org/doc/html/rfc2986#section-4>
550550
pub fn serialize_request_with_attributes(
551551
&self,
552-
subject_key: &KeyPair,
552+
subject_key: &impl SigningKey,
553553
attrs: Vec<Attribute>,
554554
) -> Result<CertificateSigningRequest, Error> {
555555
// No .. pattern, we use this to ensure every field is used
@@ -597,7 +597,7 @@ impl CertificateParams {
597597
|| !extended_key_usages.is_empty()
598598
|| !custom_extensions.is_empty();
599599

600-
let der = subject_key.sign_der(|writer| {
600+
let der = sign_der(subject_key, |writer| {
601601
// Write version
602602
writer.next().write_u8(0);
603603
write_distinguished_name(writer.next(), distinguished_name);
@@ -633,9 +633,9 @@ impl CertificateParams {
633633
pub(crate) fn serialize_der_with_signer<K: PublicKeyData>(
634634
&self,
635635
pub_key: &K,
636-
issuer: Issuer<'_>,
636+
issuer: Issuer<'_, impl SigningKey>,
637637
) -> Result<CertificateDer<'static>, Error> {
638-
let der = issuer.key_pair.sign_der(|writer| {
638+
let der = sign_der(issuer.key_pair, |writer| {
639639
let pub_key_spki = pub_key.subject_public_key_info();
640640
// Write version
641641
writer.next().write_tagged(Tag::context(0), |writer| {
@@ -659,7 +659,7 @@ impl CertificateParams {
659659
}
660660
};
661661
// Write signature algorithm
662-
issuer.key_pair.alg.write_alg_ident(writer.next());
662+
issuer.key_pair.algorithm().write_alg_ident(writer.next());
663663
// Write issuer name
664664
write_distinguished_name(writer.next(), &issuer.distinguished_name);
665665
// Write validity
@@ -1223,6 +1223,8 @@ pub enum BasicConstraints {
12231223
mod tests {
12241224
#[cfg(feature = "pem")]
12251225
use super::*;
1226+
#[cfg(feature = "crypto")]
1227+
use crate::KeyPair;
12261228

12271229
#[cfg(feature = "crypto")]
12281230
#[test]

rcgen/src/crl.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ use time::OffsetDateTime;
55
use yasna::DERWriter;
66
use yasna::Tag;
77

8+
use crate::key_pair::sign_der;
89
#[cfg(feature = "pem")]
910
use crate::ENCODE_CONFIG;
1011
use crate::{
1112
oid, write_distinguished_name, write_dt_utc_or_generalized,
1213
write_x509_authority_key_identifier, write_x509_extension, Certificate, Error, Issuer,
13-
KeyIdMethod, KeyPair, KeyUsagePurpose, PublicKeyData, SerialNumber,
14+
KeyIdMethod, KeyUsagePurpose, SerialNumber, SigningKey,
1415
};
1516

1617
/// A certificate revocation list (CRL)
@@ -41,9 +42,7 @@ use crate::{
4142
/// #[cfg(feature = "crypto")]
4243
/// let key_pair = KeyPair::generate().unwrap();
4344
/// #[cfg(not(feature = "crypto"))]
44-
/// let remote_key_pair = MyKeyPair { public_key: vec![] };
45-
/// #[cfg(not(feature = "crypto"))]
46-
/// let key_pair = KeyPair::from_remote(Box::new(remote_key_pair)).unwrap();
45+
/// let key_pair = MyKeyPair { public_key: vec![] };
4746
/// let issuer = issuer_params.self_signed(&key_pair).unwrap();
4847
/// // Describe a revoked certificate.
4948
/// let revoked_cert = RevokedCertParams{
@@ -194,7 +193,7 @@ impl CertificateRevocationListParams {
194193
pub fn signed_by(
195194
self,
196195
issuer: &Certificate,
197-
issuer_key: &KeyPair,
196+
issuer_key: &impl SigningKey,
198197
) -> Result<CertificateRevocationList, Error> {
199198
if self.next_update.le(&self.this_update) {
200199
return Err(Error::InvalidCrlNextUpdate);
@@ -217,8 +216,8 @@ impl CertificateRevocationListParams {
217216
})
218217
}
219218

220-
fn serialize_der(&self, issuer: Issuer) -> Result<Vec<u8>, Error> {
221-
issuer.key_pair.sign_der(|writer| {
219+
fn serialize_der(&self, issuer: Issuer<'_, impl SigningKey>) -> Result<Vec<u8>, Error> {
220+
sign_der(issuer.key_pair, |writer| {
222221
// Write CRL version.
223222
// RFC 5280 §5.1.2.1:
224223
// This optional field describes the version of the encoded CRL. When
@@ -234,7 +233,7 @@ impl CertificateRevocationListParams {
234233
// RFC 5280 §5.1.2.2:
235234
// This field MUST contain the same algorithm identifier as the
236235
// signatureAlgorithm field in the sequence CertificateList
237-
issuer.key_pair.alg.write_alg_ident(writer.next());
236+
issuer.key_pair.algorithm().write_alg_ident(writer.next());
238237

239238
// Write issuer.
240239
// RFC 5280 §5.1.2.3:

rcgen/src/csr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use pki_types::CertificateSigningRequestDer;
77
#[cfg(feature = "pem")]
88
use crate::ENCODE_CONFIG;
99
use crate::{
10-
Certificate, CertificateParams, Error, Issuer, KeyPair, PublicKeyData, SignatureAlgorithm,
10+
Certificate, CertificateParams, Error, Issuer, PublicKeyData, SignatureAlgorithm, SigningKey,
1111
};
1212
#[cfg(feature = "x509-parser")]
1313
use crate::{DistinguishedName, SanType};
@@ -203,7 +203,7 @@ impl CertificateSigningRequestParams {
203203
pub fn signed_by(
204204
self,
205205
issuer: &Certificate,
206-
issuer_key: &KeyPair,
206+
issuer_key: &impl SigningKey,
207207
) -> Result<Certificate, Error> {
208208
let issuer = Issuer {
209209
distinguished_name: &issuer.params.distinguished_name,

rcgen/src/key_pair.rs

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -408,58 +408,6 @@ impl KeyPair {
408408
std::iter::once(self.alg)
409409
}
410410

411-
pub(crate) fn sign_der(
412-
&self,
413-
f: impl FnOnce(&mut DERWriterSeq<'_>) -> Result<(), Error>,
414-
) -> Result<Vec<u8>, Error> {
415-
yasna::try_construct_der(|writer| {
416-
writer.write_sequence(|writer| {
417-
let data = yasna::try_construct_der(|writer| writer.write_sequence(f))?;
418-
writer.next().write_der(&data);
419-
420-
// Write signatureAlgorithm
421-
self.alg.write_alg_ident(writer.next());
422-
423-
// Write signature
424-
self.sign(&data, writer.next())?;
425-
426-
Ok(())
427-
})
428-
})
429-
}
430-
431-
pub(crate) fn sign(&self, msg: &[u8], writer: DERWriter) -> Result<(), Error> {
432-
match &self.kind {
433-
#[cfg(feature = "crypto")]
434-
KeyPairKind::Ec(kp) => {
435-
let system_random = SystemRandom::new();
436-
let signature = kp.sign(&system_random, msg)._err()?;
437-
let sig = &signature.as_ref();
438-
writer.write_bitvec_bytes(sig, &sig.len() * 8);
439-
},
440-
#[cfg(feature = "crypto")]
441-
KeyPairKind::Ed(kp) => {
442-
let signature = kp.sign(msg);
443-
let sig = &signature.as_ref();
444-
writer.write_bitvec_bytes(sig, &sig.len() * 8);
445-
},
446-
#[cfg(feature = "crypto")]
447-
KeyPairKind::Rsa(kp, padding_alg) => {
448-
let system_random = SystemRandom::new();
449-
let mut signature = vec![0; rsa_key_pair_public_modulus_len(kp)];
450-
kp.sign(*padding_alg, &system_random, msg, &mut signature)
451-
._err()?;
452-
let sig = &signature.as_ref();
453-
writer.write_bitvec_bytes(sig, &sig.len() * 8);
454-
},
455-
KeyPairKind::Remote(kp) => {
456-
let signature = kp.sign(msg)?;
457-
writer.write_bitvec_bytes(&signature, &signature.len() * 8);
458-
},
459-
}
460-
Ok(())
461-
}
462-
463411
/// Return the key pair's public key in PEM format
464412
///
465413
/// The returned string can be interpreted with `openssl pkey --inform PEM -pubout -pubin -text`
@@ -514,6 +462,28 @@ impl KeyPair {
514462
}
515463
}
516464

465+
#[cfg(feature = "crypto")]
466+
impl SigningKey for KeyPair {
467+
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, Error> {
468+
Ok(match &self.kind {
469+
KeyPairKind::Ec(kp) => {
470+
let system_random = SystemRandom::new();
471+
let signature = kp.sign(&system_random, msg)._err()?;
472+
signature.as_ref().to_owned()
473+
},
474+
KeyPairKind::Ed(kp) => kp.sign(msg).as_ref().to_owned(),
475+
KeyPairKind::Rsa(kp, padding_alg) => {
476+
let system_random = SystemRandom::new();
477+
let mut signature = vec![0; rsa_key_pair_public_modulus_len(kp)];
478+
kp.sign(*padding_alg, &system_random, msg, &mut signature)
479+
._err()?;
480+
signature
481+
},
482+
KeyPairKind::Remote(kp) => kp.sign(msg)?,
483+
})
484+
}
485+
}
486+
517487
impl PublicKeyData for KeyPair {
518488
fn der_bytes(&self) -> &[u8] {
519489
match &self.kind {
@@ -654,6 +624,28 @@ pub enum RsaKeySize {
654624
_4096,
655625
}
656626

627+
pub(crate) fn sign_der(
628+
key: &impl SigningKey,
629+
f: impl FnOnce(&mut DERWriterSeq<'_>) -> Result<(), Error>,
630+
) -> Result<Vec<u8>, Error> {
631+
yasna::try_construct_der(|writer| {
632+
writer.write_sequence(|writer| {
633+
let data = yasna::try_construct_der(|writer| writer.write_sequence(f))?;
634+
writer.next().write_der(&data);
635+
636+
// Write signatureAlgorithm
637+
key.algorithm().write_alg_ident(writer.next());
638+
639+
// Write signature
640+
let sig = key.sign(&data)?;
641+
let writer = writer.next();
642+
writer.write_bitvec_bytes(&sig, sig.len() * 8);
643+
644+
Ok(())
645+
})
646+
})
647+
}
648+
657649
/// A key that can be used to sign messages
658650
///
659651
/// Trait objects based on this trait can be passed to the [`KeyPair::from_remote`] function for generating certificates

rcgen/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ pub fn generate_simple_self_signed(
130130
Ok(CertifiedKey { cert, key_pair })
131131
}
132132

133-
struct Issuer<'a> {
133+
struct Issuer<'a, S> {
134134
distinguished_name: &'a DistinguishedName,
135135
key_identifier_method: &'a KeyIdMethod,
136136
key_usages: &'a [KeyUsagePurpose],
137-
key_pair: &'a KeyPair,
137+
key_pair: &'a S,
138138
}
139139

140140
// https://tools.ietf.org/html/rfc5280#section-4.1.1

0 commit comments

Comments
 (0)