1use crate::pem;
12use base64::Engine;
13use base64::engine::general_purpose::STANDARD as BASE64;
14use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey, Error};
15use rsa::rand_core::OsRng;
16use rsa::sha2::{Digest, Sha256};
17use rsa::signature::hazmat::PrehashVerifier;
18use rsa::signature::{Keypair, SignatureEncoding, Signer, Verifier};
19use rsa::traits::{PrivateKeyParts, PublicKeyParts};
20use rsa::{BigUint, RsaPrivateKey, RsaPublicKey};
21use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
22
23pub const SECRET_KEY_SIZE: usize = 520;
26
27pub const PUBLIC_KEY_SIZE: usize = 264;
30
31pub const SIGNATURE_SIZE: usize = 256;
33
34pub const FINGERPRINT_SIZE: usize = 32;
36
37#[derive(Clone)]
41pub struct SecretKey {
42 inner: rsa::pkcs1v15::SigningKey<Sha256>,
43}
44
45impl SecretKey {
46 pub fn generate() -> SecretKey {
48 let mut rng = OsRng;
49
50 let key = RsaPrivateKey::new(&mut rng, 2048).unwrap();
51 let sig = rsa::pkcs1v15::SigningKey::<Sha256>::new(key);
52 Self { inner: sig }
53 }
54
55 pub fn from_bytes(bytes: &[u8; SECRET_KEY_SIZE]) -> Result<Self, rsa::Error> {
60 let p = BigUint::from_bytes_be(&bytes[0..128]);
61 let q = BigUint::from_bytes_be(&bytes[128..256]);
62 let d = BigUint::from_bytes_be(&bytes[256..512]);
63 let e = BigUint::from_bytes_be(&bytes[512..520]);
64
65 let n = &p * &q;
66
67 if n.bits() != 2048 {
69 return Err(rsa::Error::InvalidModulus);
70 }
71 if e != BigUint::from(65537u32) {
75 return Err(rsa::Error::InvalidExponent);
76 }
77 let key = RsaPrivateKey::from_components(n, e, d, vec![p, q])?;
78 let sig = rsa::pkcs1v15::SigningKey::<Sha256>::new(key);
79 Ok(Self { inner: sig })
80 }
81
82 pub fn from_der(der: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
84 let inner = rsa::pkcs1v15::SigningKey::<Sha256>::from_pkcs8_der(der)?;
85
86 let key: &RsaPrivateKey = inner.as_ref();
88 if key.n().bits() != 2048 {
89 return Err(Error::KeyMalformed.into());
90 }
91 if *key.e() != BigUint::from(65537u32) {
95 return Err(Error::KeyMalformed.into());
96 }
97 let recoded = rsa::pkcs1v15::SigningKey::<Sha256>::to_pkcs8_der(&inner)?;
101 if recoded.as_bytes() != der {
102 return Err(Error::KeyMalformed.into());
103 }
104 Ok(Self { inner })
105 }
106
107 pub fn from_pem(pem_str: &str) -> Result<Self, Box<dyn std::error::Error>> {
109 let (kind, data) = pem::decode(pem_str.as_bytes())?;
111 if kind != "PRIVATE KEY" {
112 return Err(format!("invalid PEM tag {}", kind).into());
113 }
114 Self::from_der(&data)
116 }
117
118 pub fn to_bytes(&self) -> [u8; SECRET_KEY_SIZE] {
123 let key: &RsaPrivateKey = self.inner.as_ref();
124 let primes = key.primes();
125
126 let mut out = [0u8; 520];
127
128 let p_bytes = primes[0].to_bytes_be();
129 out[128 - p_bytes.len()..128].copy_from_slice(&p_bytes);
130
131 let q_bytes = primes[1].to_bytes_be();
132 out[256 - q_bytes.len()..256].copy_from_slice(&q_bytes);
133
134 let d_bytes = key.d().to_bytes_be();
135 out[512 - d_bytes.len()..512].copy_from_slice(&d_bytes);
136
137 let e_bytes = key.e().to_bytes_be();
138 out[520 - e_bytes.len()..520].copy_from_slice(&e_bytes);
139
140 out
141 }
142
143 pub fn to_der(&self) -> Vec<u8> {
145 rsa::pkcs1v15::SigningKey::<Sha256>::to_pkcs8_der(&self.inner)
146 .unwrap()
147 .as_bytes()
148 .to_vec()
149 }
150
151 pub fn to_pem(&self) -> String {
153 pem::encode("PRIVATE KEY", &self.to_der())
154 }
155
156 pub fn public_key(&self) -> PublicKey {
158 let key = self.inner.verifying_key();
159 PublicKey { inner: key }
160 }
161
162 pub fn fingerprint(&self) -> Fingerprint {
165 self.public_key().fingerprint()
166 }
167
168 pub fn sign(&self, message: &[u8]) -> Signature {
170 let sig = self.inner.sign(message);
171 Signature(sig.to_bytes().as_ref().try_into().unwrap())
172 }
173}
174
175#[derive(Debug, Clone)]
180pub struct PublicKey {
181 inner: rsa::pkcs1v15::VerifyingKey<Sha256>,
182}
183
184impl PublicKey {
185 pub fn from_bytes(bytes: &[u8; PUBLIC_KEY_SIZE]) -> Result<Self, rsa::Error> {
189 let n = BigUint::from_bytes_be(&bytes[0..256]);
190 let e = BigUint::from_bytes_be(&bytes[256..264]);
191
192 if n.bits() != 2048 {
194 return Err(rsa::Error::InvalidModulus);
195 }
196 if e != BigUint::from(65537u32) {
200 return Err(rsa::Error::InvalidExponent);
201 }
202 let key = RsaPublicKey::new(n, e)?;
203 let inner = rsa::pkcs1v15::VerifyingKey::<Sha256>::new(key);
204 Ok(Self { inner })
205 }
206
207 pub fn from_der(der: &[u8]) -> Result<Self, Box<dyn std::error::Error>> {
209 let inner = rsa::pkcs1v15::VerifyingKey::<Sha256>::from_public_key_der(der)?;
210
211 let key: &RsaPublicKey = inner.as_ref();
213 if key.n().bits() != 2048 {
214 return Err(Error::KeyMalformed.into());
215 }
216 if *key.e() != BigUint::from(65537u32) {
220 return Err(Error::KeyMalformed.into());
221 }
222 Ok(Self { inner })
223 }
224
225 pub fn from_pem(pem_str: &str) -> Result<Self, Box<dyn std::error::Error>> {
227 let (kind, data) = pem::decode(pem_str.as_bytes())?;
229 if kind != "PUBLIC KEY" {
230 return Err(format!("invalid PEM tag {}", kind).into());
231 }
232 Self::from_der(&data)
234 }
235
236 pub fn to_bytes(&self) -> [u8; PUBLIC_KEY_SIZE] {
240 let key: &RsaPublicKey = self.inner.as_ref();
241
242 let mut out = [0u8; 264];
243
244 let n_bytes = key.n().to_bytes_be();
245 out[256 - n_bytes.len()..256].copy_from_slice(&n_bytes);
246
247 let e_bytes = key.e().to_bytes_be();
248 out[264 - e_bytes.len()..264].copy_from_slice(&e_bytes);
249
250 out
251 }
252
253 pub fn to_der(&self) -> Vec<u8> {
255 rsa::pkcs1v15::VerifyingKey::<Sha256>::to_public_key_der(&self.inner)
256 .unwrap()
257 .as_bytes()
258 .to_vec()
259 }
260
261 pub fn to_pem(&self) -> String {
263 pem::encode("PUBLIC KEY", &self.to_der())
264 }
265
266 pub fn fingerprint(&self) -> Fingerprint {
269 let pubkey: RsaPublicKey = self.inner.as_ref().clone();
270
271 let mut mod_le = pubkey.n().to_bytes_le();
272 mod_le.resize(256, 0);
273 let mut exp_le = pubkey.e().to_bytes_le();
274 exp_le.resize(8, 0);
275
276 let mut hasher = Sha256::new();
277 hasher.update(&mod_le);
278 hasher.update(&exp_le);
279 Fingerprint(hasher.finalize().into())
280 }
281
282 pub fn verify(
284 &self,
285 message: &[u8],
286 signature: &Signature,
287 ) -> Result<(), rsa::signature::Error> {
288 let sig = rsa::pkcs1v15::Signature::try_from(signature.to_bytes().as_slice())?;
289 self.inner.verify(message, &sig)
290 }
291
292 pub fn verify_hash(
294 &self,
295 hash: &[u8],
296 signature: &Signature,
297 ) -> Result<(), rsa::signature::Error> {
298 let sig = rsa::pkcs1v15::Signature::try_from(signature.to_bytes().as_slice())?;
299 self.inner.verify_prehash(hash, &sig)
300 }
301}
302
303impl Serialize for PublicKey {
304 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
305 serializer.serialize_str(&BASE64.encode(self.to_bytes()))
306 }
307}
308
309impl<'de> Deserialize<'de> for PublicKey {
310 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
311 let s = String::deserialize(deserializer)?;
312 let bytes = BASE64.decode(&s).map_err(de::Error::custom)?;
313 let arr: [u8; PUBLIC_KEY_SIZE] = bytes
314 .try_into()
315 .map_err(|_| de::Error::custom("invalid public key length"))?;
316 PublicKey::from_bytes(&arr).map_err(de::Error::custom)
317 }
318}
319
320#[cfg(feature = "cbor")]
321impl crate::cbor::Encode for PublicKey {
322 fn encode_cbor(&self) -> Vec<u8> {
323 self.to_bytes().encode_cbor()
324 }
325}
326
327#[cfg(feature = "cbor")]
328impl crate::cbor::Decode for PublicKey {
329 fn decode_cbor(data: &[u8]) -> Result<Self, crate::cbor::Error> {
330 let bytes = <[u8; PUBLIC_KEY_SIZE]>::decode_cbor(data)?;
331 Self::from_bytes(&bytes).map_err(|e| crate::cbor::Error::DecodeFailed(e.to_string()))
332 }
333
334 fn decode_cbor_notrail(
335 decoder: &mut crate::cbor::Decoder<'_>,
336 ) -> Result<Self, crate::cbor::Error> {
337 let bytes = decoder.decode_bytes_fixed::<PUBLIC_KEY_SIZE>()?;
338 Self::from_bytes(&bytes).map_err(|e| crate::cbor::Error::DecodeFailed(e.to_string()))
339 }
340}
341
342#[derive(Debug, Clone, PartialEq, Eq)]
344pub struct Signature([u8; SIGNATURE_SIZE]);
345
346impl Signature {
347 pub fn from_bytes(bytes: &[u8; SIGNATURE_SIZE]) -> Self {
349 Self(*bytes)
350 }
351
352 pub fn to_bytes(&self) -> [u8; SIGNATURE_SIZE] {
354 self.0
355 }
356}
357
358impl Serialize for Signature {
359 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
360 serializer.serialize_str(&BASE64.encode(self.to_bytes()))
361 }
362}
363
364impl<'de> Deserialize<'de> for Signature {
365 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
366 let s = String::deserialize(deserializer)?;
367 let bytes = BASE64.decode(&s).map_err(de::Error::custom)?;
368 let arr: [u8; SIGNATURE_SIZE] = bytes
369 .try_into()
370 .map_err(|_| de::Error::custom("invalid signature length"))?;
371 Ok(Signature::from_bytes(&arr))
372 }
373}
374
375#[cfg(feature = "cbor")]
376impl crate::cbor::Encode for Signature {
377 fn encode_cbor(&self) -> Vec<u8> {
378 self.to_bytes().encode_cbor()
379 }
380}
381
382#[cfg(feature = "cbor")]
383impl crate::cbor::Decode for Signature {
384 fn decode_cbor(data: &[u8]) -> Result<Self, crate::cbor::Error> {
385 let bytes = <[u8; SIGNATURE_SIZE]>::decode_cbor(data)?;
386 Ok(Self::from_bytes(&bytes))
387 }
388
389 fn decode_cbor_notrail(
390 decoder: &mut crate::cbor::Decoder<'_>,
391 ) -> Result<Self, crate::cbor::Error> {
392 let bytes = decoder.decode_bytes_fixed::<SIGNATURE_SIZE>()?;
393 Ok(Self::from_bytes(&bytes))
394 }
395}
396
397#[derive(Debug, Clone, PartialEq, Eq)]
399pub struct Fingerprint([u8; FINGERPRINT_SIZE]);
400
401impl Fingerprint {
402 pub fn from_bytes(bytes: &[u8; FINGERPRINT_SIZE]) -> Self {
404 Self(*bytes)
405 }
406
407 pub fn to_bytes(&self) -> [u8; FINGERPRINT_SIZE] {
409 self.0
410 }
411}
412
413impl Serialize for Fingerprint {
414 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
415 serializer.serialize_str(&BASE64.encode(self.to_bytes()))
416 }
417}
418
419impl<'de> Deserialize<'de> for Fingerprint {
420 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
421 let s = String::deserialize(deserializer)?;
422 let bytes = BASE64.decode(&s).map_err(de::Error::custom)?;
423 let arr: [u8; FINGERPRINT_SIZE] = bytes
424 .try_into()
425 .map_err(|_| de::Error::custom("invalid fingerprint length"))?;
426 Ok(Fingerprint::from_bytes(&arr))
427 }
428}
429
430#[cfg(feature = "cbor")]
431impl crate::cbor::Encode for Fingerprint {
432 fn encode_cbor(&self) -> Vec<u8> {
433 self.to_bytes().encode_cbor()
434 }
435}
436
437#[cfg(feature = "cbor")]
438impl crate::cbor::Decode for Fingerprint {
439 fn decode_cbor(data: &[u8]) -> Result<Self, crate::cbor::Error> {
440 let bytes = <[u8; FINGERPRINT_SIZE]>::decode_cbor(data)?;
441 Ok(Self::from_bytes(&bytes))
442 }
443
444 fn decode_cbor_notrail(
445 decoder: &mut crate::cbor::Decoder<'_>,
446 ) -> Result<Self, crate::cbor::Error> {
447 let bytes = decoder.decode_bytes_fixed::<FINGERPRINT_SIZE>()?;
448 Ok(Self::from_bytes(&bytes))
449 }
450}
451
452#[cfg(test)]
453mod tests {
454 use super::*;
455
456 #[test]
460 fn test_secretkey_bytes_codec() {
461 let part_prime1 = "\
465ed9792f021b214b57fc6230d051da0783673475d9b9cf9f9003367b6362a\
46662201852f112cbb6fcadb00b17470e21dfa39ec2eef58ea2ff7e27b9e63b\
46790af84e482b53ea79760196bbd226627038d84eb16e75e2efacb9f432dbf\
468b93ec3f6fea10ec9c9b984e8c7d4e95fa76befc2f46e42c86d8479586b36\
4697cb49499b37bf01d";
470 let part_prime2 = "\
471da885d75be231c04ebf195455fcec9449044b212f2044ddeeb49c0c14898\
47235f8e91e56a6418570a9f50c2734c4fadb7f2eb2c50cff4ab0b34e389568\
47312f9b42632c66a248e09e52af8eb5e1c8cdd21fe65b86242fdf1e838235d\
474a1bf37ced6ae0e117c8dac77c34917a711bc6ecc949d0f000dae8f22dadf\
47546153c64d5ef7521";
476 let part_priv_exp = "\
47702d864d6371a3586977264fa905c01495adbeba2fbab49cc1ea22d6d5c17\
47871b0a31b2a58c546e81990fa861e0954a4d9119d3698f41ca66b37c0b4a8\
479756f4efdd814d36393e3fb8b9662f1dc7725222565c95eb5389e3caa28e5\
480429608b898d677e9feffbb66207d3e881949dc0b53568a0ea9c6ae06bef3\
4816f74422960d8447b194ebff8ab5f08842153661278bbeb115dd131d26746\
4827315402b5d75560d4c20390499887f3d33021f4dda1cb36bfb9b54ed80c5\
4839bd3213f42a4ca7025d59a64e53d559e14ac84f8438b771c1ac94fb90aa4\
4841c7708e073510ad063bada4a261bc0b311a42b8d482d26b39fb82d44f133\
485c9ab9ccdd77b098fc6c0c647ed663781";
486 let part_pub_exp = "0000000000010001";
487
488 let input = [part_prime1, part_prime2, part_priv_exp, part_pub_exp].concat();
489
490 let bytes: [u8; 520] = hex::decode(&input).unwrap().try_into().unwrap();
491 let key = SecretKey::from_bytes(&bytes).unwrap();
492 assert_eq!(hex::encode(key.to_bytes()), input);
493 }
494
495 #[test]
499 fn test_publickey_bytes_codec() {
500 let part_mod = "\
504cad1a263e36205031c65b1befe8b1f65ac0af10c72aeb69ad295d1a651a3\
505f1191d4af8afdef14ab2d66d0253ef98228ee9f85fb822f92fccb3f6c23b\
5064745ac743e002fc81c63dc04531fc176f3cdcb5aebaa2797903fd791b9c8\
507474eb7b999295cf64935d9a5a4626849e77c472a6e00b8ff73d0f1a3b7c4\
5084da7e7bae4726b4f2f7f05741d576a13c1bc9077ee14d7e9af5192f8e7dc\
5092ffb212d4ef9c7fff4e87c3debf9a48346ac3618b24d7932d8e7cf6b266c\
510dce0ad59b16fce0a8420aebd332e28294862ef288917eacabf330cb29161\
511f78fcdf089bc2cb4086af8a7980637fb9cf0b4ed86d6a21208ae5a4e49d1\
5127ab6d945b65cef700217ada913ca34bd";
513 let part_pub_exp = "0000000000010001";
514
515 let input = [part_mod, part_pub_exp].concat();
516
517 let bytes: [u8; 264] = hex::decode(&input).unwrap().try_into().unwrap();
518 let key = PublicKey::from_bytes(&bytes).unwrap();
519 assert_eq!(hex::encode(key.to_bytes()), input);
520 }
521
522 #[test]
527 fn test_secretkey_pem_codec() {
528 let input = "\
531-----BEGIN PRIVATE KEY-----
532MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCwLLXTHaYT57yN
533HZT6BTnJIDaJ8GTnu05PnwQQcV7Xgom164T52qaMmvsK/PGlzMzQdo9YjYKsExZE
534EllJe4O1mVA1T/LyKLkPZgKqcp11/9UAkk3pHsPkb0YOb3g1721K6tQ78ufjeIOt
5355WJ+n+HJHOvhvyjmO0aQ51eh0jSyUu6U9fA+qrtPO4D/mUVRDJmCLSyGzIMd4Xan
536zTSWZ8JWLjahIdMPOZYUrGpICOxwt9Jaow37ogAalRVHnTb8PkklOo9pr0a3ZdQQ
537P3yV/A5gmgXXLi2BkQ0b2y8FOuD/JjBXL4Ks9nUVn/nMMaFhDxmL3ZZ9AuvB94AR
538B0MvuZh9AgMBAAECggEABoVaB1dURJhZDBV0OcI5iVWakr63md/F3kdDnlu+koDd
539/V63rG76izDmsQQYP3Zgt0TW1ehDcmP3ziDG2blycF5WKM2tqGcwlfBvypn8WEnH
5405eWEcEul5JFZ09C8b61N8sOALq01PzVOv8dCPu9jKzL19mfPofX4myKt4esKX2gy
541psId9QmgsrRRsCSvQeUxOA3Sqaa0a+atALZByPKZN8XzmZu1Ie5QPQvh/xYDJU1D
542GEiNgwZGy0eXL2Se5OjKAR40f4SzArbs/Jb2gRFHTjpdJ9g33GqoP94jZPcogtm2
543FHgI5vl9jL4uXiSJLkgl4FfFvoIXWuUi1xAC5NDT4QKBgQDnaxGFvt6vW8JKEyEq
5446Nf9K2Y2nQbvEmqnvS/RPwuqKuh66KCNG2rePFzXLHCplbYHt9hhF+Ity9lFzxSK
545ipRC6BD9aqaqF6qhm1nZWnXsPWjWDsFYzQHv8LA4pL8gmxbz+IOs1jbbIQAdq8X5
546uv7C1YSCrPkpm/nTljzwU/d/gwKBgQDC42in2DURf1+cU9Qw+hNDCy0EgkB7STzV
547dCreCAFXhSIzFwq9bjzOeSFtvZlWxKNJKNUiDXgN/grRREG/m1kW7EdHAMiOVVNK
548SbQ/+zHy6SMKNu0ArkokaCAEludVVRjkwh5GsyFvFaBINJBnp/zDYhNkkxStjCRf
549rW0/fmcH/wKBgF/IA9+caWShEOBB3Kd66fKiJNMT2QvYToaQmhr8AiLzUXeVkuX0
550ZB4JU8/HV/YIveeh4xAEp5uW1J29IN5ajxTGIkoQ+1xJIVl0CBMbCtW1cQ+v2byc
551VWHu97DqFyUyq6RcxnshymCV3wtozi8Xg1w2rXq8hv/+y78UXrKFvllrAoGAItrb
552F9GyRAvcxK+1boD7Ou1fwsOs1p/VknNxSz5xRv7Xi/2d/R0fIOpHEUJsjzkh3u6/
553l5SDGTWLJ7wmaidVeqUNZmR8egBGoi2mYB8D4ubRTn1eS9XgCrzYpRl8DCXpCtiw
55444IcA6sBfIhyHyfLLAJ5Z25qr1M2GiqBNG7d7G8CgYBoIYe3OeuqZn2T+eA3rmMv
555djLUQsO3CvmFYBDvNqmiwNx3OOV/YFQVvSAGaEP/5pJGVmAKUDaALgTveToLV6jq
556bS99QZDnrW+xkvJi6N1ZAlQpIOX5Y/Q2qyBa1Hf2Z21mnqZSN3HHC6aQl+83uety
557JJXbL24vf1AajzeJk6CpdQ==
558-----END PRIVATE KEY-----";
559
560 let key = SecretKey::from_pem(input).unwrap();
561 assert_eq!(key.to_pem().trim(), input.trim());
562 }
563
564 #[test]
569 fn test_publickey_pem_codec() {
570 let input = "\
573-----BEGIN PUBLIC KEY-----
574MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsCy10x2mE+e8jR2U+gU5
575ySA2ifBk57tOT58EEHFe14KJteuE+dqmjJr7CvzxpczM0HaPWI2CrBMWRBJZSXuD
576tZlQNU/y8ii5D2YCqnKddf/VAJJN6R7D5G9GDm94Ne9tSurUO/Ln43iDreVifp/h
577yRzr4b8o5jtGkOdXodI0slLulPXwPqq7TzuA/5lFUQyZgi0shsyDHeF2p800lmfC
578Vi42oSHTDzmWFKxqSAjscLfSWqMN+6IAGpUVR502/D5JJTqPaa9Gt2XUED98lfwO
579YJoF1y4tgZENG9svBTrg/yYwVy+CrPZ1FZ/5zDGhYQ8Zi92WfQLrwfeAEQdDL7mY
580fQIDAQAB
581-----END PUBLIC KEY-----";
582
583 let key = PublicKey::from_pem(input).unwrap();
584 assert_eq!(key.to_pem().trim(), input.trim());
585 }
586
587 #[test]
592 fn test_privatekey_der_codec() {
593 let input = "\
597308204bc020100300d06092a864886f70d0101010500048204a6308204a2\
5980201000282010100b02cb5d31da613e7bc8d1d94fa0539c9203689f064e7\
599bb4e4f9f0410715ed78289b5eb84f9daa68c9afb0afcf1a5ccccd0768f58\
6008d82ac1316441259497b83b59950354ff2f228b90f6602aa729d75ffd500\
601924de91ec3e46f460e6f7835ef6d4aead43bf2e7e37883ade5627e9fe1c9\
6021cebe1bf28e63b4690e757a1d234b252ee94f5f03eaabb4f3b80ff994551\
6030c99822d2c86cc831de176a7cd349667c2562e36a121d30f399614ac6a48\
60408ec70b7d25aa30dfba2001a9515479d36fc3e49253a8f69af46b765d410\
6053f7c95fc0e609a05d72e2d81910d1bdb2f053ae0ff2630572f82acf67515\
6069ff9cc31a1610f198bdd967d02ebc1f7801107432fb9987d020301000102\
60782010006855a0757544498590c157439c23989559a92beb799dfc5de4743\
6089e5bbe9280ddfd5eb7ac6efa8b30e6b104183f7660b744d6d5e8437263f7\
609ce20c6d9b972705e5628cdada8673095f06fca99fc5849c7e5e584704ba5\
610e49159d3d0bc6fad4df2c3802ead353f354ebfc7423eef632b32f5f667cf\
611a1f5f89b22ade1eb0a5f6832a6c21df509a0b2b451b024af41e531380dd2\
612a9a6b46be6ad00b641c8f29937c5f3999bb521ee503d0be1ff1603254d43\
61318488d830646cb47972f649ee4e8ca011e347f84b302b6ecfc96f6811147\
6144e3a5d27d837dc6aa83fde2364f72882d9b6147808e6f97d8cbe2e5e2489\
6152e4825e057c5be82175ae522d71002e4d0d3e102818100e76b1185bedeaf\
6165bc24a13212ae8d7fd2b66369d06ef126aa7bd2fd13f0baa2ae87ae8a08d\
6171b6ade3c5cd72c70a995b607b7d86117e22dcbd945cf148a8a9442e810fd\
6186aa6aa17aaa19b59d95a75ec3d68d60ec158cd01eff0b038a4bf209b16f3\
619f883acd636db21001dabc5f9bafec2d58482acf9299bf9d3963cf053f77f\
6208302818100c2e368a7d835117f5f9c53d430fa13430b2d0482407b493cd5\
621742ade080157852233170abd6e3cce79216dbd9956c4a34928d5220d780d\
622fe0ad14441bf9b5916ec474700c88e55534a49b43ffb31f2e9230a36ed00\
623ae4a2468200496e7555518e4c21e46b3216f15a048349067a7fcc3621364\
6249314ad8c245fad6d3f7e6707ff0281805fc803df9c6964a110e041dca77a\
625e9f2a224d313d90bd84e86909a1afc0222f351779592e5f4641e0953cfc7\
62657f608bde7a1e31004a79b96d49dbd20de5a8f14c6224a10fb5c49215974\
62708131b0ad5b5710fafd9bc9c5561eef7b0ea172532aba45cc67b21ca6095\
628df0b68ce2f17835c36ad7abc86fffecbbf145eb285be596b02818022dadb\
62917d1b2440bdcc4afb56e80fb3aed5fc2c3acd69fd59273714b3e7146fed7\
6308bfd9dfd1d1f20ea4711426c8f3921deeebf97948319358b27bc266a2755\
6317aa50d66647c7a0046a22da6601f03e2e6d14e7d5e4bd5e00abcd8a5197c\
6320c25e90ad8b0e3821c03ab017c88721f27cb2c0279676e6aaf53361a2a81\
633346eddec6f028180682187b739ebaa667d93f9e037ae632f7632d442c3b7\
6340af9856010ef36a9a2c0dc7738e57f605415bd20066843ffe6924656600a\
6355036802e04ef793a0b57a8ea6d2f7d4190e7ad6fb192f262e8dd59025429\
63620e5f963f436ab205ad477f6676d669ea6523771c70ba69097ef37b9eb72\
6372495db2f6e2f7f501a8f378993a0a975";
638
639 let der = hex::decode(&input).unwrap();
640 let key = SecretKey::from_der(&der).unwrap();
641 assert_eq!(hex::encode(key.to_der()), input);
642 }
643
644 #[test]
649 fn test_publickey_der_codec() {
650 let input = "\
65430820122300d06092a864886f70d01010105000382010f003082010a0282\
655010100b02cb5d31da613e7bc8d1d94fa0539c9203689f064e7bb4e4f9f04\
65610715ed78289b5eb84f9daa68c9afb0afcf1a5ccccd0768f588d82ac1316\
657441259497b83b59950354ff2f228b90f6602aa729d75ffd500924de91ec3\
658e46f460e6f7835ef6d4aead43bf2e7e37883ade5627e9fe1c91cebe1bf28\
659e63b4690e757a1d234b252ee94f5f03eaabb4f3b80ff9945510c99822d2c\
66086cc831de176a7cd349667c2562e36a121d30f399614ac6a4808ec70b7d2\
6615aa30dfba2001a9515479d36fc3e49253a8f69af46b765d4103f7c95fc0e\
662609a05d72e2d81910d1bdb2f053ae0ff2630572f82acf675159ff9cc31a1\
663610f198bdd967d02ebc1f7801107432fb9987d0203010001";
664
665 let der = hex::decode(&input).unwrap();
666 let key = PublicKey::from_der(&der).unwrap();
667 assert_eq!(hex::encode(key.to_der()), input);
668 }
669
670 #[test]
674 fn test_fingerprint() {
675 let input = "1e2eaa59f13165ce5c3b4e028fd259767c2ee8d43d5d5ba7debf9d31834b46db";
686
687 let key = PublicKey::from_pem(
688 "-----BEGIN PUBLIC KEY-----
689MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsCy10x2mE+e8jR2U+gU5
690ySA2ifBk57tOT58EEHFe14KJteuE+dqmjJr7CvzxpczM0HaPWI2CrBMWRBJZSXuD
691tZlQNU/y8ii5D2YCqnKddf/VAJJN6R7D5G9GDm94Ne9tSurUO/Ln43iDreVifp/h
692yRzr4b8o5jtGkOdXodI0slLulPXwPqq7TzuA/5lFUQyZgi0shsyDHeF2p800lmfC
693Vi42oSHTDzmWFKxqSAjscLfSWqMN+6IAGpUVR502/D5JJTqPaa9Gt2XUED98lfwO
694YJoF1y4tgZENG9svBTrg/yYwVy+CrPZ1FZ/5zDGhYQ8Zi92WfQLrwfeAEQdDL7mY
695fQIDAQAB
696-----END PUBLIC KEY-----",
697 )
698 .unwrap();
699 assert_eq!(hex::encode(key.fingerprint().to_bytes()), input);
700 }
701
702 #[test]
708 fn test_sign_verify() {
709 let secret = SecretKey::generate();
711 let public = secret.public_key();
712
713 struct TestCase<'a> {
715 message: &'a [u8],
716 }
717 let tests = [TestCase {
718 message: b"message to authenticate",
719 }];
720
721 for tt in &tests {
722 let signature = secret.sign(tt.message);
724
725 public
727 .verify(tt.message, &signature)
728 .unwrap_or_else(|e| panic!("failed to verify message: {}", e));
729 }
730 }
731}