extern crate core;
use cms::content_info::{CmsVersion, ContentInfo};
use cms::enveloped_data::{
EnvelopedData, KeyAgreeRecipientIdentifier, OriginatorIdentifierOrKey, RecipientIdentifier,
RecipientInfo,
};
use const_oid::ObjectIdentifier;
use der::{AnyRef, Decode, Encode, Tag, Tagged};
use hex_literal::hex;
use pkcs5::pbes2::Pbkdf2Params;
use spki::AlgorithmIdentifierOwned;
use x509_cert::Certificate;
#[test]
fn reencode_enveloped_data_ktri_test() {
let der_ci = include_bytes!("examples/enveloped_data_ktri.bin");
let ci = ContentInfo::from_der(der_ci).unwrap();
assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_ENVELOPED_DATA);
let bytes = ci.content.to_der().unwrap();
let data = EnvelopedData::from_der(bytes.as_slice()).unwrap();
assert_eq!(CmsVersion::V0, data.version);
assert_eq!(
data.encrypted_content.content_type,
const_oid::db::rfc5911::ID_DATA
);
let rsa_cert = include_bytes!("examples/rsa_cert.der");
let cert = Certificate::from_der(rsa_cert).unwrap();
assert_eq!(1, data.recip_infos.0.len());
for ri in data.recip_infos.0.iter() {
match ri {
RecipientInfo::Ktri(ktri) => {
assert_eq!(CmsVersion::V0, ktri.version);
assert_eq!(
ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1"),
ktri.key_enc_alg.oid
);
assert_eq!(
Tag::Null,
ktri.key_enc_alg.parameters.as_ref().unwrap().tag()
);
match &ktri.rid {
RecipientIdentifier::IssuerAndSerialNumber(iasn) => {
assert_eq!(cert.tbs_certificate.issuer, iasn.issuer);
assert_eq!(cert.tbs_certificate.serial_number, iasn.serial_number);
}
_ => panic!(),
}
}
_ => panic!(),
}
}
let iv = hex!("FA5ABFA1AECE35AB8A6485BEFBB7D8E0");
assert_eq!(
data.encrypted_content.content_enc_alg.oid,
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.42")
);
assert_eq!(
data.encrypted_content
.content_enc_alg
.parameters
.as_ref()
.unwrap()
.value(),
iv
);
let reencoded_data = data.to_der().unwrap();
let ci2 = ContentInfo {
content_type: ci.content_type,
content: AnyRef::try_from(reencoded_data.as_slice()).unwrap().into(),
};
let reencoded_data_in_ci = ci2.to_der().unwrap();
assert_eq!(reencoded_data_in_ci, der_ci)
}
#[test]
fn reencode_enveloped_data_kari_test() {
let der_ci = include_bytes!("examples/enveloped_data_kari.bin");
let ci = ContentInfo::from_der(der_ci).unwrap();
assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_ENVELOPED_DATA);
let bytes = ci.content.to_der().unwrap();
let data = EnvelopedData::from_der(bytes.as_slice()).unwrap();
assert_eq!(CmsVersion::V2, data.version);
assert_eq!(
data.encrypted_content.content_type,
const_oid::db::rfc5911::ID_DATA
);
let ec_cert = include_bytes!("examples/ec384-ee-key.der");
let cert = Certificate::from_der(ec_cert).unwrap();
assert_eq!(1, data.recip_infos.0.len());
for ri in data.recip_infos.0.iter() {
match ri {
RecipientInfo::Kari(kari) => {
assert_eq!(CmsVersion::V3, kari.version);
match &kari.originator {
OriginatorIdentifierOrKey::OriginatorKey(ok) => {
assert_eq!(
ObjectIdentifier::new_unwrap("1.2.840.10045.2.1"),
ok.algorithm.oid
);
assert_eq!(None, ok.algorithm.parameters);
}
_ => panic!(),
}
assert_eq!(
ObjectIdentifier::new_unwrap("1.3.133.16.840.63.0.2"),
kari.key_enc_alg.oid
);
let params_alg = AlgorithmIdentifierOwned::from_der(
kari.key_enc_alg
.parameters
.as_ref()
.unwrap()
.to_der()
.unwrap()
.as_slice(),
)
.unwrap();
assert_eq!(
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.45"),
params_alg.oid
);
for rk in &kari.recipient_enc_keys {
match &rk.rid {
KeyAgreeRecipientIdentifier::IssuerAndSerialNumber(iasn) => {
assert_eq!(cert.tbs_certificate.issuer, iasn.issuer);
assert_eq!(cert.tbs_certificate.serial_number, iasn.serial_number);
}
_ => panic!(),
}
}
}
_ => panic!(),
}
}
let iv = hex!("62E7BA310340FE8CEB32765240778AFD");
assert_eq!(
data.encrypted_content.content_enc_alg.oid,
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.42")
);
assert_eq!(
data.encrypted_content
.content_enc_alg
.parameters
.as_ref()
.unwrap()
.value(),
iv
);
let reencoded_data = data.to_der().unwrap();
let ci2 = ContentInfo {
content_type: ci.content_type,
content: AnyRef::try_from(reencoded_data.as_slice()).unwrap().into(),
};
let reencoded_data_in_ci = ci2.to_der().unwrap();
assert_eq!(reencoded_data_in_ci, der_ci)
}
#[test]
fn reencode_enveloped_data_pwri_test() {
let der_ci = include_bytes!("examples/enveloped_data_pwri.bin");
let ci = ContentInfo::from_der(der_ci).unwrap();
assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_ENVELOPED_DATA);
let bytes = ci.content.to_der().unwrap();
let data = EnvelopedData::from_der(bytes.as_slice()).unwrap();
assert_eq!(CmsVersion::V3, data.version);
assert_eq!(
data.encrypted_content.content_type,
const_oid::db::rfc5911::ID_DATA
);
assert_eq!(1, data.recip_infos.0.len());
for ri in data.recip_infos.0.iter() {
match ri {
RecipientInfo::Pwri(pwri) => {
assert_eq!(CmsVersion::V0, pwri.version);
let kdf_alg = pwri.key_derivation_alg.as_ref().unwrap();
assert_eq!(
ObjectIdentifier::new_unwrap("1.2.840.113549.1.5.12"),
kdf_alg.oid
);
let enc_pbkdf2 = kdf_alg.parameters.as_ref().unwrap().to_der().unwrap();
let pbkdf2 = Pbkdf2Params::from_der(enc_pbkdf2.as_slice()).unwrap();
assert_eq!(hex!("7F EE A8 FD 56 8E 8F 07"), pbkdf2.salt);
assert_eq!(2048, pbkdf2.iteration_count);
assert_eq!(
ObjectIdentifier::new_unwrap("1.2.840.113549.1.9.16.3.9"),
pwri.key_enc_alg.oid
);
let params_alg = AlgorithmIdentifierOwned::from_der(
pwri.key_enc_alg
.parameters
.as_ref()
.unwrap()
.to_der()
.unwrap()
.as_slice(),
)
.unwrap();
assert_eq!(
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.2"),
params_alg.oid
);
let os = params_alg.parameters.as_ref().unwrap().value();
assert_eq!(hex!("9C B5 40 61 E3 9D 56 D0 40 8B 8D E7 DE AD 77 1C"), os)
}
_ => panic!(),
}
}
let iv = hex!("0381DB365D03E89C4194904626EC5713");
assert_eq!(
data.encrypted_content.content_enc_alg.oid,
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.2")
);
assert_eq!(
data.encrypted_content
.content_enc_alg
.parameters
.as_ref()
.unwrap()
.value(),
iv
);
let reencoded_data = data.to_der().unwrap();
let ci2 = ContentInfo {
content_type: ci.content_type,
content: AnyRef::try_from(reencoded_data.as_slice()).unwrap().into(),
};
let reencoded_data_in_ci = ci2.to_der().unwrap();
assert_eq!(reencoded_data_in_ci, der_ci)
}
#[test]
fn reencode_enveloped_data_kek_test() {
let der_ci = include_bytes!("examples/enveloped_data_kekri.bin");
let ci = ContentInfo::from_der(der_ci).unwrap();
assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_ENVELOPED_DATA);
let bytes = ci.content.to_der().unwrap();
let data = EnvelopedData::from_der(bytes.as_slice()).unwrap();
assert_eq!(CmsVersion::V2, data.version);
assert_eq!(
data.encrypted_content.content_type,
const_oid::db::rfc5911::ID_DATA
);
assert_eq!(1, data.recip_infos.0.len());
for ri in data.recip_infos.0.iter() {
match ri {
RecipientInfo::Kekri(kekri) => {
assert_eq!(CmsVersion::V4, kekri.version);
assert_eq!(hex!("DEADBEEF"), kekri.kek_id.kek_identifier.as_bytes());
assert_eq!(
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.5"),
kekri.key_enc_alg.oid
);
}
_ => panic!(),
}
}
let iv = hex!("F26776E818FFB5BB650F54AF38B7A6C4");
assert_eq!(
data.encrypted_content.content_enc_alg.oid,
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.2")
);
assert_eq!(
data.encrypted_content
.content_enc_alg
.parameters
.as_ref()
.unwrap()
.value(),
iv
);
let reencoded_data = data.to_der().unwrap();
let ci2 = ContentInfo {
content_type: ci.content_type,
content: AnyRef::try_from(reencoded_data.as_slice()).unwrap().into(),
};
let reencoded_data_in_ci = ci2.to_der().unwrap();
assert_eq!(reencoded_data_in_ci, der_ci)
}
#[test]
fn reencode_enveloped_data_multi_test() {
let der_ci = include_bytes!("examples/enveloped_data_multi.bin");
let ci = ContentInfo::from_der(der_ci).unwrap();
assert_eq!(ci.content_type, const_oid::db::rfc5911::ID_ENVELOPED_DATA);
let bytes = ci.content.to_der().unwrap();
let data = EnvelopedData::from_der(bytes.as_slice()).unwrap();
assert_eq!(CmsVersion::V3, data.version);
assert_eq!(
data.encrypted_content.content_type,
const_oid::db::rfc5911::ID_DATA
);
let enc_rsa_cert = include_bytes!("examples/rsa_cert.der");
let rsa_cert = Certificate::from_der(enc_rsa_cert).unwrap();
let enc_ec_cert = include_bytes!("examples/ec384-ee-key.der");
let ec_cert = Certificate::from_der(enc_ec_cert).unwrap();
assert_eq!(4, data.recip_infos.0.len());
for ri in data.recip_infos.0.iter() {
match ri {
RecipientInfo::Ktri(ktri) => {
assert_eq!(CmsVersion::V0, ktri.version);
assert_eq!(
ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1"),
ktri.key_enc_alg.oid
);
assert_eq!(
Tag::Null,
ktri.key_enc_alg.parameters.as_ref().unwrap().tag()
);
match &ktri.rid {
RecipientIdentifier::IssuerAndSerialNumber(iasn) => {
assert_eq!(rsa_cert.tbs_certificate.issuer, iasn.issuer);
assert_eq!(rsa_cert.tbs_certificate.serial_number, iasn.serial_number);
}
_ => panic!(),
}
}
RecipientInfo::Kari(kari) => {
assert_eq!(CmsVersion::V3, kari.version);
match &kari.originator {
OriginatorIdentifierOrKey::OriginatorKey(ok) => {
assert_eq!(
ObjectIdentifier::new_unwrap("1.2.840.10045.2.1"),
ok.algorithm.oid
);
assert_eq!(None, ok.algorithm.parameters);
}
_ => panic!(),
}
assert_eq!(
ObjectIdentifier::new_unwrap("1.3.133.16.840.63.0.2"),
kari.key_enc_alg.oid
);
let params_alg = AlgorithmIdentifierOwned::from_der(
kari.key_enc_alg
.parameters
.as_ref()
.unwrap()
.to_der()
.unwrap()
.as_slice(),
)
.unwrap();
assert_eq!(
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.45"),
params_alg.oid
);
for rk in &kari.recipient_enc_keys {
match &rk.rid {
KeyAgreeRecipientIdentifier::IssuerAndSerialNumber(iasn) => {
assert_eq!(ec_cert.tbs_certificate.issuer, iasn.issuer);
assert_eq!(ec_cert.tbs_certificate.serial_number, iasn.serial_number);
}
_ => panic!(),
}
}
}
RecipientInfo::Pwri(pwri) => {
assert_eq!(CmsVersion::V0, pwri.version);
let kdf_alg = pwri.key_derivation_alg.as_ref().unwrap();
assert_eq!(
ObjectIdentifier::new_unwrap("1.2.840.113549.1.5.12"),
kdf_alg.oid
);
let enc_pbkdf2 = kdf_alg.parameters.as_ref().unwrap().to_der().unwrap();
let pbkdf2 = Pbkdf2Params::from_der(enc_pbkdf2.as_slice()).unwrap();
assert_eq!(hex!("39 04 A7 33 A0 6A 1B 27"), pbkdf2.salt);
assert_eq!(2048, pbkdf2.iteration_count);
assert_eq!(
ObjectIdentifier::new_unwrap("1.2.840.113549.1.9.16.3.9"),
pwri.key_enc_alg.oid
);
let params_alg = AlgorithmIdentifierOwned::from_der(
pwri.key_enc_alg
.parameters
.as_ref()
.unwrap()
.to_der()
.unwrap()
.as_slice(),
)
.unwrap();
assert_eq!(
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.42"),
params_alg.oid
);
let os = params_alg.parameters.as_ref().unwrap().value();
assert_eq!(hex!("20ABB209D2C71522C578610E61AE8DC3"), os)
}
RecipientInfo::Kekri(kekri) => {
assert_eq!(CmsVersion::V4, kekri.version);
assert_eq!(hex!("DEADBEEF"), kekri.kek_id.kek_identifier.as_bytes());
assert_eq!(
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.5"),
kekri.key_enc_alg.oid
);
}
_ => panic!(),
}
}
let iv = hex!("3FD9F4A34B2DD65EA2CE75D8CCBAA8FE");
assert_eq!(
data.encrypted_content.content_enc_alg.oid,
ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.1.42")
);
assert_eq!(
data.encrypted_content
.content_enc_alg
.parameters
.as_ref()
.unwrap()
.value(),
iv
);
let reencoded_data = data.to_der().unwrap();
let ci2 = ContentInfo {
content_type: ci.content_type,
content: AnyRef::try_from(reencoded_data.as_slice()).unwrap().into(),
};
let reencoded_data_in_ci = ci2.to_der().unwrap();
assert_eq!(reencoded_data_in_ci, der_ci)
}