FreeOpcUa / opcua-asyncio

OPC UA library for python >= 3.7
GNU Lesser General Public License v3.0
1.13k stars 362 forks source link

"The user identity token is not valid."(BadIdentityTokenInvalid) #742

Closed floriandorre closed 2 years ago

floriandorre commented 2 years ago

Describe the bug

I am trying to connect to a SIMATIC WinCC Open Architecture Version 3.17 serve that only accepts encrypted connection using certificate. Even after moving the certificate in the certs folder i get an BadIdentityTokenInvalid.

To Reproduce
Unfortunately I was not able to reproduce the bug with a Prosys OPC UA Simulator. But the steps to reproduce are the following ones :

Expected behavior
Successful connection once the certs is trusted

Version
Python-Version: 3.7.6
opcua-asyncio Version : asyncua==0.9.92

I would appreciate any help or hints about where i need to look at to see what is causing this Bad Identity

AndreasHeine commented 2 years ago

IdentityTokenInvalid is not related to Encryption. it is related to the Authentication (Anonymus, Username, Certificate)!

floriandorre commented 2 years ago

But is there a way to know what part of my certificate is not "valid" ?

FYI: I can connect using UA expert but not with the python client

import asyncio
import logging

from asyncua import Client
from asyncua.crypto.security_policies import SecurityPolicyBasic256Sha256

logging.basicConfig(level=logging.INFO)
_logger = logging.getLogger("asyncua")

cert = f"cert.der"
private_key = f"cert.key.pem"

async def task(loop):
    url = "opc.tcp://192.168.100.20:4840/"
    client = Client(url=url)
    await client.set_security(
        policy=SecurityPolicyBasic256Sha256,
        certificate=cert,
        private_key=private_key,
        # server_certificate="server.der"
    )
    await client.load_client_certificate(cert)
    await client.load_private_key(private_key)

    client.application_uri = "urn:192.168.200.60:python:asyncua"
    client.product_uri = "urn:python:asyncua"

    async with client:
        print(client.name)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.set_debug(True)
    loop.run_until_complete(task(loop))
    loop.close()
AndreasHeine commented 2 years ago

This is for UserAuth:

    await client.load_client_certificate(cert)
    await client.load_private_key(private_key)

Did you use Certificate Authentication?

floriandorre commented 2 years ago

Yes i do use Certificate Authentication, is this not the right methods to use for certificate auth ?

AndreasHeine commented 2 years ago

i am just asking! then it could be something with the cert itself... is it a valid x509v3 with subject altname extension which matches your ip and applicationUri?

floriandorre commented 2 years ago

Here is the output of my certificate :

openssl x509 -noout -text -in cert.pem


Certificate:
Data:
Version: 3 (0x2)
Serial Number:
29:99:70:2a:81:72:ab:62:0c:1f:81:4f:f7:90:c7:e3:e7:02:da:57
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = LU, L = Roeser, O = RTC4Water
Validity
Not Before: Dec  3 13:22:36 2021 GMT
Not After : Dec  3 13:22:36 2022 GMT
Subject: C = LU, L = Roeser, O = RTC4Water
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:be:92:e7:1a:f4:85:28:8c:c0:df:cd:78:22:07:
13:12:64:de:3a:01:93:11:ff:7c:07:8f:2a:33:f8:
2d:be:6f:d2:0c:59:2d:7f:8d:ff:8f:41:87:68:e9:
f7:8e:0c:1d:79:2e:c6:75:89:34:de:40:c6:66:0d:
af:e0:3c:d9:c2:46:ce:0d:7a:54:7b:54:76:67:55:
c0:96:1b:fd:89:f7:6a:d6:c3:a1:b6:4d:4e:ff:bc:
0a:19:34:ab:98:7e:8a:0f:eb:cc:f7:25:ee:69:d4:
74:e8:7e:21:77:9e:ef:45:b0:6a:88:38:4e:73:14:
ba:6c:0b:48:68:50:83:9d:e2:c0:ac:b0:04:65:7e:
63:94:b1:ee:d7:a0:27:53:d2:05:ce:f7:43:0c:45:
a5:27:a1:2d:78:1b:b3:a7:fc:76:7f:c2:40:57:16:
88:43:f2:45:30:1c:23:23:d0:34:c5:ea:bf:d7:4c:
13:e0:8c:72:34:32:18:b0:41:65:a0:dc:23:a7:87:
9e:0e:95:42:61:96:04:d3:c4:93:2b:1c:d1:35:4c:
51:60:d2:b7:25:86:4e:73:87:a7:ed:ad:37:97:ae:
1e:af:f6:16:c6:d5:cc:cd:23:3a:12:a7:92:49:81:
19:4d:aa:4a:9e:86:ca:17:a4:5e:09:27:5a:67:a4:
b0:a3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Client, SSL Server
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Certificate Sign
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Netscape Comment:
GPC Cert
X509v3 Subject Key Identifier:
CB:93:D2:69:70:B9:1C:8C:B9:6D:66:71:A0:84:24:ED:85:9C:7E:0C
X509v3 Authority Key Identifier:
keyid:CB:93:D2:69:70:B9:1C:8C:B9:6D:66:71:A0:84:24:ED:85:9C:7E:0C
        X509v3 Subject Alternative Name:
            URI:urn:192.168.200.60:python:asyncua, IP Address:192.168.200.60, DNS:RTC4WATER-FDO
Signature Algorithm: sha256WithRSAEncryption
     58:f5:9a:ee:9a:fc:e4:40:bd:e2:cd:98:58:cb:56:6e:b9:e2:
     74:3b:46:14:0c:fa:bd:8e:e0:53:33:2b:a4:da:bd:19:3e:30:
     3d:79:6a:d2:89:dd:ea:dc:22:6a:5a:62:3b:4d:0e:cc:36:e1:
     b2:d6:b6:a2:04:c6:af:fd:92:62:19:ad:53:5e:2f:10:71:30:
     69:3c:91:57:1d:27:8a:12:19:fc:57:a9:cb:94:0e:73:61:a3:
     7c:d2:17:b6:d1:1f:84:b1:50:30:74:76:29:5b:0d:12:0a:b8:
     c6:75:36:59:24:98:90:98:3b:50:0f:f2:f4:72:72:97:fa:e1:
     79:59:0e:4b:a0:02:28:c6:b3:ee:f1:31:2f:3d:1e:9a:db:8c:
     0e:ad:b2:92:4e:cc:6c:68:5b:b0:9a:6c:49:1b:e5:25:25:00:
     3d:05:5a:89:ca:0c:81:1d:fb:08:be:51:74:1f:c5:f3:ab:59:
     7c:22:4e:dd:44:be:90:73:44:2a:4f:60:f8:41:5b:57:19:6d:
     f4:f4:4f:38:6a:85:f1:89:2c:9f:7b:1f:d3:05:cd:ff:a6:eb:
     2f:9d:15:94:2e:5e:b6:d9:55:35:6a:0d:17:2f:b2:4b:12:50:
     50:c0:0e:b0:d4:7f:9e:bd:6e:bd:b6:ef:0a:cb:c5:16:da:a9:
     fb:a7:7b:a2
floriandorre commented 2 years ago

The thing that i don't really understand is what would be the difference between UA Expert and the python interface.

With UA Expert when I use both key and cert file everything is fine once i move the generated cert from rejected to certs but for some reason the process is not the same with the python client

AndreasHeine commented 2 years ago

have you compared the certs if you open both?

floriandorre commented 2 years ago

Here it is

diff --git a/mpython_cert.txt b/mua_expert_cert.txt
index add884d..236c433 100644
--- a/mpython_cert.txt
+++ b/mua_expert_cert.txt
@@ -1,68 +1,67 @@
 Certificate:
     Data:
         Version: 3 (0x2)
-        Serial Number:
-            29:99:70:2a:81:72:ab:62:0c:1f:81:4f:f7:90:c7:e3:e7:02:da:57
+        Serial Number: 1638285578 (0x61a6410a)
         Signature Algorithm: sha256WithRSAEncryption
-        Issuer: C = LU, L = Roeser, O = RTC4Water
+        Issuer: O = RTC, CN = UaExpert@RTC4WATER-FDO
         Validity
-            Not Before: Dec  3 13:22:36 2021 GMT
-            Not After : Dec  3 13:22:36 2022 GMT
-        Subject: C = LU, L = Roeser, O = RTC4Water
+            Not Before: Nov 30 15:19:38 2021 GMT
+            Not After : Nov 29 15:19:38 2026 GMT
+        Subject: O = RTC, CN = UaExpert@RTC4WATER-FDO
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 RSA Public-Key: (2048 bit)
                 Modulus:
-                    00:be:92:e7:1a:f4:85:28:8c:c0:df:cd:78:22:07:
-                    13:12:64:de:3a:01:93:11:ff:7c:07:8f:2a:33:f8:
-                    2d:be:6f:d2:0c:59:2d:7f:8d:ff:8f:41:87:68:e9:
-                    f7:8e:0c:1d:79:2e:c6:75:89:34:de:40:c6:66:0d:
-                    af:e0:3c:d9:c2:46:ce:0d:7a:54:7b:54:76:67:55:
-                    c0:96:1b:fd:89:f7:6a:d6:c3:a1:b6:4d:4e:ff:bc:
-                    0a:19:34:ab:98:7e:8a:0f:eb:cc:f7:25:ee:69:d4:
-                    74:e8:7e:21:77:9e:ef:45:b0:6a:88:38:4e:73:14:
-                    ba:6c:0b:48:68:50:83:9d:e2:c0:ac:b0:04:65:7e:
-                    63:94:b1:ee:d7:a0:27:53:d2:05:ce:f7:43:0c:45:
-                    a5:27:a1:2d:78:1b:b3:a7:fc:76:7f:c2:40:57:16:
-                    88:43:f2:45:30:1c:23:23:d0:34:c5:ea:bf:d7:4c:
-                    13:e0:8c:72:34:32:18:b0:41:65:a0:dc:23:a7:87:
-                    9e:0e:95:42:61:96:04:d3:c4:93:2b:1c:d1:35:4c:
-                    51:60:d2:b7:25:86:4e:73:87:a7:ed:ad:37:97:ae:
-                    1e:af:f6:16:c6:d5:cc:cd:23:3a:12:a7:92:49:81:
-                    19:4d:aa:4a:9e:86:ca:17:a4:5e:09:27:5a:67:a4:
-                    b0:a3
+                    00:bd:1c:d3:fd:92:66:bc:1e:eb:df:7a:48:ee:cb:
+                    8d:9f:6a:75:a9:5c:cb:c6:49:d3:cf:d2:ed:05:c0:
+                    8e:8e:21:b2:c3:4e:9d:ed:5b:9d:1c:22:74:08:0b:
+                    44:52:a0:6a:86:24:a9:05:45:3a:48:d3:f1:00:26:
+                    a0:1d:98:18:9f:03:ae:8a:f7:a8:37:b8:1a:7c:e0:
+                    ea:00:bc:6b:aa:8c:94:be:70:22:e2:a6:06:f2:45:
+                    56:6c:a9:96:6d:2b:70:c3:77:26:cb:f7:20:7c:1d:
+                    d8:22:fd:41:0c:d4:2a:74:39:af:73:61:7d:c4:4b:
+                    0c:2f:29:08:5e:80:aa:f9:02:e4:a4:40:b8:a4:9b:
+                    b0:fe:68:da:9a:da:c0:a5:42:74:78:ca:01:03:0c:
+                    ab:71:43:34:da:72:50:12:6a:d2:b7:9b:bf:2f:7a:
+                    3b:48:7d:af:bc:43:13:8d:92:96:5d:36:4d:bc:5f:
+                    28:f1:19:ad:d6:02:a7:12:92:8d:a7:f6:04:24:eb:
+                    28:bc:33:8e:bf:e2:f0:f8:f4:26:9d:5f:08:c6:05:
+                    29:bc:b7:bc:ba:26:64:04:d3:3c:64:24:f6:9b:d0:
+                    5f:9f:4f:54:5f:1a:b8:a6:b8:2a:ae:24:fc:40:2a:
+                    44:3e:a7:aa:25:6c:9a:cc:25:25:df:e3:17:af:b2:
+                    8a:73
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
-            X509v3 Basic Constraints: 
+            X509v3 Basic Constraints: critical
                 CA:FALSE
-            Netscape Cert Type: 
-                SSL Client, SSL Server
-            X509v3 Key Usage: 
-                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Certificate Sign
-            X509v3 Extended Key Usage: 
-                TLS Web Server Authentication, TLS Web Client Authentication
             Netscape Comment: 
-                GPC Cert
+                "Generated with Unified Automation UA Base Library using OpenSSL"
             X509v3 Subject Key Identifier: 
-                CB:93:D2:69:70:B9:1C:8C:B9:6D:66:71:A0:84:24:ED:85:9C:7E:0C
+                57:54:DC:08:66:7D:3F:56:59:4E:4A:AF:DB:52:55:58:A9:D5:94:4A
             X509v3 Authority Key Identifier: 
-                keyid:CB:93:D2:69:70:B9:1C:8C:B9:6D:66:71:A0:84:24:ED:85:9C:7E:0C
+                keyid:57:54:DC:08:66:7D:3F:56:59:4E:4A:AF:DB:52:55:58:A9:D5:94:4A
+                DirName:/O=RTC/CN=UaExpert@RTC4WATER-FDO
+                serial:61:A6:41:0A

+            X509v3 Key Usage: critical
+                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Certificate Sign
+            X509v3 Extended Key Usage: critical
+                TLS Web Server Authentication, TLS Web Client Authentication
             X509v3 Subject Alternative Name: 
-                URI:urn:192.168.200.60:python:asyncua, IP Address:192.168.200.60, DNS:RTC4WATER-FDO
+                URI:urn:RTC4WATER-FDO:UnifiedAutomation:UaExpert, DNS:RTC4WATER-FDO
     Signature Algorithm: sha256WithRSAEncryption
-         58:f5:9a:ee:9a:fc:e4:40:bd:e2:cd:98:58:cb:56:6e:b9:e2:
-         74:3b:46:14:0c:fa:bd:8e:e0:53:33:2b:a4:da:bd:19:3e:30:
-         3d:79:6a:d2:89:dd:ea:dc:22:6a:5a:62:3b:4d:0e:cc:36:e1:
-         b2:d6:b6:a2:04:c6:af:fd:92:62:19:ad:53:5e:2f:10:71:30:
-         69:3c:91:57:1d:27:8a:12:19:fc:57:a9:cb:94:0e:73:61:a3:
-         7c:d2:17:b6:d1:1f:84:b1:50:30:74:76:29:5b:0d:12:0a:b8:
-         c6:75:36:59:24:98:90:98:3b:50:0f:f2:f4:72:72:97:fa:e1:
-         79:59:0e:4b:a0:02:28:c6:b3:ee:f1:31:2f:3d:1e:9a:db:8c:
-         0e:ad:b2:92:4e:cc:6c:68:5b:b0:9a:6c:49:1b:e5:25:25:00:
-         3d:05:5a:89:ca:0c:81:1d:fb:08:be:51:74:1f:c5:f3:ab:59:
-         7c:22:4e:dd:44:be:90:73:44:2a:4f:60:f8:41:5b:57:19:6d:
-         f4:f4:4f:38:6a:85:f1:89:2c:9f:7b:1f:d3:05:cd:ff:a6:eb:
-         2f:9d:15:94:2e:5e:b6:d9:55:35:6a:0d:17:2f:b2:4b:12:50:
-         50:c0:0e:b0:d4:7f:9e:bd:6e:bd:b6:ef:0a:cb:c5:16:da:a9:
-         fb:a7:7b:a2
+         8d:d1:0e:e1:4a:2d:2f:46:bc:5d:a7:96:42:9b:0b:f1:49:1e:
+         0f:f7:a9:b3:95:06:b2:e6:33:99:21:fb:5d:e6:30:d7:f0:d7:
+         32:c8:cd:25:06:7f:06:cc:b1:fd:28:8f:ec:03:03:bd:3b:e1:
+         6d:f2:a4:d8:a0:72:4e:04:f3:77:52:f4:9e:d0:44:1f:1a:83:
+         ad:f0:fb:f6:e6:2d:e3:24:57:0e:66:b7:10:13:35:32:80:43:
+         7f:10:96:87:4c:ee:ba:50:0d:29:18:12:3b:7f:4a:39:bd:39:
+         9a:05:f6:1a:ad:4c:0a:2e:c1:8d:25:05:19:ab:75:18:29:1a:
+         00:03:92:5c:ce:3d:24:8e:ac:b4:de:dd:17:66:69:be:2a:e4:
+         78:5d:1a:bc:32:c1:3d:a8:43:c0:d8:91:4a:73:ae:a1:1f:0c:
+         e3:6a:12:f2:c8:89:c6:f2:a0:f9:3c:cf:64:7f:99:be:01:86:
+         d6:a6:42:ba:2d:89:d8:c1:c0:13:63:b6:3b:47:7c:0d:ea:3f:
+         95:2f:47:99:f4:40:42:88:48:69:2a:5e:92:d4:f1:2b:7b:e5:
+         bd:65:df:16:44:33:fd:d3:16:b2:0f:a1:c5:1a:bd:7e:b3:ad:
+         4a:4b:55:b3:8e:49:19:35:d4:b3:32:2a:43:56:8b:e3:9d:d5:
+         af:a5:d9:19
floriandorre commented 2 years ago

I did try to connect using a different client (Nodejs from https://github.com/node-opcua/node-opcua but it seems that the way it works is different. With the node client is get 2 certificate generated after each rejection (one that is the client certificate that i generate and the second one that is one generated by the node opcua client certificate utilities), if I remove one of the 2 then the connection is not working anymore.

But with a normal client (like UA Expert) i only need 1 certificate to make the connection works so I am a little bit confused about how this certificate sending works from the client side

floriandorre commented 2 years ago

This issue has been solved and was just a miss-usage of the certifcates. I was using the same certificate for both MessageSecurity and Auth.

https://github.com/FreeOpcUa/python-opcua/issues/1422#issuecomment-993489969

luyi1678 commented 2 years ago

I got the same error but I didn't use certificates, the sever is a simulation created with B&R Automation Studio, which I can connect via UaExpert. I already set the security policy to "No security" and allow anonymous access. Here's my code for your reference:

`from queue import PriorityQueue import time

from opcua import Client, ua

class SubHandler(object): def datachange_notification(self, node, val, data): print("Python: New data change event", node, val, data)

client = Client('opc.tcp://127.0.0.1:4841/', timeout=10) client.set_user('Anonymous') client.set_password('') client.connect()`

The port number is 4841 because the sever is just a simulation.

AndreasHeine commented 2 years ago

@luyi1678 why do you set a user?

luyi1678 commented 2 years ago

@luyi1678 why do you set a user? Thanks, I can now connect to the server after I commented out "set_user" and "set_password". I set it just because the UserRoleSystem in B&R has such a class named "Anonymous", I thought it might need to set as the same.