mirror of
https://github.com/NLnetLabs/krill.git
synced 2026-09-23 09:54:55 +02:00
Do not use AKI extension in RFC6492/8181 CMS embedded CRL.
This commit is contained in:
@@ -1,20 +1,20 @@
|
||||
//! Support for building RPKI Certificates and Objects
|
||||
use std::fmt;
|
||||
use bcder::encode::{Constructed, PrimitiveContent, Values};
|
||||
use bcder::{decode, encode};
|
||||
use bcder::{BitString, Mode, OctetString, Oid, Tag};
|
||||
use bytes::Bytes;
|
||||
use chrono::Utc;
|
||||
use rpki::cert::ext::{AuthorityKeyIdentifier, CrlNumber, Extensions, KeyIdentifier};
|
||||
use rpki::crl::Crl;
|
||||
use rpki::cert::ext::{CrlNumber, Extensions, KeyIdentifier};
|
||||
use rpki::crypto::signer::KeyError;
|
||||
use rpki::crypto::{
|
||||
DigestAlgorithm, PublicKey, Signature, SignatureAlgorithm, Signer, SigningError,
|
||||
};
|
||||
use rpki::oid;
|
||||
use rpki::x509::{Name, Time, Validity};
|
||||
use std::fmt;
|
||||
|
||||
use crate::remote::id::{IdCert, IdExtensions};
|
||||
use crate::remote::sigmsg::SigMsgCrl;
|
||||
|
||||
//------------ TbsCertificate ------------------------------------------------
|
||||
|
||||
@@ -225,7 +225,7 @@ pub struct SignedMessageBuilder {
|
||||
content: OctetString,
|
||||
signer_info: SignedSignerInfo,
|
||||
ee_cert: IdCert,
|
||||
crl: Crl,
|
||||
crl: SigMsgCrl,
|
||||
}
|
||||
|
||||
impl SignedMessageBuilder {
|
||||
@@ -240,7 +240,7 @@ impl SignedMessageBuilder {
|
||||
|
||||
let ee_cert = IdCertBuilder::new_ee_cert(issuing_key, signer_info.one_off_key(), signer)?;
|
||||
|
||||
let crl = CrlBuilder::create(issuing_key, signer)?;
|
||||
let crl = SigMsgCrlBuilder::create(issuing_key, signer)?;
|
||||
|
||||
Ok(SignedMessageBuilder {
|
||||
content,
|
||||
@@ -470,29 +470,22 @@ impl SignerInfoBuilder {
|
||||
|
||||
//------------ CrlBuilder ----------------------------------------------------
|
||||
|
||||
pub struct CrlBuilder;
|
||||
pub struct SigMsgCrlBuilder;
|
||||
|
||||
impl CrlBuilder {
|
||||
/// Creates a CRL for use with protocol messages. I.e. it revokes nothing,
|
||||
/// because smart people use single use keys for EE certs, and it's valid
|
||||
/// for, like, forever -- cause really this thing is useless. Still it is
|
||||
/// mandatory, so make one (1) and re-use it.
|
||||
///
|
||||
/// This will all be changed in future when we implement generating CRLs
|
||||
/// for the RPKI CA.
|
||||
pub fn create<S: Signer>(issuing_key: &S::KeyId, signer: &S) -> Result<Crl, Error<S::Error>> {
|
||||
impl SigMsgCrlBuilder {
|
||||
/// Creates a CRL for use with protocol messages. This revokes nothing,
|
||||
/// because we use single use keys for EE certs.
|
||||
pub fn create<S: Signer>(
|
||||
issuing_key: &S::KeyId,
|
||||
signer: &S,
|
||||
) -> Result<SigMsgCrl, Error<S::Error>> {
|
||||
let pub_key = signer.get_key_info(issuing_key)?;
|
||||
let name = Name::from_pub_key(&pub_key);
|
||||
let now = Time::new(Utc::now());
|
||||
let eternity = Time::new(Utc::now() + ::chrono::Duration::weeks(52000));
|
||||
let just_now = Time::new(Utc::now()) - ::chrono::Duration::minutes(5);
|
||||
let in_a_bit = Time::new(Utc::now() + ::chrono::Duration::minutes(5));
|
||||
|
||||
let crl_number = CrlNumber::new(1);
|
||||
let aki = AuthorityKeyIdentifier::new(&pub_key);
|
||||
|
||||
let extensions = Constructed::new(
|
||||
Tag::CTX_0,
|
||||
encode::sequence((aki.encode(), crl_number.encode())),
|
||||
);
|
||||
let extensions = Constructed::new(Tag::CTX_0, encode::sequence(crl_number.encode()));
|
||||
|
||||
let crl_data = encode::sequence((
|
||||
(
|
||||
@@ -501,8 +494,8 @@ impl CrlBuilder {
|
||||
name.encode_ref(),
|
||||
),
|
||||
(
|
||||
now.encode(),
|
||||
eternity.encode(),
|
||||
just_now.encode(),
|
||||
in_a_bit.encode(),
|
||||
// Real revocations go here
|
||||
extensions,
|
||||
),
|
||||
@@ -526,7 +519,7 @@ impl CrlBuilder {
|
||||
signature.encode(),
|
||||
));
|
||||
|
||||
let crl = Crl::decode(crl_obj.to_captured(Mode::Der).as_ref())?;
|
||||
let crl = SigMsgCrl::decode(crl_obj.to_captured(Mode::Der).as_ref())?;
|
||||
|
||||
Ok(crl)
|
||||
}
|
||||
@@ -602,7 +595,7 @@ pub mod tests {
|
||||
let key_id = s.create_key(&PublicKeyAlgorithm::RsaEncryption).unwrap();
|
||||
let key_info = s.get_key_info(&key_id).unwrap();
|
||||
|
||||
let crl = CrlBuilder::create(&key_id, &mut s).unwrap();
|
||||
let crl = SigMsgCrlBuilder::create(&key_id, &mut s).unwrap();
|
||||
crl.validate(&key_info).unwrap();
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
|
||||
use bytes::Bytes;
|
||||
|
||||
use bcder::decode;
|
||||
use bcder::string::OctetString;
|
||||
use bcder::{decode, encode, Captured};
|
||||
use bcder::{Mode, Oid, Tag};
|
||||
|
||||
use rpki::crypto::{DigestAlgorithm, KeyIdentifier, Signature, SignatureAlgorithm};
|
||||
use rpki::crypto::{DigestAlgorithm, KeyIdentifier, PublicKey, Signature, SignatureAlgorithm};
|
||||
use rpki::oid;
|
||||
use rpki::sigobj::{MessageDigest, SignedAttrs};
|
||||
use rpki::x509::{Time, ValidationError};
|
||||
use rpki::x509::{SignedData, Time, ValidationError};
|
||||
|
||||
use crate::remote::id::IdCert;
|
||||
|
||||
@@ -29,6 +29,7 @@ pub struct SignedMessage {
|
||||
content_type: Oid<Bytes>,
|
||||
content: OctetString,
|
||||
id_cert: IdCert,
|
||||
crl: SigMsgCrl,
|
||||
|
||||
//--- From SignerInfo
|
||||
//
|
||||
@@ -83,7 +84,7 @@ impl SignedMessage {
|
||||
|
||||
let id_cert = Self::take_certificates(cons)?;
|
||||
|
||||
let _whatever = Self::drop_crls(cons);
|
||||
let crl = Self::take_crl(cons)?;
|
||||
|
||||
let (sid, attrs, signature) = {
|
||||
// signerInfos
|
||||
@@ -116,6 +117,7 @@ impl SignedMessage {
|
||||
content_type,
|
||||
content,
|
||||
id_cert,
|
||||
crl,
|
||||
|
||||
sid,
|
||||
signed_attrs: attrs.0,
|
||||
@@ -144,18 +146,13 @@ impl SignedMessage {
|
||||
})
|
||||
}
|
||||
|
||||
// Drop the CRLs, if present.
|
||||
// Take the CRL, if present.
|
||||
//
|
||||
// The ones from DRL don't seem to parse, and their value is
|
||||
// is very limited.
|
||||
//
|
||||
// These CRLs only really protect if an operator use multi-use
|
||||
// keys for their EE certificates and is given some frequently
|
||||
// re-signed CRL by the CA cert for inclusion.. then if the EE
|
||||
// key is stolen you get a bit of protection.
|
||||
//
|
||||
fn drop_crls<S: decode::Source>(cons: &mut decode::Constructed<S>) -> Result<(), S::Err> {
|
||||
cons.take_constructed_if(Tag::CTX_1, |cons| cons.skip_all())
|
||||
// In theory there could be multiple CRLs, one for each CA certificate included in signing
|
||||
// this object. However, nobody seems to do this, and it's rather poorly defined how (and why)
|
||||
// this would be done. So.. just expecting 1 CRL here.
|
||||
fn take_crl<S: decode::Source>(cons: &mut decode::Constructed<S>) -> Result<SigMsgCrl, S::Err> {
|
||||
cons.take_constructed_if(Tag::CTX_1, |cons| SigMsgCrl::take_from(cons))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +194,54 @@ impl SignedMessage {
|
||||
}
|
||||
}
|
||||
|
||||
//------------ SigMsgCrl -----------------------------------------------------
|
||||
|
||||
/// An RPKI certificate revocation list used in RFC6492 and RFC8181 protocol signed
|
||||
/// messages.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SigMsgCrl {
|
||||
/// The outer structure of the CRL.
|
||||
signed_data: SignedData,
|
||||
}
|
||||
|
||||
/// # Decode, Validate, and Encode
|
||||
///
|
||||
impl SigMsgCrl {
|
||||
/// Parses a source as a certificate revocation list.
|
||||
pub fn decode<S: decode::Source>(source: S) -> Result<Self, S::Err> {
|
||||
Mode::Der.decode(source, Self::take_from)
|
||||
}
|
||||
|
||||
/// Takes an encoded CRL from the beginning of a constructed value.
|
||||
pub fn take_from<S: decode::Source>(cons: &mut decode::Constructed<S>) -> Result<Self, S::Err> {
|
||||
cons.take_sequence(Self::from_constructed)
|
||||
}
|
||||
|
||||
/// Parses the content of a certificate revocation list.
|
||||
pub fn from_constructed<S: decode::Source>(
|
||||
cons: &mut decode::Constructed<S>,
|
||||
) -> Result<Self, S::Err> {
|
||||
let signed_data = SignedData::from_constructed(cons)?;
|
||||
Ok(Self { signed_data })
|
||||
}
|
||||
|
||||
/// Validates the certificate revocation list.
|
||||
///
|
||||
/// The list’s signature is validated against the provided public key.
|
||||
pub fn validate(&self, public_key: &PublicKey) -> Result<(), ValidationError> {
|
||||
self.signed_data.verify_signature(public_key)
|
||||
}
|
||||
|
||||
pub fn encode_ref<'a>(&'a self) -> impl encode::Values + 'a {
|
||||
self.signed_data.encode_ref()
|
||||
}
|
||||
|
||||
/// Returns a captured encoding of the CRL.
|
||||
pub fn to_captured(&self) -> Captured {
|
||||
Captured::from_values(Mode::Der, self.encode_ref())
|
||||
}
|
||||
}
|
||||
|
||||
//------------ Tests ---------------------------------------------------------
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user