|
10 | 10 | //! [`CryptoProvider`]: crate::crypto::CryptoProvider |
11 | 11 |
|
12 | 12 | use crate::algorithms::Algorithm; |
13 | | -use crate::errors::Result; |
| 13 | +use crate::errors::{self, ErrorKind, Result}; |
14 | 14 | use crate::jwk::{EllipticCurve, ThumbprintHash}; |
15 | 15 | use crate::{DecodingKey, EncodingKey}; |
16 | 16 |
|
| 17 | +const NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR: &'static str = r###" |
| 18 | +Could not automatically determine the process-level CryptoProvider from jsonwebtoken crate features, or your CryptoProvider does not support JWKs. |
| 19 | +Call CryptoProvider::install_default() before this point to select a provider manually, or make sure exactly one of the 'rust_crypto' and 'aws_lc_rs' features is enabled. |
| 20 | +See the documentation of the CryptoProvider type for more information. |
| 21 | +"###; |
17 | 22 | /// `aws_lc_rs` based CryptoProvider. |
18 | 23 | #[cfg(feature = "aws_lc_rs")] |
19 | 24 | pub mod aws_lc; |
@@ -85,8 +90,19 @@ pub struct CryptoProvider { |
85 | 90 | pub signer_factory: fn(&Algorithm, &EncodingKey) -> Result<Box<dyn JwtSigner>>, |
86 | 91 | /// A function that produces a [`JwtVerifier`] for a given [`Algorithm`] |
87 | 92 | pub verifier_factory: fn(&Algorithm, &DecodingKey) -> Result<Box<dyn JwtVerifier>>, |
88 | | - /// Struct with utility functions for JWK processing. |
89 | | - pub jwk_utils: JwkUtils, |
| 93 | + /// Given a DER encoded private key, extract the RSA public key components (n, e) |
| 94 | + #[allow(clippy::type_complexity)] |
| 95 | + pub rsa_pub_components_from_private_key: fn(&[u8]) -> Result<(Vec<u8>, Vec<u8>)>, |
| 96 | + /// Given a DER encoded public key, extract the RSA public key components (n, e) |
| 97 | + #[allow(clippy::type_complexity)] |
| 98 | + pub rsa_pub_components_from_public_key: fn(&[u8]) -> Result<(Vec<u8>, Vec<u8>)>, |
| 99 | + /// Given a DER encoded private key and an algorithm, extract the associated curve |
| 100 | + /// and the EC public key components (x, y) |
| 101 | + #[allow(clippy::type_complexity)] |
| 102 | + pub ec_pub_components_from_private_key: |
| 103 | + fn(&[u8], Algorithm) -> Result<(EllipticCurve, Vec<u8>, Vec<u8>)>, |
| 104 | + /// Given some data and a name of a hash function, compute hash_function(data) |
| 105 | + pub compute_digest: fn(&[u8], ThumbprintHash) -> Vec<u8>, |
90 | 106 | } |
91 | 107 |
|
92 | 108 | impl CryptoProvider { |
@@ -123,49 +139,38 @@ See the documentation of the CryptoProvider type for more information. |
123 | 139 | static INSTANCE: CryptoProvider = CryptoProvider { |
124 | 140 | signer_factory: |_, _| panic!("{}", NOT_INSTALLED_ERROR), |
125 | 141 | verifier_factory: |_, _| panic!("{}", NOT_INSTALLED_ERROR), |
126 | | - jwk_utils: JwkUtils::new_unimplemented(), |
| 142 | + rsa_pub_components_from_private_key: |_| { |
| 143 | + panic!("{}", NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR) |
| 144 | + }, |
| 145 | + rsa_pub_components_from_public_key: |_| { |
| 146 | + panic!("{}", NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR) |
| 147 | + }, |
| 148 | + ec_pub_components_from_private_key: |_, _| { |
| 149 | + panic!("{}", NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR) |
| 150 | + }, |
| 151 | + compute_digest: |_, _| panic!("{}", NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR), |
127 | 152 | }; |
128 | 153 |
|
129 | 154 | &INSTANCE |
130 | 155 | } |
131 | 156 | } |
132 | 157 | } |
133 | 158 |
|
134 | | -/// Holds utility functions required for JWK processing. |
135 | | -/// Use the [`JwkUtils::new_unimplemented`] function to initialize all values to dummies. |
136 | | -#[derive(Clone, Debug)] |
137 | | -pub struct JwkUtils { |
138 | | - /// Given a DER encoded private key, extract the RSA public key components (n, e) |
139 | | - #[allow(clippy::type_complexity)] |
140 | | - pub extract_rsa_public_key_components: fn(&[u8]) -> Result<(Vec<u8>, Vec<u8>)>, |
141 | | - /// Given a DER encoded private key and an algorithm, extract the associated curve |
142 | | - /// and the EC public key components (x, y) |
143 | | - #[allow(clippy::type_complexity)] |
144 | | - pub extract_ec_public_key_coordinates: |
145 | | - fn(&[u8], Algorithm) -> Result<(EllipticCurve, Vec<u8>, Vec<u8>)>, |
146 | | - /// Given some data and a name of a hash function, compute hash_function(data) |
147 | | - pub compute_digest: fn(&[u8], ThumbprintHash) -> Vec<u8>, |
148 | | -} |
149 | | - |
150 | | -impl JwkUtils { |
151 | | - /// Initialises all values to dummies. |
152 | | - /// Will lead to a panic when JWKs are required, so only use it if you don't want to support JWKs. |
153 | | - pub const fn new_unimplemented() -> Self { |
154 | | - const NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR: &str = r###" |
155 | | -Could not automatically determine the process-level CryptoProvider from jsonwebtoken crate features, or your CryptoProvider does not support JWKs. |
156 | | -Call CryptoProvider::install_default() before this point to select a provider manually, or make sure exactly one of the 'rust_crypto' and 'aws_lc_rs' features is enabled. |
157 | | -See the documentation of the CryptoProvider type for more information. |
158 | | -"###; |
159 | | - Self { |
160 | | - extract_rsa_public_key_components: |_| { |
161 | | - panic!("{}", NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR) |
162 | | - }, |
163 | | - extract_ec_public_key_coordinates: |_, _| { |
164 | | - panic!("{}", NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR) |
165 | | - }, |
166 | | - compute_digest: |_, _| panic!("{}", NOT_INSTALLED_OR_UNIMPLEMENTED_ERROR), |
167 | | - } |
| 159 | +pub(crate) fn ec_components_from_public_key( |
| 160 | + pub_bytes: &[u8], |
| 161 | +) -> errors::Result<(EllipticCurve, Vec<u8>, Vec<u8>)> { |
| 162 | + let (curve, pub_elem_bytes) = match pub_bytes.len() { |
| 163 | + 65 => (EllipticCurve::P256, 32), |
| 164 | + 97 => (EllipticCurve::P384, 48), |
| 165 | + _ => return Err(ErrorKind::InvalidEcdsaKey.into()), |
| 166 | + }; |
| 167 | + |
| 168 | + if pub_bytes[0] != 4 { |
| 169 | + return Err(ErrorKind::InvalidEcdsaKey.into()); |
168 | 170 | } |
| 171 | + |
| 172 | + let (x, y) = pub_bytes[1..].split_at(pub_elem_bytes); |
| 173 | + Ok((curve, x.to_vec(), y.to_vec())) |
169 | 174 | } |
170 | 175 |
|
171 | 176 | mod static_default { |
|
0 commit comments