asn1_struct! {
RSAPublicKey ::= SEQUENCE {
modulus INTEGER,
publicExponent INTEGER
}
}
asn1_struct! {
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER,
publicExponent INTEGER,
privateExponent INTEGER,
prime1 INTEGER,
prime2 INTEGER,
exponent1 INTEGER,
exponent2 INTEGER,
coefficient INTEGER
}
}
asn1_enum! {
Version ::= INTEGER { two_prime(0), multi(1) }
}
asn1_struct! {
OneAsymmetricKey ::= SEQUENCE {
version Pkcs8Version,
privateKeyAlgorithm AlgorithmIdentifier REF,
privateKey OCTET STRING,
publicKey [1] BIT STRING
}
}
asn1_enum! {
Pkcs8Version ::= INTEGER { Pkcs8v1(0), Pkcs8v2(1) }
}
asn1_struct! {
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY OPTIONAL
}
}
asn1_struct! {
EcPrivateKey ::= SEQUENCE {
version EcPrivateKeyVer,
privateKey OCTET STRING,
parameters [0] EXPLICIT OBJECT IDENTIFIER,
publicKey [1] EXPLICIT BIT STRING
}
}
asn1_enum! {
EcPrivateKeyVer ::= INTEGER { ecPrivkeyVer1(1) }
}
asn1_struct! {
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier REF,
subjectPublicKey BIT STRING
}
}
asn1_struct! {
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier REF,
digest OCTET STRING
}
}
asn1_struct! {
EcdsaSigValue ::= SEQUENCE {
r INTEGER,
s INTEGER
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::high::asn1::{Any, Encoder, Error, Null, OctetString, Parser, Type, oid};
#[test]
fn parse_public_key() {
let data = include_bytes!("testdata/rsapublickey-1k.bin");
let key = RSAPublicKey::parse(&mut Parser::new(data)).unwrap();
dbg!(&key);
dbg!(data.len());
assert_eq!(key.encoded_len(), data.len());
let mut buf = [0u8; 256];
let encode_len = key.encode(&mut Encoder::new(&mut buf)).unwrap();
dbg!(encode_len);
println!("{:?}", &buf[..encode_len]);
assert_eq!(data, &buf[..encode_len]);
truncation_check::<RSAPublicKey<'_>>(data);
roundtrip_check::<RSAPublicKey<'_>>(data);
}
#[test]
fn parse_private_key() {
let data = include_bytes!("testdata/rsaprivatekey-1k.bin");
let key = RSAPrivateKey::parse(&mut Parser::new(data)).unwrap();
dbg!(&key);
dbg!(data.len());
assert_eq!(key.encoded_len(), data.len());
truncation_check::<RSAPrivateKey<'_>>(data);
roundtrip_check::<RSAPrivateKey<'_>>(data);
}
#[test]
fn parse_pkcs8_key() {
let data = include_bytes!("testdata/nistp256-p8.bin");
truncation_check::<OneAsymmetricKey<'_>>(data);
roundtrip_check::<OneAsymmetricKey<'_>>(data);
let key = OneAsymmetricKey::parse(&mut Parser::new(data)).unwrap();
dbg!(&key);
assert_eq!(key.version, Pkcs8Version::Pkcs8v1);
assert_eq!(key.privateKeyAlgorithm.algorithm, oid::id_ecPublicKey);
assert_eq!(
key.privateKeyAlgorithm.parameters,
Some(Any::ObjectId(oid::id_prime256v1.clone()))
);
let inner = EcPrivateKey::parse(&mut Parser::new(key.privateKey.octets)).unwrap();
dbg!(&inner);
truncation_check::<EcPrivateKey<'_>>(key.privateKey.octets);
roundtrip_check::<EcPrivateKey<'_>>(key.privateKey.octets);
}
#[test]
fn parse_pkcs8_v2_key() {
let data = include_bytes!("testdata/ed25519-p8v2.bin");
truncation_check::<OneAsymmetricKey<'_>>(data);
roundtrip_check::<OneAsymmetricKey<'_>>(data);
let key = OneAsymmetricKey::parse(&mut Parser::new(data)).unwrap();
dbg!(&key);
assert_eq!(key.version, Pkcs8Version::Pkcs8v2);
assert_eq!(key.privateKeyAlgorithm.algorithm, oid::id_ed25519);
assert_eq!(key.privateKeyAlgorithm.parameters, None,);
dbg!(key.privateKey.octets);
let inner = OctetString::parse(&mut Parser::new(key.privateKey.octets)).unwrap();
dbg!(&inner);
truncation_check::<OctetString<'_>>(key.privateKey.octets);
roundtrip_check::<OctetString<'_>>(key.privateKey.octets);
}
#[test]
fn parse_sec1_key() {
let data = include_bytes!("testdata/nistp256-sec1.bin");
let key = EcPrivateKey::parse(&mut Parser::new(data)).unwrap();
dbg!(&key);
truncation_check::<EcPrivateKey<'_>>(data);
roundtrip_check::<EcPrivateKey<'_>>(data);
}
#[test]
fn parse_rsa_spki() {
let data = include_bytes!("testdata/spki-rsa-2k.bin");
truncation_check::<SubjectPublicKeyInfo<'_>>(data);
roundtrip_check::<SubjectPublicKeyInfo<'_>>(data);
let key = SubjectPublicKeyInfo::parse(&mut Parser::new(data)).unwrap();
dbg!(&key);
assert_eq!(key.algorithm.algorithm, oid::rsaEncryption);
assert_eq!(key.algorithm.parameters, Some(Any::Null(Null)));
let rsa_key = RSAPublicKey::parse(&mut Parser::new(key.subjectPublicKey.octets)).unwrap();
dbg!(&rsa_key);
truncation_check::<RSAPublicKey<'_>>(key.subjectPublicKey.octets);
roundtrip_check::<RSAPublicKey<'_>>(key.subjectPublicKey.octets);
}
#[test]
fn parse_ec_spki() {
let data = include_bytes!("testdata/spki-ec-nistp256.bin");
let key = SubjectPublicKeyInfo::parse(&mut Parser::new(data)).unwrap();
assert_eq!(key.algorithm.algorithm, oid::id_ecPublicKey);
assert_eq!(
key.algorithm.parameters,
Some(Any::ObjectId(oid::id_prime256v1.clone()))
);
assert_eq!(key.subjectPublicKey.octets[0], 0x04);
truncation_check::<SubjectPublicKeyInfo<'_>>(data);
roundtrip_check::<SubjectPublicKeyInfo<'_>>(data);
}
fn truncation_check<'a, T: Type<'a>>(bytes: &'a [u8]) {
T::from_bytes(bytes).unwrap();
for prefix in 0..bytes.len() {
assert_eq!(
T::from_bytes(&bytes[..prefix]).unwrap_err(),
Error::UnexpectedEof
);
}
}
fn roundtrip_check<'a, T: Type<'a>>(bytes: &'a [u8]) {
let t = T::from_bytes(bytes).unwrap();
dbg!(&t);
let mut buf = vec![0; bytes.len()];
let len = t.encode(&mut Encoder::new(&mut buf)).unwrap();
assert_eq!(&buf, bytes);
assert_eq!(len, bytes.len());
}
}