FreeOpcUa / python-opcua

LGPL Pure Python OPC-UA Client and Server
http://freeopcua.github.io/
GNU Lesser General Public License v3.0
1.36k stars 658 forks source link

connect to server with security result in BadCertificateUriInvalid #633

Open SummerSeaSun opened 6 years ago

SummerSeaSun commented 6 years ago

I'm trying to connect with security to a server, but getting this error. The same connection without security works fine.

Maybe I'm wrong but I believe the problem is that certificate got the name of the server not it's ip. But from the UA expert the same settings works fine. I'm over the network so I need to call the server by its IP address not by name.

In [7]: client = Client("opc.tcp://directipaddress:62841/ciccio/bello")
   ...: client.set_security_string("Basic256,Sign,/path/uaexpert.der,/path/uaexpert_key.pem")

In [8]: client.connect()
/home/tec1/.virtualenvs/x/lib/python3.5/site-packages/opcua/crypto/uacrypto.py:48: CryptographyDeprecationWarning: signer and verifier have been deprecated. Please use sign and verify instead.
  hashes.SHA1()
/home/tec1/.virtualenvs/x/lib/python3.5/site-packages/opcua/crypto/uacrypto.py:58: CryptographyDeprecationWarning: signer and verifier have been deprecated. Please use sign and verify instead.
  hashes.SHA1())
---------------------------------------------------------------------------
BadCertificateUriInvalid                  Traceback (most recent call last)
<ipython-input-8-be08c18772f3> in <module>()
----> 1 client.connect()

/home/tec1/.virtualenvs/x/lib/python3.5/site-packages/opcua/client/client.py in connect(self)
    253             self.send_hello()
    254             self.open_secure_channel()
--> 255             self.create_session()
    256         except Exception:
    257             self.disconnect_socket()  # clean up open socket

/home/tec1/.virtualenvs/x/lib/python3.5/site-packages/opcua/client/client.py in create_session(self)
    371         params.RequestedSessionTimeout = 3600000
    372         params.MaxResponseMessageSize = 0  # means no max size
--> 373         response = self.uaclient.create_session(params)
    374         if self.security_policy.client_certificate is None:
    375             data = nonce

/home/tec1/.virtualenvs/x/lib/python3.5/site-packages/opcua/client/ua_client.py in create_session(self, parameters)
    246         request = ua.CreateSessionRequest()
    247         request.Parameters = parameters
--> 248         data = self._uasocket.send_request(request)
    249         response = struct_from_binary(ua.CreateSessionResponse, data)
    250         self.logger.debug(response)

/home/tec1/.virtualenvs/x/lib/python3.5/site-packages/opcua/client/ua_client.py in send_request(self, request, callback, timeout, message_type)
     76         if not callback:
     77             data = future.result(self.timeout)
---> 78             self.check_answer(data, " in response to " + request.__class__.__name__)
     79             return data
     80 

/home/tec1/.virtualenvs/x/lib/python3.5/site-packages/opcua/client/ua_client.py in check_answer(self, data, context)
     85             self.logger.warning("ServiceFault from server received %s", context)
     86             hdr = struct_from_binary(ua.ResponseHeader, data)
---> 87             hdr.ServiceResult.check()
     88             return False
     89         return True

/home/tec1/.virtualenvs/x/lib/python3.5/site-packages/opcua/ua/uatypes.py in check(self)
    233         """
    234         if not self.is_good():
--> 235             raise UaStatusCodeError(self.value)
    236 
    237     def is_good(self):

BadCertificateUriInvalid: The URI specified in the ApplicationDescription does not match the URI in the certificate.(BadCertificateUriInvalid)
oroulet commented 6 years ago

you can set the application uri in client object and you can do whatever you want with your certificate. That should solve it....in worst case use wiresharck to see all packets back and forth

mikelga commented 5 years ago

Hello! I think that I have a similar problem. I want to communicate with the UaServerC++ (from Unified Automation) OPC-UA server with Basic256Sha256 and SignAndEncrypt. Without any security it let me connect properly: image image

But, then, when I add set_security_string it gives me a The URI specified in the ApplicationDescription does not match the URI in the certificate.(BadCertificateUriInvalid) error. I proved properly with same certificates files in UaExpert client, without any errors. image image

It's the problem that I have to set the application uri in client object? If the response is yes, how can I do this?

Thank you very much,

mikelga commented 5 years ago

@oroulet Sorry for not mentioning you in the previous message

jitbasemartin commented 5 years ago

Take a look here https://github.com/FreeOpcUa/python-opcua/issues/778#issuecomment-454133568 Specially the "Note" part

nobodyman1 commented 5 years ago

I did the same thing: I used the certificates from UA Expert Client. The solution is quite simple:

By the way there is no need to use client.load_client_certificate() and client.load_private_key() if you use function client.set_security_string().

mikelga commented 5 years ago

Hi @nobodyman1 ! Do you know any way to authenticate de user using certificates? Some certificates different to those used in the security settings. I want to use certificates to authenticate (instead of anonimously or username/password). Thanks!

nobodyman1 commented 5 years ago

Hi @mikelga! I don´t know because I´m connecting to a Siemens PLC S7-1500 which (as far as I know) doesn´t support certificates for user authentication only username and password or anonymous. But if I take a look at the documentation https://python-opcua.readthedocs.io/en/latest/client.html I think the functions you are using (load_client_certificate(path) and load_private_key(path)) are correct.