1use {
4 data_encoding::HEXLOWER,
5 futures_io::AsyncRead,
6 futures_util::AsyncReadExt as _,
7 ring::{
8 digest::{self, SHA256, SHA512},
9 rand::SystemRandom,
10 signature::{Ed25519KeyPair, KeyPair, ED25519},
11 },
12 serde::{
13 de::Error as DeserializeError, ser::Error as SerializeError, Deserialize, Deserializer,
14 Serialize, Serializer,
15 },
16 std::{
17 cmp::Ordering,
18 collections::HashMap,
19 fmt::{self, Debug, Display},
20 hash,
21 str::FromStr,
22 },
23 untrusted::Input,
24};
25
26use crate::error::{Error, Result};
27use crate::metadata::MetadataPath;
28use crate::pouf::pouf1::shims;
29
30const HASH_ALG_PREFS: &[HashAlgorithm] = &[HashAlgorithm::Sha512, HashAlgorithm::Sha256];
31
32const ED25519_SPKI_HEADER: &[u8] = &[
34 0x30, 0x2c, 0x30, 0x07, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x05, 0x00, 0x03, 0x21, 0x00,
35];
36
37const ED25519_PRIVATE_KEY_LENGTH: usize = 32;
39
40const ED25519_PUBLIC_KEY_LENGTH: usize = 32;
42
43const ED25519_KEYPAIR_LENGTH: usize = ED25519_PRIVATE_KEY_LENGTH + ED25519_PUBLIC_KEY_LENGTH;
45
46fn python_tuf_compatibility_keyid_hash_algorithms() -> Option<Vec<String>> {
47 Some(vec!["sha256".to_string(), "sha512".to_string()])
48}
49
50pub fn retain_supported_hashes(
90 hashes: &HashMap<HashAlgorithm, HashValue>,
91) -> Vec<(&'static HashAlgorithm, HashValue)> {
92 let mut data = vec![];
93 for alg in HASH_ALG_PREFS {
94 if let Some(value) = hashes.get(alg) {
95 data.push((alg, value.clone()));
96 }
97 }
98
99 data
100}
101
102#[cfg(test)]
103pub(crate) fn calculate_hash(data: &[u8], hash_alg: &HashAlgorithm) -> HashValue {
104 let mut context = hash_alg.digest_context().unwrap();
105 context.update(data);
106 HashValue::new(context.finish().as_ref().to_vec())
107}
108
109pub fn calculate_hashes_from_slice(
111 buf: &[u8],
112 hash_algs: &[HashAlgorithm],
113) -> Result<HashMap<HashAlgorithm, HashValue>> {
114 if hash_algs.is_empty() {
115 return Err(Error::IllegalArgument(
116 "Cannot provide empty set of hash algorithms".into(),
117 ));
118 }
119
120 let mut hashes = HashMap::new();
121 for alg in hash_algs {
122 let mut context = alg.digest_context()?;
123 context.update(buf);
124
125 hashes.insert(
126 alg.clone(),
127 HashValue::new(context.finish().as_ref().to_vec()),
128 );
129 }
130
131 Ok(hashes)
132}
133
134pub async fn calculate_hashes_from_reader<R>(
136 mut read: R,
137 hash_algs: &[HashAlgorithm],
138) -> Result<(u64, HashMap<HashAlgorithm, HashValue>)>
139where
140 R: AsyncRead + Unpin,
141{
142 if hash_algs.is_empty() {
143 return Err(Error::IllegalArgument(
144 "Cannot provide empty set of hash algorithms".into(),
145 ));
146 }
147
148 let mut size = 0;
149 let mut hashes = HashMap::new();
150 for alg in hash_algs {
151 let _ = hashes.insert(alg, alg.digest_context()?);
152 }
153
154 let mut buf = vec![0; 1024];
155 loop {
156 match read.read(&mut buf).await {
157 Ok(read_bytes) => {
158 if read_bytes == 0 {
159 break;
160 }
161
162 size += read_bytes as u64;
163
164 for context in hashes.values_mut() {
165 context.update(&buf[0..read_bytes]);
166 }
167 }
168 e @ Err(_) => e.map(|_| ())?,
169 }
170 }
171
172 let hashes = hashes
173 .drain()
174 .map(|(k, v)| (k.clone(), HashValue::new(v.finish().as_ref().to_vec())))
175 .collect();
176 Ok((size, hashes))
177}
178
179fn shim_public_key(
180 key_type: &KeyType,
181 signature_scheme: &SignatureScheme,
182 keyid_hash_algorithms: &Option<Vec<String>>,
183 public_key: &[u8],
184) -> Result<shims::PublicKey> {
185 let key = match (key_type, signature_scheme) {
186 (KeyType::Ed25519, SignatureScheme::Ed25519) => HEXLOWER.encode(public_key),
187 (_, _) => {
188 std::str::from_utf8(public_key)
190 .map_err(|err| {
191 Error::Encoding(format!(
192 "error converting public key value {:?} with key \
193 type {:?} and signature scheme {:?} to a string: {:?}",
194 public_key, key_type, signature_scheme, err
195 ))
196 })?
197 .to_string()
198 }
199 };
200
201 Ok(shims::PublicKey::new(
202 key_type.clone(),
203 signature_scheme.clone(),
204 keyid_hash_algorithms.clone(),
205 key,
206 ))
207}
208
209fn calculate_key_id(
210 key_type: &KeyType,
211 signature_scheme: &SignatureScheme,
212 keyid_hash_algorithms: &Option<Vec<String>>,
213 public_key: &[u8],
214) -> Result<KeyId> {
215 use crate::pouf::{Pouf, Pouf1};
216
217 let public_key = shim_public_key(
218 key_type,
219 signature_scheme,
220 keyid_hash_algorithms,
221 public_key,
222 )?;
223 let public_key = Pouf1::canonicalize(&Pouf1::serialize(&public_key)?)?;
224 let mut context = digest::Context::new(&SHA256);
225 context.update(&public_key);
226
227 let key_id = HEXLOWER.encode(context.finish().as_ref());
228
229 Ok(KeyId(key_id))
230}
231
232#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
239pub struct KeyId(String);
240
241impl FromStr for KeyId {
242 type Err = Error;
243
244 fn from_str(string: &str) -> Result<Self> {
246 if string.len() != 64 {
247 return Err(Error::IllegalArgument(
248 "key ID must be 64 characters long".into(),
249 ));
250 }
251 Ok(KeyId(string.to_owned()))
252 }
253}
254
255impl fmt::Display for KeyId {
256 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
257 f.write_str(&self.0)
258 }
259}
260
261impl Serialize for KeyId {
262 fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
263 where
264 S: Serializer,
265 {
266 self.0.serialize(ser)
267 }
268}
269
270impl<'de> Deserialize<'de> for KeyId {
271 fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
272 let string: String = Deserialize::deserialize(de)?;
273 KeyId::from_str(&string).map_err(|e| DeserializeError::custom(format!("{:?}", e)))
274 }
275}
276
277#[non_exhaustive]
279#[derive(Debug, Clone, PartialEq, Eq, Hash)]
280pub enum SignatureScheme {
281 Ed25519,
283
284 Unknown(String),
286}
287
288impl SignatureScheme {
289 pub fn new(name: &str) -> Self {
291 match name {
292 "ed25519" => SignatureScheme::Ed25519,
293 scheme => SignatureScheme::Unknown(scheme.to_string()),
294 }
295 }
296
297 pub fn as_str(&self) -> &str {
299 match *self {
300 SignatureScheme::Ed25519 => "ed25519",
301 SignatureScheme::Unknown(ref s) => s,
302 }
303 }
304}
305
306impl Display for SignatureScheme {
307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
308 f.write_str(self.as_str())
309 }
310}
311
312impl Serialize for SignatureScheme {
313 fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
314 where
315 S: Serializer,
316 {
317 ser.serialize_str(self.as_str())
318 }
319}
320
321impl<'de> Deserialize<'de> for SignatureScheme {
322 fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
323 let string: String = Deserialize::deserialize(de)?;
324 Ok(Self::new(&string))
325 }
326}
327
328#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
330pub struct SignatureValue(#[serde(with = "crate::format_hex")] Vec<u8>);
331
332impl SignatureValue {
333 pub fn new(bytes: Vec<u8>) -> Self {
337 SignatureValue(bytes)
338 }
339
340 pub fn as_bytes(&self) -> &[u8] {
342 &self.0
343 }
344}
345
346impl Debug for SignatureValue {
347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
348 f.debug_tuple("SignatureValue")
349 .field(&HEXLOWER.encode(&self.0))
350 .finish()
351 }
352}
353
354#[non_exhaustive]
356#[derive(Clone, PartialEq, Debug, Eq, Hash)]
357pub enum KeyType {
358 Ed25519,
360
361 Unknown(String),
363}
364
365impl KeyType {
366 pub fn new(name: &str) -> Self {
368 match name {
369 "ed25519" => KeyType::Ed25519,
370 keytype => KeyType::Unknown(keytype.to_string()),
371 }
372 }
373
374 pub fn as_str(&self) -> &str {
376 match *self {
377 KeyType::Ed25519 => "ed25519",
378 KeyType::Unknown(ref s) => s,
379 }
380 }
381}
382
383impl Display for KeyType {
384 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
385 f.write_str(self.as_str())
386 }
387}
388
389impl Serialize for KeyType {
390 fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
391 where
392 S: Serializer,
393 {
394 ser.serialize_str(self.as_str())
395 }
396}
397
398impl<'de> Deserialize<'de> for KeyType {
399 fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
400 let string: String = Deserialize::deserialize(de)?;
401 Ok(Self::new(&string))
402 }
403}
404
405pub trait PrivateKey {
407 fn sign(&self, msg: &[u8]) -> Result<Signature>;
409
410 fn public(&self) -> &PublicKey;
412}
413
414pub struct Ed25519PrivateKey {
416 private: Ed25519KeyPair,
417 public: PublicKey,
418}
419
420impl Ed25519PrivateKey {
421 pub fn pkcs8() -> Result<Vec<u8>> {
423 Ed25519KeyPair::generate_pkcs8(&SystemRandom::new())
424 .map(|bytes| bytes.as_ref().to_vec())
425 .map_err(|_| Error::Opaque("Failed to generate Ed25519 key".into()))
426 }
427
428 pub fn from_ed25519(key: &[u8]) -> Result<Self> {
431 Self::from_ed25519_with_keyid_hash_algorithms(key, None)
432 }
433
434 pub fn from_ed25519_with_keyid_hash_algorithms(
438 key: &[u8],
439 keyid_hash_algorithms: Option<Vec<String>>,
440 ) -> Result<Self> {
441 if key.len() != ED25519_KEYPAIR_LENGTH {
442 return Err(Error::Encoding(
443 "ed25519 private keys must be 64 bytes long".into(),
444 ));
445 }
446
447 let private_key_bytes = &key[..ED25519_PRIVATE_KEY_LENGTH];
448 let public_key_bytes = &key[ED25519_PUBLIC_KEY_LENGTH..];
449
450 let private = Ed25519KeyPair::from_seed_and_public_key(private_key_bytes, public_key_bytes)
451 .map_err(|err| Error::Encoding(err.to_string()))?;
452 Self::from_keypair_with_keyid_hash_algorithms(private, keyid_hash_algorithms)
453 }
454
455 pub fn from_pkcs8(der_key: &[u8]) -> Result<Self> {
475 Self::from_pkcs8_with_keyid_hash_algorithms(
476 der_key,
477 python_tuf_compatibility_keyid_hash_algorithms(),
478 )
479 }
480
481 fn from_pkcs8_with_keyid_hash_algorithms(
482 der_key: &[u8],
483 keyid_hash_algorithms: Option<Vec<String>>,
484 ) -> Result<Self> {
485 Self::from_keypair_with_keyid_hash_algorithms(
486 Ed25519KeyPair::from_pkcs8(der_key)
487 .map_err(|_| Error::Encoding("Could not parse key as PKCS#8v2".into()))?,
488 keyid_hash_algorithms,
489 )
490 }
491
492 fn from_keypair_with_keyid_hash_algorithms(
493 private: Ed25519KeyPair,
494 keyid_hash_algorithms: Option<Vec<String>>,
495 ) -> Result<Self> {
496 let public = PublicKey::new(
497 KeyType::Ed25519,
498 SignatureScheme::Ed25519,
499 keyid_hash_algorithms,
500 private.public_key().as_ref().to_vec(),
501 )?;
502
503 Ok(Ed25519PrivateKey { private, public })
504 }
505}
506
507impl PrivateKey for Ed25519PrivateKey {
508 fn sign(&self, msg: &[u8]) -> Result<Signature> {
509 debug_assert!(self.public.scheme == SignatureScheme::Ed25519);
510
511 let value = SignatureValue(self.private.sign(msg).as_ref().into());
512 Ok(Signature {
513 key_id: self.public.key_id().clone(),
514 value,
515 })
516 }
517
518 fn public(&self) -> &PublicKey {
519 &self.public
520 }
521}
522
523#[derive(Clone, Debug)]
525pub struct PublicKey {
526 typ: KeyType,
527 key_id: KeyId,
528 scheme: SignatureScheme,
529 keyid_hash_algorithms: Option<Vec<String>>,
530 value: PublicKeyValue,
531}
532
533impl PublicKey {
534 fn new(
535 typ: KeyType,
536 scheme: SignatureScheme,
537 keyid_hash_algorithms: Option<Vec<String>>,
538 value: Vec<u8>,
539 ) -> Result<Self> {
540 let key_id = calculate_key_id(&typ, &scheme, &keyid_hash_algorithms, &value)?;
541 let value = PublicKeyValue(value);
542 Ok(PublicKey {
543 typ,
544 key_id,
545 scheme,
546 keyid_hash_algorithms,
547 value,
548 })
549 }
550
551 pub fn from_spki(der_bytes: &[u8], scheme: SignatureScheme) -> Result<Self> {
555 Self::from_spki_with_keyid_hash_algorithms(
556 der_bytes,
557 scheme,
558 python_tuf_compatibility_keyid_hash_algorithms(),
559 )
560 }
561
562 fn from_spki_with_keyid_hash_algorithms(
566 der_bytes: &[u8],
567 scheme: SignatureScheme,
568 keyid_hash_algorithms: Option<Vec<String>>,
569 ) -> Result<Self> {
570 fn der_error(s: &str) -> Error {
571 Error::Encoding(s.into())
572 }
573
574 let (typ, expected_header) = match scheme {
575 SignatureScheme::Ed25519 => (KeyType::Ed25519, ED25519_SPKI_HEADER),
576 SignatureScheme::Unknown(s) => {
577 return Err(Error::UnknownSignatureScheme(s));
578 }
579 };
580
581 let input = Input::from(der_bytes);
582 let value = input.read_all(der_error("DER: unexpected trailing input"), |input| {
583 let actual_header = input
584 .read_bytes(expected_header.len())
585 .map_err(|_: untrusted::EndOfInput| der_error("DER: Invalid SPKI header"))?;
586 if actual_header.as_slice_less_safe() != expected_header {
587 return Err(Error::Encoding("DER: Unsupported SPKI header value".into()));
588 }
589 let value = input
590 .read_bytes(ED25519_PUBLIC_KEY_LENGTH)
591 .map_err(|_: untrusted::EndOfInput| der_error("DER: Invalid SPKI value"))?;
592 Ok(value.as_slice_less_safe().to_vec())
593 })?;
594
595 Self::new(typ, scheme, keyid_hash_algorithms, value)
596 }
597
598 pub fn from_ed25519<T: Into<Vec<u8>>>(bytes: T) -> Result<Self> {
600 Self::from_ed25519_with_keyid_hash_algorithms(bytes, None)
601 }
602
603 pub fn from_ed25519_with_keyid_hash_algorithms<T: Into<Vec<u8>>>(
605 bytes: T,
606 keyid_hash_algorithms: Option<Vec<String>>,
607 ) -> Result<Self> {
608 let bytes = bytes.into();
609 if bytes.len() != 32 {
610 return Err(Error::IllegalArgument(
611 "ed25519 keys must be 32 bytes long".into(),
612 ));
613 }
614
615 Self::new(
616 KeyType::Ed25519,
617 SignatureScheme::Ed25519,
618 keyid_hash_algorithms,
619 bytes,
620 )
621 }
622
623 pub fn as_spki(&self) -> Result<Vec<u8>> {
627 write_spki(&self.value.0, &self.typ)
628 }
629
630 pub fn typ(&self) -> &KeyType {
632 &self.typ
633 }
634
635 pub fn scheme(&self) -> &SignatureScheme {
637 &self.scheme
638 }
639
640 pub fn key_id(&self) -> &KeyId {
642 &self.key_id
643 }
644
645 pub fn as_bytes(&self) -> &[u8] {
647 &self.value.0
648 }
649
650 pub fn verify(&self, role: &MetadataPath, msg: &[u8], sig: &Signature) -> Result<()> {
652 let alg: &dyn ring::signature::VerificationAlgorithm = match self.scheme {
653 SignatureScheme::Ed25519 => &ED25519,
654 SignatureScheme::Unknown(ref s) => {
655 return Err(Error::UnknownSignatureScheme(s.to_string()));
656 }
657 };
658
659 let key = ring::signature::UnparsedPublicKey::new(alg, &self.value.0);
660 key.verify(msg, &sig.value.0)
661 .map_err(|_| Error::BadSignature(role.clone()))
662 }
663}
664
665impl PartialEq for PublicKey {
666 fn eq(&self, other: &Self) -> bool {
667 self.typ == other.typ
669 && self.scheme == other.scheme
670 && self.keyid_hash_algorithms == other.keyid_hash_algorithms
671 && self.value == other.value
672 }
673}
674
675impl Eq for PublicKey {}
676
677impl Ord for PublicKey {
678 fn cmp(&self, other: &Self) -> Ordering {
679 self.key_id.cmp(&other.key_id)
680 }
681}
682
683impl PartialOrd for PublicKey {
684 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
685 Some(self.key_id.cmp(&other.key_id))
686 }
687}
688
689impl hash::Hash for PublicKey {
690 fn hash<H: hash::Hasher>(&self, state: &mut H) {
691 self.typ.hash(state);
693 self.scheme.hash(state);
694 self.keyid_hash_algorithms.hash(state);
695 self.value.hash(state);
696 }
697}
698
699impl Serialize for PublicKey {
700 fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
701 where
702 S: Serializer,
703 {
704 let key = shim_public_key(
705 &self.typ,
706 &self.scheme,
707 &self.keyid_hash_algorithms,
708 &self.value.0,
709 )
710 .map_err(|e| SerializeError::custom(format!("Couldn't write key as SPKI: {:?}", e)))?;
711 key.serialize(ser)
712 }
713}
714
715impl<'de> Deserialize<'de> for PublicKey {
716 fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
717 let intermediate: shims::PublicKey = Deserialize::deserialize(de)?;
718
719 let key = match intermediate.keytype() {
720 KeyType::Ed25519 => {
721 if intermediate.scheme() != &SignatureScheme::Ed25519 {
722 return Err(DeserializeError::custom(format!(
723 "ed25519 key type must be used with the ed25519 signature scheme, not {:?}",
724 intermediate.scheme()
725 )));
726 }
727
728 let bytes = HEXLOWER
729 .decode(intermediate.public_key().as_bytes())
730 .map_err(|e| {
731 DeserializeError::custom(format!("Couldn't parse key as HEX: {:?}", e))
732 })?;
733
734 PublicKey::from_ed25519_with_keyid_hash_algorithms(
735 bytes,
736 intermediate.keyid_hash_algorithms().clone(),
737 )
738 .map_err(|e| {
739 DeserializeError::custom(format!("Couldn't parse key as ed25519: {:?}", e))
740 })?
741 }
742 KeyType::Unknown(_) => {
743 PublicKey::new(
745 intermediate.keytype().clone(),
746 intermediate.scheme().clone(),
747 intermediate.keyid_hash_algorithms().clone(),
748 intermediate.public_key().as_bytes().to_vec(),
749 )
750 .map_err(|e| DeserializeError::custom(format!("Couldn't parse key: {:?}", e)))?
751 }
752 };
753
754 if intermediate.keytype() != &key.typ {
755 return Err(DeserializeError::custom(format!(
756 "Key type listed in the metadata did not match the type extrated \
757 from the key. {:?} vs. {:?}",
758 intermediate.keytype(),
759 key.typ,
760 )));
761 }
762
763 Ok(key)
764 }
765}
766
767#[derive(Clone, PartialEq, Hash, Eq)]
768struct PublicKeyValue(Vec<u8>);
769
770impl Debug for PublicKeyValue {
771 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
772 f.debug_tuple("PublicKeyValue")
773 .field(&HEXLOWER.encode(&self.0))
774 .finish()
775 }
776}
777
778#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
780pub struct Signature {
781 #[serde(rename = "keyid")]
782 key_id: KeyId,
783 #[serde(rename = "sig")]
784 value: SignatureValue,
785}
786
787impl Signature {
788 pub fn key_id(&self) -> &KeyId {
790 &self.key_id
791 }
792
793 pub fn value(&self) -> &SignatureValue {
795 &self.value
796 }
797}
798
799impl PartialOrd for Signature {
800 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
801 Some(self.cmp(other))
802 }
803}
804
805impl Ord for Signature {
806 fn cmp(&self, other: &Self) -> Ordering {
807 (&self.key_id, &self.value).cmp(&(&other.key_id, &other.value))
808 }
809}
810
811#[non_exhaustive]
813#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
814pub enum HashAlgorithm {
815 #[serde(rename = "sha256")]
817 Sha256,
818 #[serde(rename = "sha512")]
820 Sha512,
821 Unknown(String),
823}
824
825impl HashAlgorithm {
826 pub(crate) fn digest_context(&self) -> Result<digest::Context> {
829 match self {
830 HashAlgorithm::Sha256 => Ok(digest::Context::new(&SHA256)),
831 HashAlgorithm::Sha512 => Ok(digest::Context::new(&SHA512)),
832 HashAlgorithm::Unknown(ref s) => Err(Error::IllegalArgument(format!(
833 "Unknown hash algorithm: {}",
834 s
835 ))),
836 }
837 }
838}
839
840#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
842pub struct HashValue(#[serde(with = "crate::format_hex")] Vec<u8>);
843
844impl HashValue {
845 pub fn new(bytes: Vec<u8>) -> Self {
847 HashValue(bytes)
848 }
849
850 pub fn value(&self) -> &[u8] {
852 &self.0
853 }
854}
855
856impl Debug for HashValue {
857 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
858 f.debug_tuple("HashValue")
859 .field(&HEXLOWER.encode(&self.0))
860 .finish()
861 }
862}
863
864impl Display for HashValue {
865 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
866 write!(f, "{}", HEXLOWER.encode(&self.0))
867 }
868}
869
870fn write_spki(public: &[u8], key_type: &KeyType) -> Result<Vec<u8>> {
871 let header = match key_type {
872 KeyType::Ed25519 => ED25519_SPKI_HEADER,
873 KeyType::Unknown(s) => {
874 return Err(Error::UnknownKeyType(s.to_owned()));
875 }
876 };
877
878 let mut output = Vec::with_capacity(header.len() + public.len());
879 output.extend_from_slice(header);
880 output.extend_from_slice(public);
881
882 Ok(output)
883}
884
885#[cfg(test)]
886mod test {
887 use super::*;
888 use assert_matches::assert_matches;
889 use pretty_assertions::assert_eq;
890 use serde_json::{self, json};
891
892 mod ed25519 {
893 pub(super) const PRIVATE_KEY: &[u8] = include_bytes!("../tests/ed25519/ed25519-1");
894 pub(super) const PUBLIC_KEY: &[u8] = include_bytes!("../tests/ed25519/ed25519-1.pub");
895 pub(super) const PK8_1: &[u8] = include_bytes!("../tests/ed25519/ed25519-1.pk8.der");
896 pub(super) const SPKI_1: &[u8] = include_bytes!("../tests/ed25519/ed25519-1.spki.der");
897 pub(super) const PK8_2: &[u8] = include_bytes!("../tests/ed25519/ed25519-2.pk8.der");
898 }
899
900 #[test]
901 fn parse_public_ed25519_spki() {
902 let key = PublicKey::from_spki(ed25519::SPKI_1, SignatureScheme::Ed25519).unwrap();
903 assert_eq!(key.typ, KeyType::Ed25519);
904 assert_eq!(key.scheme, SignatureScheme::Ed25519);
905 }
906
907 #[test]
908 fn parse_public_ed25519() {
909 let key = PublicKey::from_ed25519(ed25519::PUBLIC_KEY).unwrap();
910 assert_eq!(
911 key.key_id(),
912 &KeyId::from_str("e0294a3f17cc8563c3ed5fceb3bd8d3f6bfeeaca499b5c9572729ae015566554")
913 .unwrap()
914 );
915 assert_eq!(key.typ, KeyType::Ed25519);
916 assert_eq!(key.scheme, SignatureScheme::Ed25519);
917 }
918
919 #[test]
920 fn parse_public_ed25519_without_keyid_hash_algo() {
921 let key =
922 PublicKey::from_ed25519_with_keyid_hash_algorithms(ed25519::PUBLIC_KEY, None).unwrap();
923 assert_eq!(
924 key.key_id(),
925 &KeyId::from_str("e0294a3f17cc8563c3ed5fceb3bd8d3f6bfeeaca499b5c9572729ae015566554")
926 .unwrap()
927 );
928 assert_eq!(key.typ, KeyType::Ed25519);
929 assert_eq!(key.scheme, SignatureScheme::Ed25519);
930 }
931
932 #[test]
933 fn parse_public_ed25519_with_keyid_hash_algo() {
934 let key = PublicKey::from_ed25519_with_keyid_hash_algorithms(
935 ed25519::PUBLIC_KEY,
936 python_tuf_compatibility_keyid_hash_algorithms(),
937 )
938 .unwrap();
939 assert_eq!(
940 key.key_id(),
941 &KeyId::from_str("a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a")
942 .unwrap(),
943 );
944 assert_eq!(key.typ, KeyType::Ed25519);
945 assert_eq!(key.scheme, SignatureScheme::Ed25519);
946 }
947
948 #[test]
949 fn ed25519_read_pkcs8_and_sign() {
950 let key = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_1).unwrap();
951 let msg = b"test";
952
953 let sig = key.sign(msg).unwrap();
954
955 let pub_key =
956 PublicKey::from_spki(&key.public.as_spki().unwrap(), SignatureScheme::Ed25519).unwrap();
957
958 let role = MetadataPath::root();
959 assert_matches!(pub_key.verify(&role, msg, &sig), Ok(()));
960
961 let ring_key = ring::signature::Ed25519KeyPair::from_pkcs8(ed25519::PK8_1).unwrap();
963 assert_eq!(key.public().as_bytes(), ring_key.public_key().as_ref());
964 assert_eq!(sig.value().as_bytes(), ring_key.sign(msg).as_ref());
965
966 let bad_pub_key = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_2)
968 .unwrap()
969 .public()
970 .clone();
971
972 assert_matches!(
973 bad_pub_key.verify(&role, msg, &sig),
974 Err(Error::BadSignature(r))
975 if r == role
976 );
977 }
978
979 #[test]
980 fn ed25519_read_keypair_and_sign() {
981 let key = Ed25519PrivateKey::from_ed25519(ed25519::PRIVATE_KEY).unwrap();
982 let pub_key = PublicKey::from_ed25519(ed25519::PUBLIC_KEY).unwrap();
983 assert_eq!(key.public(), &pub_key);
984
985 let role = MetadataPath::root();
986 let msg = b"test";
987 let sig = key.sign(msg).unwrap();
988 assert_matches!(pub_key.verify(&role, msg, &sig), Ok(()));
989
990 let ring_key = ring::signature::Ed25519KeyPair::from_pkcs8(ed25519::PK8_1).unwrap();
992 assert_eq!(key.public().as_bytes(), ring_key.public_key().as_ref());
993 assert_eq!(sig.value().as_bytes(), ring_key.sign(msg).as_ref());
994
995 let bad_pub_key = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_2)
997 .unwrap()
998 .public()
999 .clone();
1000
1001 assert_matches!(
1002 bad_pub_key.verify(&role, msg, &sig),
1003 Err(Error::BadSignature(r))
1004 if r == role
1005 );
1006 }
1007
1008 #[test]
1009 fn ed25519_read_keypair_and_sign_with_keyid_hash_algorithms() {
1010 let key = Ed25519PrivateKey::from_ed25519_with_keyid_hash_algorithms(
1011 ed25519::PRIVATE_KEY,
1012 python_tuf_compatibility_keyid_hash_algorithms(),
1013 )
1014 .unwrap();
1015 let pub_key = PublicKey::from_ed25519_with_keyid_hash_algorithms(
1016 ed25519::PUBLIC_KEY,
1017 python_tuf_compatibility_keyid_hash_algorithms(),
1018 )
1019 .unwrap();
1020 assert_eq!(key.public(), &pub_key);
1021
1022 let role = MetadataPath::root();
1023 let msg = b"test";
1024 let sig = key.sign(msg).unwrap();
1025 assert_matches!(pub_key.verify(&role, msg, &sig), Ok(()));
1026
1027 let ring_key = ring::signature::Ed25519KeyPair::from_pkcs8(ed25519::PK8_1).unwrap();
1029 assert_eq!(key.public().as_bytes(), ring_key.public_key().as_ref());
1030 assert_eq!(sig.value().as_bytes(), ring_key.sign(msg).as_ref());
1031
1032 let bad_pub_key = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_2)
1034 .unwrap()
1035 .public()
1036 .clone();
1037
1038 assert_matches!(
1039 bad_pub_key.verify(&role, msg, &sig),
1040 Err(Error::BadSignature(r))
1041 if r == role
1042 );
1043 }
1044
1045 #[test]
1046 fn unknown_keytype_cannot_verify() {
1047 let pub_key = PublicKey::new(
1048 KeyType::Unknown("unknown-keytype".into()),
1049 SignatureScheme::Unknown("unknown-scheme".into()),
1050 None,
1051 b"unknown-key".to_vec(),
1052 )
1053 .unwrap();
1054 let role = MetadataPath::root();
1055 let msg = b"test";
1056 let sig = Signature {
1057 key_id: KeyId("key-id".into()),
1058 value: SignatureValue(b"sig-value".to_vec()),
1059 };
1060
1061 assert_matches!(
1062 pub_key.verify(&role, msg, &sig),
1063 Err(Error::UnknownSignatureScheme(s))
1064 if s == "unknown-scheme"
1065 );
1066 }
1067
1068 #[test]
1069 fn serde_key_id() {
1070 let s = "4750eaf6878740780d6f97b12dbad079fb012bec88c78de2c380add56d3f51db";
1071 let jsn = json!(s);
1072 let parsed: KeyId = serde_json::from_value(jsn.clone()).unwrap();
1073 assert_eq!(parsed, KeyId::from_str(s).unwrap());
1074 let encoded = serde_json::to_value(&parsed).unwrap();
1075 assert_eq!(encoded, jsn);
1076 }
1077
1078 #[test]
1079 fn serde_key_type() {
1080 let jsn = json!("ed25519");
1081 let parsed: KeyType = serde_json::from_value(jsn.clone()).unwrap();
1082 assert_eq!(parsed, KeyType::Ed25519);
1083
1084 let encoded = serde_json::to_value(&parsed).unwrap();
1085 assert_eq!(encoded, jsn);
1086
1087 let jsn = json!("unknown");
1088 let parsed: KeyType = serde_json::from_value(jsn).unwrap();
1089 assert_eq!(parsed, KeyType::Unknown("unknown".into()));
1090 }
1091
1092 #[test]
1093 fn serde_signature_scheme() {
1094 let jsn = json!("ed25519");
1095 let parsed: SignatureScheme = serde_json::from_value(jsn.clone()).unwrap();
1096 assert_eq!(parsed, SignatureScheme::Ed25519);
1097
1098 let encoded = serde_json::to_value(&parsed).unwrap();
1099 assert_eq!(encoded, jsn);
1100
1101 let jsn = json!("unknown");
1102 let parsed: SignatureScheme = serde_json::from_value(jsn).unwrap();
1103 assert_eq!(parsed, SignatureScheme::Unknown("unknown".into()));
1104 }
1105
1106 #[test]
1107 fn serde_signature_value() {
1108 let s = "4750eaf6878740780d6f97b12dbad079fb012bec88c78de2c380add56d3f51db";
1109 let jsn = json!(s);
1110 let parsed: SignatureValue = serde_json::from_str(&format!("\"{}\"", s)).unwrap();
1111 assert_eq!(
1112 parsed,
1113 SignatureValue(HEXLOWER.decode(s.as_bytes()).unwrap())
1114 );
1115 let encoded = serde_json::to_value(&parsed).unwrap();
1116 assert_eq!(encoded, jsn);
1117 }
1118
1119 #[test]
1120 fn serde_unknown_keytype_and_signature_scheme_public_key() {
1121 let pub_key = PublicKey::new(
1122 KeyType::Unknown("unknown-keytype".into()),
1123 SignatureScheme::Unknown("unknown-scheme".into()),
1124 None,
1125 b"unknown-key".to_vec(),
1126 )
1127 .unwrap();
1128 let encoded = serde_json::to_value(&pub_key).unwrap();
1129 let jsn = json!({
1130 "keytype": "unknown-keytype",
1131 "scheme": "unknown-scheme",
1132 "keyval": {
1133 "public": "unknown-key",
1134 }
1135 });
1136 assert_eq!(encoded, jsn);
1137 let decoded: PublicKey = serde_json::from_value(jsn).unwrap();
1138 assert_eq!(decoded, pub_key);
1139 }
1140
1141 #[test]
1142 fn serde_ed25519_public_key() {
1143 let pub_key = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_1)
1144 .unwrap()
1145 .public()
1146 .clone();
1147
1148 let pub_key = PublicKey::from_ed25519_with_keyid_hash_algorithms(
1149 pub_key.as_bytes().to_vec(),
1150 python_tuf_compatibility_keyid_hash_algorithms(),
1151 )
1152 .unwrap();
1153 let encoded = serde_json::to_value(&pub_key).unwrap();
1154 let jsn = json!({
1155 "keytype": "ed25519",
1156 "scheme": "ed25519",
1157 "keyid_hash_algorithms": ["sha256", "sha512"],
1158 "keyval": {
1159 "public": HEXLOWER.encode(pub_key.as_bytes()),
1160 }
1161 });
1162 assert_eq!(encoded, jsn);
1163 let decoded: PublicKey = serde_json::from_value(encoded).unwrap();
1164 assert_eq!(decoded, pub_key);
1165 }
1166
1167 #[test]
1168 fn de_ser_ed25519_public_key_with_keyid_hash_algo() {
1169 let pub_key = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_1)
1170 .unwrap()
1171 .public()
1172 .clone();
1173 let pub_key = PublicKey::from_ed25519_with_keyid_hash_algorithms(
1174 pub_key.as_bytes().to_vec(),
1175 python_tuf_compatibility_keyid_hash_algorithms(),
1176 )
1177 .unwrap();
1178 let original = json!({
1179 "keytype": "ed25519",
1180 "scheme": "ed25519",
1181 "keyid_hash_algorithms": ["sha256", "sha512"],
1182 "keyval": {
1183 "public": HEXLOWER.encode(pub_key.as_bytes()),
1184 }
1185 });
1186
1187 let encoded: PublicKey = serde_json::from_value(original.clone()).unwrap();
1188 #[allow(clippy::needless_borrows_for_generic_args)]
1189 let decoded = serde_json::to_value(&encoded).unwrap();
1190
1191 assert_eq!(original, decoded);
1192 }
1193
1194 #[test]
1195 fn de_ser_ed25519_public_key_without_keyid_hash_algo() {
1196 let pub_key = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_1)
1197 .unwrap()
1198 .public()
1199 .clone();
1200 let pub_key =
1201 PublicKey::from_ed25519_with_keyid_hash_algorithms(pub_key.as_bytes().to_vec(), None)
1202 .unwrap();
1203 let original = json!({
1204 "keytype": "ed25519",
1205 "scheme": "ed25519",
1206 "keyval": {
1207 "public": HEXLOWER.encode(pub_key.as_bytes()),
1208 }
1209 });
1210
1211 let encoded: PublicKey = serde_json::from_value(original.clone()).unwrap();
1212 #[allow(clippy::needless_borrows_for_generic_args)]
1213 let decoded = serde_json::to_value(&encoded).unwrap();
1214
1215 assert_eq!(original, decoded);
1216 }
1217
1218 #[test]
1219 fn serde_signature() {
1220 let key = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_1).unwrap();
1221 let msg = b"test";
1222 let sig = key.sign(msg).unwrap();
1223 let encoded = serde_json::to_value(&sig).unwrap();
1224 let jsn = json!({
1225 "keyid": "a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a",
1226 "sig": "fe4d13b2a73c033a1de7f5107b205fc7ba0e1566cb95b92349cae6aa453\
1227 8956013bfe0f7bf977cb072bb65e8782b5f33a0573fe78816299a017ca5ba55\
1228 9e390c",
1229 });
1230 assert_eq!(encoded, jsn);
1231
1232 let decoded: Signature = serde_json::from_value(encoded).unwrap();
1233 assert_eq!(decoded, sig);
1234 }
1235
1236 #[test]
1237 fn serde_signature_without_keyid_hash_algo() {
1238 let key =
1239 Ed25519PrivateKey::from_pkcs8_with_keyid_hash_algorithms(ed25519::PK8_1, None).unwrap();
1240 let msg = b"test";
1241 let sig = key.sign(msg).unwrap();
1242 let encoded = serde_json::to_value(&sig).unwrap();
1243 let jsn = json!({
1244 "keyid": "e0294a3f17cc8563c3ed5fceb3bd8d3f6bfeeaca499b5c9572729ae015566554",
1245 "sig": "fe4d13b2a73c033a1de7f5107b205fc7ba0e1566cb95b92349cae6aa453\
1246 8956013bfe0f7bf977cb072bb65e8782b5f33a0573fe78816299a017ca5ba55\
1247 9e390c",
1248 });
1249 assert_eq!(encoded, jsn);
1250
1251 let decoded: Signature = serde_json::from_value(encoded).unwrap();
1252 assert_eq!(decoded, sig);
1253 }
1254
1255 #[test]
1256 fn new_ed25519_key() {
1257 let bytes = Ed25519PrivateKey::pkcs8().unwrap();
1258 let _ = Ed25519PrivateKey::from_pkcs8(&bytes).unwrap();
1259 }
1260
1261 #[test]
1262 fn test_ed25519_public_key_eq() {
1263 let key1 = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_1).unwrap();
1264 let key2 = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_2).unwrap();
1265
1266 assert_eq!(key1.public(), key1.public());
1267 assert_ne!(key1.public(), key2.public());
1268 }
1269
1270 fn check_public_key_hash(key1: &PublicKey, key2: &PublicKey) {
1271 use std::hash::BuildHasher;
1272
1273 let state = std::collections::hash_map::RandomState::new();
1274
1275 assert_ne!(state.hash_one(key1), state.hash_one(key2));
1276 }
1277
1278 #[test]
1279 fn test_ed25519_public_key_hash() {
1280 let key1 = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_1).unwrap();
1281 let key2 = Ed25519PrivateKey::from_pkcs8(ed25519::PK8_2).unwrap();
1282
1283 check_public_key_hash(key1.public(), key2.public());
1284 }
1285}