20260410 完成五个rir 基于cir的三方回放,raw by hash 独立db,发现内存占用大,连续大rir 录制发生oom
This commit is contained in:
@@ -3,12 +3,9 @@ use crate::data_model::oid::{
|
||||
};
|
||||
use crate::data_model::rc::{
|
||||
AsIdOrRange, AsIdentifierChoice, ResourceCertKind, ResourceCertificate,
|
||||
ResourceCertificateParseError, ResourceCertificateParsed,
|
||||
ResourceCertificateProfileError,
|
||||
};
|
||||
use crate::validation::cert_path::{
|
||||
CertPathError, validate_ee_cert_path_with_predecoded_ee,
|
||||
ResourceCertificateParseError, ResourceCertificateParsed, ResourceCertificateProfileError,
|
||||
};
|
||||
use crate::validation::cert_path::{CertPathError, validate_ee_cert_path_with_predecoded_ee};
|
||||
use x509_parser::extensions::ParsedExtension;
|
||||
use x509_parser::prelude::{FromDer, X509Certificate};
|
||||
use x509_parser::public_key::PublicKey;
|
||||
@@ -33,7 +30,7 @@ pub enum BgpsecRouterCertificateParseError {
|
||||
#[error("resource certificate parse error: {0} (RFC 5280 §4.1; RFC 6487 §4; RFC 8209 §3.1)")]
|
||||
ResourceCertificate(#[from] ResourceCertificateParseError),
|
||||
|
||||
#[error("X.509 parse error: {0} (RFC 5280 §4.1; RFC 8209 §3.1)" )]
|
||||
#[error("X.509 parse error: {0} (RFC 5280 §4.1; RFC 8209 §3.1)")]
|
||||
X509(String),
|
||||
|
||||
#[error("trailing bytes after router certificate DER: {0} bytes (DER; RFC 5280 §4.1)")]
|
||||
@@ -54,46 +51,72 @@ pub enum BgpsecRouterCertificateProfileError {
|
||||
#[error("BGPsec router certificate must be an EE certificate (RFC 8209 §3.1)")]
|
||||
NotEe,
|
||||
|
||||
#[error("BGPsec router certificate must contain SubjectKeyIdentifier (RFC 6487 §4.8.2; RFC 8209 §3.3)")]
|
||||
#[error(
|
||||
"BGPsec router certificate must contain SubjectKeyIdentifier (RFC 6487 §4.8.2; RFC 8209 §3.3)"
|
||||
)]
|
||||
MissingSki,
|
||||
|
||||
#[error("BGPsec router certificate must include ExtendedKeyUsage (RFC 8209 §3.1.3.2; RFC 8209 §3.3)")]
|
||||
#[error(
|
||||
"BGPsec router certificate must include ExtendedKeyUsage (RFC 8209 §3.1.3.2; RFC 8209 §3.3)"
|
||||
)]
|
||||
MissingExtendedKeyUsage,
|
||||
|
||||
#[error("BGPsec router certificate ExtendedKeyUsage must be non-critical (RFC 6487 §4.8.4; RFC 8209 §3.1.3.2)")]
|
||||
#[error(
|
||||
"BGPsec router certificate ExtendedKeyUsage must be non-critical (RFC 6487 §4.8.4; RFC 8209 §3.1.3.2)"
|
||||
)]
|
||||
ExtendedKeyUsageCriticality,
|
||||
|
||||
#[error("BGPsec router certificate ExtendedKeyUsage must contain id-kp-bgpsec-router ({OID_KP_BGPSEC_ROUTER}) (RFC 8209 §3.1.3.2; RFC 8209 §3.3)")]
|
||||
#[error(
|
||||
"BGPsec router certificate ExtendedKeyUsage must contain id-kp-bgpsec-router ({OID_KP_BGPSEC_ROUTER}) (RFC 8209 §3.1.3.2; RFC 8209 §3.3)"
|
||||
)]
|
||||
MissingBgpsecRouterEku,
|
||||
|
||||
#[error("BGPsec router certificate MUST NOT include Subject Information Access (RFC 8209 §3.1.3.3; RFC 8209 §3.3)")]
|
||||
#[error(
|
||||
"BGPsec router certificate MUST NOT include Subject Information Access (RFC 8209 §3.1.3.3; RFC 8209 §3.3)"
|
||||
)]
|
||||
SubjectInfoAccessPresent,
|
||||
|
||||
#[error("BGPsec router certificate MUST NOT include IP resources extension (RFC 8209 §3.1.3.4; RFC 8209 §3.3)")]
|
||||
#[error(
|
||||
"BGPsec router certificate MUST NOT include IP resources extension (RFC 8209 §3.1.3.4; RFC 8209 §3.3)"
|
||||
)]
|
||||
IpResourcesPresent,
|
||||
|
||||
#[error("BGPsec router certificate MUST include AS resources extension (RFC 8209 §3.1.3.5; RFC 8209 §3.3)")]
|
||||
#[error(
|
||||
"BGPsec router certificate MUST include AS resources extension (RFC 8209 §3.1.3.5; RFC 8209 §3.3)"
|
||||
)]
|
||||
AsResourcesMissing,
|
||||
|
||||
#[error("BGPsec router certificate AS resources MUST include one or more ASNs (RFC 8209 §3.1.3.5)")]
|
||||
#[error(
|
||||
"BGPsec router certificate AS resources MUST include one or more ASNs (RFC 8209 §3.1.3.5)"
|
||||
)]
|
||||
AsResourcesAsnumMissing,
|
||||
|
||||
#[error("BGPsec router certificate AS resources MUST NOT use inherit (RFC 8209 §3.1.3.5)")]
|
||||
AsResourcesInherit,
|
||||
|
||||
#[error("BGPsec router certificate AS resources MUST contain explicit ASNs, not ranges (RFC 8209 §3.1.3.5)")]
|
||||
#[error(
|
||||
"BGPsec router certificate AS resources MUST contain explicit ASNs, not ranges (RFC 8209 §3.1.3.5)"
|
||||
)]
|
||||
AsResourcesRangeNotAllowed,
|
||||
|
||||
#[error("BGPsec router certificate subjectPublicKeyInfo.algorithm must be id-ecPublicKey ({OID_EC_PUBLIC_KEY}) (RFC 8208 §3.1)")]
|
||||
#[error(
|
||||
"BGPsec router certificate subjectPublicKeyInfo.algorithm must be id-ecPublicKey ({OID_EC_PUBLIC_KEY}) (RFC 8208 §3.1)"
|
||||
)]
|
||||
SpkiAlgorithmNotEcPublicKey,
|
||||
|
||||
#[error("BGPsec router certificate subjectPublicKeyInfo.parameters must be secp256r1 ({OID_SECP256R1}) (RFC 8208 §3.1)")]
|
||||
#[error(
|
||||
"BGPsec router certificate subjectPublicKeyInfo.parameters must be secp256r1 ({OID_SECP256R1}) (RFC 8208 §3.1)"
|
||||
)]
|
||||
SpkiWrongCurve,
|
||||
|
||||
#[error("BGPsec router certificate subjectPublicKeyInfo.parameters missing or invalid (RFC 8208 §3.1)")]
|
||||
#[error(
|
||||
"BGPsec router certificate subjectPublicKeyInfo.parameters missing or invalid (RFC 8208 §3.1)"
|
||||
)]
|
||||
SpkiParametersMissingOrInvalid,
|
||||
|
||||
#[error("BGPsec router certificate subjectPublicKey MUST be uncompressed P-256 ECPoint (RFC 8208 §3.1)")]
|
||||
#[error(
|
||||
"BGPsec router certificate subjectPublicKey MUST be uncompressed P-256 ECPoint (RFC 8208 §3.1)"
|
||||
)]
|
||||
SpkiEcPointNotUncompressedP256,
|
||||
}
|
||||
|
||||
@@ -116,16 +139,21 @@ pub enum BgpsecRouterCertificatePathError {
|
||||
}
|
||||
|
||||
impl BgpsecRouterCertificate {
|
||||
pub fn parse_der(der: &[u8]) -> Result<BgpsecRouterCertificateParsed, BgpsecRouterCertificateParseError> {
|
||||
pub fn parse_der(
|
||||
der: &[u8],
|
||||
) -> Result<BgpsecRouterCertificateParsed, BgpsecRouterCertificateParseError> {
|
||||
let (rem, cert) = X509Certificate::from_der(der)
|
||||
.map_err(|e| BgpsecRouterCertificateParseError::X509(e.to_string()))?;
|
||||
if !rem.is_empty() {
|
||||
return Err(BgpsecRouterCertificateParseError::TrailingBytes(rem.len()));
|
||||
}
|
||||
let (spki_rem, _spki) = SubjectPublicKeyInfo::from_der(cert.tbs_certificate.subject_pki.raw)
|
||||
.map_err(|e| BgpsecRouterCertificateParseError::SpkiParse(e.to_string()))?;
|
||||
let (spki_rem, _spki) =
|
||||
SubjectPublicKeyInfo::from_der(cert.tbs_certificate.subject_pki.raw)
|
||||
.map_err(|e| BgpsecRouterCertificateParseError::SpkiParse(e.to_string()))?;
|
||||
if !spki_rem.is_empty() {
|
||||
return Err(BgpsecRouterCertificateParseError::SpkiTrailingBytes(spki_rem.len()));
|
||||
return Err(BgpsecRouterCertificateParseError::SpkiTrailingBytes(
|
||||
spki_rem.len(),
|
||||
));
|
||||
}
|
||||
let rc_parsed = ResourceCertificate::parse_der(der)?;
|
||||
Ok(BgpsecRouterCertificateParsed { rc_parsed })
|
||||
@@ -170,7 +198,9 @@ impl BgpsecRouterCertificate {
|
||||
}
|
||||
|
||||
impl BgpsecRouterCertificateParsed {
|
||||
pub fn validate_profile(self) -> Result<BgpsecRouterCertificate, BgpsecRouterCertificateProfileError> {
|
||||
pub fn validate_profile(
|
||||
self,
|
||||
) -> Result<BgpsecRouterCertificate, BgpsecRouterCertificateProfileError> {
|
||||
let rc = self.rc_parsed.validate_profile()?;
|
||||
if rc.kind != ResourceCertKind::Ee {
|
||||
return Err(BgpsecRouterCertificateProfileError::NotEe);
|
||||
@@ -196,15 +226,17 @@ impl BgpsecRouterCertificateParsed {
|
||||
.ok_or(BgpsecRouterCertificateProfileError::AsResourcesMissing)?;
|
||||
let asns = extract_router_asns(as_resources)?;
|
||||
|
||||
let (rem, cert) = X509Certificate::from_der(&rc.raw_der)
|
||||
.map_err(|e| BgpsecRouterCertificateProfileError::ResourceCertificate(
|
||||
ResourceCertificateProfileError::InvalidCertificatePolicy(e.to_string())
|
||||
))?;
|
||||
let (rem, cert) = X509Certificate::from_der(&rc.raw_der).map_err(|e| {
|
||||
BgpsecRouterCertificateProfileError::ResourceCertificate(
|
||||
ResourceCertificateProfileError::InvalidCertificatePolicy(e.to_string()),
|
||||
)
|
||||
})?;
|
||||
if !rem.is_empty() {
|
||||
return Err(BgpsecRouterCertificateProfileError::ResourceCertificate(
|
||||
ResourceCertificateProfileError::InvalidCertificatePolicy(
|
||||
format!("trailing bytes after router certificate DER: {}", rem.len()),
|
||||
),
|
||||
ResourceCertificateProfileError::InvalidCertificatePolicy(format!(
|
||||
"trailing bytes after router certificate DER: {}",
|
||||
rem.len()
|
||||
)),
|
||||
));
|
||||
}
|
||||
validate_router_eku(&cert)?;
|
||||
@@ -243,7 +275,7 @@ fn extract_router_asns(
|
||||
match item {
|
||||
AsIdOrRange::Id(v) => asns.push(*v),
|
||||
AsIdOrRange::Range { .. } => {
|
||||
return Err(BgpsecRouterCertificateProfileError::AsResourcesRangeNotAllowed)
|
||||
return Err(BgpsecRouterCertificateProfileError::AsResourcesRangeNotAllowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -252,7 +284,9 @@ fn extract_router_asns(
|
||||
Ok(asns)
|
||||
}
|
||||
|
||||
fn validate_router_eku(cert: &X509Certificate<'_>) -> Result<(), BgpsecRouterCertificateProfileError> {
|
||||
fn validate_router_eku(
|
||||
cert: &X509Certificate<'_>,
|
||||
) -> Result<(), BgpsecRouterCertificateProfileError> {
|
||||
let mut matches = cert
|
||||
.tbs_certificate
|
||||
.extensions()
|
||||
|
||||
@@ -326,10 +326,7 @@ impl RpkiSignedObject {
|
||||
/// Verify the CMS signature using the embedded EE certificate public key.
|
||||
pub fn verify_signature(&self) -> Result<(), SignedObjectVerifyError> {
|
||||
let ee = &self.signed_data.certificates[0];
|
||||
self.verify_signature_with_rsa_components(
|
||||
&ee.rsa_public_modulus,
|
||||
&ee.rsa_public_exponent,
|
||||
)
|
||||
self.verify_signature_with_rsa_components(&ee.rsa_public_modulus, &ee.rsa_public_exponent)
|
||||
}
|
||||
|
||||
/// Verify the CMS signature using a DER-encoded SubjectPublicKeyInfo.
|
||||
@@ -451,9 +448,7 @@ impl<'a> CmsReader<'a> {
|
||||
let (rem, any) = Any::from_ber(self.buf).map_err(|e| format!("BER parse error: {e}"))?;
|
||||
let tag = header_to_single_byte_tag(&any.header)?;
|
||||
if tag != 0x04 && tag != 0x24 {
|
||||
return Err(format!(
|
||||
"unexpected tag: got 0x{tag:02X}, expected 0x04"
|
||||
));
|
||||
return Err(format!("unexpected tag: got 0x{tag:02X}, expected 0x04"));
|
||||
}
|
||||
let octets = flatten_octet_string(any)?;
|
||||
self.buf = rem;
|
||||
@@ -516,7 +511,9 @@ fn header_to_single_byte_tag(header: &Header<'_>) -> Result<u8, String> {
|
||||
if tag_no > 30 {
|
||||
return Err(format!("high-tag-number form not supported: {tag_no}"));
|
||||
}
|
||||
Ok(((header.class() as u8) << 6) | if header.constructed() { 0x20 } else { 0x00 } | tag_no as u8)
|
||||
Ok(((header.class() as u8) << 6)
|
||||
| if header.constructed() { 0x20 } else { 0x00 }
|
||||
| tag_no as u8)
|
||||
}
|
||||
|
||||
fn cms_take_tlv(input: &[u8]) -> Result<(u8, &[u8], &[u8]), String> {
|
||||
@@ -759,20 +756,18 @@ fn validate_ee_certificate(der: &[u8]) -> Result<ResourceEeCertificate, SignedOb
|
||||
"trailing bytes after EE SubjectPublicKeyInfo DER".to_string(),
|
||||
));
|
||||
}
|
||||
let parsed_pk = spki
|
||||
.parsed()
|
||||
.map_err(|_e| SignedObjectValidateError::EeCertificateParse(
|
||||
let parsed_pk = spki.parsed().map_err(|_e| {
|
||||
SignedObjectValidateError::EeCertificateParse(
|
||||
"unsupported EE public key algorithm".to_string(),
|
||||
))?;
|
||||
)
|
||||
})?;
|
||||
let (rsa_public_modulus, rsa_public_exponent) = match parsed_pk {
|
||||
PublicKey::RSA(rsa) => {
|
||||
let modulus = strip_leading_zeros(rsa.modulus).to_vec();
|
||||
let exponent = strip_leading_zeros(rsa.exponent).to_vec();
|
||||
let _ = rsa
|
||||
.try_exponent()
|
||||
.map_err(|_e| SignedObjectValidateError::EeCertificateParse(
|
||||
"invalid EE RSA exponent".to_string(),
|
||||
))?;
|
||||
let _ = rsa.try_exponent().map_err(|_e| {
|
||||
SignedObjectValidateError::EeCertificateParse("invalid EE RSA exponent".to_string())
|
||||
})?;
|
||||
(modulus, exponent)
|
||||
}
|
||||
_ => {
|
||||
|
||||
Reference in New Issue
Block a user