-
Notifications
You must be signed in to change notification settings - Fork 23
Description
If the Client receives a OpenSecureChannelResponse, immediatly followed by a chunk encrypted under the new token, it leads to a race condition on the decryption keys, because it is not guaranteed that the new keys for the new Security Token will be derived, before attempting do decode further chunks.
Which leads to the error BadSecureChannelClosed: Missing decryption keys
As seen in the attached logs:
2025-11-17T15:25:07.725691Z TRACE opcua_core::comms::chunker: Received chunk with sequence number 788
2025-11-17T15:25:07.725779Z INFO decode{secure_channel=SecureChannel { role: Client, security_policy: Basic256Sha256, security_mode: SignAndEncrypt, secure_channel_id: 920869287, token_created_at: DateTime { date_time: 2025-11-17T15:21:21.031915600Z }, token_lifetime: 300000, token_id: 3, ..., remote_keys: {3: RemoteKeys { ... }, 2: RemoteKeys { ... } }, local_keys: Some( ... ), encoding_context: RwLock { ... }, ,expected_node_id=None}: opcua_core::comms::chunker: new
-
Decoded chunk with OpenSecureChannelResponse:
2025-11-17T15:25:07.725889Z INFO decode{secure_channel=SecureChannel { role: Client, security_policy: Basic256Sha256, security_mode: SignAndEncrypt, secure_channel_id: 920869287, token_created_at: DateTime { date_time: 2025-11-17T15:21:21.031915600Z }, token_lifetime: 300000, token_id: 3, ..., remote_keys: {3: RemoteKeys { ... }, 2: RemoteKeys { ... } }, local_keys: Some( ... ), encoding_context: RwLock { ... }, ,expected_node_id=None}: opcua_core::comms::chunker: return=OpenSecureChannel(OpenSecureChannelResponse { response_header: ResponseHeader { timestamp: DateTime { date_time: 2025-11-17T15:25:07.757915600Z }, request_handle: 790, service_result: Good (0), service_diagnostics: DiagnosticInfo { symbolic_id: None, namespace_uri: None, locale: None, localized_text: None, additional_info: None, inner_status_code: None, inner_diagnostic_info: None }, string_table: Some([]), additional_header: ExtensionObject { body: None } }, server_protocol_version: 0, security_token: ChannelSecurityToken { channel_id: 920869287, token_id: 4, created_at: DateTime { date_time: 2025-11-17T15:25:07.757915600Z }, revised_lifetime: 300000 }, server_nonce: ByteString { value: Some([226, 205, 69, 51, 62, 134, 70, 122, 248, 68, 245, 172, 47, 42, 65, 7, 170, 16, 49, 62, 232, 232, 91, 65, 61, 177, 12, 186, 49, 63, 238, 4]) } })
2025-11-17T15:25:07.725959Z INFO decode{secure_channel=SecureChannel { role: Client, security_policy: Basic256Sha256, security_mode: SignAndEncrypt, secure_channel_id: 920869287, token_created_at: DateTime { date_time: 2025-11-17T15:21:21.031915600Z }, token_lifetime: 300000, token_id: 3, ..., remote_keys: {3: RemoteKeys { ... }, 2: RemoteKeys { ... } }, local_keys: Some( ... ), encoding_context: RwLock { ... }, ,expected_node_id=None}: opcua_core::comms::chunker: close time.busy=138µs time.idle=43.2µs -
Missing (derive keys etc. for new security token)
-
Tries to decrypt following block, who was encrypted with the new Keys (token_id:4):
2025-11-17T15:25:07.726099Z TRACE opcua_core::comms::secure_channel: Decrypting block with signature info 0..272 and encrypt info 16..304
2025-11-17T15:25:07.726121Z TRACE opcua_core::comms::secure_channel: Got Security Header: SymmetricSecurityHeader { token_id: 4 }
2025-11-17T15:25:07.726140Z INFO opcua_core::comms::secure_channel: Get Keys for: 4
2025-11-17T15:25:07.726201Z ERROR opcua_types::encoding: BadSecureChannelClosed: Missing decryption keys
2025-11-17T15:25:07.726250Z WARN opcua_client::session::event_loop: session:1 Transport disconnected: BadSecureChannelClosed
Complete logs:
2025-11-17T15:25:07.725691Z TRACE opcua_core::comms::chunker: Received chunk with sequence number 788
2025-11-17T15:25:07.725779Z INFO decode{secure_channel=SecureChannel { role: Client, security_policy: Basic256Sha256, security_mode: SignAndEncrypt, secure_channel_id: 920869287, token_created_at: DateTime { date_time: 2025-11-17T15:21:21.031915600Z }, token_lifetime: 300000, token_id: 3, cert: Some([x509]), private_key: Some([pkey]), remote_cert: Some([x509]), remote_nonce: [159, 188, 189, 221, 23, 139, 35, 90, 219, 213, 159, 179, 205, 215, 107, 0, 238, 8, 195, 204, 118, 222, 18, 4, 162, 12, 158, 233, 255, 57, 217, 206], local_nonce: [189, 158, 228, 76, 104, 99, 60, 15, 214, 168, 36, 2, 207, 218, 116, 155, 91, 84, 212, 250, 33, 107, 22, 250, 28, 9, 182, 114, 125, 163, 128, 168], remote_keys: {3: RemoteKeys { keys: ([70, 226, 74, 127, 123, 137, 75, 206, 163, 30, 88, 152, 186, 143, 86, 162, 20, 237, 10, 64, 238, 248, 174, 33, 102, 235, 189, 48, 193, 212, 138, 95], AesKey { value: [212, 146, 187, 164, 3, 119, 2, 36, 138, 224, 65, 121, 215, 53, 17, 181, 239, 253, 129, 189, 224, 97, 198, 55, 170, 197, 17, 228, 51, 218, 182, 146], security_policy: Basic256Sha256 }, [92, 142, 89, 94, 175, 175, 39, 232, 11, 222, 37, 202, 26, 92, 41, 160]), expires_at: DateTime { date_time: 2025-11-17T15:27:36.031915600Z } }, 2: RemoteKeys { keys: ([10, 234, 63, 77, 42, 110, 59, 161, 72, 26, 102, 132, 116, 124, 229, 136, 146, 101, 27, 187, 6, 247, 49, 211, 75, 250, 206, 20, 177, 4, 162, 199], AesKey { value: [92, 232, 250, 22, 242, 157, 58, 81, 57, 191, 193, 40, 126, 19, 40, 251, 243, 106, 148, 82, 215, 33, 208, 173, 49, 247, 106, 128, 144, 160, 186, 33], security_policy: Basic256Sha256 }, [142, 203, 154, 6, 99, 224, 235, 174, 218, 160, 13, 27, 94, 85, 104, 94]), expires_at: DateTime { date_time: 2025-11-17T15:23:48.989015Z } }}, local_keys: Some(([22, 206, 86, 98, 169, 224, 171, 59, 37, 86, 31, 247, 13, 18, 153, 61, 155, 81, 245, 81, 97, 14, 212, 10, 42, 177, 247, 79, 36, 0, 91, 46], AesKey { value: [174, 28, 153, 249, 108, 239, 120, 50, 74, 196, 157, 97, 68, 41, 177, 181, 98, 241, 101, 241, 193, 87, 43, 135, 203, 145, 9, 134, 240, 35, 228, 15], security_policy: Basic256Sha256 }, [186, 224, 1, 26, 115, 84, 18, 59, 105, 155, 144, 140, 107, 94, 192, 112])), encoding_context: RwLock { data: ContextOwned { namespaces: NamespaceMap { known_namespaces: {"http://opcfoundation.org/UA/": 0} }, options: DecodingOptions { client_offset: TimeDelta { secs: -9, nanos: 16084400 }, max_message_size: 327675, max_chunk_count: 5, max_string_length: 65535, max_byte_string_length: 65535, max_array_length: 1000, decoding_depth_gauge: DepthGauge { max_depth: 10, current_depth: 0 } } } } } expected_node_id=None}: opcua_core::comms::chunker: new
2025-11-17T15:25:07.725889Z INFO decode{secure_channel=SecureChannel { role: Client, security_policy: Basic256Sha256, security_mode: SignAndEncrypt, secure_channel_id: 920869287, token_created_at: DateTime { date_time: 2025-11-17T15:21:21.031915600Z }, token_lifetime: 300000, token_id: 3, cert: Some([x509]), private_key: Some([pkey]), remote_cert: Some([x509]), remote_nonce: [159, 188, 189, 221, 23, 139, 35, 90, 219, 213, 159, 179, 205, 215, 107, 0, 238, 8, 195, 204, 118, 222, 18, 4, 162, 12, 158, 233, 255, 57, 217, 206], local_nonce: [189, 158, 228, 76, 104, 99, 60, 15, 214, 168, 36, 2, 207, 218, 116, 155, 91, 84, 212, 250, 33, 107, 22, 250, 28, 9, 182, 114, 125, 163, 128, 168], remote_keys: {3: RemoteKeys { keys: ([70, 226, 74, 127, 123, 137, 75, 206, 163, 30, 88, 152, 186, 143, 86, 162, 20, 237, 10, 64, 238, 248, 174, 33, 102, 235, 189, 48, 193, 212, 138, 95], AesKey { value: [212, 146, 187, 164, 3, 119, 2, 36, 138, 224, 65, 121, 215, 53, 17, 181, 239, 253, 129, 189, 224, 97, 198, 55, 170, 197, 17, 228, 51, 218, 182, 146], security_policy: Basic256Sha256 }, [92, 142, 89, 94, 175, 175, 39, 232, 11, 222, 37, 202, 26, 92, 41, 160]), expires_at: DateTime { date_time: 2025-11-17T15:27:36.031915600Z } }, 2: RemoteKeys { keys: ([10, 234, 63, 77, 42, 110, 59, 161, 72, 26, 102, 132, 116, 124, 229, 136, 146, 101, 27, 187, 6, 247, 49, 211, 75, 250, 206, 20, 177, 4, 162, 199], AesKey { value: [92, 232, 250, 22, 242, 157, 58, 81, 57, 191, 193, 40, 126, 19, 40, 251, 243, 106, 148, 82, 215, 33, 208, 173, 49, 247, 106, 128, 144, 160, 186, 33], security_policy: Basic256Sha256 }, [142, 203, 154, 6, 99, 224, 235, 174, 218, 160, 13, 27, 94, 85, 104, 94]), expires_at: DateTime { date_time: 2025-11-17T15:23:48.989015Z } }}, local_keys: Some(([22, 206, 86, 98, 169, 224, 171, 59, 37, 86, 31, 247, 13, 18, 153, 61, 155, 81, 245, 81, 97, 14, 212, 10, 42, 177, 247, 79, 36, 0, 91, 46], AesKey { value: [174, 28, 153, 249, 108, 239, 120, 50, 74, 196, 157, 97, 68, 41, 177, 181, 98, 241, 101, 241, 193, 87, 43, 135, 203, 145, 9, 134, 240, 35, 228, 15], security_policy: Basic256Sha256 }, [186, 224, 1, 26, 115, 84, 18, 59, 105, 155, 144, 140, 107, 94, 192, 112])), encoding_context: RwLock { data: ContextOwned { namespaces: NamespaceMap { known_namespaces: {"http://opcfoundation.org/UA/": 0} }, options: DecodingOptions { client_offset: TimeDelta { secs: -9, nanos: 16084400 }, max_message_size: 327675, max_chunk_count: 5, max_string_length: 65535, max_byte_string_length: 65535, max_array_length: 1000, decoding_depth_gauge: DepthGauge { max_depth: 10, current_depth: 0 } } } } } expected_node_id=None}: opcua_core::comms::chunker: return=OpenSecureChannel(OpenSecureChannelResponse { response_header: ResponseHeader { timestamp: DateTime { date_time: 2025-11-17T15:25:07.757915600Z }, request_handle: 790, service_result: Good (0), service_diagnostics: DiagnosticInfo { symbolic_id: None, namespace_uri: None, locale: None, localized_text: None, additional_info: None, inner_status_code: None, inner_diagnostic_info: None }, string_table: Some([]), additional_header: ExtensionObject { body: None } }, server_protocol_version: 0, security_token: ChannelSecurityToken { channel_id: 920869287, token_id: 4, created_at: DateTime { date_time: 2025-11-17T15:25:07.757915600Z }, revised_lifetime: 300000 }, server_nonce: ByteString { value: Some([226, 205, 69, 51, 62, 134, 70, 122, 248, 68, 245, 172, 47, 42, 65, 7, 170, 16, 49, 62, 232, 232, 91, 65, 61, 177, 12, 186, 49, 63, 238, 4]) } })
2025-11-17T15:25:07.725959Z INFO decode{secure_channel=SecureChannel { role: Client, security_policy: Basic256Sha256, security_mode: SignAndEncrypt, secure_channel_id: 920869287, token_created_at: DateTime { date_time: 2025-11-17T15:21:21.031915600Z }, token_lifetime: 300000, token_id: 3, cert: Some([x509]), private_key: Some([pkey]), remote_cert: Some([x509]), remote_nonce: [159, 188, 189, 221, 23, 139, 35, 90, 219, 213, 159, 179, 205, 215, 107, 0, 238, 8, 195, 204, 118, 222, 18, 4, 162, 12, 158, 233, 255, 57, 217, 206], local_nonce: [189, 158, 228, 76, 104, 99, 60, 15, 214, 168, 36, 2, 207, 218, 116, 155, 91, 84, 212, 250, 33, 107, 22, 250, 28, 9, 182, 114, 125, 163, 128, 168], remote_keys: {3: RemoteKeys { keys: ([70, 226, 74, 127, 123, 137, 75, 206, 163, 30, 88, 152, 186, 143, 86, 162, 20, 237, 10, 64, 238, 248, 174, 33, 102, 235, 189, 48, 193, 212, 138, 95], AesKey { value: [212, 146, 187, 164, 3, 119, 2, 36, 138, 224, 65, 121, 215, 53, 17, 181, 239, 253, 129, 189, 224, 97, 198, 55, 170, 197, 17, 228, 51, 218, 182, 146], security_policy: Basic256Sha256 }, [92, 142, 89, 94, 175, 175, 39, 232, 11, 222, 37, 202, 26, 92, 41, 160]), expires_at: DateTime { date_time: 2025-11-17T15:27:36.031915600Z } }, 2: RemoteKeys { keys: ([10, 234, 63, 77, 42, 110, 59, 161, 72, 26, 102, 132, 116, 124, 229, 136, 146, 101, 27, 187, 6, 247, 49, 211, 75, 250, 206, 20, 177, 4, 162, 199], AesKey { value: [92, 232, 250, 22, 242, 157, 58, 81, 57, 191, 193, 40, 126, 19, 40, 251, 243, 106, 148, 82, 215, 33, 208, 173, 49, 247, 106, 128, 144, 160, 186, 33], security_policy: Basic256Sha256 }, [142, 203, 154, 6, 99, 224, 235, 174, 218, 160, 13, 27, 94, 85, 104, 94]), expires_at: DateTime { date_time: 2025-11-17T15:23:48.989015Z } }}, local_keys: Some(([22, 206, 86, 98, 169, 224, 171, 59, 37, 86, 31, 247, 13, 18, 153, 61, 155, 81, 245, 81, 97, 14, 212, 10, 42, 177, 247, 79, 36, 0, 91, 46], AesKey { value: [174, 28, 153, 249, 108, 239, 120, 50, 74, 196, 157, 97, 68, 41, 177, 181, 98, 241, 101, 241, 193, 87, 43, 135, 203, 145, 9, 134, 240, 35, 228, 15], security_policy: Basic256Sha256 }, [186, 224, 1, 26, 115, 84, 18, 59, 105, 155, 144, 140, 107, 94, 192, 112])), encoding_context: RwLock { data: ContextOwned { namespaces: NamespaceMap { known_namespaces: {"http://opcfoundation.org/UA/": 0} }, options: DecodingOptions { client_offset: TimeDelta { secs: -9, nanos: 16084400 }, max_message_size: 327675, max_chunk_count: 5, max_string_length: 65535, max_byte_string_length: 65535, max_array_length: 1000, decoding_depth_gauge: DepthGauge { max_depth: 10, current_depth: 0 } } } } } expected_node_id=None}: opcua_core::comms::chunker: close time.busy=138µs time.idle=43.2µs
2025-11-17T15:25:07.726099Z TRACE opcua_core::comms::secure_channel: Decrypting block with signature info 0..272 and encrypt info 16..304
2025-11-17T15:25:07.726121Z TRACE opcua_core::comms::secure_channel: Got Security Header: SymmetricSecurityHeader { token_id: 4 }
2025-11-17T15:25:07.726140Z INFO opcua_core::comms::secure_channel: Get Keys for: 4
2025-11-17T15:25:07.726201Z ERROR opcua_types::encoding: BadSecureChannelClosed: Missing decryption keys
2025-11-17T15:25:07.726250Z WARN opcua_client::session::event_loop: session:1 Transport disconnected: BadSecureChannelClosed