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