1
//! Directory Authority Key Certificates
2

            
3
use super::*;
4

            
5
/// SHA1 hash as used in directory authority certificates
6
//
7
// We don't have a better name for this!
8
type DirKeyCertificateHash = [u8; 20];
9

            
10
pub use crate::doc::authcert::AuthCert as DirAuthKeyCert;
11
pub use crate::doc::authcert::AuthCertUnverified as DirAuthKeyCertUnverified;
12

            
13
impl DirAuthKeyCertUnverified {
14
    /// Verify the signatures (and check validity times)
15
    ///
16
    /// # Security considerations
17
    ///
18
    /// The caller must check that the KP_auth_id is correct/relevant.
19
    //
20
    // TODO DIRAUTH move this to doc/authcert.rs and deduplicate the code.
21
10
    pub fn verify_selfcert(self, now: SystemTime) -> Result<DirAuthKeyCert, VF> {
22
        // verify main document signature (and timestamp)
23
10
        let hash = self
24
10
            .sigs
25
10
            .hashes
26
10
            .0
27
10
            .as_ref()
28
10
            .expect("AuthCertSignatures parsed so hash is set");
29
10
        let body = &self.inspect_unverified().0;
30

            
31
10
        let validity = body.dir_key_published.0..=body.dir_key_expires.0;
32
10
        check_validity_time(now, validity)?;
33
10
        body.dir_identity_key
34
10
            .verify(hash, &self.sigs.sigs.dir_key_certification.signature)?;
35

            
36
        // double-check the id hash
37
10
        if *body.fingerprint != body.dir_identity_key.to_rsa_identity() {
38
            return Err(VF::Inconsistent);
39
10
        }
40

            
41
        // verify cross-cert
42
10
        let h_kp_auth_id_rsa: DirKeyCertificateHash =
43
10
            tor_llcrypto::d::Sha1::digest(body.dir_identity_key.to_der()).into();
44
        // Cross-cert has no timestamp.  Whatever.
45
10
        body.dir_signing_key
46
10
            .verify(&h_kp_auth_id_rsa, &body.dir_key_crosscert.signature)?;
47

            
48
10
        Ok(self.unwrap_unverified().0)
49
10
    }
50
}