mundane/public/
mod.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Public key cryptography.
6
7pub mod ec;
8pub mod ed25519;
9pub mod rsa;
10
11use boringssl::{CHeapWrapper, CStackWrapper};
12use public::inner::BoringDerKey;
13use util::Sealed;
14use Error;
15
16/// The public component of a public/private key pair.
17pub trait PublicKey: Sealed + Sized {
18    /// The type of the private component.
19    type Private: PrivateKey<Public = Self>;
20
21    /// Verifies a message with this public key.
22    ///
23    /// `is_valid` verifies that a message was signed by the private key
24    /// corresponding to this public key. It is equivalent to
25    /// `signature.is_valid(self, message)`.
26    #[must_use]
27    fn is_valid<S: Signature<PrivateKey = Self::Private>>(
28        &self,
29        message: &[u8],
30        signature: &S,
31    ) -> bool {
32        signature.is_valid(self, message)
33    }
34}
35
36/// The private component of a public/private key pair.
37pub trait PrivateKey: Sealed + Sized {
38    /// The type of the public component.
39    type Public: PublicKey<Private = Self>;
40
41    /// Gets the public key corresponding to this private key.
42    #[must_use]
43    fn public(&self) -> Self::Public;
44
45    /// Signs a message with this private key.
46    ///
47    /// `sign` signs a message with this key using the signature scheme `S`. It
48    /// is equivalent to `S::sign(self, message)`.
49    #[must_use]
50    fn sign<S: Signature<PrivateKey = Self>>(&self, message: &[u8]) -> Result<S, Error> {
51        S::sign(self, message)
52    }
53}
54
55/// A public key which can be encoded as a DER object.
56pub trait DerPublicKey: PublicKey + self::inner::DerKey {
57    /// Marshals a public key in DER format.
58    ///
59    /// `marshal_to_der` marshals a public key as a DER-encoded
60    /// SubjectPublicKeyInfo structure as defined in [RFC 5280].
61    ///
62    /// [RFC 5280]: https://tools.ietf.org/html/rfc5280
63    #[must_use]
64    fn marshal_to_der(&self) -> Vec<u8> {
65        let mut evp_pkey = CHeapWrapper::default();
66        self.boring().pkey_assign(&mut evp_pkey);
67        // cbb_new can only fail due to OOM
68        let mut cbb = CStackWrapper::cbb_new(64).unwrap();
69        evp_pkey.evp_marshal_public_key(&mut cbb).expect("failed to marshal public key");
70        cbb.cbb_with_data(<[u8]>::to_vec)
71    }
72
73    /// Parses a public key in DER format.
74    ///
75    /// `parse_from_der` parses a public key from a DER-encoded
76    /// SubjectPublicKeyInfo structure as defined in [RFC 5280].
77    ///
78    /// # Elliptic Curve Keys
79    ///
80    /// For Elliptic Curve keys ([`EcPubKey`]), the curve itself is validated.
81    /// If the curve is not known ahead of time, and any curve must be supported
82    /// at runtime, use the [`EcPubKeyAnyCurve::parse_from_der`] function.
83    ///
84    /// [RFC 5280]: https://tools.ietf.org/html/rfc5280
85    /// [`EcPubKey`]: ::public::ec::EcPubKey
86    /// [`EcPubKeyAnyCurve::parse_from_der`]: ::public::ec::EcPubKeyAnyCurve::parse_from_der
87    #[must_use]
88    fn parse_from_der(bytes: &[u8]) -> Result<Self, Error> {
89        CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
90            let mut evp_pkey = CHeapWrapper::evp_parse_public_key(cbs)?;
91            // NOTE: For EC, panics if evp_pkey doesn't have its group set. This is
92            // OK because EVP_parse_public_key guarantees that the returned key has
93            // its group set.
94            let key = Self::Boring::pkey_get(&mut evp_pkey)?;
95            if cbs.cbs_len() > 0 {
96                return Err(Error::new("malformed DER input".to_string()));
97            }
98            Ok(Self::from_boring(key))
99        })
100    }
101}
102
103/// A private key which can be encoded as a DER object.
104pub trait DerPrivateKey: PrivateKey + self::inner::DerKey {
105    /// Marshals a private key in DER format.
106    ///
107    /// `marshal_to_der` marshal a private key as a DER-encoded structure. The
108    /// exact structure encoded depends on the type of key:
109    /// - For an EC key, it is an ECPrivateKey structure as defined in [RFC
110    ///   5915].
111    /// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC
112    ///   3447].
113    ///
114    /// [RFC 5915]: https://tools.ietf.org/html/rfc5915
115    /// [RFC 3447]: https://tools.ietf.org/html/rfc3447
116    #[must_use]
117    fn marshal_to_der(&self) -> Vec<u8> {
118        // cbb_new can only fail due to OOM
119        let mut cbb = CStackWrapper::cbb_new(64).unwrap();
120        self.boring().marshal_private_key(&mut cbb).expect("failed to marshal private key");
121        cbb.cbb_with_data(<[u8]>::to_vec)
122    }
123
124    /// Parses a private key in DER format.
125    ///
126    /// `parse_from_der` parses a private key from a DER-encoded format. The
127    /// exact structure expected depends on the type of key:
128    /// - For an EC key, it is an ECPrivateKey structure as defined in [RFC
129    ///   5915].
130    /// - For an RSA key, it is an RSAPrivateKey structure as defined in [RFC
131    ///   3447].
132    ///
133    /// # Elliptic Curve Keys
134    ///
135    /// For Elliptic Curve keys ([`EcPrivKey`]), the curve itself is validated. If
136    /// the curve is not known ahead of time, and any curve must be supported at
137    /// runtime, use the [`EcPrivKeyAnyCurve::parse_from_der`] function.
138    ///
139    /// [RFC 5915]: https://tools.ietf.org/html/rfc5915
140    /// [RFC 3447]: https://tools.ietf.org/html/rfc3447
141    /// [`EcPrivKey`]: ::public::ec::EcPrivKey
142    /// [`EcPrivKeyAnyCurve::parse_from_der`]: ::public::ec::EcPrivKeyAnyCurve::parse_from_der
143    #[must_use]
144    fn parse_from_der(bytes: &[u8]) -> Result<Self, Error> {
145        CStackWrapper::cbs_with_temp_buffer(bytes, |cbs| {
146            let key = Self::Boring::parse_private_key(cbs)?;
147            if cbs.cbs_len() > 0 {
148                return Err(Error::new("malformed DER input".to_string()));
149            }
150            Ok(Self::from_boring(key))
151        })
152    }
153}
154
155/// A cryptographic signature generated by a private key.
156pub trait Signature: Sealed + Sized {
157    /// The private key type used to generate this signature.
158    type PrivateKey: PrivateKey;
159
160    /// Sign a message.
161    ///
162    /// The input to this function is always a message, never a digest. If a
163    /// signature scheme calls for hashing a message and signing the hash
164    /// digest, `sign` is responsible for both hashing and signing.
165    #[must_use]
166    fn sign(key: &Self::PrivateKey, message: &[u8]) -> Result<Self, Error>;
167
168    /// Verify a signature.
169    ///
170    /// The input to this function is always a message, never a digest. If a
171    /// signature scheme calls for hashing a message and signing the hash
172    /// digest, `is_valid` is responsible for both hashing and verifying the
173    /// digest.
174    #[must_use]
175    fn is_valid(&self, key: &<Self::PrivateKey as PrivateKey>::Public, message: &[u8]) -> bool;
176}
177
178mod inner {
179    use boringssl::{self, CHeapWrapper, CStackWrapper};
180    use Error;
181
182    /// A wrapper around a BoringSSL key object.
183    pub trait BoringDerKey: Sized {
184        // evp_pkey_assign_xxx
185        fn pkey_assign(&self, pkey: &mut CHeapWrapper<boringssl::EVP_PKEY>);
186
187        // evp_pkey_get_xxx; panics if the key is an EC key and doesn't have a group set,
188        // and errors if pkey isn't the expected key type
189        fn pkey_get(pkey: &mut CHeapWrapper<boringssl::EVP_PKEY>) -> Result<Self, Error>;
190
191        // xxx_parse_private_key
192        fn parse_private_key(cbs: &mut CStackWrapper<boringssl::CBS>) -> Result<Self, Error>;
193
194        // xxx_marshal_private_key
195        fn marshal_private_key(&self, cbb: &mut CStackWrapper<boringssl::CBB>)
196            -> Result<(), Error>;
197    }
198
199    /// Properties shared by both public and private keys of a given type.
200    pub trait DerKey {
201        /// The underlying BoringSSL object wrapper type.
202        type Boring: BoringDerKey;
203
204        fn boring(&self) -> &Self::Boring;
205
206        fn from_boring(boring: Self::Boring) -> Self;
207    }
208}
209
210#[cfg(test)]
211mod testutil {
212    use super::*;
213
214    /// Smoke test a signature scheme.
215    ///
216    /// `sig_from_bytes` takes a byte slice and converts it into a signature. If
217    /// the byte slice is too long, it either truncate it or treats it as
218    /// invalid (it's up to the caller). If the byte slice is too short, it
219    /// fills in the remaining bytes with zeroes.
220    pub fn test_signature_smoke<S: Signature, F: Fn(&[u8]) -> S, G: Fn(&S) -> &[u8]>(
221        key: &S::PrivateKey,
222        sig_from_bytes: F,
223        bytes_from_sig: G,
224    ) {
225        // Sign the message, verify the signature, and return the signature.
226        // Also verify that, if the wrong signature is used, the signature fails
227        // to verify. Also verify that sig_from_bytes works.
228        fn sign_and_verify<S: Signature, F: Fn(&[u8]) -> S, G: Fn(&S) -> &[u8]>(
229            key: &S::PrivateKey,
230            message: &[u8],
231            sig_from_bytes: F,
232            bytes_from_sig: G,
233        ) -> S {
234            let sig = S::sign(key, message).unwrap();
235            assert!(sig.is_valid(&key.public(), message));
236            // Make sure the PrivateKey::sign and PublicKey::is_valid convenience
237            // functions also work.
238            let sig = key.sign::<S>(message).unwrap();
239            assert!(key.public().is_valid(message, &sig));
240            let sig2 = S::sign(&key, bytes_from_sig(&sig)).unwrap();
241            assert!(!sig2.is_valid(&key.public(), message));
242            // Make sure the PrivateKey::sign and PublicKey::is_valid convenience
243            // functions also work.
244            let sig2 = key.sign::<S>(bytes_from_sig(&sig)).unwrap();
245            assert!(!key.public().is_valid(message, &sig2));
246            sig_from_bytes(bytes_from_sig(&sig))
247        }
248
249        // Sign an empty message, and verify the signature. Use the signature as
250        // the next message to test, and repeat many times.
251        let mut msg = Vec::new();
252        for _ in 0..16 {
253            msg = bytes_from_sig(&sign_and_verify(key, &msg, &sig_from_bytes, &bytes_from_sig))
254                .to_vec();
255        }
256    }
257}