summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/tor-netdoc/semver.md1
-rw-r--r--crates/tor-netdoc/src/doc/routerdesc.rs54
2 files changed, 37 insertions, 18 deletions
diff --git a/crates/tor-netdoc/semver.md b/crates/tor-netdoc/semver.md
index 33b72f321..35288caa2 100644
--- a/crates/tor-netdoc/semver.md
+++ b/crates/tor-netdoc/semver.md
@@ -1,3 +1,4 @@
+BREAKING: `RouterDesc::identity_ed25519` now stored using `EmbeddedCert` logic
ADDED: `RouterDesc::master_key_ed25519`
BREAKING: `RouterDesc::family_ids()` now returns `RelayFamilyIds`
ADDED: `From<Ed25519Identity>` for `RelayFamilyId`
diff --git a/crates/tor-netdoc/src/doc/routerdesc.rs b/crates/tor-netdoc/src/doc/routerdesc.rs
index 9bc2ac93a..2e9e46c8f 100644
--- a/crates/tor-netdoc/src/doc/routerdesc.rs
+++ b/crates/tor-netdoc/src/doc/routerdesc.rs
@@ -115,9 +115,8 @@ pub struct RouterDesc {
/// `identity-ed25519` --- Specify the router's ed25519 identity.
///
- /// * `identity-ed25519\n<certificate object>`
- /// * Exactly once, in second position in document.
- pub identity_ed25519: tor_cert::Ed25519Cert,
+ /// <https://spec.torproject.org/dir-spec/server-descriptor-format.html#item:identity-ed25519>
+ pub identity_ed25519: EmbeddedCert<Ed25519IdentityCert, KeyUnknownCert>,
/// `master-key-ed25519` --- Redundantly specify the router's ed25519 identity.
///
@@ -453,9 +452,11 @@ impl RouterDesc {
/// Return a reference to this relay's Ed25519 identity.
pub fn ed_identity(&self) -> &Ed25519Identity {
- self.identity_ed25519
- .signing_key()
- .expect("No ed25519 identity key on identity cert")
+ &self
+ .identity_ed25519
+ .get()
+ .expect("ed25519 identity cert should be verified")
+ .id_ed25519
}
/// Return a reference to the list of subprotocol versions supported by this
@@ -569,7 +570,19 @@ impl RouterDesc {
let start_offset = header.required(ROUTER)?.offset_in(s).unwrap();
// ed25519 identity and signing key.
- let (identity_cert, ed25519_signing_key) = {
+ //
+ // Small digression: This is terrible. We return a tuple containing
+ // a KeyUnknownCert and an UncheckedCert. This is because of a parse2
+ // and legacy incongruence. For parse2, we need the KeyUnknownCert
+ // to properly include it into EmbeddedCert, whereas the legacy parser
+ // will need an UncheckedCert because the verification chain is
+ // performed at the end. Because tor-cert's method all consume self,
+ // we can not go backwards, meaning we have to store two separate
+ // copies. It is also not possible to do the conversion to
+ // UncheckedCert later, because then we lose the error context returned
+ // in EK::BadObjectVal if the signed-by extension is missing.
+ //
+ let (ku_identity_cert, identity_cert, ed25519_signing_key) = {
let cert_tok = header.required(IDENTITY_ED25519)?;
// Unwrap should be safe because above `required` call should
// return `Error::MissingToken` if `IDENTITY_ED25519` is not `Ok`
@@ -579,17 +592,16 @@ impl RouterDesc {
.with_msg("identity-ed25519")
.at_pos(cert_tok.pos()));
}
- let cert: tor_cert::UncheckedCert = cert_tok
+ let ku_cert = cert_tok
.parse_obj::<UnvalidatedEdCert>("ED25519 CERT")?
.check_cert_type(tor_cert::CertType::IDENTITY_V_SIGNING)?
- .into_unchecked()
- .should_have_signing_key()
- .map_err(|err| {
- EK::BadObjectVal
- .err()
- .with_source(err)
- .at_pos(cert_tok.pos())
- })?;
+ .into_unchecked();
+ let cert = ku_cert.clone().should_have_signing_key().map_err(|err| {
+ EK::BadObjectVal
+ .err()
+ .with_source(err)
+ .at_pos(cert_tok.pos())
+ })?;
let sk = *cert.peek_subject_key().as_ed25519().ok_or_else(|| {
EK::BadObjectVal
.at_pos(cert_tok.pos())
@@ -600,7 +612,7 @@ impl RouterDesc {
.at_pos(cert_tok.pos())
.with_msg("invalid ed25519 signing key")
})?;
- (cert, sk)
+ (ku_cert, cert, sk)
};
// master-key-ed25519: required, and should match certificate.
@@ -931,7 +943,13 @@ impl RouterDesc {
socksport: 0,
dirport,
},
- identity_ed25519: identity_cert,
+ identity_ed25519: EmbeddedCert::new(
+ Ed25519IdentityCert {
+ id_ed25519: ed25519_identity_key,
+ sign_ed25519: ed25519_signing_key.into(),
+ },
+ ku_identity_cert,
+ ),
master_key_ed25519: ed25519_identity_key.into(),
bandwidth: Default::default(),
platform,