Skip to content

Commit 1f7828f

Browse files
committed
Convert PKCS#7 types to GATs
This does not currently work because rust-asn1 doesn't handle Asn1Definedby{Readable,Writable} correctly
1 parent 9b59bb6 commit 1f7828f

File tree

5 files changed

+45
-63
lines changed

5 files changed

+45
-63
lines changed

src/rust/cryptography-x509/src/common.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ impl<T: asn1::SimpleAsn1Writable, U: asn1::SimpleAsn1Writable> asn1::SimpleAsn1W
268268

269269
pub trait Asn1Operation {
270270
type SequenceOfVec<'a, T>
271+
where
272+
T: 'a;
273+
type SetOf<'a, T>
271274
where
272275
T: 'a;
273276
type SetOfVec<'a, T>
@@ -284,6 +287,10 @@ impl Asn1Operation for Asn1Read {
284287
= asn1::SequenceOf<'a, T>
285288
where
286289
T: 'a;
290+
type SetOf<'a, T>
291+
= asn1::SetOf<'a, T>
292+
where
293+
T: 'a;
287294
type SetOfVec<'a, T>
288295
= asn1::SetOf<'a, T>
289296
where
@@ -295,6 +302,10 @@ impl Asn1Operation for Asn1Write {
295302
= asn1::SequenceOfWriter<'a, T, Vec<T>>
296303
where
297304
T: 'a;
305+
type SetOf<'a, T>
306+
= asn1::SetOfWriter<'a, T>
307+
where
308+
T: 'a;
298309
type SetOfVec<'a, T>
299310
= asn1::SetOfWriter<'a, T, Vec<T>>
300311
where

src/rust/cryptography-x509/src/pkcs12.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
33
// for complete details.
44

5-
use crate::common::Utf8StoredBMPString;
5+
use crate::common::{Asn1Operation, Utf8StoredBMPString};
66
use crate::{pkcs7, pkcs8};
77

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

1616
#[derive(asn1::Asn1Write, asn1::Asn1Read)]
17-
pub struct Pfx<'a> {
17+
pub struct Pfx<'a, Op: Asn1Operation> {
1818
pub version: u8,
19-
pub auth_safe: pkcs7::ContentInfo<'a>,
19+
pub auth_safe: pkcs7::ContentInfo<'a, Op>,
2020
pub mac_data: Option<MacData<'a>>,
2121
}
2222

src/rust/cryptography-x509/src/pkcs7.rs

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
33
// for complete details.
44

5+
use crate::common::Asn1Operation;
56
use crate::{certificate, common, csr, name};
67

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

1213
#[derive(asn1::Asn1Write, asn1::Asn1Read)]
13-
pub struct ContentInfo<'a> {
14+
pub struct ContentInfo<'a, Op: Asn1Operation> {
1415
pub _content_type: asn1::DefinedByMarker<asn1::ObjectIdentifier>,
1516

1617
#[defined_by(_content_type)]
17-
pub content: Content<'a>,
18+
pub content: Content<'a, Op>,
1819
}
1920

2021
#[derive(asn1::Asn1DefinedByWrite, asn1::Asn1DefinedByRead)]
21-
pub enum Content<'a> {
22+
pub enum Content<'a, Op: Asn1Operation> {
2223
#[defined_by(PKCS7_ENVELOPED_DATA_OID)]
23-
EnvelopedData(asn1::Explicit<Box<EnvelopedData<'a>>, 0>),
24+
EnvelopedData(asn1::Explicit<Box<EnvelopedData<'a, Op>>, 0>),
2425
#[defined_by(PKCS7_SIGNED_DATA_OID)]
25-
SignedData(asn1::Explicit<Box<SignedData<'a>>, 0>),
26+
SignedData(asn1::Explicit<Box<SignedData<'a, Op>>, 0>),
2627
#[defined_by(PKCS7_DATA_OID)]
2728
Data(Option<asn1::Explicit<&'a [u8], 0>>),
2829
#[defined_by(PKCS7_ENCRYPTED_DATA_OID)]
2930
EncryptedData(asn1::Explicit<EncryptedData<'a>, 0>),
3031
}
3132

3233
#[derive(asn1::Asn1Write, asn1::Asn1Read)]
33-
pub struct SignedData<'a> {
34+
pub struct SignedData<'a, Op: Asn1Operation> {
3435
pub version: u8,
35-
pub digest_algorithms: common::Asn1ReadableOrWritable<
36-
asn1::SetOf<'a, common::AlgorithmIdentifier<'a>>,
37-
asn1::SetOfWriter<'a, common::AlgorithmIdentifier<'a>>,
38-
>,
39-
pub content_info: ContentInfo<'a>,
36+
pub digest_algorithms: Op::SetOf<'a, common::AlgorithmIdentifier<'a>>,
37+
pub content_info: ContentInfo<'a, Op>,
4038
#[implicit(0)]
41-
pub certificates: Option<
42-
common::Asn1ReadableOrWritable<
43-
asn1::SetOf<'a, certificate::Certificate<'a>>,
44-
asn1::SetOfWriter<'a, certificate::Certificate<'a>>,
45-
>,
46-
>,
39+
pub certificates: Option<Op::SetOf<'a, certificate::Certificate<'a>>>,
4740

4841
// We don't ever supply any of these, so for now, don't fill out the fields.
4942
#[implicit(1)]
50-
pub crls: Option<
51-
common::Asn1ReadableOrWritable<
52-
asn1::SetOf<'a, asn1::Sequence<'a>>,
53-
asn1::SetOfWriter<'a, asn1::Sequence<'a>>,
54-
>,
55-
>,
56-
57-
pub signer_infos: common::Asn1ReadableOrWritable<
58-
asn1::SetOf<'a, SignerInfo<'a>>,
59-
asn1::SetOfWriter<'a, SignerInfo<'a>>,
60-
>,
43+
pub crls: Option<Op::SetOf<'a, asn1::Sequence<'a>>>,
44+
45+
pub signer_infos: Op::SetOf<'a, SignerInfo<'a>>,
6146
}
6247

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

7863
#[derive(asn1::Asn1Write, asn1::Asn1Read)]
79-
pub struct EnvelopedData<'a> {
64+
pub struct EnvelopedData<'a, Op: Asn1Operation> {
8065
pub version: u8,
81-
pub recipient_infos: common::Asn1ReadableOrWritable<
82-
asn1::SetOf<'a, RecipientInfo<'a>>,
83-
asn1::SetOfWriter<'a, RecipientInfo<'a>>,
84-
>,
66+
pub recipient_infos: Op::SetOf<'a, RecipientInfo<'a>>,
8567
pub encrypted_content_info: EncryptedContentInfo<'a>,
8668
}
8769

src/rust/src/pkcs12.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::padding::PKCS7PaddingContext;
99
use crate::utils::cstr_from_literal;
1010
use crate::x509::certificate::Certificate;
1111
use crate::{types, x509};
12-
use cryptography_x509::common::Utf8StoredBMPString;
12+
use cryptography_x509::common::{Asn1Write, Utf8StoredBMPString};
1313
use pyo3::types::{PyAnyMethods, PyBytesMethods, PyListMethods};
1414
use pyo3::IntoPyObject;
1515
use pyo3::PyTypeInfo;
@@ -478,7 +478,7 @@ fn serialize_key_and_certificates<'p>(
478478
&cert_bag_contents,
479479
)?;
480480

481-
auth_safe_contents.push(cryptography_x509::pkcs7::ContentInfo {
481+
auth_safe_contents.push(cryptography_x509::pkcs7::ContentInfo::<Asn1Write> {
482482
_content_type: asn1::DefinedByMarker::marker(),
483483
content: cryptography_x509::pkcs7::Content::EncryptedData(asn1::Explicit::new(
484484
cryptography_x509::pkcs7::EncryptedData {
@@ -496,7 +496,7 @@ fn serialize_key_and_certificates<'p>(
496496
)),
497497
})
498498
} else {
499-
auth_safe_contents.push(cryptography_x509::pkcs7::ContentInfo {
499+
auth_safe_contents.push(cryptography_x509::pkcs7::ContentInfo::<Asn1Write> {
500500
_content_type: asn1::DefinedByMarker::marker(),
501501
content: cryptography_x509::pkcs7::Content::Data(Some(asn1::Explicit::new(
502502
&cert_bag_contents,

src/rust/src/pkcs7.rs

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::borrow::Cow;
66
use std::collections::HashMap;
77
use std::ops::Deref;
88

9-
use cryptography_x509::common::{AlgorithmIdentifier, AlgorithmParameters};
9+
use cryptography_x509::common::{AlgorithmIdentifier, AlgorithmParameters, Asn1Read, Asn1Write};
1010
use cryptography_x509::csr::Attribute;
1111
use cryptography_x509::pkcs7::PKCS7_DATA_OID;
1212
use cryptography_x509::{common, oid, pkcs7};
@@ -63,19 +63,17 @@ fn serialize_certificates<'p>(
6363

6464
let signed_data = pkcs7::SignedData {
6565
version: 1,
66-
digest_algorithms: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(&[])),
66+
digest_algorithms: asn1::SetOfWriter::new([].as_slice()),
6767
content_info: pkcs7::ContentInfo {
6868
_content_type: asn1::DefinedByMarker::marker(),
6969
content: pkcs7::Content::Data(None),
7070
},
71-
certificates: Some(common::Asn1ReadableOrWritable::new_write(
72-
asn1::SetOfWriter::new(&raw_certs),
73-
)),
71+
certificates: Some(asn1::SetOfWriter::new(raw_certs.as_slice())),
7472
crls: None,
75-
signer_infos: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(&[])),
73+
signer_infos: asn1::SetOfWriter::new([].as_slice()),
7674
};
7775

78-
let content_info = pkcs7::ContentInfo {
76+
let content_info = pkcs7::ContentInfo::<Asn1Write> {
7977
_content_type: asn1::DefinedByMarker::marker(),
8078
content: pkcs7::Content::SignedData(asn1::Explicit::new(Box::new(signed_data))),
8179
};
@@ -157,9 +155,7 @@ fn encrypt_and_serialize<'p>(
157155

158156
let enveloped_data = pkcs7::EnvelopedData {
159157
version: 0,
160-
recipient_infos: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(
161-
&recipient_infos,
162-
)),
158+
recipient_infos: asn1::SetOfWriter::new(recipient_infos.as_slice()),
163159

164160
encrypted_content_info: pkcs7::EncryptedContentInfo {
165161
content_type: PKCS7_DATA_OID,
@@ -171,7 +167,7 @@ fn encrypt_and_serialize<'p>(
171167
},
172168
};
173169

174-
let content_info = pkcs7::ContentInfo {
170+
let content_info = pkcs7::ContentInfo::<Asn1Write> {
175171
_content_type: asn1::DefinedByMarker::marker(),
176172
content: pkcs7::Content::EnvelopedData(asn1::Explicit::new(Box::new(enveloped_data))),
177173
};
@@ -240,18 +236,17 @@ fn decrypt_der<'p>(
240236
check_decrypt_parameters(py, &certificate, &private_key, options)?;
241237

242238
// Decrypt the data
243-
let content_info = asn1::parse_single::<pkcs7::ContentInfo<'_>>(data)?;
239+
let content_info = asn1::parse_single::<pkcs7::ContentInfo<'_, Asn1Read>>(data)?;
244240
let plain_content = match content_info.content {
245241
pkcs7::Content::EnvelopedData(data) => {
246242
// Extract enveloped data
247243
let enveloped_data = data.into_inner();
248244

249245
// Get recipients, and the one matching with the given certificate (if any)
250-
let mut recipient_infos = enveloped_data.recipient_infos.unwrap_read().clone();
251246
let recipient_certificate = certificate.get().raw.borrow_dependent();
252247
let recipient_serial_number = recipient_certificate.tbs_cert.serial;
253248
let recipient_issuer = recipient_certificate.tbs_cert.issuer.clone();
254-
let found_recipient_info = recipient_infos.find(|info| {
249+
let found_recipient_info = enveloped_data.recipient_infos.find(|info| {
255250
info.issuer_and_serial_number.serial_number == recipient_serial_number
256251
&& info.issuer_and_serial_number.issuer == recipient_issuer
257252
});
@@ -610,27 +605,21 @@ fn sign_and_serialize<'p>(
610605

611606
let signed_data = pkcs7::SignedData {
612607
version: 1,
613-
digest_algorithms: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(
614-
&digest_algs,
615-
)),
608+
digest_algorithms: asn1::SetOfWriter::new(digest_algs.as_slice()),
616609
content_info: pkcs7::ContentInfo {
617610
_content_type: asn1::DefinedByMarker::marker(),
618611
content: pkcs7::Content::Data(content.map(asn1::Explicit::new)),
619612
},
620613
certificates: if options.contains(types::PKCS7_NO_CERTS.get(py)?)? {
621614
None
622615
} else {
623-
Some(common::Asn1ReadableOrWritable::new_write(
624-
asn1::SetOfWriter::new(&certs),
625-
))
616+
Some(asn1::SetOfWriter::new(certs.as_slice()))
626617
},
627618
crls: None,
628-
signer_infos: common::Asn1ReadableOrWritable::new_write(asn1::SetOfWriter::new(
629-
&signer_infos,
630-
)),
619+
signer_infos: asn1::SetOfWriter::new(signer_infos.as_slice()),
631620
};
632621

633-
let content_info = pkcs7::ContentInfo {
622+
let content_info = pkcs7::ContentInfo::<Asn1Write> {
634623
_content_type: asn1::DefinedByMarker::marker(),
635624
content: pkcs7::Content::SignedData(asn1::Explicit::new(Box::new(signed_data))),
636625
};

0 commit comments

Comments
 (0)