Closed VitorKawao closed 1 year ago
Can you paste a full Wireshark capture, or try a new security mode such as Aes128Sha256RsaOaep?
If both fail, the default client certificate probably failed security checks. You can trust an untrusted certificate on the server but it still may reject due to security checks. If that happened, you can provide your own client certificate.
Hello nauful, Thank you for your reply, I don't know if I understand correctly the full WireShark, but I saved my WireShark and attached it.
The LibUa.pcapng is using Basic256Sha256, it is in my product (it is not with the latest version of LibUa).The LibUaAes128_Sha256_RsaOaep.pcapng is tested with Aes128_Sha256_RsaOaep at the Demo application (the latest version of LibUa).The UaExpert.pcapng is using UaExpert that it works with.
I forgot to ask about the second part
If both fail, the default client certificate probably failed security checks. You can trust an untrusted certificate on the server but it still may reject due to security checks. If that happened, you can provide your own client certificate.
Both failed, so I need to try to provide my own certificate, sorry for the question, but how do I do it? I am creating the .pem and .der like almost the demo, exchanging for my data.
This doesn't look like a library issue, so I closed the issue but we can keep looking at your configuration.
Instructions for generating .pem and .der with openssl: https://serverfault.com/questions/1006639/create-der-certificatekey-from-pem Do check that your server can accept the generated certficates. Default security policies usually reject self-signed certificates, so if you don't have a key from a certificate authority, you would have to figure out how to change the security configuration on your server.
Hello Nauful,
To fix the problem at OpenSecureChannel, I needed to insert some information in the cfg file of Codesys. I didn't change the certificate. But after that I have another problem, at CreateSession, it is returning StatusCode.BadUnknownResponse.
I notice that it happens with a Siemens plc that I have too. It is seems to be the same problem. I've attached the WireShark using libua + codesys, libua + siemens, uaexpert + codesys and uaexpert + siemens. WireShark.zip
With uaexpert everything works. With CodeSys I tested with SecurityPolicy.Basic256Sha256 and SecurityPolicy.Aes256_Sha256_RsaPss. With Siemens only Basic256Sha256 because it doesn't support Aes policy.
My code:
var appDesc = new ApplicationDescription("urn:DemoApplication", "uri:DemoApplication", new LocalizedText("UA SDK client"), ApplicationType.Client, null, null, null);
//Siemens
//var client = new DemoClient("192.168.1.160", 4840, 1000);
//CodeSys
var client = new DemoClient("192.168.1.111", 4840, 1000);
var messageSecurityMode = MessageSecurityMode.SignAndEncrypt;
var securityPolicy = SecurityPolicy.Basic256Sha256;
bool useAnonymousUser = true;
ApplicationDescription[] appDescs = null;
EndpointDescription[] endpointDescs = null;
client.Connect();
client.OpenSecureChannel(MessageSecurityMode.None, SecurityPolicy.None, null);
client.FindServers(out appDescs, new[] { "en" });
client.GetEndpoints(out endpointDescs, new[] { "en" });
client.Disconnect();
// Will fail if no matching message security mode and security policy is found
var endpointDesc = endpointDescs.First(e => e.SecurityMode == messageSecurityMode && e.SecurityPolicyUri == Types.SLSecurityPolicyUris[(int)securityPolicy]);byte[] serverCert = endpointDesc.ServerCertificate;
var connectRes = client.Connect();
var openRes = client.OpenSecureChannel(messageSecurityMode, securityPolicy, serverCert);
if(openRes != StatusCode.Good)
return;
var createRes = client.CreateSession(appDesc, "urn:DemoApplication", 120);
if (createRes != StatusCode.Good)
{
//Enter Here
return;
}
Thank you for your help, Vítor Guedes
Can you try using the latest version? There is a nonce bug in previous versions which might affect this. Not sure what else could be the problem.
I am already using the latest version.
Sorry, I don't know what else could be wrong. You would have to debug through the Connect method to see what failed. I suspect something in the encryption method is failing to encode or decode but I don't know exactly what.
Apparently the connection is successful, at least the SandHello is good, and at MemoryBufferExtensions and Encoding classes nothing returns false. Maybe it is encoding some wrong information or missing some field, but I can't see what is wrong with it.
At the response of CreateSession it is not returning RequestCode.CreateSessionResponse, it is returning RequestCode.ServiceFault. As it is sending RequestCode.CreateSessionRequest at the message I suposing that I am sending something wrong or missing something
That means that no received message could be matched with CreateSessionRequest, mostly likely due to decryption failure. I'm not sure what would be causing that if there are no other errors.
Hello Nauful, I have a question for you, do you know if libua works with any Siemens plc or CodeSys with sign and encrypt (Basic256Sha256)? Or is there a problem with my configuration?
If you would like to test on these plcs I can provide you access to them.
Thank you
Basic256Sha256 is old. I added support for Aes128Sha256RsaOaep and Aes256Sha256RsaPss to replace the older methods which were causing problems with PLCs in recent issues here.
You might have to debug the client locally, not sure what else I can do.
I tested the CodeSys locally with Aes128Sha256RsaOaep and Aes256Sha256RsaPss, but it has the same error.
I could not teste my Siemens plc because it does not have these security mode.
Thanks for all your help Nauful
I haven't been able to reproduce this with any system I have but another user might have one. I will update here if I make any progress there.
Let me know if you have any software server which I can use to reproduce.
Hello, CodeSys could be downloaded at https://store.codesys.com/en/. I added the installer at google drive too, https://drive.google.com/file/d/15r5xlJw2EzQNCcWLW8GxGQ4ZndAOjsnX/view?usp=share_link
But If you prefer I can give you access to my vpn then you can access my CodeSys or my Siemens plc (it only has old security mode).
Thank you
I attached a document that specify how to use CodeSys as Opc Ua Server
Thanks, will take a look when I get time to work on this.
I've installed and set up with these settings:
However I don't see any security mode options:
Did I miss a step?
Hello Nauful,
To save changes of security, follow the steps:
Thanks, I can now connect and send a user/pass. It looks like the trouble is with encrypting the user identification token and the SignatureAlgorithmRsaOaep
signature isn't acceptable for this specific server:
Will investigate in more detail.
Using the latest code and a user (username admin-plc
, password 123
), I am able to connect:
var appDesc = new ApplicationDescription(
"urn:DemoApplication", "uri:DemoApplication", new LocalizedText("UA SDK client"),
ApplicationType.Client, null, null, null);
var client = new DemoClient("127.0.0.1", 4840, 1000);
var messageSecurityMode = MessageSecurityMode.SignAndEncrypt;
var securityPolicy = SecurityPolicy.Aes256_Sha256_RsaPss;
bool useAnonymousUser = false;
ApplicationDescription[] appDescs = null;
EndpointDescription[] endpointDescs = null;
client.Connect();
client.OpenSecureChannel(MessageSecurityMode.None, SecurityPolicy.None, null);
client.FindServers(out appDescs, new[] { "en" });
client.GetEndpoints(out endpointDescs, new[] { "en" });
client.Disconnect();
// Will fail if no matching message security mode and security policy is found
var endpointDesc = endpointDescs.First(e =>
e.SecurityMode == messageSecurityMode &&
e.SecurityPolicyUri == Types.SLSecurityPolicyUris[(int)securityPolicy]);
byte[] serverCert = endpointDesc.ServerCertificate;
var connectRes = client.Connect();
var openRes = client.OpenSecureChannel(messageSecurityMode, securityPolicy, serverCert);
var createRes = client.CreateSession(appDesc, "urn:DemoApplication", 120);
StatusCode activateRes;
if (useAnonymousUser)
{
// Will fail if this endpoint does not allow Anonymous user tokens
string policyId = endpointDesc.UserIdentityTokens.First(e => e.TokenType == UserTokenType.Anonymous).PolicyId
activateRes = client.ActivateSession(new UserIdentityAnonymousToken(policyId), new[] { "en" });
}
else
{
// Will fail if this endpoint does not allow UserName user tokens
string policyId = endpointDesc.UserIdentityTokens.First(e => e.TokenType == UserTokenType.UserName).PolicyId;
activateRes = client.ActivateSession(
new UserIdentityUsernameToken(policyId, "admin-plc",
(new UTF8Encoding()).GetBytes("123"), Types.SignatureAlgorithmRsaOaep),
new[] { "en" });
}
Any incorrect username or password gives that service fault above (and BadUnknownResponse
). Please try this code, either by creating a user with the same login in a test environment, or substituting the username and password with your own.
Updated the library, ActivateSession
can return BadUserAccessDenied
instead of BadUnknownResponse
and specific responses for other calls.
Hello Nauful, Thanks a lot. I downloaded the new code and tested it with the demo. It works correctly.
Now I'll update my application, but It will probably work too. If I have some problems, I will contact you again.
Thanks again, Vítor Guedes
Let me know how it goes, and feel free to let me know if you run into other issues.
By the way, if you are using this library for any projects, there is no obligation but I would be very interested in hearing where and how. I would appreciate your permission to use that information in my list of use cases. If you prefer email, my email is my username @gmail.com
Thanks.
Forgot to metion: if needed, the latest sample client can also generate better self-signed certificates now.
Forgot to metion: if needed, the latest sample client can also generate better self-signed certificates now.
Thank you.
I send a email to you, explaning our product
Hello, Sorry for bothering you again about this topic.Can you still connect at codesys? I am having some troubles and it does not connect anymore.Probably there is some configuration issue. I tried to install a new one and it does not work either.
Hello Vitor,
Yes, although I already have a VM as the result of following the steps above. Does that version with those steps still work for you? If not, you can share a new installer with me and I can set up another VM to try.
Also, can you check with the git version of code as it was on Feb 21? If something has broken in the source, I can revert that.
Thanks, Nauful
Hello Vitor,
In client.ActivateSession, please try changing the algorithm field to Types.SignatureAlgorithmRsaOaep256
:
new UserIdentityUsernameToken(policyId, "username",
(new UTF8Encoding()).GetBytes("password"), Types.SignatureAlgorithmRsaOaep256),
new[] { "en" });
That should fix one potential issue I found: UserIdentityUsernameToken
needs a different algorithm.
Thanks, Nauful
Hello Nauful,
I added the last installer of CodeSys at my drive. https://drive.google.com/file/d/1H8xypiy3xBxqAs0mU4T2oj8nJ6xYrFwQ/view?usp=sharing
I am having problem at
var openRes = client.OpenSecureChannel(messageSecurityMode, securityPolicy, serverCert);
It is returning BadInvalidArgument, so my problem is before the Activate Session.
Thank you, Vítor
Hello Vitor,
I'll install that on a new VM and take a look.
Thanks, Nauful
Hello Vitor,
On this screen I have two errors:
If I press enter to set the active path:
Scan network doesn't find anything:
How do I set up a new application?
Thanks, Nauful
Hello nauful,
To fix this error try to do this please:
Check plc version through icon tray->right click->about
In the navigation tree, right-click on the device and choose update device
Change the device to CODESYS Control Win V3 x64 - version 3.5.19.0 (should be the same version of icon tray plc)
Thanks, it works now. I'm able to reproduce, will investigate further.
I'm trying to enable the following config option:
Which file should receive this update?
It is at CODESYSControl.cfg On my pc is locates at C:\ProgramData\CODESYS\CODESYSControlWinV3x64\268E8ADF\CODESYSControl.cfg
I don't see any other error messages in the trace.
How did you make this work with the previous Codesys version?
I'm fairly sure the error is here: https://github.com/OPCFoundation/UA-LDS/blob/a5980842030791339220a03746fcc73748f0e418/stack/Stack/securechannel/opcua_securelistener.c#L1842
However I can't determine exactly what I'm missing. If you have a UA ANSI-C server with security enabled, I can step through that to debug. The only ANSI-C server I found doesn't include any security modes.
Tested with UA-LDS on Linux with the old ANSI-C stack, but this only supports up to Basic256 (no newer security modes) and uaservercpp with Basic256Sha256, didn't have any errors. I'm stuck on how to fix this.
How did you make this work with the previous Codesys version?
For a very oldCodeSys I needed to set some properties at CODESYSControl.cfg, but at the newest versions including the first one that I sent to you, I did not do anything. But It stopped working there too, I don't know why. At the latest installer that I sent to you I could never run there
I'm fairly sure the error is here: https://github.com/OPCFoundation/UA-LDS/blob/a5980842030791339220a03746fcc73748f0e418/stack/Stack/securechannel/opcua_securelistener.c#L1842
This is the official api of opc ua? Does your api use it? Maybe it is the bug there?
If you have a UA ANSI-C server with security enabled, I can step through that to debug. The only ANSI-C server I found doesn't include any security modes.
Sorry but I don't have any UA ANSI-C server with security enabled.
I'll try to convince my client to use without sign and encrypt for now. I hope he accepts it.
I understand that it is hard to fix it without a server to debug. Thanks you for all your help, Vitor Guedes
Hello Vitor,
That's one version of the ANSI C stack used for OPC UA which I believe Codesys uses. I have tested the following versions: ANSI C Stack 1.02 Release [334.5] UA-AnsiC-Legacy-master UA-AnsiC-Legacy-1.04.342 UA-.NETStandard-master UA-.NET-Legacy-master UA-LDS-master
All of these worked fine. The AnsiC servers contain the same error messages I couldn't trigger this error with my client. Tried to debug Codesys' service exe with IDA but it looks like they protect the exe so I can't find error strings to set a breakpoint. I couldn't find anything else to try.
This is where I stopped:
Thanks, Nauful
Good news! I have found a server where I can reproduce this issue and will investigate. More updates soon.
Great new!!!
Thank you
I have pushed an update. It looks like it works for Codesys, could you please test that?
I will continue to investigate.
I updated the demo and checked.
It fixed the error at
var openRes = client.OpenSecureChannel(messageSecurityMode, securityPolicy, serverCert);
But now I am having problem to ActivateSession, it returns an error: BadIdentityTokenInvalid
If I try to connect with anonymous it works perfectly.
At your test is it working with user/password?
Hello Vitor,
Please change SignatureAlgorithmRsaOaep256
to SignatureAlgorithmRsaOaep
. That makes ActivateSession
pass for me.
Thanks, Nauful
Thank you Nauful!!
It worked!!!
Hello Vitor,
Glad to hear. Let me know if anything else comes up.
I might do some clean-up in the next few days but at least Codesys is working fine now.
Thanks, Nauful
Hello Nauful, A question, how do I know which Signature Algorithm I need to use?
I have an old Siemens plc, it does not have the newest security policy so I need to connect with Basic256Sha256. Which Signature Algorithm should I use? I tried to all and I get the error BadIdentityTokenInvalid
Hello Vitor,
Can you browse the endpoints and give me a Wireshark capture of that activity? It's somewhere in EndpointDescription
, the dump will help me find that.
Thanks, Nauful
Hello,
I am having some troubles connecting to CodeSys Server with Sign or Sign & Encrypt (Basic256Sha256). If I connect with None and None it works correctly.
When I first execute it shows an error BadSecurityChecksFailed, so I go to the CodeSys Server and trust my certificate. After that, when I try to OpenSecureChannel the servers return an BadInvalidArgument. Using WireShark I can see that there is something that is null, but I do not know what I am doing wrong.
If I try to connect CodeSys with another client like UaExpert, it shows a warning.
But clicking at Ignore it works.