1010//!
1111//! Key verification follows a chain of trust:
1212//! 1. The FPF signing key is a trust anchor (pre-distributed out of band).
13- //! 2. The newsroom's verifying key is signed by FPF. (This is not yet verified by `handle_journalist_key_response()`.)
13+ //! 2. The newsroom's verifying key is signed by FPF and stored by [`Api::handle_newsroom_key_response`].
1414//! 3. Each journalist's signing key is signed by the newsroom.
1515//! 4. Each journalist's key bundles are self-signed.
1616
@@ -20,8 +20,8 @@ use crate::{
2020 encrypt_decrypt:: { encrypt, solve_fetch_challenges} ,
2121 messages:: {
2222 core:: {
23- MessageChallengeFetchRequest , MessageFetchRequest , SourceJournalistKeyRequest ,
24- SourceJournalistKeyResponse , SourceNewsroomKeyRequest , SourceNewsroomKeyResponse ,
23+ KeyRequest , KeyResponse , MessageChallengeFetchRequest , MessageFetchRequest ,
24+ NewsroomKeyRequest , NewsroomKeyResponse ,
2525 } ,
2626 setup:: { JournalistEphemeralKeyRequest , JournalistSetupRequest } ,
2727 } ,
@@ -38,26 +38,29 @@ use uuid::Uuid;
3838/// [`set_newsroom_verifying_key`](Api::set_newsroom_verifying_key).
3939/// All other methods have default implementations.
4040pub trait Api {
41- /// Returns the stored newsroom verifying key, if one has been verified .
41+ /// Returns the stored newsroom verifying key.
4242 fn newsroom_verifying_key ( & self ) -> Option < & VerifyingKey > ;
4343
44- /// Stores a verified newsroom verifying key.
44+ /// Stores a newsroom verifying key.
45+ ///
46+ /// The caller is responsible for ensuring the key has been verified before
47+ /// storing it. Prefer [`handle_newsroom_key_response`](Api::handle_newsroom_key_response),
48+ /// which verifies the FPF signature before storing.
4549 fn set_newsroom_verifying_key ( & mut self , key : VerifyingKey ) ;
4650
47- /// Creates a request to fetch the newsroom's public keys from the server.
51+ /// Creates a `NewsroomKeyRequest` to fetch the newsroom's public keys from the server.
4852 ///
4953 /// This is the first part of step 5 in the protocol spec.
50- fn fetch_newsroom_keys ( & self ) -> SourceNewsroomKeyRequest {
51- SourceNewsroomKeyRequest { }
54+ fn newsroom_key_request ( & self ) -> NewsroomKeyRequest {
55+ NewsroomKeyRequest { }
5256 }
5357
54- /// Creates a request to fetch journalist public keys from the server .
58+ /// Creates a `RequestKeys` request (step 5 in the spec) .
5559 ///
56- /// This is the second part of step 5 in the protocol spec. The server
57- /// responds with long-term keys and a one-time ephemeral key bundle
58- /// for each available journalist.
59- fn fetch_journalist_keys ( & self ) -> SourceJournalistKeyRequest {
60- SourceJournalistKeyRequest { }
60+ /// The server responds with long-term keys and a one-time ephemeral key
61+ /// bundle for each available journalist.
62+ fn request_keys ( & self ) -> KeyRequest {
63+ KeyRequest { }
6164 }
6265
6366 /// Creates a request to fetch encrypted message IDs from the server.
@@ -133,15 +136,15 @@ pub trait Api {
133136 /// Returns an error if the FPF signature is invalid.
134137 fn handle_newsroom_key_response (
135138 & mut self ,
136- response : & SourceNewsroomKeyResponse ,
139+ response : & NewsroomKeyResponse ,
137140 fpf_verifying_key : & VerifyingKey ,
138141 ) -> Result < ( ) , Error > {
139- let newsroom_vk_bytes = response. newsroom_verifying_key . into_bytes ( ) ;
142+ let newsroom_vk_bytes = response. newsroom_verifying_key ( ) . into_bytes ( ) ;
140143 fpf_verifying_key
141- . verify ( & newsroom_vk_bytes, & response. fpf_sig )
144+ . verify ( & newsroom_vk_bytes, response. fpf_sig ( ) )
142145 . map_err ( |_| anyhow:: anyhow!( "invalid FPF signature on newsroom verifying key" ) ) ?;
143146
144- self . set_newsroom_verifying_key ( response. newsroom_verifying_key ) ;
147+ self . set_newsroom_verifying_key ( * response. newsroom_verifying_key ( ) ) ;
145148 Ok ( ( ) )
146149 }
147150
@@ -154,32 +157,36 @@ pub trait Api {
154157 ///
155158 /// # Errors
156159 ///
157- /// Returns an error if any signature check fails.
158- fn handle_journalist_key_response (
159- & self ,
160- response : & SourceJournalistKeyResponse ,
161- newsroom_verifying_key : & VerifyingKey ,
162- ) -> Result < ( ) , Error > {
160+ /// Returns an error if:
161+ /// - The newsroom verifying key has not been set (call [`handle_newsroom_key_response`](Api::handle_newsroom_key_response) first).
162+ /// - Any of the three signature checks fail.
163+ fn handle_key_response ( & self , response : & KeyResponse ) -> Result < ( ) , Error > {
164+ let newsroom_verifying_key = self . newsroom_verifying_key ( ) . ok_or_else ( || {
165+ anyhow:: anyhow!(
166+ "newsroom verifying key not set; call handle_newsroom_key_response first"
167+ )
168+ } ) ?;
169+
163170 // 1. Verify newsroom signature on journalist's verifying key.
164171 newsroom_verifying_key
165172 . verify (
166- & response. journalist . verifying_key ( ) . into_bytes ( ) ,
167- & response. nr_signature ,
173+ & response. journalist ( ) . verifying_key ( ) . into_bytes ( ) ,
174+ response. nr_signature ( ) ,
168175 )
169176 . map_err ( |_| anyhow:: anyhow!( "invalid newsroom signature on journalist signing key" ) ) ?;
170177
171178 // 2. Verify journalist's self-signature on long-term key bundle.
172- let vk = response. journalist . verifying_key ( ) ;
179+ let vk = response. journalist ( ) . verifying_key ( ) ;
173180 vk. verify (
174- response. journalist . signed_keybytes ( ) . as_bytes ( ) ,
175- response. journalist . self_signature ( ) ,
181+ response. journalist ( ) . signed_keybytes ( ) . as_bytes ( ) ,
182+ response. journalist ( ) . self_signature ( ) ,
176183 )
177184 . map_err ( |_| anyhow:: anyhow!( "invalid journalist self-signature on long-term keys" ) ) ?;
178185
179186 // 3. Verify journalist's self-signature on one-time ephemeral key bundle.
180187 vk. verify (
181- & response. journalist . ephemeral_bundle ( ) . as_bytes ( ) ,
182- response. journalist . ephemeral_signature ( ) ,
188+ & response. journalist ( ) . ephemeral_bundle ( ) . as_bytes ( ) ,
189+ response. journalist ( ) . ephemeral_signature ( ) ,
183190 )
184191 . map_err ( |_| anyhow:: anyhow!( "invalid journalist self-signature on one-time keys" ) ) ?;
185192
0 commit comments