1
1
//! Deserializer and verifier of version metadata
2
2
3
3
use anyhow:: Context ;
4
+ use vec1:: Vec1 ;
4
5
5
6
use super :: key:: * ;
6
7
use super :: Response ;
@@ -10,11 +11,11 @@ impl SignedResponse {
10
11
/// Deserialize some bytes to JSON, and verify them, including signature and expiry.
11
12
/// If successful, the deserialized data is returned.
12
13
pub fn deserialize_and_verify (
13
- key : & VerifyingKey ,
14
+ keys : & Vec1 < VerifyingKey > ,
14
15
bytes : & [ u8 ] ,
15
16
min_metadata_version : usize ,
16
17
) -> Result < Self , anyhow:: Error > {
17
- Self :: deserialize_and_verify_at_time ( key , bytes, chrono:: Utc :: now ( ) , min_metadata_version)
18
+ Self :: deserialize_and_verify_at_time ( keys , bytes, chrono:: Utc :: now ( ) , min_metadata_version)
18
19
}
19
20
20
21
/// This method is used mostly for testing, and skips all verification.
@@ -33,13 +34,13 @@ impl SignedResponse {
33
34
/// Deserialize some bytes to JSON, and verify them, including signature and expiry.
34
35
/// If successful, the deserialized data is returned.
35
36
fn deserialize_and_verify_at_time (
36
- key : & VerifyingKey ,
37
+ keys : & Vec1 < VerifyingKey > ,
37
38
bytes : & [ u8 ] ,
38
39
current_time : chrono:: DateTime < chrono:: Utc > ,
39
40
min_metadata_version : usize ,
40
41
) -> Result < Self , anyhow:: Error > {
41
42
// Deserialize and verify signature
42
- let partial_data = deserialize_and_verify ( key , bytes) ?;
43
+ let partial_data = deserialize_and_verify ( keys , bytes) ?;
43
44
44
45
// Deserialize the canonical JSON to structured representation
45
46
let signed_response: Response = serde_json:: from_value ( partial_data. signed )
@@ -74,16 +75,20 @@ impl SignedResponse {
74
75
///
75
76
/// On success, this returns verified data and signature
76
77
pub ( super ) fn deserialize_and_verify (
77
- key : & VerifyingKey ,
78
+ keys : & Vec1 < VerifyingKey > ,
78
79
bytes : & [ u8 ] ,
79
80
) -> anyhow:: Result < PartialSignedResponse > {
80
81
let partial_data: PartialSignedResponse =
81
82
serde_json:: from_slice ( bytes) . context ( "Invalid version JSON" ) ?;
82
83
83
- // Check if the key matches
84
- let Some ( sig) = partial_data. signatures . iter ( ) . find_map ( |sig| match sig {
84
+ let valid_keys: Vec < _ > = keys. into_iter ( ) . map ( |k| k. 0 ) . collect ( ) ;
85
+
86
+ // Check if one of the keys matches
87
+ let Some ( ( key, sig) ) = partial_data. signatures . iter ( ) . find_map ( |sig| match sig {
85
88
// Check if ed25519 key matches
86
- ResponseSignature :: Ed25519 { keyid, sig } if keyid. 0 == key. 0 => Some ( sig) ,
89
+ ResponseSignature :: Ed25519 { keyid, sig } if valid_keys. contains ( & keyid. 0 ) => {
90
+ Some ( ( keyid, sig) )
91
+ }
87
92
// Ignore all non-matching key
88
93
_ => None ,
89
94
} ) else {
@@ -109,6 +114,8 @@ pub(super) fn deserialize_and_verify(
109
114
mod test {
110
115
use std:: str:: FromStr ;
111
116
117
+ use vec1:: vec1;
118
+
112
119
use super :: * ;
113
120
114
121
/// Test that a valid signed version response is successfully deserialized and verified
@@ -119,7 +126,7 @@ mod test {
119
126
ed25519_dalek:: VerifyingKey :: from_bytes ( & pubkey. try_into ( ) . unwrap ( ) ) . unwrap ( ) ;
120
127
121
128
SignedResponse :: deserialize_and_verify_at_time (
122
- & VerifyingKey ( verifying_key) ,
129
+ & vec1 ! [ VerifyingKey ( verifying_key) ] ,
123
130
include_bytes ! ( "../../test-version-response.json" ) ,
124
131
// It's 1970 again
125
132
chrono:: DateTime :: UNIX_EPOCH ,
@@ -130,7 +137,7 @@ mod test {
130
137
131
138
// Reject expired data
132
139
SignedResponse :: deserialize_and_verify_at_time (
133
- & VerifyingKey ( verifying_key) ,
140
+ & vec1 ! [ VerifyingKey ( verifying_key) ] ,
134
141
include_bytes ! ( "../../test-version-response.json" ) ,
135
142
// In the year 3000
136
143
chrono:: DateTime :: from_str ( "3000-01-01T00:00:00Z" ) . unwrap ( ) ,
@@ -141,7 +148,7 @@ mod test {
141
148
142
149
// Reject expired version number
143
150
SignedResponse :: deserialize_and_verify_at_time (
144
- & VerifyingKey ( verifying_key) ,
151
+ & vec1 ! [ VerifyingKey ( verifying_key) ] ,
145
152
include_bytes ! ( "../../test-version-response.json" ) ,
146
153
chrono:: DateTime :: UNIX_EPOCH ,
147
154
usize:: MAX ,
0 commit comments