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 rsa::pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey};
19
use std::fmt;
20
use subtle::{Choice, ConstantTimeEq};
21

            
22
use crate::util::ct::CtByteArray;
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 an RSA key, based on SHA1 and DER.
30
///
31
/// These are used (for legacy purposes) all over the Tor protocol.
32
///
33
/// This object is an "identity" in the sense that it identifies (up to) one RSA
34
/// key.  It may also represent the identity for a particular entity, such as a
35
/// relay or a directory authority.
36
///
37
/// Note that for modern purposes, you should almost always identify a relay by
38
/// its [`Ed25519Identity`](crate::pk::ed25519::Ed25519Identity) instead of by
39
/// this kind of identity key.
40
20832
#[derive(Clone, Copy, Hash, Ord, PartialOrd, Eq, PartialEq)]
41
pub struct RsaIdentity {
42
    /// SHA1 digest of a DER encoded public key.
43
    id: CtByteArray<RSA_ID_LEN>,
44
}
45

            
46
impl ConstantTimeEq for RsaIdentity {
47
    fn ct_eq(&self, other: &Self) -> Choice {
48
        self.id.ct_eq(&other.id)
49
    }
50
}
51

            
52
impl fmt::Display for RsaIdentity {
53
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54
        write!(f, "${}", hex::encode(&self.id.as_ref()[..]))
55
    }
56
}
57
impl fmt::Debug for RsaIdentity {
58
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59
        write!(f, "RsaIdentity {{ {} }}", self)
60
    }
61
}
62

            
63
impl safelog::Redactable for RsaIdentity {
64
    /// Warning: This displays 16 bits of the RSA identity, which is
65
    /// enough to narrow down a public relay by a great deal.
66
    fn display_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67
        write!(f, "${}…", hex::encode(&self.id.as_ref()[..1]))
68
    }
69

            
70
    fn debug_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71
        write!(f, "RsaIdentity {{ {} }}", self.redacted())
72
    }
73
}
74

            
75
impl serde::Serialize for RsaIdentity {
76
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
77
    where
78
        S: serde::Serializer,
79
    {
80
        if serializer.is_human_readable() {
81
            serializer.serialize_str(&hex::encode(&self.id.as_ref()[..]))
82
        } else {
83
            serializer.serialize_bytes(&self.id.as_ref()[..])
84
        }
85
    }
86
}
87

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

            
110
42
            deserializer.deserialize_str(RsaIdentityVisitor)
111
        } else {
112
            /// Deserialization helper
113
            struct RsaIdentityVisitor;
114
            impl<'de> serde::de::Visitor<'de> for RsaIdentityVisitor {
115
                type Value = RsaIdentity;
116
                fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
117
                    fmt.write_str("RSA identity")
118
                }
119
                fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
120
                where
121
                    E: serde::de::Error,
122
                {
123
                    RsaIdentity::from_bytes(bytes)
124
                        .ok_or_else(|| E::custom("wrong length for RSA identity"))
125
                }
126
            }
127
            deserializer.deserialize_bytes(RsaIdentityVisitor)
128
        }
129
42
    }
130
}
131

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

            
168
    /// Return true if this `RsaIdentity` is composed entirely of zero-valued
169
    /// bytes.
170
    ///
171
    /// Such all-zero values should not be used internally, since they are not
172
    /// the ID of any valid key.  Instead, they are used in some places in the
173
    /// Tor protocols.
174
    pub fn is_zero(&self) -> bool {
175
        // We do a constant-time comparison to avoid side-channels.
176
        self.id.ct_eq(&[0; RSA_ID_LEN].into()).into()
177
    }
178
}
179

            
180
impl From<[u8; 20]> for RsaIdentity {
181
4746
    fn from(id: [u8; 20]) -> RsaIdentity {
182
4746
        RsaIdentity { id: id.into() }
183
4746
    }
184
}
185

            
186
/// An RSA public key.
187
///
188
/// This implementation is a simple wrapper so that we can define new
189
/// methods and traits on the type.
190
126
#[derive(Clone, Debug)]
191
pub struct PublicKey(rsa::RsaPublicKey);
192

            
193
/// An RSA private key.
194
///
195
/// This is not so useful at present, since Arti currently only has
196
/// client support, and Tor clients never actually need RSA private
197
/// keys.
198
pub struct PrivateKey(rsa::RsaPrivateKey);
199

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

            
266
294
        let asn1 = ASN1Block::Sequence(0, vec![to_asn1_int(self.0.n()), to_asn1_int(self.0.e())]);
267
294
        simple_asn1::to_der(&asn1).expect("RSA key not encodable as DER")
268
294
    }
269

            
270
    /// Compute the RsaIdentity for this public key.
271
294
    pub fn to_rsa_identity(&self) -> RsaIdentity {
272
294
        use crate::d::Sha1;
273
294
        use digest::Digest;
274
294
        let id: [u8; RSA_ID_LEN] = Sha1::digest(self.to_der()).into();
275
294
        RsaIdentity { id: id.into() }
276
294
    }
277
}
278

            
279
/// An RSA signature plus all the information needed to validate it.
280
pub struct ValidatableRsaSignature {
281
    /// The key that allegedly signed this signature
282
    key: PublicKey,
283
    /// The signature in question
284
    sig: Vec<u8>,
285
    /// The value we expect to find that the signature is a signature of.
286
    expected_hash: Vec<u8>,
287
}
288

            
289
impl ValidatableRsaSignature {
290
    /// Construct a new ValidatableRsaSignature.
291
126
    pub fn new(key: &PublicKey, sig: &[u8], expected_hash: &[u8]) -> Self {
292
126
        ValidatableRsaSignature {
293
126
            key: key.clone(),
294
126
            sig: sig.into(),
295
126
            expected_hash: expected_hash.into(),
296
126
        }
297
126
    }
298
}
299

            
300
impl super::ValidatableSignature for ValidatableRsaSignature {
301
126
    fn is_valid(&self) -> bool {
302
126
        self.key
303
126
            .verify(&self.expected_hash[..], &self.sig[..])
304
126
            .is_ok()
305
126
    }
306
}