1
//! Re-exporting RSA implementations.
2
//!
3
//! This module can currently handle public keys and signature
4
//! verification used in the Tor directory protocol and
5
//! similar places.
6
//!
7
//! Currently, that means validating PKCSv1 signatures, and encoding
8
//! and decoding RSA public keys from DER.
9
//!
10
//! # Limitations:
11
//!
12
//! Currently missing are support for signing and RSA-OEAP.  In Tor,
13
//! RSA signing is only needed for relays and authorities, and
14
//! RSA-OAEP padding is only needed for the (obsolete) TAP protocol.
15
//!
16
//! This module should expose RustCrypto trait-based wrappers,
17
//! but the [`rsa`] crate didn't support them as of initial writing.
18
use arrayref::array_ref;
19
use rsa::pkcs1::{FromRsaPrivateKey, FromRsaPublicKey};
20
use std::fmt;
21
use subtle::{Choice, ConstantTimeEq};
22
use zeroize::Zeroize;
23

            
24
/// How many bytes are in an "RSA ID"?  (This is a legacy tor
25
/// concept, and refers to identifying a relay by a SHA1 digest
26
/// of its RSA public identity key.)
27
pub const RSA_ID_LEN: usize = 20;
28

            
29
/// An identifier for a Tor relay, based on its legacy RSA identity
30
/// key.  These are used all over the Tor protocol.
31
///
32
/// Note that for modern purposes, you should almost always identify a
33
/// relay by its [`Ed25519Identity`](crate::pk::ed25519::Ed25519Identity)
34
/// instead of by this kind of identity key.
35
1856805
#[derive(Clone, Copy, Hash, Zeroize, Ord, PartialOrd)]
36
#[allow(clippy::derive_hash_xor_eq)]
37
pub struct RsaIdentity {
38
    /// SHA1 digest of a DER encoded public key.
39
    id: [u8; RSA_ID_LEN],
40
}
41

            
42
impl ConstantTimeEq for RsaIdentity {
43
13741695
    fn ct_eq(&self, other: &Self) -> Choice {
44
13741695
        self.id.ct_eq(&other.id)
45
13741695
    }
46
}
47

            
48
impl PartialEq<RsaIdentity> for RsaIdentity {
49
13738923
    fn eq(&self, rhs: &RsaIdentity) -> bool {
50
13738923
        self.ct_eq(rhs).unwrap_u8() == 1
51
13738923
    }
52
}
53

            
54
impl Eq for RsaIdentity {}
55

            
56
impl fmt::Display for RsaIdentity {
57
891
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58
891
        write!(f, "${}", hex::encode(&self.id[..]))
59
891
    }
60
}
61
impl fmt::Debug for RsaIdentity {
62
792
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63
792
        write!(f, "RsaIdentity {{ {} }}", self)
64
792
    }
65
}
66

            
67
impl serde::Serialize for RsaIdentity {
68
26
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
69
26
    where
70
26
        S: serde::Serializer,
71
26
    {
72
26
        if serializer.is_human_readable() {
73
25
            serializer.serialize_str(&hex::encode(&self.id[..]))
74
        } else {
75
1
            serializer.serialize_bytes(&self.id[..])
76
        }
77
26
    }
78
}
79

            
80
impl<'de> serde::Deserialize<'de> for RsaIdentity {
81
28
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82
28
    where
83
28
        D: serde::Deserializer<'de>,
84
28
    {
85
28
        if deserializer.is_human_readable() {
86
            /// Deserialization helper
87
            struct RsaIdentityVisitor;
88
            impl<'de> serde::de::Visitor<'de> for RsaIdentityVisitor {
89
                type Value = RsaIdentity;
90
                fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
91
                    fmt.write_str("hex-encoded RSA identity")
92
                }
93
26
                fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
94
26
                where
95
26
                    E: serde::de::Error,
96
26
                {
97
26
                    RsaIdentity::from_hex(s)
98
26
                        .ok_or_else(|| E::custom("wrong encoding for RSA identity"))
99
26
                }
100
            }
101

            
102
26
            deserializer.deserialize_str(RsaIdentityVisitor)
103
        } else {
104
            /// Deserialization helper
105
            struct RsaIdentityVisitor;
106
            impl<'de> serde::de::Visitor<'de> for RsaIdentityVisitor {
107
                type Value = RsaIdentity;
108
                fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
109
                    fmt.write_str("RSA identity")
110
                }
111
2
                fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
112
2
                where
113
2
                    E: serde::de::Error,
114
2
                {
115
2
                    RsaIdentity::from_bytes(bytes)
116
2
                        .ok_or_else(|| E::custom("wrong length for RSA identity"))
117
2
                }
118
            }
119
2
            deserializer.deserialize_bytes(RsaIdentityVisitor)
120
        }
121
28
    }
122
}
123

            
124
impl RsaIdentity {
125
    /// Expose an RsaIdentity as a slice of bytes.
126
339405
    pub fn as_bytes(&self) -> &[u8] {
127
339405
        &self.id[..]
128
339405
    }
129
    /// Construct an RsaIdentity from a slice of bytes.
130
    ///
131
    /// Returns None if the input is not of the correct length.
132
    ///
133
    /// ```
134
    /// use tor_llcrypto::pk::rsa::RsaIdentity;
135
    ///
136
    /// let bytes = b"xyzzyxyzzyxyzzyxyzzy";
137
    /// let id = RsaIdentity::from_bytes(bytes);
138
    /// assert_eq!(id.unwrap().as_bytes(), bytes);
139
    ///
140
    /// let truncated = b"xyzzy";
141
    /// let id = RsaIdentity::from_bytes(truncated);
142
    /// assert_eq!(id, None);
143
    /// ```
144
4257
    pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
145
4257
        if bytes.len() == RSA_ID_LEN {
146
4191
            Some(RsaIdentity {
147
4191
                id: *array_ref![bytes, 0, RSA_ID_LEN],
148
4191
            })
149
        } else {
150
66
            None
151
        }
152
4257
    }
153
    /// Decode an `RsaIdentity` from a hexadecimal string.
154
    ///
155
    /// The string must have no spaces, or any extra characters.
156
230868
    pub fn from_hex(s: &str) -> Option<Self> {
157
230868
        let mut array = [0_u8; 20];
158
230868
        match hex::decode_to_slice(s, &mut array) {
159
594
            Err(_) => None,
160
230274
            Ok(()) => Some(RsaIdentity::from(array)),
161
        }
162
230868
    }
163
}
164

            
165
impl From<[u8; 20]> for RsaIdentity {
166
496980
    fn from(id: [u8; 20]) -> RsaIdentity {
167
496980
        RsaIdentity { id }
168
496980
    }
169
}
170

            
171
/// An RSA public key.
172
///
173
/// This implementation is a simple wrapper so that we can define new
174
/// methods and traits on the type.
175
1230
#[derive(Clone, Debug)]
176
pub struct PublicKey(rsa::RsaPublicKey);
177

            
178
/// An RSA private key.
179
///
180
/// This is not so useful at present, since Arti currently only has
181
/// client support, and Tor clients never actually need RSA private
182
/// keys.
183
pub struct PrivateKey(rsa::RsaPrivateKey);
184

            
185
impl PrivateKey {
186
    /// Return the public component of this key.
187
33
    pub fn to_public_key(&self) -> PublicKey {
188
33
        PublicKey(self.0.to_public_key())
189
33
    }
190
    /// Construct a PrivateKey from DER pkcs1 encoding.
191
33
    pub fn from_der(der: &[u8]) -> Option<Self> {
192
33
        Some(PrivateKey(rsa::RsaPrivateKey::from_pkcs1_der(der).ok()?))
193
33
    }
194
    // ....
195
}
196
impl PublicKey {
197
    /// Return true iff the exponent for this key is the same
198
    /// number as 'e'.
199
1916
    pub fn exponent_is(&self, e: u32) -> bool {
200
1916
        use rsa::PublicKeyParts;
201
1916
        *self.0.e() == rsa::BigUint::new(vec![e])
202
1916
    }
203
    /// Return the number of bits in the modulus for this key.
204
1883
    pub fn bits(&self) -> usize {
205
1883
        use rsa::PublicKeyParts;
206
1883
        self.0.n().bits()
207
1883
    }
208
    /// Try to check a signature (as used in Tor.)  The signed hash
209
    /// should be in 'hashed', and the alleged signature in 'sig'.
210
    ///
211
    /// Tor uses RSA-PKCSv1 signatures, with hash algorithm OIDs
212
    /// omitted.
213
1353
    pub fn verify(&self, hashed: &[u8], sig: &[u8]) -> Result<(), signature::Error> {
214
1353
        use rsa::PublicKey;
215
1353
        let padding = rsa::PaddingScheme::new_pkcs1v15_sign(None);
216
1353
        self.0
217
1353
            .verify(padding, hashed, sig)
218
1353
            .map_err(|_| signature::Error::new())
219
1353
    }
220
    /// Decode an alleged DER byte string into a PublicKey.
221
    ///
222
    /// Return None  if the DER string does not have a valid PublicKey.
223
    ///
224
    /// (This function expects an RsaPublicKey, as used by Tor.  It
225
    /// does not expect or accept a PublicKeyInfo.)
226
2477
    pub fn from_der(der: &[u8]) -> Option<Self> {
227
2477
        Some(PublicKey(rsa::RsaPublicKey::from_pkcs1_der(der).ok()?))
228
2477
    }
229
    /// Encode this public key into the DER format as used by Tor.
230
    ///
231
    /// The result is an RsaPublicKey, not a PublicKeyInfo.
232
2477
    pub fn to_der(&self) -> Vec<u8> {
233
2477
        // There seem to be version issues with these two
234
2477
        // versions of bigint: yuck!
235
2477
        use rsa::BigUint; // not the same as the one in simple_asn1.
236
2477
        use rsa::PublicKeyParts;
237
2477
        use simple_asn1::{ASN1Block, BigInt};
238
2477
        /// Helper: convert a BigUInt to signed asn1.
239
4954
        fn to_asn1_int(x: &BigUint) -> ASN1Block {
240
4954
            // We stick a "0" on the front so that we can used
241
4954
            // from_signed_bytes_be.  The 0 guarantees that we'll
242
4954
            // have a positive value.
243
4954
            let mut bytes = vec![0];
244
4954
            bytes.extend(x.to_bytes_be());
245
4954
            // We use from_signed_bytes_be() here because simple_asn1
246
4954
            // exposes BigInt but not Sign, so we can't call
247
4954
            // its version of from_signed_bytes().
248
4954
            let bigint = BigInt::from_signed_bytes_be(&bytes);
249
4954
            ASN1Block::Integer(0, bigint)
250
4954
        }
251
2477

            
252
2477
        let asn1 = ASN1Block::Sequence(0, vec![to_asn1_int(self.0.n()), to_asn1_int(self.0.e())]);
253
2477
        simple_asn1::to_der(&asn1).expect("RSA key not encodable as DER")
254
2477
    }
255

            
256
    /// Compute the RsaIdentity for this public key.
257
2442
    pub fn to_rsa_identity(&self) -> RsaIdentity {
258
2442
        use crate::d::Sha1;
259
2442
        use digest::Digest;
260
2442
        let id = Sha1::digest(&self.to_der()).into();
261
2442
        RsaIdentity { id }
262
2442
    }
263
}
264

            
265
/// An RSA signature plus all the information needed to validate it.
266
pub struct ValidatableRsaSignature {
267
    /// The key that allegedly signed this signature
268
    key: PublicKey,
269
    /// The signature in question
270
    sig: Vec<u8>,
271
    /// The value we expect to find that the signature is a signature of.
272
    expected_hash: Vec<u8>,
273
}
274

            
275
impl ValidatableRsaSignature {
276
    /// Construct a new ValidatableRsaSignature.
277
1221
    pub fn new(key: &PublicKey, sig: &[u8], expected_hash: &[u8]) -> Self {
278
1221
        ValidatableRsaSignature {
279
1221
            key: key.clone(),
280
1221
            sig: sig.into(),
281
1221
            expected_hash: expected_hash.into(),
282
1221
        }
283
1221
    }
284
}
285

            
286
impl super::ValidatableSignature for ValidatableRsaSignature {
287
759
    fn is_valid(&self) -> bool {
288
759
        self.key
289
759
            .verify(&self.expected_hash[..], &self.sig[..])
290
759
            .is_ok()
291
759
    }
292
}