1use super::AlgorithmName;
2use crate::{
3 error::{HttpSigError, HttpSigResult},
4 trace::*,
5};
6use ecdsa::{
7 elliptic_curve::{sec1::ToEncodedPoint, PublicKey as EcPublicKey, SecretKey as EcSecretKey},
8 signature::{DigestSigner, DigestVerifier},
9};
10use ed25519_compact::{PublicKey as Ed25519PublicKey, SecretKey as Ed25519SecretKey};
11use p256::NistP256;
12use p384::NistP384;
13use pkcs8::{der::Decode, Document, PrivateKeyInfo};
14use sha2::{Digest, Sha256, Sha384};
15use spki::SubjectPublicKeyInfoRef;
16
17#[cfg(feature = "rsa-signature")]
18use rsa::{
19 pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey, EncodeRsaPublicKey},
20 pkcs1v15, pss,
21 signature::{Keypair, RandomizedSigner, SignatureEncoding, Verifier},
22 RsaPrivateKey, RsaPublicKey,
23};
24
25#[allow(non_upper_case_globals, dead_code)]
26mod algorithm_oids {
28 pub const EC: &str = "1.2.840.10045.2.1";
30 pub const Ed25519: &str = "1.3.101.112";
32 #[cfg(feature = "rsa-signature")]
33 pub const rsaEncryption: &str = "1.2.840.113549.1.1.1";
35}
36#[allow(non_upper_case_globals, dead_code)]
37mod params_oids {
39 pub const Secp256r1: &str = "1.2.840.10045.3.1.7";
41 pub const Secp384r1: &str = "1.3.132.0.34";
43}
44
45#[derive(Debug, Clone)]
47pub enum SecretKey {
50 EcdsaP384Sha384(EcSecretKey<NistP384>),
52 EcdsaP256Sha256(EcSecretKey<NistP256>),
54 Ed25519(Ed25519SecretKey),
56 #[cfg(feature = "rsa-signature")]
57 RsaV1_5Sha256(pkcs1v15::SigningKey<rsa::sha2::Sha256>),
59 #[cfg(feature = "rsa-signature")]
60 RsaPssSha512(pss::SigningKey<rsa::sha2::Sha512>),
61}
62
63impl SecretKey {
64 pub fn from_bytes(alg: &AlgorithmName, bytes: &[u8]) -> HttpSigResult<Self> {
66 match alg {
67 AlgorithmName::EcdsaP256Sha256 => {
68 debug!("Read P256 private key");
69 let sk = EcSecretKey::from_bytes(bytes.into()).map_err(|e| HttpSigError::ParsePrivateKeyError(e.to_string()))?;
70 Ok(Self::EcdsaP256Sha256(sk))
71 }
72 AlgorithmName::EcdsaP384Sha384 => {
73 debug!("Read P384 private key");
74 let sk = EcSecretKey::from_bytes(bytes.into()).map_err(|e| HttpSigError::ParsePrivateKeyError(e.to_string()))?;
75 Ok(Self::EcdsaP384Sha384(sk))
76 }
77 AlgorithmName::Ed25519 => {
78 debug!("Read Ed25519 private key");
79 let mut seed = [0u8; 32];
80 seed.copy_from_slice(bytes);
81 let sk = ed25519_compact::KeyPair::from_seed(ed25519_compact::Seed::new(seed)).sk;
82 Ok(Self::Ed25519(sk))
83 }
84 #[cfg(feature = "rsa-signature")]
85 AlgorithmName::RsaV1_5Sha256 => {
86 debug!("Read RSA private key");
87 let sk = RsaPrivateKey::from_pkcs1_der(bytes).map_err(|e| HttpSigError::ParsePrivateKeyError(e.to_string()))?;
89 Ok(Self::RsaV1_5Sha256(pkcs1v15::SigningKey::<rsa::sha2::Sha256>::new(sk)))
90 }
91 #[cfg(feature = "rsa-signature")]
92 AlgorithmName::RsaPssSha512 => {
93 debug!("Read RSA-PSS private key");
94 let sk = RsaPrivateKey::from_pkcs1_der(bytes).map_err(|e| HttpSigError::ParsePrivateKeyError(e.to_string()))?;
96 Ok(Self::RsaPssSha512(pss::SigningKey::<rsa::sha2::Sha512>::new(sk)))
97 }
98 _ => Err(HttpSigError::ParsePrivateKeyError("Unsupported algorithm".to_string())),
99 }
100 }
101 pub fn from_der(alg: &AlgorithmName, der: &[u8]) -> HttpSigResult<Self> {
104 let pki = PrivateKeyInfo::from_der(der).map_err(|e| HttpSigError::ParsePrivateKeyError(e.to_string()))?;
105
106 let sk_bytes = match pki.algorithm.oid.to_string().as_ref() {
107 algorithm_oids::EC => {
109 let param = pki
110 .algorithm
111 .parameters_oid()
112 .map_err(|e| HttpSigError::ParsePrivateKeyError(e.to_string()))?;
113 let algorithm_name = match param.to_string().as_ref() {
114 params_oids::Secp256r1 => AlgorithmName::EcdsaP256Sha256,
115 params_oids::Secp384r1 => AlgorithmName::EcdsaP384Sha384,
116 _ => return Err(HttpSigError::ParsePrivateKeyError("Unsupported curve".to_string())),
117 };
118 if algorithm_name != *alg {
120 return Err(HttpSigError::ParsePrivateKeyError("Algorithm mismatch".to_string()));
121 }
122 let sk_bytes = sec1::EcPrivateKey::try_from(pki.private_key)
123 .map_err(|e| HttpSigError::ParsePrivateKeyError(format!("Error decoding EcPrivateKey: {e}")))?
124 .private_key;
125 sk_bytes
126 }
127 algorithm_oids::Ed25519 => {
129 if AlgorithmName::Ed25519 != *alg {
131 return Err(HttpSigError::ParsePrivateKeyError("Algorithm mismatch".to_string()));
132 }
133 &pki.private_key[2..]
134 }
135 #[cfg(feature = "rsa-signature")]
137 algorithm_oids::rsaEncryption => {
138 match alg {
140 AlgorithmName::RsaV1_5Sha256 | AlgorithmName::RsaPssSha512 => {}
141 _ => return Err(HttpSigError::ParsePrivateKeyError("Algorithm mismatch".to_string())),
142 }
143 pki.private_key
144 }
145 _ => return Err(HttpSigError::ParsePrivateKeyError("Unsupported algorithm".to_string())),
146 };
147 let sk = Self::from_bytes(alg, sk_bytes)?;
148 Ok(sk)
149 }
150
151 pub fn from_pem(alg: &AlgorithmName, pem: &str) -> HttpSigResult<Self> {
153 let (tag, doc) = Document::from_pem(pem).map_err(|e| HttpSigError::ParsePrivateKeyError(e.to_string()))?;
154 if tag != "PRIVATE KEY" {
155 return Err(HttpSigError::ParsePrivateKeyError("Invalid tag".to_string()));
156 };
157 Self::from_der(alg, doc.as_bytes())
158 }
159
160 pub fn public_key(&self) -> PublicKey {
162 match &self {
163 Self::EcdsaP256Sha256(key) => PublicKey::EcdsaP256Sha256(key.public_key()),
164 Self::EcdsaP384Sha384(key) => PublicKey::EcdsaP384Sha384(key.public_key()),
165 Self::Ed25519(key) => PublicKey::Ed25519(key.public_key()),
166 #[cfg(feature = "rsa-signature")]
167 Self::RsaV1_5Sha256(key) => PublicKey::RsaV1_5Sha256(key.verifying_key()),
168 #[cfg(feature = "rsa-signature")]
169 Self::RsaPssSha512(key) => PublicKey::RsaPssSha512(key.verifying_key()),
170 }
171 }
172}
173
174impl super::SigningKey for SecretKey {
175 fn sign(&self, data: &[u8]) -> HttpSigResult<Vec<u8>> {
177 match &self {
178 Self::EcdsaP256Sha256(sk) => {
179 debug!("Sign EcdsaP256Sha256");
180 let sk = ecdsa::SigningKey::from(sk);
181 let mut digest = <Sha256 as Digest>::new();
182 digest.update(data);
183 let sig: ecdsa::Signature<NistP256> = sk.sign_digest(digest);
184 Ok(sig.to_bytes().to_vec())
185 }
186 Self::EcdsaP384Sha384(sk) => {
187 debug!("Sign EcdsaP384Sha384");
188 let sk = ecdsa::SigningKey::from(sk);
189 let mut digest = <Sha384 as Digest>::new();
190 digest.update(data);
191 let sig: ecdsa::Signature<NistP384> = sk.sign_digest(digest);
192 Ok(sig.to_bytes().to_vec())
193 }
194 Self::Ed25519(sk) => {
195 debug!("Sign Ed25519");
196 let sig = sk.sign(data, Some(ed25519_compact::Noise::default()));
197 Ok(sig.as_ref().to_vec())
198 }
199 #[cfg(feature = "rsa-signature")]
200 Self::RsaV1_5Sha256(sk) => {
201 debug!("Sign RsaV1_5Sha256");
202 let sig = sk.sign_with_rng(&mut rand::rng(), data);
203 Ok(sig.to_vec())
204 }
205 #[cfg(feature = "rsa-signature")]
206 Self::RsaPssSha512(sk) => {
207 debug!("Sign RsaPssSha512");
208 let sig = sk.sign_with_rng(&mut rand::rng(), data);
209 Ok(sig.to_vec())
210 }
211 }
212 }
213
214 fn key_id(&self) -> String {
215 use super::VerifyingKey;
216 self.public_key().key_id()
217 }
218
219 fn alg(&self) -> AlgorithmName {
220 use super::VerifyingKey;
221 self.public_key().alg()
222 }
223}
224
225impl super::VerifyingKey for SecretKey {
226 fn verify(&self, data: &[u8], signature: &[u8]) -> HttpSigResult<()> {
227 self.public_key().verify(data, signature)
228 }
229
230 fn key_id(&self) -> String {
231 self.public_key().key_id()
232 }
233
234 fn alg(&self) -> AlgorithmName {
235 self.public_key().alg()
236 }
237}
238
239#[derive(Debug, Clone)]
241pub enum PublicKey {
244 EcdsaP256Sha256(EcPublicKey<NistP256>),
246 EcdsaP384Sha384(EcPublicKey<NistP384>),
248 Ed25519(Ed25519PublicKey),
250 #[cfg(feature = "rsa-signature")]
251 RsaV1_5Sha256(pkcs1v15::VerifyingKey<rsa::sha2::Sha256>),
253 #[cfg(feature = "rsa-signature")]
254 RsaPssSha512(pss::VerifyingKey<rsa::sha2::Sha512>),
256}
257
258impl PublicKey {
259 pub fn from_bytes(alg: &AlgorithmName, bytes: &[u8]) -> HttpSigResult<Self> {
261 match alg {
262 AlgorithmName::EcdsaP256Sha256 => {
263 debug!("Read P256 public key");
264 let pk = EcPublicKey::from_sec1_bytes(bytes).map_err(|e| HttpSigError::ParsePublicKeyError(e.to_string()))?;
265 Ok(Self::EcdsaP256Sha256(pk))
266 }
267 AlgorithmName::EcdsaP384Sha384 => {
268 debug!("Read P384 public key");
269 let pk = EcPublicKey::from_sec1_bytes(bytes).map_err(|e| HttpSigError::ParsePublicKeyError(e.to_string()))?;
270 Ok(Self::EcdsaP384Sha384(pk))
271 }
272 AlgorithmName::Ed25519 => {
273 debug!("Read Ed25519 public key");
274 let pk = ed25519_compact::PublicKey::from_slice(bytes).map_err(|e| HttpSigError::ParsePublicKeyError(e.to_string()))?;
275 Ok(Self::Ed25519(pk))
276 }
277 #[cfg(feature = "rsa-signature")]
278 AlgorithmName::RsaV1_5Sha256 => {
279 debug!("Read RSA public key");
280 let pk = RsaPublicKey::from_pkcs1_der(bytes).map_err(|e| HttpSigError::ParsePublicKeyError(e.to_string()))?;
282 Ok(Self::RsaV1_5Sha256(pkcs1v15::VerifyingKey::new(pk)))
283 }
284 #[cfg(feature = "rsa-signature")]
285 AlgorithmName::RsaPssSha512 => {
286 debug!("Read RSA-PSS public key");
287 let pk = RsaPublicKey::from_pkcs1_der(bytes).map_err(|e| HttpSigError::ParsePublicKeyError(e.to_string()))?;
289 Ok(Self::RsaPssSha512(pss::VerifyingKey::new(pk)))
290 }
291 _ => Err(HttpSigError::ParsePublicKeyError("Unsupported algorithm".to_string())),
292 }
293 }
294
295 #[allow(dead_code)]
296 pub fn from_pem(alg: &AlgorithmName, pem: &str) -> HttpSigResult<Self> {
298 let (tag, doc) = Document::from_pem(pem).map_err(|e| HttpSigError::ParsePublicKeyError(e.to_string()))?;
299 if tag != "PUBLIC KEY" {
300 return Err(HttpSigError::ParsePublicKeyError("Invalid tag".to_string()));
301 };
302
303 let spki_ref = SubjectPublicKeyInfoRef::from_der(doc.as_bytes())
304 .map_err(|e| HttpSigError::ParsePublicKeyError(format!("Error decoding SubjectPublicKeyInfo: {e}").to_string()))?;
305
306 let pk_bytes = match spki_ref.algorithm.oid.to_string().as_ref() {
307 algorithm_oids::EC => {
309 let param = spki_ref
310 .algorithm
311 .parameters_oid()
312 .map_err(|e| HttpSigError::ParsePublicKeyError(e.to_string()))?;
313 let algorithm_name = match param.to_string().as_ref() {
314 params_oids::Secp256r1 => AlgorithmName::EcdsaP256Sha256,
315 params_oids::Secp384r1 => AlgorithmName::EcdsaP384Sha384,
316 _ => return Err(HttpSigError::ParsePublicKeyError("Unsupported curve".to_string())),
317 };
318 if algorithm_name != *alg {
320 return Err(HttpSigError::ParsePublicKeyError("Algorithm mismatch".to_string()));
321 }
322 spki_ref
323 .subject_public_key
324 .as_bytes()
325 .ok_or(HttpSigError::ParsePublicKeyError("Invalid public key".to_string()))?
326 }
327 algorithm_oids::Ed25519 => {
329 if AlgorithmName::Ed25519 != *alg {
331 return Err(HttpSigError::ParsePublicKeyError("Algorithm mismatch".to_string()));
332 }
333 spki_ref
334 .subject_public_key
335 .as_bytes()
336 .ok_or(HttpSigError::ParsePublicKeyError("Invalid public key".to_string()))?
337 }
338 #[cfg(feature = "rsa-signature")]
340 algorithm_oids::rsaEncryption => {
341 match alg {
342 AlgorithmName::RsaV1_5Sha256 | AlgorithmName::RsaPssSha512 => {}
343 _ => return Err(HttpSigError::ParsePublicKeyError("Algorithm mismatch".to_string())),
344 }
345 spki_ref
346 .subject_public_key
347 .as_bytes()
348 .ok_or(HttpSigError::ParsePublicKeyError("Invalid public key".to_string()))?
349 }
350 _ => return Err(HttpSigError::ParsePublicKeyError("Unsupported algorithm".to_string())),
351 };
352 Self::from_bytes(alg, pk_bytes)
353 }
354}
355
356impl super::VerifyingKey for PublicKey {
357 fn verify(&self, data: &[u8], signature: &[u8]) -> HttpSigResult<()> {
359 match self {
360 Self::EcdsaP256Sha256(pk) => {
361 debug!("Verify EcdsaP256Sha256");
362 let signature = ecdsa::Signature::<NistP256>::from_bytes(signature.into())
363 .map_err(|e| HttpSigError::ParseSignatureError(e.to_string()))?;
364 let vk = ecdsa::VerifyingKey::from(pk);
365 let mut digest = <Sha256 as Digest>::new();
366 digest.update(data);
367 vk.verify_digest(digest, &signature)
368 .map_err(|e| HttpSigError::InvalidSignature(e.to_string()))
369 }
370 Self::EcdsaP384Sha384(pk) => {
371 debug!("Verify EcdsaP384Sha384");
372 let signature = ecdsa::Signature::<NistP384>::from_bytes(signature.into())
373 .map_err(|e| HttpSigError::ParseSignatureError(e.to_string()))?;
374 let vk = ecdsa::VerifyingKey::from(pk);
375 let mut digest = <Sha384 as Digest>::new();
376 digest.update(data);
377 vk.verify_digest(digest, &signature)
378 .map_err(|e| HttpSigError::InvalidSignature(e.to_string()))
379 }
380 Self::Ed25519(pk) => {
381 debug!("Verify Ed25519");
382 let sig =
383 ed25519_compact::Signature::from_slice(signature).map_err(|e| HttpSigError::ParseSignatureError(e.to_string()))?;
384 pk.verify(data, &sig)
385 .map_err(|e| HttpSigError::InvalidSignature(e.to_string()))
386 }
387 #[cfg(feature = "rsa-signature")]
388 Self::RsaV1_5Sha256(pk) => {
389 debug!("Verify RsaV1_5Sha256");
390 let sig = pkcs1v15::Signature::try_from(signature).map_err(|e| HttpSigError::ParseSignatureError(e.to_string()))?;
391 pk.verify(data, &sig)
392 .map_err(|e| HttpSigError::InvalidSignature(e.to_string()))
393 }
394 #[cfg(feature = "rsa-signature")]
395 Self::RsaPssSha512(pk) => {
396 debug!("Verify RsaPssSha512");
397 let sig = pss::Signature::try_from(signature).map_err(|e| HttpSigError::ParseSignatureError(e.to_string()))?;
398 pk.verify(data, &sig)
399 .map_err(|e| HttpSigError::InvalidSignature(e.to_string()))
400 }
401 }
402 }
403
404 fn key_id(&self) -> String {
409 use base64::{engine::general_purpose, Engine as _};
410
411 let bytes = match self {
412 Self::EcdsaP256Sha256(vk) => vk.to_encoded_point(true).as_bytes().to_vec(),
413 Self::EcdsaP384Sha384(vk) => vk.to_encoded_point(true).as_bytes().to_vec(),
414 Self::Ed25519(vk) => vk.as_ref().to_vec(),
415 #[cfg(feature = "rsa-signature")]
416 Self::RsaV1_5Sha256(vk) => vk
417 .as_ref()
418 .to_pkcs1_der()
419 .map(|der| der.as_bytes().to_vec())
420 .unwrap_or(b"rsa-der-serialization-failed".to_vec()),
421 #[cfg(feature = "rsa-signature")]
422 Self::RsaPssSha512(vk) => vk
423 .as_ref()
424 .to_pkcs1_der()
425 .map(|der| der.as_bytes().to_vec())
426 .unwrap_or(b"rsa-der-serialization-failed".to_vec()),
427 };
428 let mut hasher = <Sha256 as Digest>::new();
429 hasher.update(&bytes);
430 let hash = hasher.finalize();
431 general_purpose::STANDARD.encode(hash)
432 }
433
434 fn alg(&self) -> AlgorithmName {
436 match self {
437 Self::EcdsaP256Sha256(_) => AlgorithmName::EcdsaP256Sha256,
438 Self::EcdsaP384Sha384(_) => AlgorithmName::EcdsaP384Sha384,
439 Self::Ed25519(_) => AlgorithmName::Ed25519,
440 #[cfg(feature = "rsa-signature")]
441 Self::RsaV1_5Sha256(_) => AlgorithmName::RsaV1_5Sha256,
442 #[cfg(feature = "rsa-signature")]
443 Self::RsaPssSha512(_) => AlgorithmName::RsaPssSha512,
444 }
445 }
446}
447
448#[cfg(test)]
449mod tests {
450 use p256::elliptic_curve::group::GroupEncoding;
451
452 use super::*;
453 use std::matches;
454
455 const P256_SECRET_KEY: &str = r##"-----BEGIN PRIVATE KEY-----
456MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgv7zxW56ojrWwmSo1
4574uOdbVhUfj9Jd+5aZIB9u8gtWnihRANCAARGYsMe0CT6pIypwRvoJlLNs4+cTh2K
458L7fUNb5i6WbKxkpAoO+6T3pMBG5Yw7+8NuGTvvtrZAXduA2giPxQ8zCf
459-----END PRIVATE KEY-----
460"##;
461 const P256_PUBLIC_KEY: &str = r##"-----BEGIN PUBLIC KEY-----
462MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERmLDHtAk+qSMqcEb6CZSzbOPnE4d
463ii+31DW+YulmysZKQKDvuk96TARuWMO/vDbhk777a2QF3bgNoIj8UPMwnw==
464-----END PUBLIC KEY-----
465"##;
466 const P384_SECRET_KEY: &str = r##"-----BEGIN PRIVATE KEY-----
467MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCPYbeLLlIQKUzVyVGH
468MeuFp/9o2Lr+4GrI3bsbHuViMMceiuM+8xqzFCSm4Ltl5UyhZANiAARKg3yM+Ltx
469n4ZptF3hI6Q167crEtPRklCEsRTyWUqy+VrrnM5LU/+fqxVbyniBZHd4vmQVYtjF
470xsv8P3DpjvpKJZqFfVdIr2ZR+kYDKHwIruIF9fCPawAH2tnbuc3xEzQ=
471-----END PRIVATE KEY-----
472"##;
473 const P384_PUBLIC_KEY: &str = r##"-----BEGIN PUBLIC KEY-----
474MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAESoN8jPi7cZ+GabRd4SOkNeu3KxLT0ZJQ
475hLEU8llKsvla65zOS1P/n6sVW8p4gWR3eL5kFWLYxcbL/D9w6Y76SiWahX1XSK9m
476UfpGAyh8CK7iBfXwj2sAB9rZ27nN8RM0
477-----END PUBLIC KEY-----
478"##;
479
480 const EDDSA_SECRET_KEY: &str = r##"-----BEGIN PRIVATE KEY-----
481MC4CAQAwBQYDK2VwBCIEIDSHAE++q1BP7T8tk+mJtS+hLf81B0o6CFyWgucDFN/C
482-----END PRIVATE KEY-----
483"##;
484 const EDDSA_PUBLIC_KEY: &str = r##"-----BEGIN PUBLIC KEY-----
485MCowBQYDK2VwAyEA1ixMQcxO46PLlgQfYS46ivFd+n0CcDHSKUnuhm3i1O0=
486-----END PUBLIC KEY-----
487"##;
488
489 #[cfg(feature = "rsa-signature")]
490 const RSA2048_SECRET_KEY: &str = r##"-----BEGIN PRIVATE KEY-----
491MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCrjtdIxemmmL9V
492wfp7qqwytfRDZqQM6XNWcAi3x+j5dHFFIKKWQktJ7eCTRYQrBwjQs5sb0ieNUYwQ
493vTIH53z9PqKl1bCIk/6Pago2JNBQAUP9DSs+zcYYC1TYwPM12mxIqz6tHVBabBuG
49449OoqWGgU4J5YkXvjyNFPVK1+dePLalm4/jUJb4VpbppN5NQ9qaqRTB3vQPW9i3D
495uy2hefxh7FGfKx9BwrtKcV4JmjN9IjPpdjZTex/8GF3eIiePkHIJS88w8lkC4F03
49606EuaMRs6KyWpj1aof+LvMG6iIRAigc0K//4tTwfKALRky4tW9JAYe3cFACDulu2
497VXKGatq1AgMBAAECggEAH/cOb9XIci0VwXHSLQag7RXv/Dr8qBc7UUiwpyWNaCVl
498EX9CLAMQKiczZ91VAftejhxY8zcV/YPLODc4QjbEmB76iTGmodwJW0lju7DiS3Xg
4996B5zB1Gp7kL2PSi+aDNZZ7TYicLjfOWVv21lu5BLy2aj8d/4rekapkUFyzhRDLEk
500E9/mvztCrLjLXMS6SFXY/rjfwckBT/tACbmgHInzRcoyX75FYyGtOc3w1S1tXEM8
5017j/7EHZf+mNcHlpV5OMw+StVfl1Qwx8eJ9ZW1TmZEoysRe4zj/ej7+wTBSAC7AoA
502UVB6G8hVU1NP+KD7Z9/6SvfJGvj8yR1HdBE5BZ54JQKBgQDfkpDEH4EH0pRSd867
503nrijAwnqd4xdP11aOwgrrppxavUWAmd3vmki8k4O3ghkz8MtNd+bTcZNKcl4ioS3
504boFA++wZQuzPBu6dbwlM9QX0VyzKAmGITrcnFrxCk3k8d6r9DzTVrzY8oK7nvo+1
505n9QYtlBs/SyJZl4McEOCV0fsowKBgQDEcO6KkwQPt//Qm6Qb1ImrQQ1kgvOu77iG
506R5Gn/FkURJvy+I4g9ANRXmHFTcdMSIS3dzY5Zr4kwa0UYJ/ivQ5QYwzYISiW3kgj
507jmoLhxfWOXaO+vGNBXoZb5JkKrT2pnLlbbeiHaur6jfg20T2w2whts4vJ8aI6V3k
508HagrXuz4xwKBgQDWhMhZFq109w4QTxrTFYmuCAVkr07ETj9hi5DccQ2J1AnUE3x5
509/f7dZEeXpl3BdUSeRboHR0oF0hmZirerVeG5m7+/wWJ9hvY/o0H2UIhlGZxFPKGe
51064B7hiofa2eBqIUtiYC1pAfTho4smMFFkVUuXQiwewBX2hxVrQZpsxu1JwKBgEwH
511fXuqvPase1ks9A5Fa2cZzWoqeNArPdrS1mAS/hMnHsiiRLgiWSpkAilQGiO/KYas
512oBMFXfBx+WAaqacjDugz/eOkqcYCkB8a3pZJmgMyyF08aMLw7LntgdY85T9VWsDL
513fzhCjZADHc9sbjunlTFTRGfh2ChjUhCZHd5zZfo/AoGBANk7kXrHZlAsmEEoeA8R
514yVpIaTIu64SzCsn4lWzh02zuSB20uNzYdNYBkHT/JHMvV4ctxjAXjDWI8aYzHaHY
515KDYy4jUp2TeTPBpqwS24KzFaFx0y2U99TWrzt6sQJr7Y9NlR7S0znc/L7wwFobjr
516XVdlU40OaPP7xs0er/tWVAPY
517-----END PRIVATE KEY-----"##;
518
519 #[cfg(feature = "rsa-signature")]
520 const RSA2048_PUBLIC_KEY: &str = r##"-----BEGIN PUBLIC KEY-----
521MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq47XSMXpppi/VcH6e6qs
522MrX0Q2akDOlzVnAIt8fo+XRxRSCilkJLSe3gk0WEKwcI0LObG9InjVGMEL0yB+d8
523/T6ipdWwiJP+j2oKNiTQUAFD/Q0rPs3GGAtU2MDzNdpsSKs+rR1QWmwbhuPTqKlh
524oFOCeWJF748jRT1StfnXjy2pZuP41CW+FaW6aTeTUPamqkUwd70D1vYtw7stoXn8
525YexRnysfQcK7SnFeCZozfSIz6XY2U3sf/Bhd3iInj5ByCUvPMPJZAuBdN9OhLmjE
526bOislqY9WqH/i7zBuoiEQIoHNCv/+LU8HygC0ZMuLVvSQGHt3BQAg7pbtlVyhmra
527tQIDAQAB
528-----END PUBLIC KEY-----"##;
529
530 #[test]
531 fn test_from_bytes() {
532 let ed25519_kp = ed25519_compact::KeyPair::from_seed(ed25519_compact::Seed::default());
533 let ed25519_sk = ed25519_kp.sk.seed().to_vec();
534 let ed25519_pk = ed25519_kp.pk.as_ref();
535 let sk = SecretKey::from_bytes(&AlgorithmName::Ed25519, &ed25519_sk).unwrap();
536 assert!(matches!(sk, SecretKey::Ed25519(_)));
537 let pk = PublicKey::from_bytes(&AlgorithmName::Ed25519, ed25519_pk).unwrap();
538 assert!(matches!(pk, PublicKey::Ed25519(_)));
539
540 let mut rng = rand_085::thread_rng();
541 let es256_sk = p256::ecdsa::SigningKey::random(&mut rng);
542 let es256_pk = es256_sk.verifying_key();
543 let sk = SecretKey::from_bytes(&AlgorithmName::EcdsaP256Sha256, es256_sk.to_bytes().as_ref()).unwrap();
544 assert!(matches!(sk, SecretKey::EcdsaP256Sha256(_)));
545 let pk_bytes = es256_pk.as_affine().to_bytes();
546 let pk = PublicKey::from_bytes(&AlgorithmName::EcdsaP256Sha256, pk_bytes.as_ref()).unwrap();
547 assert!(matches!(pk, PublicKey::EcdsaP256Sha256(_)));
548 }
549
550 #[test]
551 fn test_from_pem() {
552 let sk = SecretKey::from_pem(&AlgorithmName::EcdsaP256Sha256, P256_SECRET_KEY).unwrap();
553 assert!(matches!(sk, SecretKey::EcdsaP256Sha256(_)));
554 let pk = PublicKey::from_pem(&AlgorithmName::EcdsaP256Sha256, P256_PUBLIC_KEY).unwrap();
555 assert!(matches!(pk, PublicKey::EcdsaP256Sha256(_)));
556
557 let sk = SecretKey::from_pem(&AlgorithmName::EcdsaP384Sha384, P384_SECRET_KEY).unwrap();
558 assert!(matches!(sk, SecretKey::EcdsaP384Sha384(_)));
559 let pk = PublicKey::from_pem(&AlgorithmName::EcdsaP384Sha384, P384_PUBLIC_KEY).unwrap();
560 assert!(matches!(pk, PublicKey::EcdsaP384Sha384(_)));
561
562 let sk = SecretKey::from_pem(&AlgorithmName::Ed25519, EDDSA_SECRET_KEY).unwrap();
563 assert!(matches!(sk, SecretKey::Ed25519(_)));
564 let pk = PublicKey::from_pem(&AlgorithmName::Ed25519, EDDSA_PUBLIC_KEY).unwrap();
565 assert!(matches!(pk, PublicKey::Ed25519(_)));
566 }
567
568 #[cfg(feature = "rsa-signature")]
569 #[test]
570 fn test_from_pem_rsa() {
571 let sk = SecretKey::from_pem(&AlgorithmName::RsaV1_5Sha256, RSA2048_SECRET_KEY).unwrap();
572 assert!(matches!(sk, SecretKey::RsaV1_5Sha256(_)));
573 let pk = PublicKey::from_pem(&AlgorithmName::RsaV1_5Sha256, RSA2048_PUBLIC_KEY).unwrap();
574 assert!(matches!(pk, PublicKey::RsaV1_5Sha256(_)));
575
576 let sk = SecretKey::from_pem(&AlgorithmName::RsaPssSha512, RSA2048_SECRET_KEY).unwrap();
577 assert!(matches!(sk, SecretKey::RsaPssSha512(_)));
578 let pk = PublicKey::from_pem(&AlgorithmName::RsaPssSha512, RSA2048_PUBLIC_KEY).unwrap();
579 assert!(matches!(pk, PublicKey::RsaPssSha512(_)));
580 }
581
582 #[test]
583 fn test_sign_verify() {
584 use super::super::{SigningKey, VerifyingKey};
585 let sk = SecretKey::from_pem(&AlgorithmName::EcdsaP256Sha256, P256_SECRET_KEY).unwrap();
586 let pk = PublicKey::from_pem(&AlgorithmName::EcdsaP256Sha256, P256_PUBLIC_KEY).unwrap();
587 let data = b"hello world";
588 let signature = sk.sign(data).unwrap();
589 pk.verify(data, &signature).unwrap();
590 assert!(pk.verify(b"hello", &signature).is_err());
591
592 let sk = SecretKey::from_pem(&AlgorithmName::EcdsaP384Sha384, P384_SECRET_KEY).unwrap();
593 let pk = PublicKey::from_pem(&AlgorithmName::EcdsaP384Sha384, P384_PUBLIC_KEY).unwrap();
594 let data = b"hello world";
595 let signature = sk.sign(data).unwrap();
596 pk.verify(data, &signature).unwrap();
597 assert!(pk.verify(b"hello", &signature).is_err());
598
599 let sk = SecretKey::from_pem(&AlgorithmName::Ed25519, EDDSA_SECRET_KEY).unwrap();
600 let pk = PublicKey::from_pem(&AlgorithmName::Ed25519, EDDSA_PUBLIC_KEY).unwrap();
601 let data = b"hello world";
602 let signature = sk.sign(data).unwrap();
603 pk.verify(data, &signature).unwrap();
604 assert!(pk.verify(b"hello", &signature).is_err());
605 }
606
607 #[cfg(feature = "rsa-signature")]
608 #[test]
609 fn test_sign_verify_rsa() {
610 use super::super::{SigningKey, VerifyingKey};
611 let sk = SecretKey::from_pem(&AlgorithmName::RsaV1_5Sha256, RSA2048_SECRET_KEY).unwrap();
612 let pk = PublicKey::from_pem(&AlgorithmName::RsaV1_5Sha256, RSA2048_PUBLIC_KEY).unwrap();
613 let data = b"hello world";
614 let signature = sk.sign(data).unwrap();
615 pk.verify(data, &signature).unwrap();
616 assert!(pk.verify(b"hello", &signature).is_err());
617
618 let sk = SecretKey::from_pem(&AlgorithmName::RsaPssSha512, RSA2048_SECRET_KEY).unwrap();
619 let pk = PublicKey::from_pem(&AlgorithmName::RsaPssSha512, RSA2048_PUBLIC_KEY).unwrap();
620 let data = b"hello world";
621 let signature = sk.sign(data).unwrap();
622 pk.verify(data, &signature).unwrap();
623 assert!(pk.verify(b"hello", &signature).is_err());
624 }
625
626 #[test]
627 fn test_kid() -> HttpSigResult<()> {
628 use super::super::VerifyingKey;
629 let sk = SecretKey::from_pem(&AlgorithmName::EcdsaP256Sha256, P256_SECRET_KEY)?;
630 let pk = PublicKey::from_pem(&AlgorithmName::EcdsaP256Sha256, P256_PUBLIC_KEY)?;
631 assert_eq!(sk.public_key().key_id(), pk.key_id());
632 assert_eq!(pk.key_id(), "k34r3Nqfak67bhJSXTjTRo5tCIr1Bsre1cPoJ3LJ9xE=");
633
634 let sk = SecretKey::from_pem(&AlgorithmName::EcdsaP384Sha384, P384_SECRET_KEY)?;
635 let pk = PublicKey::from_pem(&AlgorithmName::EcdsaP384Sha384, P384_PUBLIC_KEY)?;
636 assert_eq!(sk.public_key().key_id(), pk.key_id());
637 assert_eq!(pk.key_id(), "JluSJKLaQsbGcgg1Ves4FfP/Kf7qS11RT88TvU0eNSo=");
638
639 let sk = SecretKey::from_pem(&AlgorithmName::Ed25519, EDDSA_SECRET_KEY)?;
640 let pk = PublicKey::from_pem(&AlgorithmName::Ed25519, EDDSA_PUBLIC_KEY)?;
641 assert_eq!(sk.public_key().key_id(), pk.key_id());
642 assert_eq!(pk.key_id(), "gjrE7ACMxgzYfFHgabgf4kLTg1eKIdsJ94AiFTFj1is=");
643 Ok(())
644 }
645
646 #[cfg(feature = "rsa-signature")]
647 #[test]
648 fn test_kid_rsa() -> HttpSigResult<()> {
649 use super::super::VerifyingKey;
650 let sk = SecretKey::from_pem(&AlgorithmName::RsaV1_5Sha256, RSA2048_SECRET_KEY)?;
651 let pk = PublicKey::from_pem(&AlgorithmName::RsaV1_5Sha256, RSA2048_PUBLIC_KEY)?;
652 assert_eq!(sk.public_key().key_id(), pk.key_id());
653 assert_eq!(pk.key_id(), "NoJFUyf2XUdhrTK66RlrGEemIlr1tOScYVeNVCv+5Ns=");
654
655 let sk = SecretKey::from_pem(&AlgorithmName::RsaPssSha512, RSA2048_SECRET_KEY)?;
656 let pk = PublicKey::from_pem(&AlgorithmName::RsaPssSha512, RSA2048_PUBLIC_KEY)?;
657 assert_eq!(sk.public_key().key_id(), pk.key_id());
658 assert_eq!(pk.key_id(), "NoJFUyf2XUdhrTK66RlrGEemIlr1tOScYVeNVCv+5Ns="); Ok(())
660 }
661}