Skip to main content

tuf/
crypto.rs

1//! Cryptographic structures and functions.
2
3use {
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
32/// 1.3.101.112 curveEd25519(EdDSA 25519 signature algorithm)
33const ED25519_SPKI_HEADER: &[u8] = &[
34    0x30, 0x2c, 0x30, 0x07, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x05, 0x00, 0x03, 0x21, 0x00,
35];
36
37/// The length of an ed25519 private key in bytes
38const ED25519_PRIVATE_KEY_LENGTH: usize = 32;
39
40/// The length of an ed25519 public key in bytes
41const ED25519_PUBLIC_KEY_LENGTH: usize = 32;
42
43/// The length of an ed25519 keypair in bytes
44const 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
50/// Given a map of hash algorithms and their values and retains the supported
51/// hashes. Returns an `Err` if there is no match.
52///
53/// ```
54/// use std::collections::HashMap;
55/// use tuf::crypto::{retain_supported_hashes, HashValue, HashAlgorithm};
56///
57/// let mut map = HashMap::new();
58/// assert!(retain_supported_hashes(&map).is_empty());
59///
60/// let sha512_value = HashValue::new(vec![0x00, 0x01]);
61/// let _ = map.insert(HashAlgorithm::Sha512, sha512_value.clone());
62/// assert_eq!(
63///     retain_supported_hashes(&map),
64///     vec![
65///         (&HashAlgorithm::Sha512, sha512_value.clone()),
66///     ],
67/// );
68///
69/// let sha256_value = HashValue::new(vec![0x02, 0x03]);
70/// let _ = map.insert(HashAlgorithm::Sha256, sha256_value.clone());
71/// assert_eq!(
72///     retain_supported_hashes(&map),
73///     vec![
74///         (&HashAlgorithm::Sha512, sha512_value.clone()),
75///         (&HashAlgorithm::Sha256, sha256_value.clone()),
76///     ],
77/// );
78///
79/// let md5_value = HashValue::new(vec![0x04, 0x05]);
80/// let _ = map.insert(HashAlgorithm::Unknown("md5".into()), md5_value);
81/// assert_eq!(
82///     retain_supported_hashes(&map),
83///     vec![
84///         (&HashAlgorithm::Sha512, sha512_value),
85///         (&HashAlgorithm::Sha256, sha256_value),
86///     ],
87/// );
88/// ```
89pub 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
109/// Calculate the size and hash digest from a given `AsyncRead`.
110pub 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
134/// Calculate the size and hash digest from a given `AsyncRead`.
135pub 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            // We don't understand this key type and/or signature scheme, so we left it as a UTF-8 string.
189            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/// Wrapper type for public key's ID.
233///
234/// # Calculating
235///
236/// A `KeyId` is calculated as the hex digest of the SHA-256 hash of the
237/// canonical form of the public key, or `hexdigest(sha256(cjson(public_key)))`.
238#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
239pub struct KeyId(String);
240
241impl FromStr for KeyId {
242    type Err = Error;
243
244    /// Parse a key ID from a string.
245    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/// Cryptographic signature schemes.
278#[non_exhaustive]
279#[derive(Debug, Clone, PartialEq, Eq, Hash)]
280pub enum SignatureScheme {
281    /// [Ed25519](https://ed25519.cr.yp.to/)
282    Ed25519,
283
284    /// Placeholder for an unknown scheme.
285    Unknown(String),
286}
287
288impl SignatureScheme {
289    /// Construct a signature scheme from a `&str`.
290    pub fn new(name: &str) -> Self {
291        match name {
292            "ed25519" => SignatureScheme::Ed25519,
293            scheme => SignatureScheme::Unknown(scheme.to_string()),
294        }
295    }
296
297    /// Return the signature scheme as a `&str`.
298    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/// Wrapper type for the value of a cryptographic signature.
329#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
330pub struct SignatureValue(#[serde(with = "crate::format_hex")] Vec<u8>);
331
332impl SignatureValue {
333    /// Create a new `SignatureValue` from the given bytes.
334    ///
335    /// Note: It is unlikely that you ever want to do this manually.
336    pub fn new(bytes: Vec<u8>) -> Self {
337        SignatureValue(bytes)
338    }
339
340    /// Return the signature as bytes.
341    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/// Types of public keys.
355#[non_exhaustive]
356#[derive(Clone, PartialEq, Debug, Eq, Hash)]
357pub enum KeyType {
358    /// [Ed25519](https://ed25519.cr.yp.to/)
359    Ed25519,
360
361    /// Placeholder for an unknown key type.
362    Unknown(String),
363}
364
365impl KeyType {
366    /// Construct a key type from a `&str`.
367    pub fn new(name: &str) -> Self {
368        match name {
369            "ed25519" => KeyType::Ed25519,
370            keytype => KeyType::Unknown(keytype.to_string()),
371        }
372    }
373
374    /// Return the key type as a `&str`.
375    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
405/// A structure containing information about a private key.
406pub trait PrivateKey {
407    /// Sign a message.
408    fn sign(&self, msg: &[u8]) -> Result<Signature>;
409
410    /// Return the public component of the key.
411    fn public(&self) -> &PublicKey;
412}
413
414/// A structure containing information about an Ed25519 private key.
415pub struct Ed25519PrivateKey {
416    private: Ed25519KeyPair,
417    public: PublicKey,
418}
419
420impl Ed25519PrivateKey {
421    /// Generate Ed25519 key bytes in pkcs8 format.
422    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    /// Create a new `PrivateKey` from an ed25519 keypair. The keypair is a 64 byte slice, where the
429    /// first 32 bytes are the ed25519 seed, and the second 32 bytes are the public key.
430    pub fn from_ed25519(key: &[u8]) -> Result<Self> {
431        Self::from_ed25519_with_keyid_hash_algorithms(key, None)
432    }
433
434    /// Create a new `PrivateKey` from an ed25519 keypair with a custom `keyid_hash_algorithms`. The
435    /// keypair is a 64 byte slice, where the first 32 bytes are the ed25519 seed, and the second 32
436    /// bytes are the public key.
437    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    /// Create a private key from PKCS#8v2 DER bytes.
456    ///
457    /// # Generating Keys
458    ///
459    /// ```bash
460    /// $ touch ed25519-private-key.pk8
461    /// $ chmod 0600 ed25519-private-key.pk8
462    /// ```
463    ///
464    /// ```no_run
465    /// # use ring::rand::SystemRandom;
466    /// # use ring::signature::Ed25519KeyPair;
467    /// # use std::fs::File;
468    /// # use std::io::Write;
469    /// #
470    /// let mut file = File::open("ed25519-private-key.pk8").unwrap();
471    /// let key = Ed25519KeyPair::generate_pkcs8(&SystemRandom::new()).unwrap();
472    /// file.write_all(key.as_ref()).unwrap()
473    /// ```
474    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/// A structure containing information about a public key.
524#[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    /// Parse DER bytes as an SPKI key.
552    ///
553    /// See the documentation on `KeyValue` for more information on SPKI.
554    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    /// Parse DER bytes as an SPKI key and the `keyid_hash_algorithms`.
563    ///
564    /// See the documentation on `KeyValue` for more information on SPKI.
565    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    /// Parse ED25519 bytes as a public key.
599    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    /// Parse ED25519 bytes as a public key with a custom `keyid_hash_algorithms`.
604    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    /// Write the public key as SPKI DER bytes.
624    ///
625    /// See the documentation on `KeyValue` for more information on SPKI.
626    pub fn as_spki(&self) -> Result<Vec<u8>> {
627        write_spki(&self.value.0, &self.typ)
628    }
629
630    /// An immutable reference to the key's type.
631    pub fn typ(&self) -> &KeyType {
632        &self.typ
633    }
634
635    /// An immutable referece to the key's authorized signing scheme.
636    pub fn scheme(&self) -> &SignatureScheme {
637        &self.scheme
638    }
639
640    /// An immutable reference to the key's ID.
641    pub fn key_id(&self) -> &KeyId {
642        &self.key_id
643    }
644
645    /// Return the public key as bytes.
646    pub fn as_bytes(&self) -> &[u8] {
647        &self.value.0
648    }
649
650    /// Use this key to verify a message with a signature.
651    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        // key_id is derived from these fields, so we ignore it.
668        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        // key_id is derived from these fields, so we ignore it.
692        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                // We don't know this key type, so just leave it as a UTF-8 string.
744                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/// A structure that contains a `Signature` and associated data for verifying it.
779#[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    /// An immutable reference to the `KeyId` of the key that produced the signature.
789    pub fn key_id(&self) -> &KeyId {
790        &self.key_id
791    }
792
793    /// An immutable reference to the `SignatureValue`.
794    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/// The available hash algorithms.
812#[non_exhaustive]
813#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
814pub enum HashAlgorithm {
815    /// SHA256 as describe in [RFC-6234](https://tools.ietf.org/html/rfc6234)
816    #[serde(rename = "sha256")]
817    Sha256,
818    /// SHA512 as describe in [RFC-6234](https://tools.ietf.org/html/rfc6234)
819    #[serde(rename = "sha512")]
820    Sha512,
821    /// Placeholder for an unknown hash algorithm.
822    Unknown(String),
823}
824
825impl HashAlgorithm {
826    /// Create a new `digest::Context` suitable for computing the hash of some data using this hash
827    /// algorithm.
828    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/// Wrapper for the value of a hash digest.
841#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
842pub struct HashValue(#[serde(with = "crate::format_hex")] Vec<u8>);
843
844impl HashValue {
845    /// Create a new `HashValue` from the given digest bytes.
846    pub fn new(bytes: Vec<u8>) -> Self {
847        HashValue(bytes)
848    }
849
850    /// An immutable reference to the bytes of the hash value.
851    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        // Make sure we match what ring expects.
962        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        // Make sure verification fails with the wrong key.
967        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        // Make sure we match what ring expects.
991        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        // Make sure verification fails with the wrong key.
996        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        // Make sure we match what ring expects.
1028        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        // Make sure verification fails with the wrong key.
1033        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}