Commit 733b55b5 authored by Clara Engler's avatar Clara Engler 🥘
Browse files

Merge branch 'directory-signature-hash-algo' into 'main'

Unknown keyword handling fixes; use a more principled type for directory signature hash algo

See merge request !3923
parents baefa68d c78493ff
Loading
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -61,3 +61,8 @@ BREAKING: `ConsensusVoterInfo`; several field types changed
ADDED: `ConsensusVoterInfo`: `ItemValueParseable`, `ItemValueEncodable`, `Constructor`
ADDED: `ConsensusVoterInfo`: `ItemValueParseable`, `ItemValueEncodable`, `Constructor`
ADDED: `VoteAuthorityEntry`, `VoteAuthoritySection`
ADDED: `VoteAuthorityEntry`, `VoteAuthoritySection`
ADDED: `SupersededAuthorityKey`, `ConsensusAuthoritySection`
ADDED: `SupersededAuthorityKey`, `ConsensusAuthoritySection`
BREAKING: `NormalItemArgument` no longer has `FromStr` and `Display` as supertraits
BREAKING: `Unknown::as_ref` signature changed; `only_known` may be needed too now.
ADDED: `Unknown::only_known`
ADDED: `Unknown` is now an exhaustive enum.
ADDED: `KeywordOrString`
+15 −7
Original line number Original line Diff line number Diff line
@@ -85,6 +85,7 @@ use std::sync::Arc;
use std::{net, result, time};
use std::{net, result, time};
use tor_error::{Bug, HasKind, bad_api_usage, internal};
use tor_error::{Bug, HasKind, bad_api_usage, internal};
use tor_protover::Protocols;
use tor_protover::Protocols;
use void::ResultVoidExt as _;


use derive_deftly::{Deftly, define_derive_deftly};
use derive_deftly::{Deftly, define_derive_deftly};
use digest::Digest;
use digest::Digest;
@@ -518,6 +519,10 @@ impl ConsensusFlavor {
    }
    }
}
}


define_directory_signature_hash_algo! {
    #[derive_deftly_adhoc] // TODO DIRAUTH; suppresses complaints about attrs used only in poc
}

/// The signature of a single directory authority on a networkstatus document.
/// The signature of a single directory authority on a networkstatus document.
#[derive(Debug, Clone)]
#[derive(Debug, Clone)]
#[non_exhaustive]
#[non_exhaustive]
@@ -526,7 +531,7 @@ pub struct Signature {
    ///
    ///
    /// Currently sha1 and sh256 are recognized.  Here we only support
    /// Currently sha1 and sh256 are recognized.  Here we only support
    /// sha256.
    /// sha256.
    pub digestname: String,
    pub digest_algo: KeywordOrString<DirectorySignatureHashAlgo>,
    /// Fingerprints of the keys for the authority that made
    /// Fingerprints of the keys for the authority that made
    /// this signature.
    /// this signature.
    pub key_ids: AuthCertKeyIds,
    pub key_ids: AuthCertKeyIds,
@@ -1447,7 +1452,7 @@ impl Signature {
            .at_pos(item.pos()));
            .at_pos(item.pos()));
        }
        }


        let (alg, id_fp, sk_fp) = if item.n_args() > 2 {
        let (digest_algo, id_fp, sk_fp) = if item.n_args() > 2 {
            (
            (
                item.required_arg(0)?,
                item.required_arg(0)?,
                item.required_arg(1)?,
                item.required_arg(1)?,
@@ -1457,7 +1462,7 @@ impl Signature {
            ("sha1", item.required_arg(0)?, item.required_arg(1)?)
            ("sha1", item.required_arg(0)?, item.required_arg(1)?)
        };
        };


        let digestname = alg.to_string();
        let digest_algo = digest_algo.to_string().parse().void_unwrap();
        let id_fingerprint = id_fp.parse::<Fingerprint>()?.into();
        let id_fingerprint = id_fp.parse::<Fingerprint>()?.into();
        let sk_fingerprint = sk_fp.parse::<Fingerprint>()?.into();
        let sk_fingerprint = sk_fp.parse::<Fingerprint>()?.into();
        let key_ids = AuthCertKeyIds {
        let key_ids = AuthCertKeyIds {
@@ -1467,7 +1472,7 @@ impl Signature {
        let signature = item.obj("SIGNATURE")?;
        let signature = item.obj("SIGNATURE")?;


        Ok(Signature {
        Ok(Signature {
            digestname,
            digest_algo,
            key_ids,
            key_ids,
            signature,
            signature,
        })
        })
@@ -1566,9 +1571,12 @@ impl SignatureGroup {
                continue;
                continue;
            }
            }


            let d: Option<&[u8]> = match sig.digestname.as_ref() {
            use DirectorySignatureHashAlgo as DSHA;
                "sha256" => self.sha256.as_ref().map(|a| &a[..]),
            use KeywordOrString as KOS;
                "sha1" => self.sha1.as_ref().map(|a| &a[..]),

            let d: Option<&[u8]> = match sig.digest_algo {
                KOS::Known(DSHA::Sha256) => self.sha256.as_ref().map(|a| &a[..]),
                KOS::Known(DSHA::Sha1) => self.sha1.as_ref().map(|a| &a[..]),
                _ => None, // We don't know how to find this digest.
                _ => None, // We don't know how to find this digest.
            };
            };
            if d.is_none() {
            if d.is_none() {
+1 −1
Original line number Original line Diff line number Diff line
@@ -230,7 +230,7 @@ impl Default for NetdocEncoder {
    }
    }
}
}


impl<T: crate::NormalItemArgument> ItemArgument for T {
impl<T: crate::NormalItemArgument + Display> ItemArgument for T {
    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
        (*self.to_string()).write_arg_onto(out)
        (*self.to_string()).write_arg_onto(out)
    }
    }
+5 −3
Original line number Original line Diff line number Diff line
@@ -119,9 +119,11 @@ pub enum AllowAnnotations {
/// A type that is represented as a single argument
/// A type that is represented as a single argument
/// whose representation is as for the type's `FromStr` and `Display`.
/// whose representation is as for the type's `FromStr` and `Display`.
///
///
/// Implementing this trait enables a blanket impl of `parse2::ItemArgumentParseable`
/// Implementing this trait enables a blanket impl of
/// and `build::ItemArgument`.
/// [`parse2::ItemArgumentParseable`] (if `FromStr`)
pub trait NormalItemArgument: std::str::FromStr + std::fmt::Display {}
/// and
/// [`encode::ItemArgument`] (if `Display`).
pub trait NormalItemArgument {}
// TODO: should we implement ItemArgument for, say, tor_llcrypto::pk::rsa::RsaIdentity ?
// TODO: should we implement ItemArgument for, say, tor_llcrypto::pk::rsa::RsaIdentity ?
// It's not clear whether it's always formatted the same way in all parts of the spec.
// It's not clear whether it's always formatted the same way in all parts of the spec.
// The Display impl of RsaIdentity adds a `$` which is not supposed to be present
// The Display impl of RsaIdentity adds a `$` which is not supposed to be present
+2 −11
Original line number Original line Diff line number Diff line
@@ -134,17 +134,8 @@ define_derive_deftly! {
    }
    }
}
}


/// `directory-signature` hash algorithm argument
define_directory_signature_hash_algo! {
#[derive(Clone, Copy, Debug, Eq, PartialEq, strum::EnumString, Deftly)]
    #[derive_deftly(DirectorySignatureHashesAccu)]
    #[derive_deftly(DirectorySignatureHashesAccu)]
#[non_exhaustive]
pub enum DirectorySignatureHashAlgo {
    /// SHA-1
    #[deftly(hash_len = "20")]
    Sha1,
    /// SHA-256
    #[deftly(hash_len = "32")]
    Sha256,
}
}


/// Unsupported `vote-status` value
/// Unsupported `vote-status` value
Loading