Skip to content
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

Convert PKCS#7 types to GATs #12037

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
11 changes: 11 additions & 0 deletions src/rust/cryptography-x509/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ impl<T: asn1::SimpleAsn1Writable, U: asn1::SimpleAsn1Writable> asn1::SimpleAsn1W

pub trait Asn1Operation {
type SequenceOfVec<'a, T>
where
T: 'a;
type SetOf<'a, T>
where
T: 'a;
type SetOfVec<'a, T>
Expand All @@ -281,6 +284,10 @@ impl Asn1Operation for Asn1Read {
= asn1::SequenceOf<'a, T>
where
T: 'a;
type SetOf<'a, T>
= asn1::SetOf<'a, T>
where
T: 'a;
type SetOfVec<'a, T>
= asn1::SetOf<'a, T>
where
Expand All @@ -292,6 +299,10 @@ impl Asn1Operation for Asn1Write {
= asn1::SequenceOfWriter<'a, T, Vec<T>>
where
T: 'a;
type SetOf<'a, T>
= asn1::SetOfWriter<'a, T>
where
T: 'a;
type SetOfVec<'a, T>
= asn1::SetOfWriter<'a, T, Vec<T>>
where
Expand Down
6 changes: 3 additions & 3 deletions src/rust/cryptography-x509/src/pkcs12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use crate::common::{AlgorithmIdentifier, Utf8StoredBMPString};
use crate::common::{AlgorithmIdentifier, Asn1Operation, Utf8StoredBMPString};
use crate::pkcs7;

pub const CERT_BAG_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 12, 10, 1, 3);
Expand All @@ -14,9 +14,9 @@ pub const FRIENDLY_NAME_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 1135
pub const LOCAL_KEY_ID_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 9, 21);

#[derive(asn1::Asn1Write)]
pub struct Pfx<'a> {
pub struct Pfx<'a, Op: Asn1Operation> {
pub version: u8,
pub auth_safe: pkcs7::ContentInfo<'a>,
pub auth_safe: pkcs7::ContentInfo<'a, Op>,
pub mac_data: Option<MacData<'a>>,
}

Expand Down
48 changes: 15 additions & 33 deletions src/rust/cryptography-x509/src/pkcs7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use crate::common::Asn1Operation;
use crate::{certificate, common, csr, name};

pub const PKCS7_DATA_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 7, 1);
Expand All @@ -10,54 +11,38 @@ pub const PKCS7_ENVELOPED_DATA_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 84
pub const PKCS7_ENCRYPTED_DATA_OID: asn1::ObjectIdentifier = asn1::oid!(1, 2, 840, 113549, 1, 7, 6);

#[derive(asn1::Asn1Write, asn1::Asn1Read)]
pub struct ContentInfo<'a> {
pub struct ContentInfo<'a, Op: Asn1Operation> {
pub _content_type: asn1::DefinedByMarker<asn1::ObjectIdentifier>,

#[defined_by(_content_type)]
pub content: Content<'a>,
pub content: Content<'a, Op>,
}

#[derive(asn1::Asn1DefinedByWrite, asn1::Asn1DefinedByRead)]
pub enum Content<'a> {
pub enum Content<'a, Op: Asn1Operation> {
#[defined_by(PKCS7_ENVELOPED_DATA_OID)]
EnvelopedData(asn1::Explicit<Box<EnvelopedData<'a>>, 0>),
EnvelopedData(asn1::Explicit<Box<EnvelopedData<'a, Op>>, 0>),
#[defined_by(PKCS7_SIGNED_DATA_OID)]
SignedData(asn1::Explicit<Box<SignedData<'a>>, 0>),
SignedData(asn1::Explicit<Box<SignedData<'a, Op>>, 0>),
#[defined_by(PKCS7_DATA_OID)]
Data(Option<asn1::Explicit<&'a [u8], 0>>),
#[defined_by(PKCS7_ENCRYPTED_DATA_OID)]
EncryptedData(asn1::Explicit<EncryptedData<'a>, 0>),
}

#[derive(asn1::Asn1Write, asn1::Asn1Read)]
pub struct SignedData<'a> {
pub struct SignedData<'a, Op: Asn1Operation> {
pub version: u8,
pub digest_algorithms: common::Asn1ReadableOrWritable<
asn1::SetOf<'a, common::AlgorithmIdentifier<'a>>,
asn1::SetOfWriter<'a, common::AlgorithmIdentifier<'a>>,
>,
pub content_info: ContentInfo<'a>,
pub digest_algorithms: Op::SetOf<'a, common::AlgorithmIdentifier<'a>>,
pub content_info: ContentInfo<'a, Op>,
#[implicit(0)]
pub certificates: Option<
common::Asn1ReadableOrWritable<
asn1::SetOf<'a, certificate::Certificate<'a>>,
asn1::SetOfWriter<'a, certificate::Certificate<'a>>,
>,
>,
pub certificates: Option<Op::SetOf<'a, certificate::Certificate<'a>>>,

// We don't ever supply any of these, so for now, don't fill out the fields.
#[implicit(1)]
pub crls: Option<
common::Asn1ReadableOrWritable<
asn1::SetOf<'a, asn1::Sequence<'a>>,
asn1::SetOfWriter<'a, asn1::Sequence<'a>>,
>,
>,

pub signer_infos: common::Asn1ReadableOrWritable<
asn1::SetOf<'a, SignerInfo<'a>>,
asn1::SetOfWriter<'a, SignerInfo<'a>>,
>,
pub crls: Option<Op::SetOf<'a, asn1::Sequence<'a>>>,

pub signer_infos: Op::SetOf<'a, SignerInfo<'a>>,
}

#[derive(asn1::Asn1Write, asn1::Asn1Read)]
Expand All @@ -76,12 +61,9 @@ pub struct SignerInfo<'a> {
}

#[derive(asn1::Asn1Write, asn1::Asn1Read)]
pub struct EnvelopedData<'a> {
pub struct EnvelopedData<'a, Op: Asn1Operation> {
pub version: u8,
pub recipient_infos: common::Asn1ReadableOrWritable<
asn1::SetOf<'a, RecipientInfo<'a>>,
asn1::SetOfWriter<'a, RecipientInfo<'a>>,
>,
pub recipient_infos: Op::SetOf<'a, RecipientInfo<'a>>,
pub encrypted_content_info: EncryptedContentInfo<'a>,
}

Expand Down
6 changes: 3 additions & 3 deletions src/rust/src/pkcs12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::error::{CryptographyError, CryptographyResult};
use crate::padding::PKCS7PaddingContext;
use crate::x509::certificate::Certificate;
use crate::{types, x509};
use cryptography_x509::common::Utf8StoredBMPString;
use cryptography_x509::common::{Asn1Write, Utf8StoredBMPString};
use pyo3::types::{PyAnyMethods, PyBytesMethods, PyListMethods};
use pyo3::IntoPyObject;
use std::collections::hash_map::DefaultHasher;
Expand Down Expand Up @@ -577,7 +577,7 @@ fn serialize_key_and_certificates<'p>(
&cert_bag_contents,
)?;

auth_safe_contents.push(cryptography_x509::pkcs7::ContentInfo {
auth_safe_contents.push(cryptography_x509::pkcs7::ContentInfo::<Asn1Write> {
_content_type: asn1::DefinedByMarker::marker(),
content: cryptography_x509::pkcs7::Content::EncryptedData(asn1::Explicit::new(
cryptography_x509::pkcs7::EncryptedData {
Expand All @@ -595,7 +595,7 @@ fn serialize_key_and_certificates<'p>(
)),
})
} else {
auth_safe_contents.push(cryptography_x509::pkcs7::ContentInfo {
auth_safe_contents.push(cryptography_x509::pkcs7::ContentInfo::<Asn1Write> {
_content_type: asn1::DefinedByMarker::marker(),
content: cryptography_x509::pkcs7::Content::Data(Some(asn1::Explicit::new(
&cert_bag_contents,
Expand Down
37 changes: 13 additions & 24 deletions src/rust/src/pkcs7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::borrow::Cow;
use std::collections::HashMap;
use std::ops::Deref;

use cryptography_x509::common::{AlgorithmIdentifier, AlgorithmParameters};
use cryptography_x509::common::{AlgorithmIdentifier, AlgorithmParameters, Asn1Read, Asn1Write};
use cryptography_x509::csr::Attribute;
use cryptography_x509::pkcs7::PKCS7_DATA_OID;
use cryptography_x509::{common, oid, pkcs7};
Expand Down Expand Up @@ -59,19 +59,17 @@ fn serialize_certificates<'p>(

let signed_data = pkcs7::SignedData {
version: 1,
digest_algorithms: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(&[])),
digest_algorithms: asn1::SetOfWriter::new([].as_slice()),
content_info: pkcs7::ContentInfo {
_content_type: asn1::DefinedByMarker::marker(),
content: pkcs7::Content::Data(None),
},
certificates: Some(common::Asn1ReadableOrWritable::new_write(
asn1::SetOfWriter::new(&raw_certs),
)),
certificates: Some(asn1::SetOfWriter::new(raw_certs.as_slice())),
crls: None,
signer_infos: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(&[])),
signer_infos: asn1::SetOfWriter::new([].as_slice()),
};

let content_info = pkcs7::ContentInfo {
let content_info = pkcs7::ContentInfo::<Asn1Write> {
_content_type: asn1::DefinedByMarker::marker(),
content: pkcs7::Content::SignedData(asn1::Explicit::new(Box::new(signed_data))),
};
Expand Down Expand Up @@ -135,9 +133,7 @@ fn encrypt_and_serialize<'p>(

let enveloped_data = pkcs7::EnvelopedData {
version: 0,
recipient_infos: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(
&recipient_infos,
)),
recipient_infos: asn1::SetOfWriter::new(recipient_infos.as_slice()),

encrypted_content_info: pkcs7::EncryptedContentInfo {
content_type: PKCS7_DATA_OID,
Expand All @@ -149,7 +145,7 @@ fn encrypt_and_serialize<'p>(
},
};

let content_info = pkcs7::ContentInfo {
let content_info = pkcs7::ContentInfo::<Asn1Write> {
_content_type: asn1::DefinedByMarker::marker(),
content: pkcs7::Content::EnvelopedData(asn1::Explicit::new(Box::new(enveloped_data))),
};
Expand Down Expand Up @@ -218,18 +214,17 @@ fn decrypt_der<'p>(
check_decrypt_parameters(py, &certificate, &private_key, options)?;

// Decrypt the data
let content_info = asn1::parse_single::<pkcs7::ContentInfo<'_>>(data)?;
let content_info = asn1::parse_single::<pkcs7::ContentInfo<'_, Asn1Read>>(data)?;
let plain_content = match content_info.content {
pkcs7::Content::EnvelopedData(data) => {
// Extract enveloped data
let enveloped_data = data.into_inner();

// Get recipients, and the one matching with the given certificate (if any)
let mut recipient_infos = enveloped_data.recipient_infos.unwrap_read().clone();
let recipient_certificate = certificate.get().raw.borrow_dependent();
let recipient_serial_number = recipient_certificate.tbs_cert.serial;
let recipient_issuer = recipient_certificate.tbs_cert.issuer.clone();
let found_recipient_info = recipient_infos.find(|info| {
let found_recipient_info = enveloped_data.recipient_infos.find(|info| {
info.issuer_and_serial_number.serial_number == recipient_serial_number
&& info.issuer_and_serial_number.issuer == recipient_issuer
});
Expand Down Expand Up @@ -580,27 +575,21 @@ fn sign_and_serialize<'p>(

let signed_data = pkcs7::SignedData {
version: 1,
digest_algorithms: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(
&digest_algs,
)),
digest_algorithms: asn1::SetOfWriter::new(digest_algs.as_slice()),
content_info: pkcs7::ContentInfo {
_content_type: asn1::DefinedByMarker::marker(),
content: pkcs7::Content::Data(content.map(asn1::Explicit::new)),
},
certificates: if options.contains(types::PKCS7_NO_CERTS.get(py)?)? {
None
} else {
Some(common::Asn1ReadableOrWritable::new_write(
asn1::SetOfWriter::new(&certs),
))
Some(asn1::SetOfWriter::new(certs.as_slice()))
},
crls: None,
signer_infos: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(
&signer_infos,
)),
signer_infos: asn1::SetOfWriter::new(signer_infos.as_slice()),
};

let content_info = pkcs7::ContentInfo {
let content_info = pkcs7::ContentInfo::<Asn1Write> {
_content_type: asn1::DefinedByMarker::marker(),
content: pkcs7::Content::SignedData(asn1::Explicit::new(Box::new(signed_data))),
};
Expand Down
Loading