1mod ecc;
6mod rsa;
7
8pub use ecc::*;
9pub use rsa::*;
10
11use crate::key::KeyError;
12use rasn::{
13 types::{Any, Integer, ObjectIdentifier, OctetString, SetOf},
14 AsnType, Decode, Decoder, Encode,
15};
16use std::{borrow::Cow, fmt};
17
18pub const OID_EC_PUBLIC_KEY: ObjectIdentifier =
19 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 10_045, 2, 1]));
20pub const OID_SHA1_WITH_RSA_ENCRYPTION: ObjectIdentifier =
21 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 113_549, 1, 1, 5]));
22pub const OID_SHA256_WITH_RSA_ENCRYPTION: ObjectIdentifier =
23 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 113_549, 1, 1, 11]));
24pub const OID_SHA384_WITH_RSA_ENCRYPTION: ObjectIdentifier =
25 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 113_549, 1, 1, 12]));
26pub const OID_SHA512_WITH_RSA_ENCRYPTION: ObjectIdentifier =
27 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 113_549, 1, 1, 13]));
28pub const OID_ECDSA_WITH_SHA256: ObjectIdentifier =
29 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 10045, 4, 3, 2]));
30pub const OID_ECDSA_WITH_SHA384: ObjectIdentifier =
31 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 10045, 4, 3, 3]));
32pub const OID_ECDSA_WITH_SHA512: ObjectIdentifier =
33 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 10045, 4, 3, 4]));
34pub const OID_RSA_ENCRYPTION: ObjectIdentifier =
35 ObjectIdentifier::new_unchecked(Cow::Borrowed(&[1, 2, 840, 113_549, 1, 1, 1]));
36
37#[derive(AsnType, Decode, Encode, Debug)]
38pub struct Pkcs8AlgorithmIdentifier {
39 pub algorithm: ObjectIdentifier,
40 pub parameters: Option<Any>,
41}
42
43#[derive(AsnType, Decode, Encode, Debug)]
44pub struct Pkcs8PrivateKeyInfo {
45 pub version: Integer,
46 pub private_key_algorithm: Pkcs8AlgorithmIdentifier,
47 pub private_key: OctetString,
48 #[rasn(tag(context, 0))]
49 pub attributes: Option<SetOf<Any>>,
50}
51
52#[derive(Clone)]
53pub enum ExternalKey {
54 Rsa2048(Box<::rsa::RsaPrivateKey>),
55 Rsa3072(Box<::rsa::RsaPrivateKey>),
56 Rsa4096(Box<::rsa::RsaPrivateKey>),
57 EccP256(Box<::p256::SecretKey>),
58 EccP384(Box<::p384::SecretKey>),
59 EccP521(Box<::p521::SecretKey>),
60}
61
62impl fmt::Debug for ExternalKey {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 match self {
65 Self::Rsa2048(_) => f.debug_tuple("rsa-2048").field(&"<sensitive>").finish(),
66 Self::Rsa3072(_) => f.debug_tuple("rsa-3072").field(&"<sensitive>").finish(),
67 Self::Rsa4096(_) => f.debug_tuple("rsa-4096").field(&"<sensitive>").finish(),
68 Self::EccP256(_) => f
69 .debug_tuple("ecc-nist-p256")
70 .field(&"<sensitive>")
71 .finish(),
72 Self::EccP384(_) => f
73 .debug_tuple("ecc-nist-p384")
74 .field(&"<sensitive>")
75 .finish(),
76 Self::EccP521(_) => f
77 .debug_tuple("ecc-nist-p521")
78 .field(&"<sensitive>")
79 .finish(),
80 }
81 }
82}
83
84impl ExternalKey {
85 pub fn from_der(der_bytes: &[u8]) -> Result<ExternalKey, KeyError> {
91 if let Ok(pkcs8_key) = rasn::der::decode::<Pkcs8PrivateKeyInfo>(der_bytes) {
92 let oid = &pkcs8_key.private_key_algorithm.algorithm;
93 let inner_key_bytes = pkcs8_key.private_key.as_ref();
94
95 if oid == &OID_RSA_ENCRYPTION {
96 return parse_rsa_from_der(inner_key_bytes);
97 }
98 if oid == &OID_EC_PUBLIC_KEY {
99 let params_any = pkcs8_key.private_key_algorithm.parameters.as_ref().ok_or(
100 KeyError::ValueConversionFailed(
101 "missing curve OID in AlgorithmIdentifier".to_string(),
102 ),
103 )?;
104 let curve_oid: ObjectIdentifier = rasn::der::decode(params_any.as_ref())?;
105 return parse_ecc_from_der(inner_key_bytes, Some(&curve_oid));
106 }
107 return Err(KeyError::UnsupportedOid(oid.to_string()));
108 }
109
110 if let Ok(key) = parse_rsa_from_der(der_bytes) {
111 return Ok(key);
112 }
113
114 if let Ok(key) = parse_ecc_from_der(der_bytes, None) {
115 return Ok(key);
116 }
117
118 Err(KeyError::InvalidFormat)
119 }
120}