mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-27 19:48:14 -06:00
M9: require eContentType and at most one certificates and CRLs field
The bundle's encapContentInfo must start with its eContentType, and the optional [0] certificates and [1] CRLs appear at most once each, in that order (RFC 5652 §5.1; CodeRabbit on #3561). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f96e440a47
commit
b941402558
@@ -89,7 +89,13 @@ pub fn certificate_bundle(bytes: &[u8]) -> Result<Vec<Certificate>, SignError> {
|
||||
// then signerInfos (RFC 5652 §5.1).
|
||||
let [version, digests, encap, middle @ .., signers] = sd.as_slice() else { return Err(bad("SignedData")) };
|
||||
let shape = [(version, tag::INTEGER), (digests, tag::SET), (encap, tag::SEQUENCE), (signers, tag::SET)];
|
||||
if shape.iter().any(|(t, want)| t.tag != *want) || middle.iter().any(|t| t.tag != tag::ctx(0) && t.tag != tag::ctx(1)) {
|
||||
// At most one [0] certificates and one [1] CRLs, in that order.
|
||||
const CERTS: u8 = tag::ctx(0);
|
||||
const CRLS: u8 = tag::ctx(1);
|
||||
let middle_ok = matches!(middle.iter().map(|t| t.tag).collect::<Vec<_>>().as_slice(), [] | [CERTS] | [CRLS] | [CERTS, CRLS]);
|
||||
// encapContentInfo starts with its eContentType OID.
|
||||
let encap_ok = encap.children()?.first().is_some_and(|t| t.tag == tag::OID);
|
||||
if shape.iter().any(|(t, want)| t.tag != *want) || !middle_ok || !encap_ok {
|
||||
return Err(bad("SignedData"));
|
||||
}
|
||||
let mut certificates = Vec::new();
|
||||
|
||||
@@ -303,6 +303,12 @@ fn certificates_load_from_pkcs7_bundles() {
|
||||
assert_eq!(load_certificates(&wrap(&[&int(1), &set_of(&[]), &encap, &certs, &set_of(&[])])).unwrap().len(), 2);
|
||||
assert!(load_certificates(&wrap(&[&int(1), &set_of(&[]), &encap, &certs])).is_err());
|
||||
assert!(load_certificates(&wrap(&[&set_of(&[]), &set_of(&[]), &encap, &certs, &set_of(&[])])).is_err());
|
||||
// An empty encapContentInfo, a repeated [0], and [1] CRLs before [0] certificates.
|
||||
let crls = tlv(0xA1, &[]);
|
||||
assert!(load_certificates(&wrap(&[&int(1), &set_of(&[]), &seq(&[]), &certs, &set_of(&[])])).is_err());
|
||||
assert!(load_certificates(&wrap(&[&int(1), &set_of(&[]), &encap, &certs, &certs, &set_of(&[])])).is_err());
|
||||
assert!(load_certificates(&wrap(&[&int(1), &set_of(&[]), &encap, &crls, &certs, &set_of(&[])])).is_err());
|
||||
assert_eq!(load_certificates(&wrap(&[&int(1), &set_of(&[]), &encap, &certs, &crls, &set_of(&[])])).unwrap().len(), 2);
|
||||
}
|
||||
let mut trailing = bundle.clone();
|
||||
trailing.extend_from_slice(&[0x05, 0x00]);
|
||||
|
||||
Reference in New Issue
Block a user