@@ -35,6 +35,9 @@ pub enum Role {
35
35
Server ,
36
36
}
37
37
38
+ // Number of stored remote keys.
39
+ const STORED_REMOTE_KEYS : usize = 5 ;
40
+
38
41
/// Holds all of the security information related to this session
39
42
#[ derive( Debug ) ]
40
43
pub struct SecureChannel {
@@ -63,7 +66,15 @@ pub struct SecureChannel {
63
66
/// Our nonce generated while handling open secure channel
64
67
local_nonce : Vec < u8 > ,
65
68
/// Client (i.e. other end's set of keys) Symmetric Signing Key, Encrypt Key, IV
66
- remote_keys : Option < ( Vec < u8 > , AesKey , Vec < u8 > ) > ,
69
+ ///
70
+ /// Store the last 5 used remote keys and choose which one to use based on the
71
+ /// token ID in the security header of the received message. This allows us to
72
+ /// properly decrypt messages that were encrypted with a previous key.
73
+ ///
74
+ /// See the "OpenSecureChannel" section in the spec for more info:
75
+ /// https://reference.opcfoundation.org/Core/Part4/v105/docs/5.5.2
76
+ #[ allow( clippy:: type_complexity) ]
77
+ remote_keys : [ Option < ( Vec < u8 > , AesKey , Vec < u8 > ) > ; STORED_REMOTE_KEYS ] ,
67
78
/// Server (i.e. our end's set of keys) Symmetric Signing Key, Decrypt Key, IV
68
79
local_keys : Option < ( Vec < u8 > , AesKey , Vec < u8 > ) > ,
69
80
/// Decoding options
@@ -88,7 +99,7 @@ impl SecureChannel {
88
99
private_key : None ,
89
100
remote_cert : None ,
90
101
local_keys : None ,
91
- remote_keys : None ,
102
+ remote_keys : [ const { None } ; STORED_REMOTE_KEYS ] ,
92
103
decoding_options : DecodingOptions :: default ( ) ,
93
104
}
94
105
}
@@ -121,7 +132,7 @@ impl SecureChannel {
121
132
private_key,
122
133
remote_cert : None ,
123
134
local_keys : None ,
124
- remote_keys : None ,
135
+ remote_keys : [ const { None } ; STORED_REMOTE_KEYS ] ,
125
136
decoding_options,
126
137
}
127
138
}
@@ -226,10 +237,10 @@ impl SecureChannel {
226
237
false
227
238
} else {
228
239
// Check if secure channel 75% close to expiration in which case send a renew
229
- let renew_lifetime = ( self . token_lifetime ( ) * 3 ) / 4 ;
240
+ let renew_lifetime = ( self . token_lifetime * 3 ) / 4 ;
230
241
let renew_lifetime = TimeDelta :: try_milliseconds ( renew_lifetime as i64 ) . unwrap ( ) ;
231
242
// Renew the token?
232
- DateTime :: now ( ) - self . token_created_at ( ) > renew_lifetime
243
+ DateTime :: now ( ) - self . token_created_at > renew_lifetime
233
244
}
234
245
}
235
246
@@ -356,7 +367,7 @@ impl SecureChannel {
356
367
/// are used to secure Messages sent by the Server.
357
368
///
358
369
pub fn derive_keys ( & mut self ) {
359
- self . remote_keys = Some (
370
+ self . insert_remote_keys (
360
371
self . security_policy
361
372
. make_secure_channel_keys ( & self . local_nonce , & self . remote_nonce ) ,
362
373
) ;
@@ -366,7 +377,10 @@ impl SecureChannel {
366
377
) ;
367
378
trace ! ( "Remote nonce = {:?}" , self . remote_nonce) ;
368
379
trace ! ( "Local nonce = {:?}" , self . local_nonce) ;
369
- trace ! ( "Derived remote keys = {:?}" , self . remote_keys) ;
380
+ trace ! (
381
+ "Derived remote keys = {:?}" ,
382
+ self . get_remote_keys( self . token_id)
383
+ ) ;
370
384
trace ! ( "Derived local keys = {:?}" , self . local_keys) ;
371
385
}
372
386
@@ -739,11 +753,20 @@ impl SecureChannel {
739
753
encrypted_range
740
754
) ;
741
755
756
+ let SecurityHeader :: Symmetric ( security_header) = security_header else {
757
+ error ! (
758
+ "Expected symmetric security header, got {:?}" ,
759
+ security_header
760
+ ) ;
761
+ return Err ( StatusCode :: BadUnexpectedError ) ;
762
+ } ;
763
+
742
764
let mut decrypted_data = vec ! [ 0u8 ; message_size] ;
743
765
let decrypted_size = self . symmetric_decrypt_and_verify (
744
766
src,
745
767
signed_range,
746
768
encrypted_range,
769
+ security_header. token_id ,
747
770
& mut decrypted_data,
748
771
) ?;
749
772
@@ -1048,8 +1071,18 @@ impl SecureChannel {
1048
1071
self . local_keys . as_ref ( ) . unwrap ( )
1049
1072
}
1050
1073
1051
- fn remote_keys ( & self ) -> & ( Vec < u8 > , AesKey , Vec < u8 > ) {
1052
- self . remote_keys . as_ref ( ) . unwrap ( )
1074
+ fn insert_remote_keys ( & mut self , keys : ( Vec < u8 > , AesKey , Vec < u8 > ) ) {
1075
+ self . remote_keys [ self . token_id as usize % STORED_REMOTE_KEYS ] = Some ( keys) ;
1076
+ }
1077
+
1078
+ fn get_remote_keys ( & self , token_id : u32 ) -> Result < & ( Vec < u8 > , AesKey , Vec < u8 > ) , StatusCode > {
1079
+ match self . remote_keys [ token_id as usize % STORED_REMOTE_KEYS ] {
1080
+ Some ( ref keys) => Ok ( keys) ,
1081
+ None => {
1082
+ error ! ( "No remote keys found for channel token id: {}" , token_id) ;
1083
+ Err ( StatusCode :: BadUnexpectedError )
1084
+ }
1085
+ }
1053
1086
}
1054
1087
1055
1088
fn encryption_keys ( & self ) -> ( & AesKey , & [ u8 ] ) {
@@ -1061,13 +1094,13 @@ impl SecureChannel {
1061
1094
& ( self . local_keys ( ) ) . 0
1062
1095
}
1063
1096
1064
- fn decryption_keys ( & self ) -> ( & AesKey , & [ u8 ] ) {
1065
- let keys = self . remote_keys ( ) ;
1066
- ( & keys. 1 , & keys. 2 )
1097
+ fn decryption_keys ( & self , token_id : u32 ) -> Result < ( & AesKey , & [ u8 ] ) , StatusCode > {
1098
+ let keys = self . get_remote_keys ( token_id ) ? ;
1099
+ Ok ( ( & keys. 1 , & keys. 2 ) )
1067
1100
}
1068
1101
1069
- fn verification_key ( & self ) -> & [ u8 ] {
1070
- & ( self . remote_keys ( ) ) . 0
1102
+ fn verification_key ( & self , token_id : u32 ) -> Result < & [ u8 ] , StatusCode > {
1103
+ Ok ( & ( self . get_remote_keys ( token_id ) ) ? . 0 )
1071
1104
}
1072
1105
1073
1106
/// Encode data using security. Destination buffer is expected to be same size as src and expected
@@ -1178,6 +1211,7 @@ impl SecureChannel {
1178
1211
src : & [ u8 ] ,
1179
1212
signed_range : Range < usize > ,
1180
1213
encrypted_range : Range < usize > ,
1214
+ token_id : u32 ,
1181
1215
dst : & mut [ u8 ] ,
1182
1216
) -> Result < usize , StatusCode > {
1183
1217
match self . security_mode {
@@ -1198,7 +1232,7 @@ impl SecureChannel {
1198
1232
signed_range,
1199
1233
signed_range. end
1200
1234
) ;
1201
- let verification_key = self . verification_key ( ) ;
1235
+ let verification_key = self . verification_key ( token_id ) ? ;
1202
1236
self . security_policy . symmetric_verify_signature (
1203
1237
verification_key,
1204
1238
& dst[ signed_range. clone ( ) ] ,
@@ -1222,7 +1256,7 @@ impl SecureChannel {
1222
1256
1223
1257
// Decrypt encrypted portion
1224
1258
let mut decrypted_tmp = vec ! [ 0u8 ; ciphertext_size + 16 ] ; // tmp includes +16 for blocksize
1225
- let ( key, iv) = self . decryption_keys ( ) ;
1259
+ let ( key, iv) = self . decryption_keys ( token_id ) ? ;
1226
1260
1227
1261
trace ! (
1228
1262
"Secure decrypt called with encrypted range {:?}" ,
@@ -1250,7 +1284,7 @@ impl SecureChannel {
1250
1284
signed_range,
1251
1285
signature_range
1252
1286
) ;
1253
- let verification_key = self . verification_key ( ) ;
1287
+ let verification_key = self . verification_key ( token_id ) ? ;
1254
1288
self . security_policy . symmetric_verify_signature (
1255
1289
verification_key,
1256
1290
& dst[ signed_range] ,
0 commit comments