1use std::{backtrace::Backtrace, io::Cursor};
4
5use digest::DynDigest;
6use ed25519_dalek::VerifyingKey;
7use log::{error, warn};
8pub use pgp::composed::{Deserializable, SignedSecretKey};
10pub use pgp::types::Timestamp;
11use pgp::{
12 composed::{ArmorOptions, DetachedSignature, SignedPublicKey},
13 crypto::{hash::HashAlgorithm, public_key::PublicKeyAlgorithm},
14 packet::{
15 Notation,
16 PacketTrait,
17 PubKeyInner,
18 PublicKey,
19 Signature,
20 SignatureConfig,
21 SignatureType,
22 Subpacket,
23 SubpacketData,
24 UserId,
25 },
26 ser::Serialize,
27 types::{
28 CompressionAlgorithm,
29 EcdsaPublicParams,
30 KeyDetails as _,
31 KeyId,
32 KeyVersion,
33 Mpi,
34 Password,
35 PlainSecretParams,
36 PublicParams,
37 RsaPublicParams,
38 SecretParams,
39 SignatureBytes,
40 SigningKey as RpgpSigningKey,
41 },
42};
43use rsa::BigUint;
44use rsa::traits::PublicKeyParts as _;
45use sha2::digest::Digest as _;
46
47use crate::{
48 key::{KeyMechanism, KeyType, PrivateKeyImport, key_type_matches_length},
49 openpgp::{OpenPgpKeyUsageFlags, OpenPgpUserId, OpenPgpVersion},
50 signer::{
51 error::Error,
52 traits::{RawPublicKey, RawSigningKey},
53 },
54};
55
56struct SigningKey<'a> {
61 public_key: PublicKey,
62 raw_signer: &'a dyn RawSigningKey,
63}
64
65impl std::fmt::Debug for SigningKey<'_> {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 f.debug_struct("SigningKey")
68 .field("public_key", &self.public_key)
69 .finish()
70 }
71}
72
73#[inline]
79fn to_rpgp_error(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> pgp::errors::Error {
80 pgp::errors::Error::IO {
81 source: std::io::Error::other(e),
82 backtrace: Some(Backtrace::capture()),
83 }
84}
85
86impl<'a> SigningKey<'a> {
87 fn new(raw_signer: &'a dyn RawSigningKey, public_key: PublicKey) -> Self {
89 Self {
90 raw_signer,
91 public_key,
92 }
93 }
94
95 fn new_provisioned(raw_signer: &'a dyn RawSigningKey) -> Result<Self, Error> {
108 let public_key = if let Some(cert) = raw_signer.certificate()?.as_ref() {
109 SignedPublicKey::from_bytes(Cursor::new(cert))?.primary_key
110 } else {
111 return Err(Error::OpenPpgCertificateMissing);
112 };
113 Ok(Self::new(raw_signer, public_key))
114 }
115}
116
117impl pgp::types::KeyDetails for SigningKey<'_> {
118 fn version(&self) -> KeyVersion {
119 self.public_key.version()
120 }
121
122 fn fingerprint(&self) -> pgp::types::Fingerprint {
123 self.public_key.fingerprint()
124 }
125
126 fn legacy_key_id(&self) -> KeyId {
127 self.public_key.legacy_key_id()
128 }
129
130 fn algorithm(&self) -> PublicKeyAlgorithm {
131 self.public_key.algorithm()
132 }
133
134 fn created_at(&self) -> Timestamp {
135 self.public_key.created_at()
136 }
137
138 fn legacy_v3_expiration_days(&self) -> Option<u16> {
139 self.public_key.legacy_v3_expiration_days()
140 }
141
142 fn public_params(&self) -> &PublicParams {
143 self.public_key.public_params()
144 }
145}
146
147impl RpgpSigningKey for SigningKey<'_> {
148 fn sign(
166 &self,
167 _key_pw: &Password,
168 hash: HashAlgorithm,
169 data: &[u8],
170 ) -> pgp::errors::Result<SignatureBytes> {
171 if hash != self.hash_alg() {
172 error!(
173 "Requested signing hash is different from the default supported, got {hash} expected {expected}",
174 expected = self.hash_alg()
175 );
176 return Err(to_rpgp_error(Error::UnsupportedHashAlgorithm {
177 actual: hash,
178 expected: self.hash_alg(),
179 }));
180 }
181 let sig = self.raw_signer.sign(data).map_err(|e| {
182 error!("RawSigner::sign failed: {e:?}");
183 to_rpgp_error(e)
184 })?;
185
186 Ok(SignatureBytes::Mpis(
187 sig.into_iter().map(|b| Mpi::from_slice(&b)).collect(),
188 ))
189 }
190
191 fn hash_alg(&self) -> HashAlgorithm {
197 HashAlgorithm::Sha512
198 }
199}
200
201pub fn add_certificate(
211 raw_signer: &dyn RawSigningKey,
212 flags: OpenPgpKeyUsageFlags,
213 user_id: OpenPgpUserId,
214 created_at: Timestamp,
215 version: OpenPgpVersion,
216) -> Result<Vec<u8>, Error> {
217 if version != OpenPgpVersion::V4 {
218 return Err(crate::openpgp::Error::InvalidOpenPgpVersion(version.to_string()).into());
219 }
220 let public_key = raw_signer.public()?.to_openpgp_public_key(created_at)?;
221 let signer = SigningKey::new(raw_signer, public_key.clone());
222
223 let signed_pk = SignedPublicKey {
224 details: pgp::composed::KeyDetails::new(
225 Some(UserId::from_str(Default::default(), user_id.as_ref())?),
226 vec![],
227 vec![],
228 flags.into(),
229 Default::default(),
230 Default::default(),
231 Default::default(),
232 vec![CompressionAlgorithm::Uncompressed].into(),
233 vec![].into(),
234 )
235 .sign(rand::thread_rng(), &signer, &public_key, &Password::empty())?,
236 primary_key: public_key,
237 public_subkeys: vec![],
238 };
239
240 let mut buffer = vec![];
241 signed_pk.to_writer(&mut buffer)?;
242 Ok(buffer)
243}
244
245pub fn tsk_to_private_key_import(
255 key: &SignedSecretKey,
256) -> Result<(PrivateKeyImport, KeyMechanism), Error> {
257 if !key.secret_subkeys.is_empty() {
258 return Err(Error::OpenPgpTskContainsMultipleComponentKeys {
259 fingerprint: key.fingerprint(),
260 });
261 }
262 let SecretParams::Plain(secret) = key.primary_key.secret_params() else {
263 return Err(Error::OpenPgpTskIsPassphraseProtected {
264 fingerprint: key.fingerprint(),
265 });
266 };
267 Ok(match (secret, key.public_key().public_params()) {
268 (PlainSecretParams::RSA(secret), PublicParams::RSA(public)) => {
269 key_type_matches_length(
271 KeyType::Rsa,
272 Some(public.key.n().to_bytes_be().len() as u32 * 8),
273 )?;
274
275 let (_d, p, q, _u) = secret.to_bytes();
276
277 (
278 PrivateKeyImport::from_rsa(p, q, public.key.e().to_bytes_be().to_vec()),
279 KeyMechanism::RsaSignaturePkcs1,
280 )
281 }
282 (PlainSecretParams::ECDSA(secret_key), _) => {
283 let ec = if let PublicParams::ECDSA(pp) = key.primary_key.public_key().public_params() {
284 match pp {
285 EcdsaPublicParams::P256 { .. } => KeyType::EcP256,
286 EcdsaPublicParams::P384 { .. } => KeyType::EcP384,
287 EcdsaPublicParams::P521 { .. } => KeyType::EcP521,
288 pp => {
289 warn!("Unsupported ECDSA parameters: {pp:?}");
290 return Err(Error::UnsupportedKeyFormat {
291 context: "converting ECDSA key to private key import",
292 public_params: Box::new(key.public_key().public_params().clone()),
293 })?;
294 }
295 }
296 } else {
297 return Err(Error::UnsupportedKeyFormat {
298 context: "converting non-ECDSA key to private key import",
299 public_params: Box::new(key.public_key().public_params().clone()),
300 });
301 };
302
303 let bytes = match secret_key {
304 pgp::crypto::ecdsa::SecretKey::P256(secret_key) => secret_key.to_bytes().to_vec(),
305 pgp::crypto::ecdsa::SecretKey::P384(secret_key) => secret_key.to_bytes().to_vec(),
306 pgp::crypto::ecdsa::SecretKey::P521(secret_key) => secret_key.to_bytes().to_vec(),
307
308 pgp::crypto::ecdsa::SecretKey::Secp256k1(secret_key) => {
309 secret_key.to_bytes().to_vec()
310 }
311 secret_key => {
312 warn!("Unsupported secret key parameters: {secret_key:?}");
313 return Err(Error::UnsupportedKeyFormat {
314 context: "converting unsupported ECDSA key to private key import",
315 public_params: Box::new(key.public_key().public_params().clone()),
316 })?;
317 }
318 };
319
320 (
321 PrivateKeyImport::from_raw_bytes(ec, bytes).map_err(to_rpgp_error)?,
322 KeyMechanism::EcdsaSignature,
323 )
324 }
325 (PlainSecretParams::Ed25519Legacy(bytes), _) => (
326 PrivateKeyImport::from_raw_bytes(KeyType::Curve25519, bytes.as_bytes())
327 .map_err(to_rpgp_error)?,
328 KeyMechanism::EdDsaSignature,
329 ),
330 (_, public_params) => {
331 return Err(Error::UnsupportedKeyFormat {
332 context: "converting unknown key format to private key import",
333 public_params: Box::new(public_params.clone()),
334 });
335 }
336 })
337}
338
339pub fn sign(raw_signer: &dyn RawSigningKey, message: &[u8]) -> Result<Vec<u8>, Error> {
358 let signer = SigningKey::new_provisioned(raw_signer)?;
359
360 let mut sig_config =
361 SignatureConfig::v4(SignatureType::Binary, signer.algorithm(), signer.hash_alg());
362 sig_config.hashed_subpackets = vec![
363 Subpacket::regular(SubpacketData::SignatureCreationTime(Timestamp::now()))?,
364 Subpacket::regular(SubpacketData::IssuerKeyId(signer.legacy_key_id()))?,
365 Subpacket::regular(SubpacketData::IssuerFingerprint(signer.fingerprint()))?,
366 ];
367
368 let mut hasher = sig_config.hash_alg.new_hasher().map_err(to_rpgp_error)?;
369 sig_config.hash_data_to_sign(&mut hasher, message)?;
370
371 let len = sig_config.hash_signature_data(&mut hasher)?;
372
373 hasher.update(&sig_config.trailer(len)?);
374
375 let hash = &hasher.finalize()[..];
376
377 let signed_hash_value = [hash[0], hash[1]];
378 let raw_sig = signer.sign(&Password::empty(), sig_config.hash_alg, hash)?;
379
380 let signature = Signature::from_config(sig_config, signed_hash_value, raw_sig)?;
381
382 let mut out = vec![];
383 signature.to_writer_with_header(&mut out)?;
384
385 Ok(out)
386}
387
388#[derive(Clone, Default)]
398struct Hasher(sha2::Sha512);
399
400impl DynDigest for Hasher {
401 fn update(&mut self, data: &[u8]) {
405 self.0.update(data);
406 }
407
408 fn finalize_into(self, buf: &mut [u8]) -> Result<(), digest::InvalidBufferSize> {
414 sha2::digest::DynDigest::finalize_into(self.0, buf)
415 .map_err(|_| digest::InvalidBufferSize)?;
416 Ok(())
417 }
418
419 fn finalize_into_reset(&mut self, out: &mut [u8]) -> Result<(), digest::InvalidBufferSize> {
425 sha2::digest::DynDigest::finalize_into_reset(&mut self.0, out)
426 .map_err(|_| digest::InvalidBufferSize)?;
427 Ok(())
428 }
429
430 fn reset(&mut self) {
432 sha2::digest::DynDigest::reset(&mut self.0)
433 }
434
435 fn output_size(&self) -> usize {
437 sha2::digest::DynDigest::output_size(&self.0)
438 }
439
440 fn box_clone(&self) -> Box<dyn DynDigest> {
442 Box::new(self.clone())
443 }
444}
445
446pub fn sign_hasher_state(
465 raw_signer: &dyn RawSigningKey,
466 state: sha2::Sha512,
467) -> Result<String, Error> {
468 let signer = SigningKey::new_provisioned(raw_signer)?;
469 let hasher = state.clone();
470
471 let file_hash = Box::new(hasher).finalize().to_vec();
472
473 let sig_config = {
474 let mut sig_config =
475 SignatureConfig::v4(SignatureType::Binary, signer.algorithm(), signer.hash_alg());
476 sig_config.hashed_subpackets = vec![
477 Subpacket::regular(SubpacketData::SignatureCreationTime(Timestamp::now()))?,
478 Subpacket::regular(SubpacketData::IssuerKeyId(signer.legacy_key_id()))?,
479 Subpacket::regular(SubpacketData::IssuerFingerprint(signer.fingerprint()))?,
480 Subpacket::regular(SubpacketData::Notation(Notation {
481 readable: false,
482 name: "data-digest@archlinux.org".into(),
483 value: file_hash.into(),
484 }))?,
485 ];
486 sig_config
487 };
488
489 let mut hasher = Box::new(Hasher(state.clone())) as Box<dyn DynDigest + Send>;
490
491 let len = sig_config.hash_signature_data(&mut hasher)?;
492
493 hasher.update(&sig_config.trailer(len)?);
494
495 let hash = &hasher.finalize()[..];
496
497 let signed_hash_value = [hash[0], hash[1]];
498
499 let raw_sig = signer.sign(&Password::empty(), sig_config.hash_alg, hash)?;
500
501 let signature = pgp::packet::Signature::from_config(sig_config, signed_hash_value, raw_sig)?;
502
503 let signature = DetachedSignature { signature };
504 Ok(signature.to_armored_string(ArmorOptions::default())?)
505}
506
507fn ecdsa_to_public_key(created_at: Timestamp, key: EcdsaPublicParams) -> Result<PublicKey, Error> {
518 Ok(PublicKey::from_inner(PubKeyInner::new(
519 KeyVersion::V4,
520 PublicKeyAlgorithm::ECDSA,
521 created_at,
522 None,
523 PublicParams::ECDSA(key),
524 )?)?)
525}
526
527impl RawPublicKey {
528 fn to_openpgp_public_key(&self, created_at: Timestamp) -> Result<PublicKey, Error> {
544 Ok(match self {
545 RawPublicKey::Rsa { modulus, exponent } => PublicKey::from_inner(PubKeyInner::new(
546 KeyVersion::V4,
547 PublicKeyAlgorithm::RSA,
548 created_at,
549 None,
550 PublicParams::RSA(RsaPublicParams {
551 key: rsa::RsaPublicKey::new(
552 BigUint::from_bytes_be(modulus),
553 BigUint::from_bytes_be(exponent),
554 )
555 .map_err(to_rpgp_error)?,
556 }),
557 )?)?,
558
559 RawPublicKey::Ed25519(pubkey) => PublicKey::from_inner(PubKeyInner::new(
560 KeyVersion::V4,
561 PublicKeyAlgorithm::EdDSALegacy,
562 created_at,
563 None,
564 PublicParams::EdDSALegacy(pgp::types::EddsaLegacyPublicParams::Ed25519 {
565 key: VerifyingKey::from_bytes(&pubkey[..].try_into().map_err(to_rpgp_error)?)
566 .map_err(to_rpgp_error)?,
567 }),
568 )?)?,
569
570 RawPublicKey::P256(pubkey) => ecdsa_to_public_key(
571 created_at,
572 EcdsaPublicParams::P256 {
573 key: p256::PublicKey::from_sec1_bytes(pubkey)?,
574 },
575 )?,
576
577 RawPublicKey::P384(pubkey) => ecdsa_to_public_key(
578 created_at,
579 EcdsaPublicParams::P384 {
580 key: p384::PublicKey::from_sec1_bytes(pubkey)?,
581 },
582 )?,
583
584 RawPublicKey::P521(pubkey) => ecdsa_to_public_key(
585 created_at,
586 EcdsaPublicParams::P521 {
587 key: p521::PublicKey::from_sec1_bytes(pubkey)?,
588 },
589 )?,
590 })
591 }
592}
593
594pub fn extract_certificate(key: SignedSecretKey) -> Result<Vec<u8>, Error> {
607 let public: SignedPublicKey = key.into();
608 let mut buffer = vec![];
609 public.to_writer(&mut buffer)?;
610 Ok(buffer)
611}
612
613#[cfg(test)]
614mod tests {
615 use ed25519_dalek::{Signer, SigningKey};
616 use pgp::{
617 composed::SecretKeyParamsBuilder,
618 crypto::ecc_curve::ECCCurve,
619 types::{EcdsaPublicParams, PublicParams},
620 };
621 use rand::RngCore;
622 use rsa::rand_core::OsRng;
623 use testresult::TestResult;
624
625 use super::*;
626
627 #[test]
628 fn convert_ed25519_to_pgp() -> TestResult {
629 let hsm_key = RawPublicKey::Ed25519(vec![
630 252, 224, 232, 104, 60, 215, 247, 16, 227, 167, 29, 139, 125, 29, 3, 8, 136, 29, 198,
631 163, 167, 117, 143, 109, 186, 65, 5, 45, 80, 142, 109, 10,
632 ]);
633
634 let pgp_key = hsm_key.to_openpgp_public_key(Timestamp::now())?;
635 let PublicParams::EdDSALegacy(pgp::types::EddsaLegacyPublicParams::Ed25519 { key }) =
636 pgp_key.public_params()
637 else {
638 panic!("Wrong type of public params");
639 };
640 assert_eq!(
641 key.to_bytes(),
642 [
643 252, 224, 232, 104, 60, 215, 247, 16, 227, 167, 29, 139, 125, 29, 3, 8, 136, 29,
644 198, 163, 167, 117, 143, 109, 186, 65, 5, 45, 80, 142, 109, 10
645 ]
646 );
647
648 Ok(())
649 }
650
651 #[test]
652 fn convert_p256_to_pgp() -> TestResult {
653 let hsm_key = RawPublicKey::P256(vec![
654 4, 222, 106, 236, 96, 145, 243, 13, 81, 181, 119, 76, 5, 29, 72, 112, 134, 130, 169,
655 182, 231, 247, 107, 204, 228, 178, 45, 77, 196, 91, 117, 122, 57, 69, 240, 240, 134,
656 114, 138, 232, 63, 45, 141, 102, 164, 169, 118, 214, 99, 215, 138, 122, 89, 2, 180, 2,
657 237, 15, 248, 104, 83, 142, 22, 185, 133,
658 ]);
659 let pgp_key = hsm_key.to_openpgp_public_key(Timestamp::now())?;
660 let PublicParams::ECDSA(EcdsaPublicParams::P256 { key, .. }) = pgp_key.public_params()
661 else {
662 panic!("Wrong type of public params");
663 };
664 assert_eq!(
665 key.to_sec1_bytes().to_vec(),
666 [
667 4, 222, 106, 236, 96, 145, 243, 13, 81, 181, 119, 76, 5, 29, 72, 112, 134, 130,
668 169, 182, 231, 247, 107, 204, 228, 178, 45, 77, 196, 91, 117, 122, 57, 69, 240,
669 240, 134, 114, 138, 232, 63, 45, 141, 102, 164, 169, 118, 214, 99, 215, 138, 122,
670 89, 2, 180, 2, 237, 15, 248, 104, 83, 142, 22, 185, 133
671 ]
672 );
673
674 Ok(())
675 }
676
677 #[test]
678 fn convert_p384_to_pgp() -> TestResult {
679 let hsm_key = RawPublicKey::P384(vec![
680 4, 127, 136, 147, 111, 187, 191, 131, 84, 166, 118, 67, 76, 107, 52, 142, 175, 72, 250,
681 64, 197, 76, 154, 162, 48, 211, 135, 63, 153, 60, 213, 168, 40, 41, 111, 8, 8, 66, 117,
682 221, 162, 244, 233, 210, 205, 206, 70, 64, 116, 30, 98, 186, 88, 17, 8, 75, 151, 252,
683 123, 98, 182, 40, 183, 6, 28, 110, 29, 53, 15, 90, 227, 116, 185, 82, 134, 134, 6, 17,
684 117, 218, 83, 181, 230, 154, 106, 235, 244, 112, 227, 231, 139, 217, 90, 220, 239, 191,
685 148,
686 ]);
687 let pgp_key = hsm_key.to_openpgp_public_key(Timestamp::now())?;
688 let PublicParams::ECDSA(EcdsaPublicParams::P384 { key, .. }) = pgp_key.public_params()
689 else {
690 panic!("Wrong type of public params");
691 };
692 assert_eq!(
693 key.to_sec1_bytes().to_vec(),
694 [
695 4, 127, 136, 147, 111, 187, 191, 131, 84, 166, 118, 67, 76, 107, 52, 142, 175, 72,
696 250, 64, 197, 76, 154, 162, 48, 211, 135, 63, 153, 60, 213, 168, 40, 41, 111, 8, 8,
697 66, 117, 221, 162, 244, 233, 210, 205, 206, 70, 64, 116, 30, 98, 186, 88, 17, 8,
698 75, 151, 252, 123, 98, 182, 40, 183, 6, 28, 110, 29, 53, 15, 90, 227, 116, 185, 82,
699 134, 134, 6, 17, 117, 218, 83, 181, 230, 154, 106, 235, 244, 112, 227, 231, 139,
700 217, 90, 220, 239, 191, 148
701 ]
702 );
703
704 Ok(())
705 }
706
707 #[test]
708 fn convert_p521_to_pgp() -> TestResult {
709 let hsm_key = RawPublicKey::P521(vec![
710 4, 1, 33, 39, 193, 238, 201, 51, 127, 12, 24, 192, 161, 112, 247, 31, 184, 211, 118,
711 95, 147, 192, 236, 9, 222, 214, 138, 194, 173, 170, 248, 123, 1, 138, 201, 96, 102, 55,
712 160, 212, 150, 101, 58, 235, 53, 50, 30, 47, 136, 171, 244, 138, 236, 26, 190, 40, 157,
713 208, 63, 92, 170, 195, 182, 80, 114, 205, 253, 1, 211, 88, 102, 243, 67, 14, 159, 46,
714 35, 89, 188, 38, 134, 184, 208, 223, 213, 206, 126, 106, 33, 76, 198, 240, 32, 108, 48,
715 124, 170, 158, 30, 4, 11, 37, 233, 254, 171, 163, 153, 10, 65, 118, 233, 79, 179, 90,
716 185, 21, 71, 99, 21, 47, 223, 100, 224, 196, 110, 102, 113, 26, 103, 127, 234, 47, 81,
717 ]);
718 let pgp_key = hsm_key.to_openpgp_public_key(Timestamp::now())?;
719 let PublicParams::ECDSA(EcdsaPublicParams::P521 { key, .. }) = pgp_key.public_params()
720 else {
721 panic!("Wrong type of public params");
722 };
723 assert_eq!(
724 key.to_sec1_bytes().to_vec(),
725 [
726 4, 1, 33, 39, 193, 238, 201, 51, 127, 12, 24, 192, 161, 112, 247, 31, 184, 211,
727 118, 95, 147, 192, 236, 9, 222, 214, 138, 194, 173, 170, 248, 123, 1, 138, 201, 96,
728 102, 55, 160, 212, 150, 101, 58, 235, 53, 50, 30, 47, 136, 171, 244, 138, 236, 26,
729 190, 40, 157, 208, 63, 92, 170, 195, 182, 80, 114, 205, 253, 1, 211, 88, 102, 243,
730 67, 14, 159, 46, 35, 89, 188, 38, 134, 184, 208, 223, 213, 206, 126, 106, 33, 76,
731 198, 240, 32, 108, 48, 124, 170, 158, 30, 4, 11, 37, 233, 254, 171, 163, 153, 10,
732 65, 118, 233, 79, 179, 90, 185, 21, 71, 99, 21, 47, 223, 100, 224, 196, 110, 102,
733 113, 26, 103, 127, 234, 47, 81
734 ]
735 );
736
737 Ok(())
738 }
739
740 #[test]
741 fn convert_rsa_to_pgp() -> TestResult {
742 let hsm_key = RawPublicKey::Rsa {
743 modulus: vec![
744 227, 127, 58, 151, 86, 130, 213, 238, 13, 247, 122, 241, 51, 227, 105, 143, 231,
745 114, 208, 33, 152, 209, 109, 207, 53, 179, 147, 4, 100, 99, 238, 212, 196, 126, 89,
746 4, 151, 106, 177, 219, 21, 187, 147, 41, 158, 242, 194, 208, 67, 252, 177, 135, 34,
747 120, 154, 170, 63, 130, 4, 125, 56, 55, 239, 99, 43, 115, 198, 196, 191, 159, 243,
748 13, 103, 7, 64, 76, 96, 184, 64, 48, 99, 62, 254, 248, 179, 254, 117, 156, 47, 224,
749 100, 122, 189, 87, 59, 216, 171, 118, 230, 23, 71, 180, 88, 216, 151, 69, 61, 233,
750 231, 118, 104, 126, 107, 245, 8, 16, 207, 4, 64, 235, 172, 154, 183, 50, 175, 142,
751 223, 228, 199, 243, 251, 171, 220, 227, 140, 130, 243, 113, 216, 32, 224, 195, 4,
752 53, 88, 100, 150, 221, 114, 19, 55, 215, 164, 102, 154, 35, 254, 31, 28, 195, 17,
753 100, 207, 153, 99, 155, 40, 2, 45, 27, 87, 116, 213, 171, 205, 82, 70, 91, 113,
754 185, 47, 242, 115, 246, 199, 82, 124, 77, 173, 201, 191, 62, 223, 93, 136, 84, 82,
755 121, 239, 55, 47, 71, 40, 42, 2, 73, 18, 215, 91, 152, 32, 252, 110, 161, 166, 211,
756 232, 130, 124, 74, 148, 156, 126, 169, 109, 26, 197, 55, 142, 32, 11, 43, 33, 81,
757 87, 159, 8, 247, 82, 148, 149, 119, 160, 141, 69, 81, 223, 81, 49, 21, 205, 30, 0,
758 59, 161, 187,
759 ],
760 exponent: vec![1, 0, 1],
761 };
762 let pgp_key = hsm_key.to_openpgp_public_key(Timestamp::now())?;
763 let PublicParams::RSA(public) = pgp_key.public_params() else {
764 panic!("Wrong type of public params");
765 };
766 assert_eq!(public.key.e().to_bytes_be(), [1, 0, 1]);
767 assert_eq!(
768 public.key.n().to_bytes_be(),
769 [
770 227, 127, 58, 151, 86, 130, 213, 238, 13, 247, 122, 241, 51, 227, 105, 143, 231,
771 114, 208, 33, 152, 209, 109, 207, 53, 179, 147, 4, 100, 99, 238, 212, 196, 126, 89,
772 4, 151, 106, 177, 219, 21, 187, 147, 41, 158, 242, 194, 208, 67, 252, 177, 135, 34,
773 120, 154, 170, 63, 130, 4, 125, 56, 55, 239, 99, 43, 115, 198, 196, 191, 159, 243,
774 13, 103, 7, 64, 76, 96, 184, 64, 48, 99, 62, 254, 248, 179, 254, 117, 156, 47, 224,
775 100, 122, 189, 87, 59, 216, 171, 118, 230, 23, 71, 180, 88, 216, 151, 69, 61, 233,
776 231, 118, 104, 126, 107, 245, 8, 16, 207, 4, 64, 235, 172, 154, 183, 50, 175, 142,
777 223, 228, 199, 243, 251, 171, 220, 227, 140, 130, 243, 113, 216, 32, 224, 195, 4,
778 53, 88, 100, 150, 221, 114, 19, 55, 215, 164, 102, 154, 35, 254, 31, 28, 195, 17,
779 100, 207, 153, 99, 155, 40, 2, 45, 27, 87, 116, 213, 171, 205, 82, 70, 91, 113,
780 185, 47, 242, 115, 246, 199, 82, 124, 77, 173, 201, 191, 62, 223, 93, 136, 84, 82,
781 121, 239, 55, 47, 71, 40, 42, 2, 73, 18, 215, 91, 152, 32, 252, 110, 161, 166, 211,
782 232, 130, 124, 74, 148, 156, 126, 169, 109, 26, 197, 55, 142, 32, 11, 43, 33, 81,
783 87, 159, 8, 247, 82, 148, 149, 119, 160, 141, 69, 81, 223, 81, 49, 21, 205, 30, 0,
784 59, 161, 187
785 ]
786 );
787
788 Ok(())
789 }
790
791 #[cfg(feature = "nethsm")]
793 mod nethsm {
794 use std::fs::File;
795
796 use base64ct::{Base64, Encoding as _};
797 use nethsm_sdk_rs::models::KeyPrivateData;
798
799 use super::*;
800
801 #[test]
802 fn private_key_import_ed25199_is_correctly_zero_padded() -> TestResult {
803 let key = SignedSecretKey::from_armor_single(File::open(
804 "tests/fixtures/ed25519-key-with-31-byte-private-key-scalar.asc",
805 )?)?
806 .0;
807
808 let import: KeyPrivateData = tsk_to_private_key_import(&key)?.0.into();
809
810 let data = Base64::decode_vec(&import.data.unwrap())?;
811
812 assert_eq!(data.len(), 32);
815 assert_eq!(data[0], 0x00);
816
817 Ok(())
818 }
819
820 #[test]
821 #[cfg(feature = "nethsm")]
822 fn private_key_import_rsa_key_with_nonstandard_moduli_is_read_correctly() -> TestResult {
823 let key = SignedSecretKey::from_armor_single(File::open(
824 "tests/fixtures/rsa-key-with-modulus-e-257.asc",
825 )?)?
826 .0;
827
828 let import: KeyPrivateData = tsk_to_private_key_import(&key)?.0.into();
829
830 let data = Base64::decode_vec(&import.public_exponent.unwrap())?;
831
832 assert_eq!(data, vec![0x01, 0x01]); Ok(())
836 }
837 }
838
839 struct Ed25519SoftKey {
841 signing_key: SigningKey,
843
844 certificate: Option<Vec<u8>>,
846 }
847
848 impl Ed25519SoftKey {
849 fn new() -> Self {
853 Self {
854 signing_key: SigningKey::generate(&mut OsRng),
857 certificate: None,
858 }
859 }
860 }
861
862 impl RawSigningKey for Ed25519SoftKey {
863 fn key_id(&self) -> String {
865 "Software key".into()
866 }
867
868 fn sign(&self, digest: &[u8]) -> Result<Vec<Vec<u8>>, Error> {
874 let signature = self.signing_key.sign(digest);
875 Ok(vec![signature.r_bytes().into(), signature.s_bytes().into()])
876 }
877
878 fn certificate(&self) -> Result<Option<Vec<u8>>, Error> {
884 Ok(self.certificate.clone())
885 }
886
887 fn public(&self) -> Result<RawPublicKey, Error> {
893 Ok(RawPublicKey::Ed25519(
894 self.signing_key.verifying_key().to_bytes().into(),
895 ))
896 }
897 }
898
899 #[test]
900 fn sign_dummy() -> TestResult {
901 let mut raw_signer = Ed25519SoftKey::new();
902
903 let cert = add_certificate(
904 &raw_signer,
905 Default::default(),
906 OpenPgpUserId::new("test".into())?,
907 Timestamp::now(),
908 Default::default(),
909 )?;
910
911 raw_signer.certificate = Some(cert);
912
913 let mut data_to_sign = [0; 32];
914 OsRng::fill_bytes(&mut OsRng, &mut data_to_sign);
915
916 let signature = sign(&raw_signer, &data_to_sign)?;
917 assert!(!signature.is_empty());
918
919 Ok(())
920 }
921
922 #[rstest::rstest]
923 #[case::p256(ECCCurve::P256, KeyType::EcP256)]
924 #[case::p384(ECCCurve::P384, KeyType::EcP384)]
925 #[case::p521(ECCCurve::P521, KeyType::EcP521)]
926 fn import_ecdsa(#[case] pgp_curve: ECCCurve, #[case] expected_type: KeyType) -> TestResult {
927 let params = SecretKeyParamsBuilder::default()
928 .key_type(pgp::composed::KeyType::ECDSA(pgp_curve))
929 .can_sign(true)
930 .build()?;
931
932 let rng = rsa::rand_core::OsRng;
933
934 let key = params.generate(rng)?;
935 let actual_type = tsk_to_private_key_import(&key)?.0.key_type();
936 assert_eq!(actual_type, expected_type);
937
938 Ok(())
939 }
940
941 #[test]
942 fn test_unsupported_ecdsa_curve() -> TestResult {
943 let key = SecretKeyParamsBuilder::default()
944 .key_type(pgp::composed::KeyType::ECDSA(ECCCurve::Secp256k1))
945 .can_sign(true)
946 .build()?
947 .generate(rsa::rand_core::OsRng)?;
948
949 assert!(tsk_to_private_key_import(&key).is_err());
950
951 Ok(())
952 }
953}