20260711 验证TAL信任锚自签名

This commit is contained in:
yuyr 2026-07-11 21:13:52 +08:00
parent 8613cfae60
commit 8e37ef48cb
3 changed files with 38 additions and 1 deletions

View File

@ -244,6 +244,9 @@ pub enum TrustAnchorError {
#[error("TA certificate error: {0} (RFC 8630 §2.3)")]
TaCertificate(#[from] TaCertificateDecodeError),
#[error("TA certificate self-signature error: {0} (RFC 8630 §2.3)")]
TaSelfSignature(#[from] TaCertificateVerifyError),
#[error("{0}")]
Bind(#[from] TrustAnchorBindError),
}
@ -269,6 +272,7 @@ impl TrustAnchor {
resolved_uri: Option<&Url>,
) -> Result<Self, TrustAnchorError> {
let ta_certificate = TaCertificate::decode_der(ta_der)?;
ta_certificate.verify_self_signature()?;
Ok(Self::bind(tal, ta_certificate, resolved_uri)?)
}
@ -278,6 +282,7 @@ impl TrustAnchor {
resolved_uri: Option<&Url>,
) -> Result<Self, TrustAnchorError> {
let ta_certificate = TaCertificate::decode_der_with_strict_name(ta_der)?;
ta_certificate.verify_self_signature()?;
Ok(Self::bind(tal, ta_certificate, resolved_uri)?)
}

View File

@ -88,6 +88,18 @@ fn offline_discovery_from_apnic_tal_and_ta_der_fixture_works() {
}
}
#[test]
fn offline_discovery_rejects_tampered_ta_self_signature() {
let tal_bytes = apnic_tal_bytes();
let mut ta_der = apnic_ta_der();
let last = ta_der.last_mut().expect("TA fixture must not be empty");
*last ^= 0x01;
let err = discover_root_ca_instance_from_tal_and_ta_der(&tal_bytes, &ta_der, None)
.expect_err("tampered TA signature must not form a root CA instance");
assert!(err.to_string().contains("self-signature"), "{err}");
}
#[test]
fn discover_root_from_tal_url_works_with_mock_fetcher() {
let tal_bytes = apnic_tal_bytes();

View File

@ -1,4 +1,6 @@
use rpki::data_model::ta::{TrustAnchor, TrustAnchorBindError, TrustAnchorError};
use rpki::data_model::ta::{
TaCertificateVerifyError, TrustAnchor, TrustAnchorBindError, TrustAnchorError,
};
use rpki::data_model::tal::Tal;
use url::Url;
@ -76,3 +78,21 @@ fn bind_rejects_resolved_uri_not_listed_in_tal() {
))
));
}
#[test]
fn bind_rejects_tampered_ta_self_signature() {
let tal_raw =
std::fs::read("tests/fixtures/tal/apnic-rfc7730-https.tal").expect("read TAL fixture");
let tal = Tal::decode_bytes(&tal_raw).expect("decode TAL fixture");
let mut ta_der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read TA fixture");
let last = ta_der.last_mut().expect("TA fixture must not be empty");
*last ^= 0x01;
assert!(matches!(
TrustAnchor::bind_der(tal, &ta_der, None),
Err(TrustAnchorError::TaSelfSignature(
TaCertificateVerifyError::InvalidSelfSignature(_)
))
));
}