From the docs, openssl::pkcs7
crate doesn't implement decoding the wrapped content, which makes some sense, as the RFC initially describes the format:
This document describes a general syntax for data that may have cryptography applied to it
and only at the end of the introduction notes:
A degenerate case of the syntax provides a means for disseminating certificates and certificate-revocation lists.
The degenerate case seems to be described in section 9, which describes the "Signed Data" content type, and notes:
the syntax has a degenerate case in which there are no signers on the content. The degenerate case provides a means for disseminating certificates and certificate-revocation lists.
and goes on to describe the encoded data with the ASN.1 schema:
SignedData ::= SEQUENCE {
version Version,
digestAlgorithms DigestAlgorithmIdentifiers,
contentInfo ContentInfo,
certificates
[0] IMPLICIT ExtendedCertificatesAndCertificates
OPTIONAL,
crls
[1] IMPLICIT CertificateRevocationLists OPTIONAL,
signerInfos SignerInfos }
which means it definitely is defined by PKCS #7, and not imported from some other ASN.1 module.
Since neither openssl
nor the pkcs7
crate (written by the Rust Crypto team) implement the SignedData
type, you'll probably have to give it a go yourself.
I suggest grabbing the der
crate and start implementing Decode
from the RFC syntax. I've found it's generally not too tough when I've messed with this before, for example, the above should look like (completely untested!):
#[derive(der::Sequence)]
struct SignedData {
pub version: Version,
pub digest_algorithms: DigestAlgorithmIdentifiers,
pub content_info: ContentInfo,
#[asn1(context_specific = "0")]
pub certificates: Option<ExtendedCertificatesAndCertificates>,
#[asn1(context_specific = "1")]
pub crls: Option<CertificateRevocationLists>,
}
#[repr(u8)]
enum Version { V1 = 1 };
// Or you can define `AlgorithmIdentifier` yourself, it's even the `der` crate example!
type DigestAlgorithmIdentifiers = der::asn1::SetOfVec<spki::AlgorithmIdentifier>;
// This is presumably what "content" you get out of openssl::pkcs7::Pkcs7::verify(),
// which the docs imply is probably empty!
#[derive(der::Sequence)]
struct ContentInfo {
pub content_type: der::asn1::ObjectIdentifier,
#[asn1(context_specific = "0")]
pub content: Option<der::asn1::Any>,
}
type ExtendedCertificatesAndCertificates = der::asn1::SetOfVec<ExtendedCertificateOrCertificate>;
#[derive(der::Choice)]
enum ExtendedCertificateOrCertificate {
Certificate(x509::Certificate),
// ExtendedCertificate(pkcs6::Certificate), // not implemented...
}