Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to connect to a Basic256, SignAndEncrypt endpoint. #57

Closed
execuc opened this issue Jun 19, 2020 · 13 comments
Closed

Trying to connect to a Basic256, SignAndEncrypt endpoint. #57

execuc opened this issue Jun 19, 2020 · 13 comments

Comments

@execuc
Copy link

execuc commented Jun 19, 2020

Hello,

From samples/simple_client, I'm trying to connect to a Basic256,SignAndEncrypt endpoint with X509 token and client.connect_to_endpoint_id returns

ERROR - opcua_client::comms::tcp_transport - Expecting a chunk, got an error message BadSecurityChecksFailed

I think that certificate is OK because I use it with an other application.

First connection without security policy/mode seems to work because it retrieves endpoint.
Error arrives when it wants to connect to the endpoint and sends a secure channel request.
On wireshark, viewable value in frame seems to be OK and corresponds to a frame sent with an other application.

Do you have any idea what I could look at to try to find the problem ?
Thank you very much for this library.

@locka99
Copy link
Owner

locka99 commented Jun 22, 2020

Hi when you say X509 token, are you talking about as the user identity or as the certificate of your client?

It would be useful if you could set "set RUST_OPCUA_LOG=debug" so I can look at the log and see what errors you are seeing. While I do have support for X509 identity certs in the code it hasn't received a whole lot of testing and it might be caused by a configuration that I wasn't using.

Thanks

@execuc
Copy link
Author

execuc commented Jun 22, 2020

Yes I am talking about user identity using certificate. But in fact the code does not go until the creation of the token and its signature because I have the impression that it fails to create the secure channel. It is hard to debug because I do not have access to the server log.

I attach the logs where I anonymize the certificates with RUST_OPCUA_LOG=debug.
I will continue to search my problem, thank you very much.

log_conn.txt

@locka99
Copy link
Owner

locka99 commented Jun 22, 2020

Okay that sounds like it's not getting as far as activating the session. Can you check that the server and client are accepting each other's certs? Some OPCUA servers might reject a cert and put it in a rejected folder and it has to be copied out. The server might also have a log where it says why it didn't like the connection.

The client side also does a a cert check on the server the sample's client.conf sets trust_server_certs to true so it should automatically trust the server.

@execuc
Copy link
Author

execuc commented Jun 23, 2020

Thank you ! it seems works with another certificate which is also trusted by server. Sorry for inconvenience !

Now I try to simply read a variable from this string path : "ns=2;DA.ABCD.F1.FAN01.P" but I really don't know how to do it and I start with the rust in addition !

Basically I started with the simple-client sample:

if let Ok(session) = client.connect_to_endpoint_id(Some("sample_basic256")) {
    println!("OK");
    let _ = Session::run(session);
} else {
      // Loops forever. The publish thread will call the callback with changes on the variables
      println!("Errrrr");
}

In same file, there is a subscribe_to_variables which I don't understand and I can't adapt to just read a variable in a first time.
would you have an example code, please ?

Thank you very much for this opc ua library.

@locka99
Copy link
Owner

locka99 commented Jun 23, 2020

If all you want to do is read a variable, you don't need the Session::run(session) that's basically there for clients that subscribe to variables and need to run in a loop

Instead you would call something like this:

    let mut session = session.write().unwrap();

    // Read the variable
    let values = {
        let read_nodes = vec![ReadValueId::from(NodeId::new(2, "DA.ABCD.F1.FAN01.P")];
        session.read(&read_nodes).unwrap()
    };
    let value = values.remove(0).value;

@execuc
Copy link
Author

execuc commented Jun 23, 2020

Thank you for the help.
I'm sorry to bother you again but contrary to what I thought authenticate failed in my case.

When client send the x509 token (server certificate + nonce => sha1 with private_key), it waits response that it seems to receive (with wireshark) but it don't do anything.

I have attached logs where we see the response to request 3 which is not processed.
I think I'm close to the goal but i need some help again, please.

log_x509_token.txt

@execuc
Copy link
Author

execuc commented Jun 24, 2020

Hi,
Do not take into account the last message, I managed to connect and retrieve a variable! In fact, the certificate I was using was not validated for authentication. Sorry !

But I have two strange behaviors:

  • In certificate token creation, I have to manually force the security_policy with = SecurityPolicy::from_uri("http://opcfoundation.org/UA/SecurityPolicy#Basic256").

Because let policy = endpoint.find_policy(UserTokenType::Certificate); returns a NULL policy because UserTokenPolicy does not have a security_policy_uri :

 UserTokenPolicy {
                policy_id: UAString {
                    value: Some(
                        "0",
                    ),
                },
                token_type: Certificate,
                issued_token_type: UAString {
                    value: None,
                },
                issuer_endpoint_url: UAString {
                    value: None,
                },
                security_policy_uri: UAString {
                    value: None,
                },
  • I have a certificate with a 1024 key which has been validated by the server for the connection and the authentication token. But server rejects it at connection step (OPN message) with a message Could not verify security on opensecureChannel request. This certificate works with an other client at connexion step and auth step.

I have an other certificate with 2048 key which works for connection step. Could there be a problem with the 1024 keys or is it pure chance ?

Thank you.

@locka99
Copy link
Owner

locka99 commented Jun 24, 2020

Is the user token policy info coming from your server? I looked at the code for EndpointDescription::find_policy and literally all it does is look for a user token within itself with a matching UserTokenType. So it shouldn't matter that the policy id is empty or some weird value.

As for certificate length OPCUA expects Basic256 policy should allow certificates between 1024 and 2048 bits but there may be something about the certificate is invalid and it may only be obvious from looking at the logs or by inspecting the certificate itself. It may even be that the server is rejecting the certificate so look at the server's logs to see if it yields any clues.

@execuc
Copy link
Author

execuc commented Jun 24, 2020

Yes this user token policy is a print from client log of what I received from the server. I don't understand everything about protocol, that's why I'm a bit lost !

Actually I will analyze library logs and I will request the server lofs to find out what is going on.

Thank you for the time spent helping me !

@execuc
Copy link
Author

execuc commented Jun 27, 2020

Hello,

I received the server log when I try to connect with the certificate that is problematic. The server indicates it cannot verify the signature on the message.
Indeed, this same certificate works with other clients. There are the logs:
server_log.txt

Would you have some time to watch them, please ?

Out of curiosity, I looked a little at the code for "secure_channel :: asymmetric_sign_and_encrypt" and I can't understand why the padding between the body and the signature is not inserted before the call to security_policy.asymmetric_encrypt.

Thank you.

@locka99
Copy link
Owner

locka99 commented Jun 27, 2020

I can't think of any reason that a certificate would work for one client and not another but I would check the following:

  1. That you have the correct cert.der AND the matching private.pem in the pki/ folder. The public key (in the cert) and the private key must be the same key pair.
  2. That the cert is valid for the client PC, i.e. that the subject alt name starts with a URL, followed by DNS entries matching the client's IP address
  3. That all the other fields in the cert are correct, e.g. valid to & from dates,
  4. That your server is set to trust self-signed certs

@execuc
Copy link
Author

execuc commented Jul 9, 2020

Okay, thank for all the advice !
With a new certificate, it works very well !

Thank you very much

@execuc execuc closed this as completed Jul 9, 2020
@LongZoz
Copy link

LongZoz commented Nov 23, 2023

Hi, Do not take into account the last message, I managed to connect and retrieve a variable! In fact, the certificate I was using was not validated for authentication. Sorry !

But I have two strange behaviors:

  • In certificate token creation, I have to manually force the security_policy with = SecurityPolicy::from_uri("http://opcfoundation.org/UA/SecurityPolicy#Basic256").

Because let policy = endpoint.find_policy(UserTokenType::Certificate); returns a NULL policy because UserTokenPolicy does not have a security_policy_uri :

 UserTokenPolicy {
                policy_id: UAString {
                    value: Some(
                        "0",
                    ),
                },
                token_type: Certificate,
                issued_token_type: UAString {
                    value: None,
                },
                issuer_endpoint_url: UAString {
                    value: None,
                },
                security_policy_uri: UAString {
                    value: None,
                },
  • I have a certificate with a 1024 key which has been validated by the server for the connection and the authentication token. But server rejects it at connection step (OPN message) with a message Could not verify security on opensecureChannel request. This certificate works with an other client at connexion step and auth step.

I have an other certificate with 2048 key which works for connection step. Could there be a problem with the 1024 keys or is it pure chance ?

Thank you.

Hello, I am also trying to use the secretary and certificate of the client to connect to the server, it seems to use "UserTokenPolicy", I follow what you wrote is all None, the client has generated a trust certificate for the server, and the server also has a trust certificate for the client. I think the problem is with this assignment of "UserTokenPolicy".
The current client error is:
ERROR opcua::client Received a service fault of BadIdentityTokenInvalid for the request,
Error Opcua :: Client received a service fault of Badidentitytokeninvalid for the request,
ERROR opcua::client::client Got an error while creating the default session - BadIdentityTokenInvalid
The server error is:
ERROR opcua::server::services::session activate_session, invalid endpoint
ERROR opcua::server::services::session activate_session error, fault = IS_ERROR | BadIdentityTokenInvalid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants