1 use crate::{oids, AlgorithmIdentifier};
2 use picky_asn1::wrapper::{BitStringAsn1, BitStringAsn1Container, IntegerAsn1, OctetStringAsn1};
3 use serde::{de, ser, Deserialize, Serialize};
4 use std::fmt;
5 
6 #[derive(Debug, PartialEq, Clone)]
7 pub enum PublicKey {
8     RSA(EncapsulatedRSAPublicKey),
9     EC(EncapsulatedECPoint),
10     Ed(EncapsulatedECPoint),
11 }
12 
13 #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
14 pub struct RSAPublicKey {
15     pub modulus: IntegerAsn1,         // n
16     pub public_exponent: IntegerAsn1, // e
17 }
18 pub type EncapsulatedRSAPublicKey = BitStringAsn1Container<RSAPublicKey>;
19 
20 pub type ECPoint = OctetStringAsn1;
21 
22 pub type EncapsulatedECPoint = BitStringAsn1;
23 
24 #[derive(Debug, PartialEq, Clone)]
25 pub struct SubjectPublicKeyInfo {
26     pub algorithm: AlgorithmIdentifier,
27     pub subject_public_key: PublicKey,
28 }
29 
30 impl SubjectPublicKeyInfo {
new_rsa_key(modulus: IntegerAsn1, public_exponent: IntegerAsn1) -> Self31     pub fn new_rsa_key(modulus: IntegerAsn1, public_exponent: IntegerAsn1) -> Self {
32         Self {
33             algorithm: AlgorithmIdentifier::new_rsa_encryption(),
34             subject_public_key: PublicKey::RSA(
35                 RSAPublicKey {
36                     modulus,
37                     public_exponent,
38                 }
39                 .into(),
40             ),
41         }
42     }
43 }
44 
45 impl ser::Serialize for SubjectPublicKeyInfo {
serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error> where S: ser::Serializer,46     fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
47     where
48         S: ser::Serializer,
49     {
50         use ser::SerializeSeq;
51         let mut seq = serializer.serialize_seq(Some(2))?;
52         seq.serialize_element(&self.algorithm)?;
53         match &self.subject_public_key {
54             PublicKey::RSA(key) => seq.serialize_element(key)?,
55             PublicKey::EC(key) => seq.serialize_element(key)?,
56             PublicKey::Ed(key) => seq.serialize_element(key)?,
57         }
58         seq.end()
59     }
60 }
61 
62 impl<'de> de::Deserialize<'de> for SubjectPublicKeyInfo {
deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error> where D: de::Deserializer<'de>,63     fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
64     where
65         D: de::Deserializer<'de>,
66     {
67         struct Visitor;
68 
69         impl<'de> de::Visitor<'de> for Visitor {
70             type Value = SubjectPublicKeyInfo;
71 
72             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
73                 formatter.write_str("a valid DER-encoded subject public key info")
74             }
75 
76             fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
77             where
78                 A: de::SeqAccess<'de>,
79             {
80                 let algorithm: AlgorithmIdentifier = seq_next_element!(seq, AlgorithmIdentifier, "algorithm oid");
81 
82                 let subject_public_key = match Into::<String>::into(algorithm.oid()).as_str() {
83                     oids::RSA_ENCRYPTION => PublicKey::RSA(seq_next_element!(seq, SubjectPublicKeyInfo, "rsa key")),
84                     oids::EC_PUBLIC_KEY => {
85                         PublicKey::EC(seq_next_element!(seq, SubjectPublicKeyInfo, "elliptic curves key"))
86                     }
87                     oids::ED25519 => PublicKey::Ed(seq_next_element!(seq, SubjectPublicKeyInfo, "curve25519 key")),
88                     _ => {
89                         return Err(serde_invalid_value!(
90                             SubjectPublicKeyInfo,
91                             "unsupported algorithm (unknown oid)",
92                             "a supported algorithm"
93                         ));
94                     }
95                 };
96 
97                 Ok(SubjectPublicKeyInfo {
98                     algorithm,
99                     subject_public_key,
100                 })
101             }
102         }
103 
104         deserializer.deserialize_seq(Visitor)
105     }
106 }
107 
108 #[cfg(test)]
109 mod tests {
110     use super::*;
111     use num_bigint_dig::BigInt;
112 
113     #[test]
rsa_subject_public_key_info()114     fn rsa_subject_public_key_info() {
115         let encoded = base64::decode(
116             "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsiLoIx\
117              mXaZAFRBKtHYZhiF8m+pYR+xGIpupvsdDEvKO92D6fIccgVLIW6p6sSNk\
118              oXx5J6KDSMbA/chy5M6pRvJkaCXCI4zlCPMYvPhI8OxN3RYPfdQTLpgPy\
119              wrlfdn2CAum7o4D8nR4NJacB3NfPnS9tsJ2L3p5iHviuTB4xm03IKmPPq\
120              saJy+nXUFC1XS9E/PseVHRuNvKa7WmlwSZngQzKAVSIwqpgCc+oP1pKEe\
121              J0M3LHFo8ao5SuzhfXUIGrPnkUKEE3m7B0b8xXZfP1N6ELoonWDK+RMgY\
122              IBaZdgBhPfHxF8KfTHvSzcUzWZojuR+ynaFL9AJK+8RiXnB4CJwIDAQAB",
123         )
124         .expect("invalid base64");
125 
126         // RSA algorithm identifier
127 
128         let algorithm = AlgorithmIdentifier::new_rsa_encryption();
129         check_serde!(algorithm: AlgorithmIdentifier in encoded[4..19]);
130 
131         // RSA modulus and public exponent
132 
133         let modulus = IntegerAsn1::from_bytes_be_signed(vec![
134             0x00, 0xb2, 0x22, 0xe8, 0x23, 0x19, 0x97, 0x69, 0x90, 0x5, 0x44, 0x12, 0xad, 0x1d, 0x86, 0x61, 0x88, 0x5f,
135             0x26, 0xfa, 0x96, 0x11, 0xfb, 0x11, 0x88, 0xa6, 0xea, 0x6f, 0xb1, 0xd0, 0xc4, 0xbc, 0xa3, 0xbd, 0xd8, 0x3e,
136             0x9f, 0x21, 0xc7, 0x20, 0x54, 0xb2, 0x16, 0xea, 0x9e, 0xac, 0x48, 0xd9, 0x28, 0x5f, 0x1e, 0x49, 0xe8, 0xa0,
137             0xd2, 0x31, 0xb0, 0x3f, 0x72, 0x1c, 0xb9, 0x33, 0xaa, 0x51, 0xbc, 0x99, 0x1a, 0x9, 0x70, 0x88, 0xe3, 0x39,
138             0x42, 0x3c, 0xc6, 0x2f, 0x3e, 0x12, 0x3c, 0x3b, 0x13, 0x77, 0x45, 0x83, 0xdf, 0x75, 0x4, 0xcb, 0xa6, 0x3,
139             0xf2, 0xc2, 0xb9, 0x5f, 0x76, 0x7d, 0x82, 0x2, 0xe9, 0xbb, 0xa3, 0x80, 0xfc, 0x9d, 0x1e, 0xd, 0x25, 0xa7,
140             0x1, 0xdc, 0xd7, 0xcf, 0x9d, 0x2f, 0x6d, 0xb0, 0x9d, 0x8b, 0xde, 0x9e, 0x62, 0x1e, 0xf8, 0xae, 0x4c, 0x1e,
141             0x31, 0x9b, 0x4d, 0xc8, 0x2a, 0x63, 0xcf, 0xaa, 0xc6, 0x89, 0xcb, 0xe9, 0xd7, 0x50, 0x50, 0xb5, 0x5d, 0x2f,
142             0x44, 0xfc, 0xfb, 0x1e, 0x54, 0x74, 0x6e, 0x36, 0xf2, 0x9a, 0xed, 0x69, 0xa5, 0xc1, 0x26, 0x67, 0x81, 0xc,
143             0xca, 0x1, 0x54, 0x88, 0xc2, 0xaa, 0x60, 0x9, 0xcf, 0xa8, 0x3f, 0x5a, 0x4a, 0x11, 0xe2, 0x74, 0x33, 0x72,
144             0xc7, 0x16, 0x8f, 0x1a, 0xa3, 0x94, 0xae, 0xce, 0x17, 0xd7, 0x50, 0x81, 0xab, 0x3e, 0x79, 0x14, 0x28, 0x41,
145             0x37, 0x9b, 0xb0, 0x74, 0x6f, 0xcc, 0x57, 0x65, 0xf3, 0xf5, 0x37, 0xa1, 0xb, 0xa2, 0x89, 0xd6, 0xc, 0xaf,
146             0x91, 0x32, 0x6, 0x8, 0x5, 0xa6, 0x5d, 0x80, 0x18, 0x4f, 0x7c, 0x7c, 0x45, 0xf0, 0xa7, 0xd3, 0x1e, 0xf4,
147             0xb3, 0x71, 0x4c, 0xd6, 0x66, 0x88, 0xee, 0x47, 0xec, 0xa7, 0x68, 0x52, 0xfd, 0x0, 0x92, 0xbe, 0xf1, 0x18,
148             0x97, 0x9c, 0x1e, 0x2, 0x27,
149         ]);
150         check_serde!(modulus: IntegerAsn1 in encoded[28..289]);
151 
152         let public_exponent: IntegerAsn1 = BigInt::from(65537).to_signed_bytes_be().into();
153         check_serde!(public_exponent: IntegerAsn1 in encoded[289..294]);
154 
155         // RSA public key
156 
157         let subject_public_key: EncapsulatedRSAPublicKey = RSAPublicKey {
158             modulus,
159             public_exponent,
160         }
161         .into();
162         check_serde!(subject_public_key: EncapsulatedRSAPublicKey in encoded[19..294]);
163 
164         // full encode / decode
165 
166         let info = SubjectPublicKeyInfo {
167             algorithm,
168             subject_public_key: PublicKey::RSA(subject_public_key),
169         };
170         check_serde!(info: SubjectPublicKeyInfo in encoded);
171     }
172 }
173