@@ -8,6 +8,7 @@ use schemars::JsonSchema;
8
8
use serde:: { Deserialize , Serialize } ;
9
9
use std:: fmt:: { Display , Formatter } ;
10
10
use std:: ops:: Deref ;
11
+ use v1:: node:: models:: LegacyHostInformationV3 ;
11
12
12
13
#[ cfg( feature = "client" ) ]
13
14
pub mod client;
@@ -68,9 +69,18 @@ impl SignedHostInformation {
68
69
69
70
// TODO: @JS: to remove downgrade support in future release(s)
70
71
72
+ let legacy_v3 = SignedData {
73
+ data : LegacyHostInformationV3 :: from ( self . data . clone ( ) ) ,
74
+ signature : self . signature . clone ( ) ,
75
+ } ;
76
+
77
+ if legacy_v3. verify ( & self . keys . ed25519_identity ) {
78
+ return true ;
79
+ }
80
+
71
81
// attempt to verify legacy signatures
72
82
let legacy_v2 = SignedData {
73
- data : LegacyHostInformationV2 :: from ( self . data . clone ( ) ) ,
83
+ data : LegacyHostInformationV2 :: from ( legacy_v3 . data ) ,
74
84
signature : self . signature . clone ( ) ,
75
85
} ;
76
86
@@ -119,7 +129,7 @@ mod tests {
119
129
let mut rng = rand_chacha:: ChaCha20Rng :: from_seed ( [ 0u8 ; 32 ] ) ;
120
130
let ed22519 = ed25519:: KeyPair :: new ( & mut rng) ;
121
131
let x25519_sphinx = x25519:: KeyPair :: new ( & mut rng) ;
122
- let x25519_noise = VersionedNoiseKey {
132
+ let x25519_versioned_noise = VersionedNoiseKey {
123
133
version : NoiseVersion :: V1 ,
124
134
x25519_pubkey : * x25519:: KeyPair :: new ( & mut rng) . public_key ( ) ,
125
135
} ;
@@ -130,7 +140,7 @@ mod tests {
130
140
keys : crate :: api:: v1:: node:: models:: HostKeys {
131
141
ed25519_identity : * ed22519. public_key ( ) ,
132
142
x25519_sphinx : * x25519_sphinx. public_key ( ) ,
133
- x25519_noise : None ,
143
+ x25519_versioned_noise : None ,
134
144
} ,
135
145
} ;
136
146
@@ -144,7 +154,7 @@ mod tests {
144
154
keys : crate :: api:: v1:: node:: models:: HostKeys {
145
155
ed25519_identity : * ed22519. public_key ( ) ,
146
156
x25519_sphinx : * x25519_sphinx. public_key ( ) ,
147
- x25519_noise : Some ( x25519_noise ) ,
157
+ x25519_versioned_noise : Some ( x25519_versioned_noise ) ,
148
158
} ,
149
159
} ;
150
160
@@ -154,6 +164,84 @@ mod tests {
154
164
assert ! ( signed_info. verify_host_information( ) ) ;
155
165
}
156
166
167
+ #[ test]
168
+ fn dummy_legacy_v3_signed_host_verification ( ) {
169
+ let mut rng = rand_chacha:: ChaCha20Rng :: from_seed ( [ 0u8 ; 32 ] ) ;
170
+ let ed22519 = ed25519:: KeyPair :: new ( & mut rng) ;
171
+ let x25519_sphinx = x25519:: KeyPair :: new ( & mut rng) ;
172
+ let x25519_noise = x25519:: KeyPair :: new ( & mut rng) ;
173
+
174
+ let legacy_info_no_noise = crate :: api:: v1:: node:: models:: LegacyHostInformationV3 {
175
+ ip_address : vec ! [ "1.1.1.1" . parse( ) . unwrap( ) ] ,
176
+ hostname : Some ( "foomp.com" . to_string ( ) ) ,
177
+ keys : crate :: api:: v1:: node:: models:: LegacyHostKeysV3 {
178
+ ed25519_identity : * ed22519. public_key ( ) ,
179
+ x25519_sphinx : * x25519_sphinx. public_key ( ) ,
180
+ x25519_noise : None ,
181
+ } ,
182
+ } ;
183
+
184
+ //technically this variant should never happen
185
+ let legacy_info_noise = crate :: api:: v1:: node:: models:: LegacyHostInformationV3 {
186
+ ip_address : vec ! [ "1.1.1.1" . parse( ) . unwrap( ) ] ,
187
+ hostname : Some ( "foomp.com" . to_string ( ) ) ,
188
+ keys : crate :: api:: v1:: node:: models:: LegacyHostKeysV3 {
189
+ ed25519_identity : * ed22519. public_key ( ) ,
190
+ x25519_sphinx : * x25519_sphinx. public_key ( ) ,
191
+ x25519_noise : Some ( * x25519_noise. public_key ( ) ) ,
192
+ } ,
193
+ } ;
194
+
195
+ let host_info_no_noise = crate :: api:: v1:: node:: models:: HostInformation {
196
+ ip_address : legacy_info_no_noise. ip_address . clone ( ) ,
197
+ hostname : legacy_info_no_noise. hostname . clone ( ) ,
198
+ keys : crate :: api:: v1:: node:: models:: HostKeys {
199
+ ed25519_identity : legacy_info_no_noise. keys . ed25519_identity ,
200
+ x25519_sphinx : legacy_info_no_noise. keys . x25519_sphinx ,
201
+ x25519_versioned_noise : None ,
202
+ } ,
203
+ } ;
204
+
205
+ let host_info_noise = crate :: api:: v1:: node:: models:: HostInformation {
206
+ ip_address : legacy_info_noise. ip_address . clone ( ) ,
207
+ hostname : legacy_info_noise. hostname . clone ( ) ,
208
+ keys : crate :: api:: v1:: node:: models:: HostKeys {
209
+ ed25519_identity : legacy_info_noise. keys . ed25519_identity ,
210
+ x25519_sphinx : legacy_info_noise. keys . x25519_sphinx ,
211
+ x25519_versioned_noise : Some ( VersionedNoiseKey {
212
+ version : NoiseVersion :: V1 ,
213
+ x25519_pubkey : legacy_info_noise. keys . x25519_noise . unwrap ( ) ,
214
+ } ) ,
215
+ } ,
216
+ } ;
217
+
218
+ // signature on legacy data
219
+ let signature_no_noise = SignedData :: new ( legacy_info_no_noise, ed22519. private_key ( ) )
220
+ . unwrap ( )
221
+ . signature ;
222
+
223
+ let signature_noise = SignedData :: new ( legacy_info_noise, ed22519. private_key ( ) )
224
+ . unwrap ( )
225
+ . signature ;
226
+
227
+ // signed blob with the 'current' structure
228
+ let current_struct_no_noise = SignedData {
229
+ data : host_info_no_noise,
230
+ signature : signature_no_noise,
231
+ } ;
232
+
233
+ let current_struct_noise = SignedData {
234
+ data : host_info_noise,
235
+ signature : signature_noise,
236
+ } ;
237
+
238
+ assert ! ( !current_struct_no_noise. verify( ed22519. public_key( ) ) ) ;
239
+ assert ! ( current_struct_no_noise. verify_host_information( ) ) ;
240
+
241
+ assert ! ( !current_struct_noise. verify( ed22519. public_key( ) ) ) ;
242
+ assert ! ( current_struct_noise. verify_host_information( ) )
243
+ }
244
+
157
245
#[ test]
158
246
fn dummy_legacy_v2_signed_host_verification ( ) {
159
247
let mut rng = rand_chacha:: ChaCha20Rng :: from_seed ( [ 0u8 ; 32 ] ) ;
@@ -187,7 +275,7 @@ mod tests {
187
275
keys : crate :: api:: v1:: node:: models:: HostKeys {
188
276
ed25519_identity : legacy_info_no_noise. keys . ed25519_identity . parse ( ) . unwrap ( ) ,
189
277
x25519_sphinx : legacy_info_no_noise. keys . x25519_sphinx . parse ( ) . unwrap ( ) ,
190
- x25519_noise : None ,
278
+ x25519_versioned_noise : None ,
191
279
} ,
192
280
} ;
193
281
@@ -197,7 +285,7 @@ mod tests {
197
285
keys : crate :: api:: v1:: node:: models:: HostKeys {
198
286
ed25519_identity : legacy_info_noise. keys . ed25519_identity . parse ( ) . unwrap ( ) ,
199
287
x25519_sphinx : legacy_info_noise. keys . x25519_sphinx . parse ( ) . unwrap ( ) ,
200
- x25519_noise : Some ( VersionedNoiseKey {
288
+ x25519_versioned_noise : Some ( VersionedNoiseKey {
201
289
version : NoiseVersion :: V1 ,
202
290
x25519_pubkey : legacy_info_noise. keys . x25519_noise . parse ( ) . unwrap ( ) ,
203
291
} ) ,
@@ -244,7 +332,7 @@ mod tests {
244
332
keys : crate :: api:: v1:: node:: models:: HostKeys {
245
333
ed25519_identity : * ed22519. public_key ( ) ,
246
334
x25519_sphinx : * x25519_sphinx. public_key ( ) ,
247
- x25519_noise : None ,
335
+ x25519_versioned_noise : None ,
248
336
} ,
249
337
} ;
250
338
@@ -254,7 +342,7 @@ mod tests {
254
342
keys : crate :: api:: v1:: node:: models:: HostKeys {
255
343
ed25519_identity : * ed22519. public_key ( ) ,
256
344
x25519_sphinx : * x25519_sphinx. public_key ( ) ,
257
- x25519_noise : Some ( VersionedNoiseKey {
345
+ x25519_versioned_noise : Some ( VersionedNoiseKey {
258
346
version : NoiseVersion :: V1 ,
259
347
x25519_pubkey : * x25519_noise. public_key ( ) ,
260
348
} ) ,
@@ -295,7 +383,7 @@ mod tests {
295
383
keys : crate :: api:: v1:: node:: models:: HostKeys {
296
384
ed25519_identity : legacy_info. keys . ed25519 . parse ( ) . unwrap ( ) ,
297
385
x25519_sphinx : legacy_info. keys . x25519 . parse ( ) . unwrap ( ) ,
298
- x25519_noise : None ,
386
+ x25519_versioned_noise : None ,
299
387
} ,
300
388
} ;
301
389
0 commit comments