1use std::fmt::{Debug, Formatter};
2
3use base64::{
4 Engine,
5 engine::general_purpose::{STANDARD, URL_SAFE},
6};
7use serde::ser::Serialize;
8
9use crate::Algorithm;
10use crate::algorithms::AlgorithmFamily;
11use crate::crypto::JwtSigner;
12use crate::errors::{ErrorKind, Result, new_error};
13use crate::header::Header;
14#[cfg(feature = "use_pem")]
15use crate::pem::decoder::PemEncodedKey;
16use crate::serialization::{b64_encode, b64_encode_part};
17#[cfg(feature = "aws_lc_rs")]
19use crate::crypto::aws_lc::{
20 ecdsa::{Es256Signer, Es384Signer},
21 eddsa::EdDSASigner,
22 hmac::{Hs256Signer, Hs384Signer, Hs512Signer},
23 rsa::{
24 Rsa256Signer, Rsa384Signer, Rsa512Signer, RsaPss256Signer, RsaPss384Signer, RsaPss512Signer,
25 },
26};
27#[cfg(feature = "rust_crypto")]
28use crate::crypto::rust_crypto::{
29 ecdsa::{Es256Signer, Es384Signer},
30 eddsa::EdDSASigner,
31 hmac::{Hs256Signer, Hs384Signer, Hs512Signer},
32 rsa::{
33 Rsa256Signer, Rsa384Signer, Rsa512Signer, RsaPss256Signer, RsaPss384Signer, RsaPss512Signer,
34 },
35};
36
37#[derive(Clone)]
40pub struct EncodingKey {
41 pub(crate) family: AlgorithmFamily,
42 pub(crate) content: Vec<u8>,
43}
44
45impl EncodingKey {
46 pub fn family(&self) -> AlgorithmFamily {
48 self.family
49 }
50
51 pub fn from_secret(secret: &[u8]) -> Self {
53 EncodingKey { family: AlgorithmFamily::Hmac, content: secret.to_vec() }
54 }
55
56 pub fn from_base64_secret(secret: &str) -> Result<Self> {
58 let out = STANDARD.decode(secret)?;
59 Ok(EncodingKey { family: AlgorithmFamily::Hmac, content: out })
60 }
61
62 pub fn from_urlsafe_base64_secret(secret: &str) -> Result<Self> {
64 let out = URL_SAFE.decode(secret)?;
65 Ok(EncodingKey { family: AlgorithmFamily::Hmac, content: out })
66 }
67
68 #[cfg(feature = "use_pem")]
78 pub fn from_rsa_pem(key: &[u8]) -> Result<Self> {
79 let pem_key = PemEncodedKey::new(key)?;
80 let content = pem_key.as_rsa_key()?;
81 Ok(EncodingKey { family: AlgorithmFamily::Rsa, content: content.to_vec() })
82 }
83
84 #[cfg(feature = "use_pem")]
99 pub fn from_ec_pem(key: &[u8]) -> Result<Self> {
100 let pem_key = PemEncodedKey::new(key)?;
101 let content = pem_key.as_ec_private_key()?;
102 Ok(EncodingKey { family: AlgorithmFamily::Ec, content: content.to_vec() })
103 }
104
105 #[cfg(feature = "use_pem")]
109 pub fn from_ed_pem(key: &[u8]) -> Result<Self> {
110 let pem_key = PemEncodedKey::new(key)?;
111 let content = pem_key.as_ed_private_key()?;
112 Ok(EncodingKey { family: AlgorithmFamily::Ed, content: content.to_vec() })
113 }
114
115 pub fn from_rsa_der(der: &[u8]) -> Self {
117 EncodingKey { family: AlgorithmFamily::Rsa, content: der.to_vec() }
118 }
119
120 pub fn from_ec_der(der: &[u8]) -> Self {
122 EncodingKey { family: AlgorithmFamily::Ec, content: der.to_vec() }
123 }
124
125 pub fn from_ed_der(der: &[u8]) -> Self {
127 EncodingKey { family: AlgorithmFamily::Ed, content: der.to_vec() }
128 }
129
130 pub(crate) fn inner(&self) -> &[u8] {
131 &self.content
132 }
133
134 pub(crate) fn try_get_hmac_secret(&self) -> Result<&[u8]> {
135 if self.family == AlgorithmFamily::Hmac {
136 Ok(self.inner())
137 } else {
138 Err(new_error(ErrorKind::InvalidKeyFormat))
139 }
140 }
141}
142
143impl Debug for EncodingKey {
144 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
145 f.debug_struct("EncodingKey")
146 .field("family", &self.family)
147 .field("content", &"[redacted]")
148 .finish()
149 }
150}
151
152pub fn encode<T: Serialize>(header: &Header, claims: &T, key: &EncodingKey) -> Result<String> {
175 if key.family != header.alg.family() {
176 return Err(new_error(ErrorKind::InvalidAlgorithm));
177 }
178
179 let signing_provider = jwt_signer_factory(&header.alg, key)?;
180
181 if signing_provider.algorithm() != header.alg {
182 return Err(new_error(ErrorKind::InvalidAlgorithm));
183 }
184
185 let encoded_header = b64_encode_part(&header)?;
186 let encoded_claims = b64_encode_part(claims)?;
187 let message = [encoded_header, encoded_claims].join(".");
188
189 let signature = b64_encode(signing_provider.sign(message.as_bytes()));
190
191 Ok([message, signature].join("."))
192}
193
194pub(crate) fn jwt_signer_factory(
196 algorithm: &Algorithm,
197 key: &EncodingKey,
198) -> Result<Box<dyn JwtSigner>> {
199 let jwt_signer = match algorithm {
200 Algorithm::HS256 => Box::new(Hs256Signer::new(key)?) as Box<dyn JwtSigner>,
201 Algorithm::HS384 => Box::new(Hs384Signer::new(key)?) as Box<dyn JwtSigner>,
202 Algorithm::HS512 => Box::new(Hs512Signer::new(key)?) as Box<dyn JwtSigner>,
203 Algorithm::ES256 => Box::new(Es256Signer::new(key)?) as Box<dyn JwtSigner>,
204 Algorithm::ES384 => Box::new(Es384Signer::new(key)?) as Box<dyn JwtSigner>,
205 Algorithm::RS256 => Box::new(Rsa256Signer::new(key)?) as Box<dyn JwtSigner>,
206 Algorithm::RS384 => Box::new(Rsa384Signer::new(key)?) as Box<dyn JwtSigner>,
207 Algorithm::RS512 => Box::new(Rsa512Signer::new(key)?) as Box<dyn JwtSigner>,
208 Algorithm::PS256 => Box::new(RsaPss256Signer::new(key)?) as Box<dyn JwtSigner>,
209 Algorithm::PS384 => Box::new(RsaPss384Signer::new(key)?) as Box<dyn JwtSigner>,
210 Algorithm::PS512 => Box::new(RsaPss512Signer::new(key)?) as Box<dyn JwtSigner>,
211 Algorithm::EdDSA => Box::new(EdDSASigner::new(key)?) as Box<dyn JwtSigner>,
212 };
213
214 Ok(jwt_signer)
215}