| 1 | // Copyright 2015 Brian Smith. |
| 2 | // |
| 3 | // Permission to use, copy, modify, and/or distribute this software for any |
| 4 | // purpose with or without fee is hereby granted, provided that the above |
| 5 | // copyright notice and this permission notice appear in all copies. |
| 6 | // |
| 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES |
| 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR |
| 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 14 | |
| 15 | use crate::der::{self, FromDer}; |
| 16 | use crate::error::{DerTypeId, Error}; |
| 17 | use crate::verify_cert::Budget; |
| 18 | |
| 19 | use pki_types::SignatureVerificationAlgorithm; |
| 20 | |
| 21 | #[cfg (feature = "alloc" )] |
| 22 | use alloc::vec::Vec; |
| 23 | |
| 24 | /// X.509 certificates and related items that are signed are almost always |
| 25 | /// encoded in the format "tbs||signatureAlgorithm||signature". This structure |
| 26 | /// captures this pattern as an owned data type. |
| 27 | #[cfg (feature = "alloc" )] |
| 28 | #[derive (Clone, Debug)] |
| 29 | pub(crate) struct OwnedSignedData { |
| 30 | /// The signed data. This would be `tbsCertificate` in the case of an X.509 |
| 31 | /// certificate, `tbsResponseData` in the case of an OCSP response, `tbsCertList` |
| 32 | /// in the case of a CRL, and the data nested in the `digitally-signed` construct for |
| 33 | /// TLS 1.2 signed data. |
| 34 | pub(crate) data: Vec<u8>, |
| 35 | |
| 36 | /// The value of the `AlgorithmIdentifier`. This would be |
| 37 | /// `signatureAlgorithm` in the case of an X.509 certificate, OCSP |
| 38 | /// response or CRL. This would have to be synthesized in the case of TLS 1.2 |
| 39 | /// signed data, since TLS does not identify algorithms by ASN.1 OIDs. |
| 40 | pub(crate) algorithm: Vec<u8>, |
| 41 | |
| 42 | /// The value of the signature. This would be `signature` in an X.509 |
| 43 | /// certificate, OCSP response or CRL. This would be the value of |
| 44 | /// `DigitallySigned.signature` for TLS 1.2 signed data. |
| 45 | pub(crate) signature: Vec<u8>, |
| 46 | } |
| 47 | |
| 48 | #[cfg (feature = "alloc" )] |
| 49 | impl OwnedSignedData { |
| 50 | /// Return a borrowed [`SignedData`] from the owned representation. |
| 51 | pub(crate) fn borrow(&self) -> SignedData<'_> { |
| 52 | SignedData { |
| 53 | data: untrusted::Input::from(&self.data), |
| 54 | algorithm: untrusted::Input::from(&self.algorithm), |
| 55 | signature: untrusted::Input::from(&self.signature), |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | /// X.509 certificates and related items that are signed are almost always |
| 61 | /// encoded in the format "tbs||signatureAlgorithm||signature". This structure |
| 62 | /// captures this pattern. |
| 63 | #[derive (Debug)] |
| 64 | pub(crate) struct SignedData<'a> { |
| 65 | /// The signed data. This would be `tbsCertificate` in the case of an X.509 |
| 66 | /// certificate, `tbsResponseData` in the case of an OCSP response, `tbsCertList` |
| 67 | /// in the case of a CRL, and the data nested in the `digitally-signed` construct for |
| 68 | /// TLS 1.2 signed data. |
| 69 | pub(crate) data: untrusted::Input<'a>, |
| 70 | |
| 71 | /// The value of the `AlgorithmIdentifier`. This would be |
| 72 | /// `signatureAlgorithm` in the case of an X.509 certificate, OCSP |
| 73 | /// response or CRL. This would have to be synthesized in the case of TLS 1.2 |
| 74 | /// signed data, since TLS does not identify algorithms by ASN.1 OIDs. |
| 75 | pub(crate) algorithm: untrusted::Input<'a>, |
| 76 | |
| 77 | /// The value of the signature. This would be `signature` in an X.509 |
| 78 | /// certificate, OCSP response or CRL. This would be the value of |
| 79 | /// `DigitallySigned.signature` for TLS 1.2 signed data. |
| 80 | pub(crate) signature: untrusted::Input<'a>, |
| 81 | } |
| 82 | |
| 83 | impl<'a> SignedData<'a> { |
| 84 | /// Parses the concatenation of "tbs||signatureAlgorithm||signature" that |
| 85 | /// is common in the X.509 certificate and OCSP response syntaxes. |
| 86 | /// |
| 87 | /// X.509 Certificates (RFC 5280) look like this: |
| 88 | /// |
| 89 | /// ```ASN.1 |
| 90 | /// Certificate (SEQUENCE) { |
| 91 | /// tbsCertificate TBSCertificate, |
| 92 | /// signatureAlgorithm AlgorithmIdentifier, |
| 93 | /// signatureValue BIT STRING |
| 94 | /// } |
| 95 | /// ``` |
| 96 | /// |
| 97 | /// OCSP responses (RFC 6960) look like this: |
| 98 | /// ```ASN.1 |
| 99 | /// BasicOCSPResponse { |
| 100 | /// tbsResponseData ResponseData, |
| 101 | /// signatureAlgorithm AlgorithmIdentifier, |
| 102 | /// signature BIT STRING, |
| 103 | /// certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL |
| 104 | /// } |
| 105 | /// ``` |
| 106 | /// |
| 107 | /// Note that this function does NOT parse the outermost `SEQUENCE` or the |
| 108 | /// `certs` value. |
| 109 | /// |
| 110 | /// The return value's first component is the contents of |
| 111 | /// `tbsCertificate`/`tbsResponseData`; the second component is a `SignedData` |
| 112 | /// structure that can be passed to `verify_signed_data`. |
| 113 | /// |
| 114 | /// The provided size_limit will enforce the largest possible outermost `SEQUENCE` this |
| 115 | /// function will read. |
| 116 | pub(crate) fn from_der( |
| 117 | der: &mut untrusted::Reader<'a>, |
| 118 | size_limit: usize, |
| 119 | ) -> Result<(untrusted::Input<'a>, Self), Error> { |
| 120 | let (data, tbs) = der.read_partial(|input| { |
| 121 | der::expect_tag_and_get_value_limited(input, der::Tag::Sequence, size_limit) |
| 122 | })?; |
| 123 | let algorithm = der::expect_tag(der, der::Tag::Sequence)?; |
| 124 | let signature = der::bit_string_with_no_unused_bits(der)?; |
| 125 | |
| 126 | Ok(( |
| 127 | tbs, |
| 128 | SignedData { |
| 129 | data, |
| 130 | algorithm, |
| 131 | signature, |
| 132 | }, |
| 133 | )) |
| 134 | } |
| 135 | |
| 136 | /// Convert the borrowed signed data to an [`OwnedSignedData`]. |
| 137 | #[cfg (feature = "alloc" )] |
| 138 | pub(crate) fn to_owned(&self) -> OwnedSignedData { |
| 139 | OwnedSignedData { |
| 140 | data: self.data.as_slice_less_safe().to_vec(), |
| 141 | algorithm: self.algorithm.as_slice_less_safe().to_vec(), |
| 142 | signature: self.signature.as_slice_less_safe().to_vec(), |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | /// Verify `signed_data` using the public key in the DER-encoded |
| 148 | /// SubjectPublicKeyInfo `spki` using one of the algorithms in |
| 149 | /// `supported_algorithms`. |
| 150 | /// |
| 151 | /// The algorithm is chosen based on the algorithm information encoded in the |
| 152 | /// algorithm identifiers in `public_key` and `signed_data.algorithm`. The |
| 153 | /// ordering of the algorithms in `supported_algorithms` does not really matter, |
| 154 | /// but generally more common algorithms should go first, as it is scanned |
| 155 | /// linearly for matches. |
| 156 | pub(crate) fn verify_signed_data( |
| 157 | supported_algorithms: &[&dyn SignatureVerificationAlgorithm], |
| 158 | spki_value: untrusted::Input<'_>, |
| 159 | signed_data: &SignedData<'_>, |
| 160 | budget: &mut Budget, |
| 161 | ) -> Result<(), Error> { |
| 162 | budget.consume_signature()?; |
| 163 | |
| 164 | // We need to verify the signature in `signed_data` using the public key |
| 165 | // in `public_key`. In order to know which *ring* signature verification |
| 166 | // algorithm to use, we need to know the public key algorithm (ECDSA, |
| 167 | // RSA PKCS#1, etc.), the curve (if applicable), and the digest algorithm. |
| 168 | // `signed_data` identifies only the public key algorithm and the digest |
| 169 | // algorithm, and `public_key` identifies only the public key algorithm and |
| 170 | // the curve (if any). Thus, we have to combine information from both |
| 171 | // inputs to figure out which `ring::signature::VerificationAlgorithm` to |
| 172 | // use to verify the signature. |
| 173 | // |
| 174 | // This is all further complicated by the fact that we don't have any |
| 175 | // implicit knowledge about any algorithms or identifiers, since all of |
| 176 | // that information is encoded in `supported_algorithms.` In particular, we |
| 177 | // avoid hard-coding any of that information so that (link-time) dead code |
| 178 | // elimination will work effectively in eliminating code for unused |
| 179 | // algorithms. |
| 180 | |
| 181 | // Parse the signature. |
| 182 | // |
| 183 | let mut found_signature_alg_match = false; |
| 184 | for supported_alg in supported_algorithms |
| 185 | .iter() |
| 186 | .filter(|alg| alg.signature_alg_id().as_ref() == signed_data.algorithm.as_slice_less_safe()) |
| 187 | { |
| 188 | match verify_signature( |
| 189 | *supported_alg, |
| 190 | spki_value, |
| 191 | signed_data.data, |
| 192 | signed_data.signature, |
| 193 | ) { |
| 194 | Err(Error::UnsupportedSignatureAlgorithmForPublicKey) => { |
| 195 | found_signature_alg_match = true; |
| 196 | continue; |
| 197 | } |
| 198 | result => { |
| 199 | return result; |
| 200 | } |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | if found_signature_alg_match { |
| 205 | Err(Error::UnsupportedSignatureAlgorithmForPublicKey) |
| 206 | } else { |
| 207 | Err(Error::UnsupportedSignatureAlgorithm) |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | pub(crate) fn verify_signature( |
| 212 | signature_alg: &dyn SignatureVerificationAlgorithm, |
| 213 | spki_value: untrusted::Input<'_>, |
| 214 | msg: untrusted::Input<'_>, |
| 215 | signature: untrusted::Input<'_>, |
| 216 | ) -> Result<(), Error> { |
| 217 | let spki: SubjectPublicKeyInfo<'_> = der::read_all::<SubjectPublicKeyInfo<'_>>(input:spki_value)?; |
| 218 | if signature_alg.public_key_alg_id().as_ref() != spki.algorithm_id_value.as_slice_less_safe() { |
| 219 | return Err(Error::UnsupportedSignatureAlgorithmForPublicKey); |
| 220 | } |
| 221 | |
| 222 | signature_alg |
| 223 | .verify_signature( |
| 224 | spki.key_value.as_slice_less_safe(), |
| 225 | msg.as_slice_less_safe(), |
| 226 | signature.as_slice_less_safe(), |
| 227 | ) |
| 228 | .map_err(|_| Error::InvalidSignatureForPublicKey) |
| 229 | } |
| 230 | |
| 231 | pub(crate) struct SubjectPublicKeyInfo<'a> { |
| 232 | algorithm_id_value: untrusted::Input<'a>, |
| 233 | key_value: untrusted::Input<'a>, |
| 234 | } |
| 235 | |
| 236 | impl<'a> FromDer<'a> for SubjectPublicKeyInfo<'a> { |
| 237 | // Parse the public key into an algorithm OID, an optional curve OID, and the |
| 238 | // key value. The caller needs to check whether these match the |
| 239 | // `PublicKeyAlgorithm` for the `SignatureVerificationAlgorithm` that is matched when |
| 240 | // parsing the signature. |
| 241 | fn from_der(reader: &mut untrusted::Reader<'a>) -> Result<Self, Error> { |
| 242 | let algorithm_id_value: Input<'_> = der::expect_tag(input:reader, der::Tag::Sequence)?; |
| 243 | let key_value: Input<'_> = der::bit_string_with_no_unused_bits(input:reader)?; |
| 244 | Ok(SubjectPublicKeyInfo { |
| 245 | algorithm_id_value, |
| 246 | key_value, |
| 247 | }) |
| 248 | } |
| 249 | |
| 250 | const TYPE_ID: DerTypeId = DerTypeId::SubjectPublicKeyInfo; |
| 251 | } |
| 252 | |