Skip to content

pkcs7: make types for creating messages public #991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pkcs7/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ spki = { version = "0.7" }
x509-cert = { version = "0.2", default-features = false }

[dev-dependencies]
der = { version = "0.7", features = ["oid", "pem"] }
hex-literal = "0.4"
x509-cert = { version = "0.2", default-features = false, features = ["pem"] }

[package.metadata.docs.rs]
all-features = true
Expand Down
21 changes: 21 additions & 0 deletions pkcs7/src/algorithm_identifier_types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! `Algorithm Identifier Types` [RFC 5652 § 10.1](https://datatracker.ietf.org/doc/html/rfc5652#section-10.1)

use der::asn1::SetOfVec;
use spki::AlgorithmIdentifierRef;

/// ```text
/// DigestAlgorithmIdentifier ::= AlgorithmIdentifier
/// ```
/// See [RFC 5652 10.1.1](https://datatracker.ietf.org/doc/html/rfc5652#section-10.1.1).
pub type DigestAlgorithmIdentifier<'a> = AlgorithmIdentifierRef<'a>;

/// ```text
/// DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
/// ```
pub type DigestAlgorithmIdentifiers<'a> = SetOfVec<DigestAlgorithmIdentifier<'a>>;

/// ```text
/// SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
/// ```
/// See [RFC 5652 10.1.2](https://datatracker.ietf.org/doc/html/rfc5652#section-10.1.2).
pub type SignatureAlgorithmIdentifier<'a> = AlgorithmIdentifierRef<'a>;
1 change: 1 addition & 0 deletions pkcs7/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
unused_qualifications
)]

pub mod algorithm_identifier_types;
pub mod certificate_choices;
pub mod cms_version;
pub mod data_content;
Expand Down
14 changes: 2 additions & 12 deletions pkcs7/src/signed_data_content.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,17 @@
//! `signed-data` content type [RFC 5652 § 5](https://datatracker.ietf.org/doc/html/rfc5652#section-5)

use crate::{
algorithm_identifier_types::DigestAlgorithmIdentifiers,
certificate_choices::CertificateChoices, cms_version::CmsVersion,
encapsulated_content_info::EncapsulatedContentInfo,
revocation_info_choices::RevocationInfoChoices, signer_info::SignerInfos,
};
use der::{asn1::SetOfVec, Sequence};
use spki::AlgorithmIdentifierRef;

/// ```text
/// DigestAlgorithmIdentifier ::= AlgorithmIdentifier
/// ```
type DigestAlgorithmIdentifier<'a> = AlgorithmIdentifierRef<'a>;

/// ```text
/// DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
/// ```
type DigestAlgorithmIdentifiers<'a> = SetOfVec<DigestAlgorithmIdentifier<'a>>;

/// ```text
/// CertificateSet ::= SET OF CertificateChoices
/// ```
type CertificateSet<'a> = SetOfVec<CertificateChoices<'a>>;
pub type CertificateSet<'a> = SetOfVec<CertificateChoices<'a>>;

/// Signed-data content type [RFC 5652 § 5](https://datatracker.ietf.org/doc/html/rfc5652#section-5)
///
Expand Down
16 changes: 4 additions & 12 deletions pkcs7/src/signer_info.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
//! `SignerInfo` data type [RFC 5652 § 5.3](https://datatracker.ietf.org/doc/html/rfc5652#section-5.3)

use crate::cms_version::CmsVersion;
use crate::{
algorithm_identifier_types::{DigestAlgorithmIdentifier, SignatureAlgorithmIdentifier},
cms_version::CmsVersion,
};
use der::{
asn1::{OctetStringRef, SetOfVec},
Choice, Sequence, ValueOrd,
};
use spki::AlgorithmIdentifierRef;
use x509_cert::{
attr::Attribute, ext::pkix::SubjectKeyIdentifier, name::Name, serial_number::SerialNumber,
};

/// ```text
/// DigestAlgorithmIdentifier ::= AlgorithmIdentifier
/// ```
type DigestAlgorithmIdentifier<'a> = AlgorithmIdentifierRef<'a>;

/// ```text
/// SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
/// ```
type SignatureAlgorithmIdentifier<'a> = AlgorithmIdentifierRef<'a>;

/// ```text
/// SignedAttributes ::= SET SIZE (1..MAX) OF Attribute
/// ```
Expand Down
60 changes: 59 additions & 1 deletion pkcs7/tests/content_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

use der::{
asn1::{ObjectIdentifier, OctetStringRef, SequenceRef},
Decode, SliceWriter,
Decode, DecodePem, SliceWriter,
};
use hex_literal::hex;
use pkcs7::algorithm_identifier_types::{DigestAlgorithmIdentifier, DigestAlgorithmIdentifiers};
use pkcs7::certificate_choices::CertificateChoices;
use pkcs7::signed_data_content::CertificateSet;
use pkcs7::signer_info::SignerInfos;
use pkcs7::{
cms_version::CmsVersion, encapsulated_content_info::EncapsulatedContentInfo,
encrypted_data_content::EncryptedDataContent, enveloped_data_content::EncryptedContentInfo,
Expand Down Expand Up @@ -139,6 +143,9 @@ fn decode_signed_scep_example() {
}
_ => panic!("expected ContentInfo::SignedData(Some(_))"),
}

let mut buf = vec![0u8; bytes.len()];
encode_content_info(&content, &mut buf);
}

// TODO(tarcieri): BER support
Expand Down Expand Up @@ -186,3 +193,54 @@ fn decode_signed_der() {
10034
);
}

#[test]
fn create_pkcs7_signed_data() {
// {iso(1) identified-organization(3) thawte(101) id-Ed25519(112)}
const OID_ED25519: &str = "1.3.101.112";
// {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7) signedData(2)}
const OID_PKCS7_SIGNED_DATA: &str = "1.2.840.113549.1.7.2";

let digest_algorithms = {
let digest_algorithm = DigestAlgorithmIdentifier {
oid: der::asn1::ObjectIdentifier::new(OID_ED25519).unwrap(),
parameters: None,
};
let mut digest_algorithms = DigestAlgorithmIdentifiers::new();
digest_algorithms.add(digest_algorithm).unwrap();
digest_algorithms
};

let encap_content_info = {
EncapsulatedContentInfo {
e_content_type: der::asn1::ObjectIdentifier::new(OID_PKCS7_SIGNED_DATA).unwrap(),
e_content: None,
}
};

let certificates = {
let cert_pem = include_bytes!("../tests/examples/cert.pem");
let cert: x509_cert::Certificate = x509_cert::Certificate::from_pem(cert_pem).unwrap();
let cert_choice = CertificateChoices::Certificate(cert);
let mut certs = CertificateSet::new();
certs.add(cert_choice).unwrap();
Some(certs)
};

fn get_signer_infos<'a>() -> SignerInfos<'a> {
let signer_infos = SignerInfos::new();
signer_infos
}

let content_info = ContentInfo::SignedData(SignedDataContent {
version: pkcs7::cms_version::CmsVersion::V1,
digest_algorithms,
encap_content_info,
certificates,
crls: None,
signer_infos: get_signer_infos(),
});

let mut buf = vec![0u8; 10000]; // buffer length must be guessed in advance :|
encode_content_info(&content_info, &mut buf);
}