libp2p_identity/
rsa.rs

1// Copyright 2019 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21//! RSA keys.
22
23use std::{fmt, sync::Arc};
24
25use asn1_der::{
26    typed::{DerDecodable, DerEncodable, DerTypeView, Sequence},
27    Asn1DerError, Asn1DerErrorVariant, DerObject, Sink, VecBacking,
28};
29use ring::{
30    rand::SystemRandom,
31    signature::{self, KeyPair, RsaKeyPair, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_SHA256},
32};
33use zeroize::Zeroize;
34
35use super::error::*;
36
37/// An RSA keypair.
38#[derive(Clone)]
39pub struct Keypair(Arc<RsaKeyPair>);
40
41impl std::fmt::Debug for Keypair {
42    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
43        f.debug_struct("Keypair")
44            .field("public", self.0.public_key())
45            .finish()
46    }
47}
48
49impl Keypair {
50    /// Decode an RSA keypair from a DER-encoded private key in PKCS#1 RSAPrivateKey
51    /// format (i.e. unencrypted) as defined in [RFC3447].
52    ///
53    /// [RFC3447]: https://tools.ietf.org/html/rfc3447#appendix-A.1.2
54    pub fn try_decode_pkcs1(der: &mut [u8]) -> Result<Keypair, DecodingError> {
55        let kp = RsaKeyPair::from_der(der)
56            .map_err(|e| DecodingError::failed_to_parse("RSA DER PKCS#1 RSAPrivateKey", e))?;
57        der.zeroize();
58        Ok(Keypair(Arc::new(kp)))
59    }
60
61    /// Decode an RSA keypair from a DER-encoded private key in PKCS#8 PrivateKeyInfo
62    /// format (i.e. unencrypted) as defined in [RFC5208].
63    ///
64    /// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
65    pub fn try_decode_pkcs8(der: &mut [u8]) -> Result<Keypair, DecodingError> {
66        let kp = RsaKeyPair::from_pkcs8(der)
67            .map_err(|e| DecodingError::failed_to_parse("RSA PKCS#8 PrivateKeyInfo", e))?;
68        der.zeroize();
69        Ok(Keypair(Arc::new(kp)))
70    }
71
72    /// Get the public key from the keypair.
73    pub fn public(&self) -> PublicKey {
74        PublicKey(self.0.public_key().as_ref().to_vec())
75    }
76
77    /// Sign a message with this keypair.
78    pub fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SigningError> {
79        let mut signature = vec![0; self.0.public().modulus_len()];
80        let rng = SystemRandom::new();
81        match self.0.sign(&RSA_PKCS1_SHA256, &rng, data, &mut signature) {
82            Ok(()) => Ok(signature),
83            Err(e) => Err(SigningError::new("RSA").source(e)),
84        }
85    }
86}
87
88/// An RSA public key.
89#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
90pub struct PublicKey(Vec<u8>);
91
92impl PublicKey {
93    /// Verify an RSA signature on a message using the public key.
94    pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
95        let key = signature::UnparsedPublicKey::new(&RSA_PKCS1_2048_8192_SHA256, &self.0);
96        key.verify(msg, sig).is_ok()
97    }
98
99    /// Encode the RSA public key in DER as a PKCS#1 RSAPublicKey structure,
100    /// as defined in [RFC3447].
101    ///
102    /// [RFC3447]: https://tools.ietf.org/html/rfc3447#appendix-A.1.1
103    pub fn encode_pkcs1(&self) -> Vec<u8> {
104        // This is the encoding currently used in-memory, so it is trivial.
105        self.0.clone()
106    }
107
108    /// Encode the RSA public key in DER as an X.509 SubjectPublicKeyInfo structure,
109    /// as defined in [RFC5280].
110    ///
111    /// [RFC5280]: https://tools.ietf.org/html/rfc5280#section-4.1
112    pub fn encode_x509(&self) -> Vec<u8> {
113        let spki = Asn1SubjectPublicKeyInfo {
114            algorithmIdentifier: Asn1RsaEncryption {
115                algorithm: Asn1OidRsaEncryption,
116                parameters: (),
117            },
118            subjectPublicKey: Asn1SubjectPublicKey(self.clone()),
119        };
120        let mut buf = Vec::new();
121        spki.encode(&mut buf)
122            .map(|_| buf)
123            .expect("RSA X.509 public key encoding failed.")
124    }
125
126    /// Decode an RSA public key from a DER-encoded X.509 SubjectPublicKeyInfo
127    /// structure. See also `encode_x509`.
128    pub fn try_decode_x509(pk: &[u8]) -> Result<PublicKey, DecodingError> {
129        Asn1SubjectPublicKeyInfo::decode(pk)
130            .map_err(|e| DecodingError::failed_to_parse("RSA X.509", e))
131            .map(|spki| spki.subjectPublicKey.0)
132    }
133}
134
135impl fmt::Debug for PublicKey {
136    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137        f.write_str("PublicKey(PKCS1): ")?;
138        for byte in &self.0 {
139            write!(f, "{byte:x}")?;
140        }
141        Ok(())
142    }
143}
144
145//////////////////////////////////////////////////////////////////////////////
146// DER encoding / decoding of public keys
147//
148// Primer: http://luca.ntop.org/Teaching/Appunti/asn1.html
149// Playground: https://lapo.it/asn1js/
150
151/// A raw ASN1 OID.
152#[derive(Copy, Clone)]
153struct Asn1RawOid<'a> {
154    object: DerObject<'a>,
155}
156
157impl Asn1RawOid<'_> {
158    /// The underlying OID as byte literal.
159    pub(crate) fn oid(&self) -> &[u8] {
160        self.object.value()
161    }
162
163    /// Writes an OID raw `value` as DER-object to `sink`.
164    pub(crate) fn write<S: Sink>(value: &[u8], sink: &mut S) -> Result<(), Asn1DerError> {
165        DerObject::write(Self::TAG, value.len(), &mut value.iter(), sink)
166    }
167}
168
169impl<'a> DerTypeView<'a> for Asn1RawOid<'a> {
170    const TAG: u8 = 6;
171
172    fn object(&self) -> DerObject<'a> {
173        self.object
174    }
175}
176
177impl DerEncodable for Asn1RawOid<'_> {
178    fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
179        self.object.encode(sink)
180    }
181}
182
183impl<'a> DerDecodable<'a> for Asn1RawOid<'a> {
184    fn load(object: DerObject<'a>) -> Result<Self, Asn1DerError> {
185        if object.tag() != Self::TAG {
186            return Err(Asn1DerError::new(Asn1DerErrorVariant::InvalidData(
187                "DER object tag is not the object identifier tag.",
188            )));
189        }
190
191        Ok(Self { object })
192    }
193}
194
195/// The ASN.1 OID for "rsaEncryption".
196#[derive(Clone)]
197struct Asn1OidRsaEncryption;
198
199impl Asn1OidRsaEncryption {
200    /// The DER encoding of the object identifier (OID) 'rsaEncryption' for
201    /// RSA public keys defined for X.509 in [RFC-3279] and used in
202    /// SubjectPublicKeyInfo structures defined in [RFC-5280].
203    ///
204    /// [RFC-3279]: https://tools.ietf.org/html/rfc3279#section-2.3.1
205    /// [RFC-5280]: https://tools.ietf.org/html/rfc5280#section-4.1
206    const OID: [u8; 9] = [0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01];
207}
208
209impl DerEncodable for Asn1OidRsaEncryption {
210    fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
211        Asn1RawOid::write(&Self::OID, sink)
212    }
213}
214
215impl DerDecodable<'_> for Asn1OidRsaEncryption {
216    fn load(object: DerObject<'_>) -> Result<Self, Asn1DerError> {
217        match Asn1RawOid::load(object)?.oid() {
218            oid if oid == Self::OID => Ok(Self),
219            _ => Err(Asn1DerError::new(Asn1DerErrorVariant::InvalidData(
220                "DER object is not the 'rsaEncryption' identifier.",
221            ))),
222        }
223    }
224}
225
226/// The ASN.1 AlgorithmIdentifier for "rsaEncryption".
227struct Asn1RsaEncryption {
228    algorithm: Asn1OidRsaEncryption,
229    parameters: (),
230}
231
232impl DerEncodable for Asn1RsaEncryption {
233    fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
234        let mut algorithm_buf = Vec::new();
235        let algorithm = self.algorithm.der_object(VecBacking(&mut algorithm_buf))?;
236
237        let mut parameters_buf = Vec::new();
238        let parameters = self
239            .parameters
240            .der_object(VecBacking(&mut parameters_buf))?;
241
242        Sequence::write(&[algorithm, parameters], sink)
243    }
244}
245
246impl DerDecodable<'_> for Asn1RsaEncryption {
247    fn load(object: DerObject<'_>) -> Result<Self, Asn1DerError> {
248        let seq: Sequence = Sequence::load(object)?;
249
250        Ok(Self {
251            algorithm: seq.get_as(0)?,
252            parameters: seq.get_as(1)?,
253        })
254    }
255}
256
257/// The ASN.1 SubjectPublicKey inside a SubjectPublicKeyInfo,
258/// i.e. encoded as a DER BIT STRING.
259struct Asn1SubjectPublicKey(PublicKey);
260
261impl DerEncodable for Asn1SubjectPublicKey {
262    fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
263        let pk_der = &(self.0).0;
264        let mut bit_string = Vec::with_capacity(pk_der.len() + 1);
265        // The number of bits in pk_der is trivially always a multiple of 8,
266        // so there are always 0 "unused bits" signaled by the first byte.
267        bit_string.push(0u8);
268        bit_string.extend(pk_der);
269        DerObject::write(3, bit_string.len(), &mut bit_string.iter(), sink)?;
270        Ok(())
271    }
272}
273
274impl DerDecodable<'_> for Asn1SubjectPublicKey {
275    fn load(object: DerObject<'_>) -> Result<Self, Asn1DerError> {
276        if object.tag() != 3 {
277            return Err(Asn1DerError::new(Asn1DerErrorVariant::InvalidData(
278                "DER object tag is not the bit string tag.",
279            )));
280        }
281
282        let pk_der: Vec<u8> = object.value().iter().skip(1).cloned().collect();
283        // We don't parse pk_der further as an ASN.1 RsaPublicKey, since
284        // we only need the DER encoding for `verify`.
285        Ok(Self(PublicKey(pk_der)))
286    }
287}
288
289/// ASN.1 SubjectPublicKeyInfo
290#[allow(non_snake_case)]
291struct Asn1SubjectPublicKeyInfo {
292    algorithmIdentifier: Asn1RsaEncryption,
293    subjectPublicKey: Asn1SubjectPublicKey,
294}
295
296impl DerEncodable for Asn1SubjectPublicKeyInfo {
297    fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
298        let mut identifier_buf = Vec::new();
299        let identifier = self
300            .algorithmIdentifier
301            .der_object(VecBacking(&mut identifier_buf))?;
302
303        let mut key_buf = Vec::new();
304        let key = self.subjectPublicKey.der_object(VecBacking(&mut key_buf))?;
305
306        Sequence::write(&[identifier, key], sink)
307    }
308}
309
310impl DerDecodable<'_> for Asn1SubjectPublicKeyInfo {
311    fn load(object: DerObject<'_>) -> Result<Self, Asn1DerError> {
312        let seq: Sequence = Sequence::load(object)?;
313
314        Ok(Self {
315            algorithmIdentifier: seq.get_as(0)?,
316            subjectPublicKey: seq.get_as(1)?,
317        })
318    }
319}
320
321#[cfg(test)]
322mod tests {
323    use quickcheck::*;
324
325    use super::*;
326
327    const KEY1: &[u8] = include_bytes!("test/rsa-2048.pk8");
328    const KEY2: &[u8] = include_bytes!("test/rsa-3072.pk8");
329    const KEY3: &[u8] = include_bytes!("test/rsa-4096.pk8");
330
331    #[derive(Clone, Debug)]
332    struct SomeKeypair(Keypair);
333
334    impl Arbitrary for SomeKeypair {
335        fn arbitrary(g: &mut Gen) -> SomeKeypair {
336            let mut key = g.choose(&[KEY1, KEY2, KEY3]).unwrap().to_vec();
337            SomeKeypair(Keypair::try_decode_pkcs8(&mut key).unwrap())
338        }
339    }
340
341    #[test]
342    fn rsa_from_pkcs8() {
343        assert!(Keypair::try_decode_pkcs8(&mut KEY1.to_vec()).is_ok());
344        assert!(Keypair::try_decode_pkcs8(&mut KEY2.to_vec()).is_ok());
345        assert!(Keypair::try_decode_pkcs8(&mut KEY3.to_vec()).is_ok());
346    }
347
348    #[test]
349    fn rsa_x509_encode_decode() {
350        fn prop(SomeKeypair(kp): SomeKeypair) -> Result<bool, String> {
351            let pk = kp.public();
352            PublicKey::try_decode_x509(&pk.encode_x509())
353                .map_err(|e| e.to_string())
354                .map(|pk2| pk2 == pk)
355        }
356        QuickCheck::new().tests(10).quickcheck(prop as fn(_) -> _);
357    }
358
359    #[test]
360    fn rsa_sign_verify() {
361        fn prop(SomeKeypair(kp): SomeKeypair, msg: Vec<u8>) -> Result<bool, SigningError> {
362            kp.sign(&msg).map(|s| kp.public().verify(&msg, &s))
363        }
364        QuickCheck::new()
365            .tests(10)
366            .quickcheck(prop as fn(_, _) -> _);
367    }
368}