Skip to content
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ test = true
bindgen = "0.71"

[dependencies]
asn1 = "0.21"
asn1 = "0.22"
bimap = "0.6.3"
bitflags = "2.4.1"
constant_time_eq = "0.3.0"
Expand Down
6 changes: 6 additions & 0 deletions src/kasn1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ impl<'a> asn1::SimpleAsn1Writable for DerEncBigUint<'a> {
fn write_data(&self, dest: &mut asn1::WriteBuf) -> asn1::WriteResult {
dest.push_slice(self.as_bytes())
}
fn data_length(&self) -> Option<usize> {
Some(self.data.len())
}
}

/// Represents a ASN.1 OctetString wrapper
Expand Down Expand Up @@ -164,6 +167,9 @@ impl<'a> asn1::SimpleAsn1Writable for DerEncOctetString<'a> {
fn write_data(&self, dest: &mut asn1::WriteBuf) -> asn1::WriteResult {
dest.push_slice(self.as_bytes())
}
fn data_length(&self) -> Option<usize> {
Some(self.data.len())
}
}

/// This type is used in PrivateKeyInfo
Expand Down
11 changes: 0 additions & 11 deletions src/kasn1/oid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,3 @@ pub const KKDF1_OID: asn1::ObjectIdentifier =
/// Kryoptic Key Based Protection Scheme v1
pub const KKBPS1_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 3, 6, 1, 4, 1, 2312, 20, 2, 1);

// The SHA3 OIDs are wrong in pyca
// https://github.com/pyca/cryptography/issues/13331
pub const SHA3_224_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 7);
pub const SHA3_256_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 8);
pub const SHA3_384_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 9);
pub const SHA3_512_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 10);
36 changes: 24 additions & 12 deletions src/kasn1/pyca/oid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,24 @@ pub const SHA384_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 2);
pub const SHA512_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 3);
// The SHA3 OIDs are wrong in pyca -- redefined in ../oids.rs
// https://github.com/pyca/cryptography/issues/13331
//pub const SHA3_224_OID: asn1::ObjectIdentifier =
// asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 224);
//pub const SHA3_256_OID: asn1::ObjectIdentifier =
// asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 256);
//pub const SHA3_384_OID: asn1::ObjectIdentifier =
// asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 384);
//pub const SHA3_512_OID: asn1::ObjectIdentifier =
// asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 512);
pub const SHA3_224_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 224);
pub const SHA3_256_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 256);
pub const SHA3_384_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 384);
pub const SHA3_512_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 3, 6, 1, 4, 1, 37476, 3, 2, 1, 99, 7, 512);

// NIST SHA3 OIDs (standard values)
pub const SHA3_224_NIST_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 7);
pub const SHA3_256_NIST_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 8);
pub const SHA3_384_NIST_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 9);
pub const SHA3_512_NIST_OID: asn1::ObjectIdentifier =
asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 10);

pub const MGF1_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 1, 8);
Expand Down Expand Up @@ -220,12 +228,16 @@ pub const PBES2_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 5, 13);
pub const PBKDF2_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 5, 12);
pub const PBE_WITH_MD5_AND_DES_CBC: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 5, 3);
pub const SCRYPT_OID: asn1::ObjectIdentifier =
asn1::oid!(1, 3, 6, 1, 4, 1, 11591, 4, 11);

pub const PBES1_WITH_SHA_AND_3KEY_TRIPLEDES_CBC: asn1::ObjectIdentifier =
pub const PBE_WITH_SHA_AND_128_BIT_RC4: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 12, 1, 1);
pub const PBE_WITH_SHA_AND_3KEY_TRIPLEDES_CBC: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 12, 1, 3);
pub const PBES1_WITH_SHA_AND_40_BIT_RC2_CBC: asn1::ObjectIdentifier =
pub const PBE_WITH_SHA_AND_40_BIT_RC2_CBC: asn1::ObjectIdentifier =
asn1::oid!(1, 2, 840, 113549, 1, 12, 1, 6);

pub const AES_128_CBC_OID: asn1::ObjectIdentifier =
Expand Down
88 changes: 79 additions & 9 deletions src/kasn1/pyca/pkcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use asn1::Asn1DefinedByWritable;
use asn1::{Asn1DefinedByWritable, SimpleAsn1Writable};

//use crate::oid;

Expand Down Expand Up @@ -54,6 +54,14 @@ pub enum AlgorithmParameters<'a> {
Sha3_384(Option<asn1::Null>),
#[defined_by(oid::SHA3_512_OID)]
Sha3_512(Option<asn1::Null>),
#[defined_by(oid::SHA3_224_NIST_OID)]
Sha3_224Nist(Option<asn1::Null>),
#[defined_by(oid::SHA3_256_NIST_OID)]
Sha3_256Nist(Option<asn1::Null>),
#[defined_by(oid::SHA3_384_NIST_OID)]
Sha3_384Nist(Option<asn1::Null>),
#[defined_by(oid::SHA3_512_NIST_OID)]
Sha3_512Nist(Option<asn1::Null>),

#[defined_by(oid::ED25519_OID)]
Ed25519,
Expand Down Expand Up @@ -180,10 +188,14 @@ pub enum AlgorithmParameters<'a> {
#[defined_by(oid::RC2_CBC)]
Rc2Cbc(Rc2CbcParams),

#[defined_by(oid::PBES1_WITH_SHA_AND_3KEY_TRIPLEDES_CBC)]
Pbes1WithShaAnd3KeyTripleDesCbc(PBES1Params),
#[defined_by(oid::PBES1_WITH_SHA_AND_40_BIT_RC2_CBC)]
Pbe1WithShaAnd40BitRc2Cbc(PBES1Params),
#[defined_by(oid::PBE_WITH_MD5_AND_DES_CBC)]
PbeWithMd5AndDesCbc(PbeParams),
#[defined_by(oid::PBE_WITH_SHA_AND_128_BIT_RC4)]
PbeWithShaAnd128BitRc4(Pkcs12PbeParams<'a>),
#[defined_by(oid::PBE_WITH_SHA_AND_3KEY_TRIPLEDES_CBC)]
PbeWithShaAnd3KeyTripleDesCbc(Pkcs12PbeParams<'a>),
#[defined_by(oid::PBE_WITH_SHA_AND_40_BIT_RC2_CBC)]
PbeWithShaAnd40BitRc2Cbc(Pkcs12PbeParams<'a>),

#[default]
Other(asn1::ObjectIdentifier, Option<asn1::Tlv<'a>>),
Expand All @@ -198,7 +210,28 @@ pub struct SubjectPublicKeyInfo<'a> {
#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)]
pub struct AttributeTypeValue<'a> {
pub type_id: asn1::ObjectIdentifier,
pub value: RawTlv<'a>,
pub value: AttributeValue<'a>,
}

#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)]
pub enum AttributeValue<'a> {
UniversalString(asn1::UniversalString<'a>),
BmpString(asn1::BMPString<'a>),
PrintableString(asn1::PrintableString<'a>),

// Must be last, because enums parse things in order.
AnyString(RawTlv<'a>),
}

impl AttributeValue<'_> {
pub fn tag(&self) -> asn1::Tag {
match self {
AttributeValue::AnyString(tlv) => tlv.tag(),
AttributeValue::PrintableString(_) => asn1::PrintableString::TAG,
AttributeValue::UniversalString(_) => asn1::UniversalString::TAG,
AttributeValue::BmpString(_) => asn1::BMPString::TAG,
}
}
}

// Like `asn1::Tlv` but doesn't store `full_data` so it can be constructed from
Expand Down Expand Up @@ -233,7 +266,14 @@ impl<'a> asn1::Asn1Readable<'a> for RawTlv<'a> {
}
impl asn1::Asn1Writable for RawTlv<'_> {
fn write(&self, w: &mut asn1::Writer<'_>) -> asn1::WriteResult {
w.write_tlv(self.tag, move |dest| dest.push_slice(self.value))
w.write_tlv(self.tag, Some(self.value.len()), move |dest| {
dest.push_slice(self.value)
})
}

fn encoded_length(&self) -> Option<usize> {
// TODO: we're missing an API to make this easy.
None
}
}

Expand Down Expand Up @@ -296,6 +336,13 @@ impl<T: asn1::SimpleAsn1Writable, U: asn1::SimpleAsn1Writable>
Asn1ReadableOrWritable::Write(v) => U::write_data(v, w),
}
}

fn data_length(&self) -> Option<usize> {
match self {
Asn1ReadableOrWritable::Read(v) => T::data_length(v),
Asn1ReadableOrWritable::Write(v) => U::data_length(v),
}
}
}

pub trait Asn1Operation {
Expand Down Expand Up @@ -543,14 +590,24 @@ pub struct ScryptParams<'a> {
pub key_length: Option<u32>,
}

// RFC 8018 Appendix A.3
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
pub struct PBES1Params {
pub struct PbeParams {
pub salt: [u8; 8],
pub iterations: u64,
}

// From RFC 7202 Appendix C
#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
pub struct Pkcs12PbeParams<'a> {
pub salt: &'a [u8],
pub iterations: u64,
}

#[derive(
asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone, Debug,
)]
Expand All @@ -571,7 +628,8 @@ impl<'a> UnvalidatedVisibleString<'a> {
}

impl<'a> asn1::SimpleAsn1Readable<'a> for UnvalidatedVisibleString<'a> {
const TAG: asn1::Tag = asn1::VisibleString::TAG;
const TAG: asn1::Tag =
<asn1::VisibleString<'_> as asn1::SimpleAsn1Readable>::TAG;
fn parse_data(data: &'a [u8]) -> asn1::ParseResult<Self> {
Ok(UnvalidatedVisibleString(
std::str::from_utf8(data).map_err(|_| {
Expand All @@ -586,6 +644,10 @@ impl asn1::SimpleAsn1Writable for UnvalidatedVisibleString<'_> {
fn write_data(&self, _: &mut asn1::WriteBuf) -> asn1::WriteResult {
unimplemented!();
}

fn data_length(&self) -> Option<usize> {
None
}
}

/// A BMPString ASN.1 element, where it is stored as a UTF-8 string in memory.
Expand All @@ -605,6 +667,10 @@ impl asn1::SimpleAsn1Writable for Utf8StoredBMPString<'_> {
}
Ok(())
}

fn data_length(&self) -> Option<usize> {
Some(self.0.encode_utf16().count() * 2)
}
}

#[derive(Clone)]
Expand Down Expand Up @@ -645,6 +711,10 @@ impl<T: asn1::Asn1Writable> asn1::Asn1Writable for WithTlv<'_, T> {
fn write(&self, w: &mut asn1::Writer<'_>) -> asn1::WriteResult<()> {
self.value.write(w)
}

fn encoded_length(&self) -> Option<usize> {
self.value.encoded_length()
}
}

impl<T: PartialEq> PartialEq for WithTlv<'_, T> {
Expand Down
8 changes: 4 additions & 4 deletions src/ossl/mldsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,10 @@ impl MlDsaOperation {
CKM_SHA256 => SHA256_OID,
CKM_SHA384 => SHA384_OID,
CKM_SHA512 => SHA512_OID,
CKM_SHA3_224 => SHA3_224_OID,
CKM_SHA3_256 => SHA3_256_OID,
CKM_SHA3_384 => SHA3_384_OID,
CKM_SHA3_512 => SHA3_512_OID,
CKM_SHA3_224 => SHA3_224_NIST_OID,
CKM_SHA3_256 => SHA3_256_NIST_OID,
CKM_SHA3_384 => SHA3_384_NIST_OID,
CKM_SHA3_512 => SHA3_512_NIST_OID,
/* TODO SHAKE hashes? */
_ => return Err(CKR_MECHANISM_PARAM_INVALID)?,
};
Expand Down
8 changes: 4 additions & 4 deletions src/ossl/slhdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,10 @@ impl SlhDsaOperation {
CKM_SHA256 => SHA256_OID,
CKM_SHA384 => SHA384_OID,
CKM_SHA512 => SHA512_OID,
CKM_SHA3_224 => SHA3_224_OID,
CKM_SHA3_256 => SHA3_256_OID,
CKM_SHA3_384 => SHA3_384_OID,
CKM_SHA3_512 => SHA3_512_OID,
CKM_SHA3_224 => SHA3_224_NIST_OID,
CKM_SHA3_256 => SHA3_256_NIST_OID,
CKM_SHA3_384 => SHA3_384_NIST_OID,
CKM_SHA3_512 => SHA3_512_NIST_OID,
/* TODO SHAKE hashes? */
_ => return Err(CKR_MECHANISM_PARAM_INVALID)?,
};
Expand Down
Loading