Do not use AKI extension in RFC6492/8181 CMS embedded CRL.

This commit is contained in:
Tim Bruijnzeels
2019-08-05 12:33:50 +02:00
parent 24b038d7ff
commit 21baec11ea
2 changed files with 80 additions and 42 deletions
+20 -27
View File
@@ -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();
})
}
+60 -15
View File
@@ -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 lists 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)]