libp2prs_core/identity/
rsa.rs1use super::error::*;
25use asn1_der::{Asn1Der, Asn1DerError, DerObject, DerTag, DerValue, FromDerObject, IntoDerObject};
26use lazy_static::lazy_static;
27use ring::rand::SystemRandom;
28use ring::signature::KeyPair;
29use ring::signature::{self, RsaKeyPair, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_SHA256};
30use std::{
31 fmt::{self, Write},
32 sync::Arc,
33};
34use zeroize::Zeroize;
35
36#[derive(Clone)]
38pub struct Keypair(Arc<RsaKeyPair>);
39
40impl Keypair {
41 pub fn from_pkcs8(der: &mut [u8]) -> Result<Keypair, DecodingError> {
46 let kp = RsaKeyPair::from_pkcs8(&der).map_err(|e| DecodingError::new("RSA PKCS#8 PrivateKeyInfo").source(e))?;
47 der.zeroize();
48 Ok(Keypair(Arc::new(kp)))
49 }
50
51 pub fn public(&self) -> PublicKey {
53 PublicKey(self.0.public_key().as_ref().to_vec())
54 }
55
56 pub fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SigningError> {
58 let mut signature = vec![0; self.0.public_modulus_len()];
59 let rng = SystemRandom::new();
60 match self.0.sign(&RSA_PKCS1_SHA256, &rng, &data, &mut signature) {
61 Ok(()) => Ok(signature),
62 Err(e) => Err(SigningError::new("RSA").source(e)),
63 }
64 }
65}
66
67#[derive(Clone, PartialEq, Eq)]
69pub struct PublicKey(Vec<u8>);
70
71impl PublicKey {
72 pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
74 let key = signature::UnparsedPublicKey::new(&RSA_PKCS1_2048_8192_SHA256, &self.0);
75 key.verify(msg, sig).is_ok()
76 }
77
78 pub fn encode_pkcs1(&self) -> Vec<u8> {
83 self.0.clone()
85 }
86
87 pub fn encode_x509(&self) -> Vec<u8> {
92 let spki = Asn1SubjectPublicKeyInfo {
93 algorithmIdentifier: Asn1RsaEncryption {
94 algorithm: Asn1OidRsaEncryption(),
95 parameters: (),
96 },
97 subjectPublicKey: Asn1SubjectPublicKey(self.clone()),
98 };
99 let mut buf = vec![0u8; spki.serialized_len()];
100 spki.serialize(buf.iter_mut())
101 .map(|_| buf)
102 .expect("RSA X.509 public key encoding failed.")
103 }
104
105 pub fn decode_x509(pk: &[u8]) -> Result<PublicKey, DecodingError> {
108 Asn1SubjectPublicKeyInfo::deserialize(pk.iter())
109 .map_err(|e| DecodingError::new("RSA X.509").source(e))
110 .map(|spki| spki.subjectPublicKey.0)
111 }
112}
113
114impl fmt::Debug for PublicKey {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 let bytes = &self.0;
117 let mut hex = String::with_capacity(bytes.len() * 2);
118
119 for byte in bytes {
120 write!(hex, "{:02x}", byte).expect("Can't fail on writing to string");
121 }
122
123 f.debug_struct("PublicKey").field("pkcs1", &hex).finish()
124 }
125}
126
127lazy_static! {
134 static ref OID_RSA_ENCRYPTION_DER: DerObject =
141 DerObject {
142 tag: DerTag::x06,
143 value: DerValue {
144 data: vec![ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 ]
145 }
146 };
147}
148
149#[derive(Clone)]
151struct Asn1OidRsaEncryption();
152
153impl IntoDerObject for Asn1OidRsaEncryption {
154 fn into_der_object(self) -> DerObject {
155 OID_RSA_ENCRYPTION_DER.clone()
156 }
157 fn serialized_len(&self) -> usize {
158 OID_RSA_ENCRYPTION_DER.serialized_len()
159 }
160}
161
162impl FromDerObject for Asn1OidRsaEncryption {
163 fn from_der_object(o: DerObject) -> Result<Self, Asn1DerError> {
164 if o.tag != DerTag::x06 {
165 return Err(Asn1DerError::InvalidTag);
166 }
167 if o.value != OID_RSA_ENCRYPTION_DER.value {
168 return Err(Asn1DerError::InvalidEncoding);
169 }
170 Ok(Asn1OidRsaEncryption())
171 }
172}
173
174#[derive(Asn1Der)]
176struct Asn1RsaEncryption {
177 algorithm: Asn1OidRsaEncryption,
178 parameters: (),
179}
180
181struct Asn1SubjectPublicKey(PublicKey);
184
185impl IntoDerObject for Asn1SubjectPublicKey {
186 fn into_der_object(self) -> DerObject {
187 let pk_der = (self.0).0;
188 let mut bit_string = Vec::with_capacity(pk_der.len() + 1);
189 bit_string.push(0u8);
192 bit_string.extend(pk_der);
193 DerObject::new(DerTag::x03, bit_string.into())
194 }
195 fn serialized_len(&self) -> usize {
196 DerObject::compute_serialized_len((self.0).0.len() + 1)
197 }
198}
199
200impl FromDerObject for Asn1SubjectPublicKey {
201 fn from_der_object(o: DerObject) -> Result<Self, Asn1DerError> {
202 if o.tag != DerTag::x03 {
203 return Err(Asn1DerError::InvalidTag);
204 }
205 let pk_der: Vec<u8> = o.value.data.into_iter().skip(1).collect();
206 Ok(Asn1SubjectPublicKey(PublicKey(pk_der)))
209 }
210}
211
212#[derive(Asn1Der)]
214#[allow(non_snake_case)]
215struct Asn1SubjectPublicKeyInfo {
216 algorithmIdentifier: Asn1RsaEncryption,
217 subjectPublicKey: Asn1SubjectPublicKey,
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223 use quickcheck::*;
224 use rand::seq::SliceRandom;
225 use std::fmt;
226
227 const KEY1: &[u8] = include_bytes!("test/rsa-2048.pk8");
228 const KEY2: &[u8] = include_bytes!("test/rsa-3072.pk8");
229 const KEY3: &[u8] = include_bytes!("test/rsa-4096.pk8");
230
231 #[derive(Clone)]
232 struct SomeKeypair(Keypair);
233
234 impl fmt::Debug for SomeKeypair {
235 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
236 write!(f, "SomeKeypair")
237 }
238 }
239
240 impl Arbitrary for SomeKeypair {
241 fn arbitrary<G: Gen>(g: &mut G) -> SomeKeypair {
242 let mut key = [KEY1, KEY2, KEY3].choose(g).unwrap().to_vec();
243 SomeKeypair(Keypair::from_pkcs8(&mut key).unwrap())
244 }
245 }
246
247 #[test]
248 fn rsa_from_pkcs8() {
249 assert!(Keypair::from_pkcs8(&mut KEY1.to_vec()).is_ok());
250 assert!(Keypair::from_pkcs8(&mut KEY2.to_vec()).is_ok());
251 assert!(Keypair::from_pkcs8(&mut KEY3.to_vec()).is_ok());
252 }
253
254 #[test]
255 fn rsa_x509_encode_decode() {
256 fn prop(SomeKeypair(kp): SomeKeypair) -> Result<bool, String> {
257 let pk = kp.public();
258 PublicKey::decode_x509(&pk.encode_x509())
259 .map_err(|e| e.to_string())
260 .map(|pk2| pk2 == pk)
261 }
262 QuickCheck::new().tests(10).quickcheck(prop as fn(_) -> _);
263 }
264
265 #[test]
266 fn rsa_sign_verify() {
267 fn prop(SomeKeypair(kp): SomeKeypair, msg: Vec<u8>) -> Result<bool, SigningError> {
268 kp.sign(&msg).map(|s| kp.public().verify(&msg, &s))
269 }
270 QuickCheck::new().tests(10).quickcheck(prop as fn(_, _) -> _);
271 }
272}