Closed d-rothe closed 6 years ago
Hi,
Thanks for the issue and suggested fixes. In practice this is more of a missing feature than maybe a direct bug, as receiving certificate chains to my knowledge is not supported at all at the moment. Also at least personally I have not been aware of any server that would actually try to send one (they would send the last of the chain and clients are expected to have all middle->root steps).
Even the option to actually receive more than a single certificate is quite hidden in the spec, as most req/res and data structures only mention "ApplicationInstanceCertificate", which is a single ByteString of the certificate, without any references to chains. I remember reading somewhere that it should be possible to append the chain within the ByteString, but I'm currently unable to find the exact spec location where this is mentioned.
So there are 2 issues:
Hi, the spec has a very general statement about certificate chains, saying that in every place where a certificate is provided as a ByteString, one may also provide a chain, appending issuer certificates. In most cases, providing the full chain will be the best way to handle certificates. In 1.04 Part 6, 6.2.3 Certificate Chains it says: "applications have the option of including a partial or complete chain whenever they pass a Certificate to a peer during the SecureChannel negotiation and during the CreateSession/ActivateSession handshake. All OPC UA applications shall accept partial or complete chains in any field that contains a DER encoded Certificate." Therefore, the client must be able to distinguish between certificates and chains. In my case, the issue appears because the C++ UA server provides a certificate chain, and the client takes it as a simple certificate, leading to the incorrect thumbprint. The fix that I posted just handles the thumbprint calculation. But I a agree that full support of certificate chains is another issue, which would indeed be a great improvement.
It would seem that spec part is added only in 1.04 (Part 6, 6.2.3). However there is a small mention in 1.03 in Part 6 section 6.7.2 Table 27.
The included fix in 1.3.344 handles only thumbprint calculation correctly, cert chains will be handled in a separate, future, issue.
Hi, I found a problem in the Java stack which prevents secured communication between a java-based client and a c++-based server (in my case). The problem appears only when certificate chains are used, like in the case of CA-signed certificates obtained from a GDS.
My java test client uses the OPC Foundation Java Stack version 1.3.343. My reference server creates an application certificate with sha256RSA signature. If I use the Java test client to connect to my reference server which has a self-signed certificate, establishing an encrypted connection works. However, after I use the OPC Foundation GDS to exchange the server certificate by one signed by a CA, connecting no longer works.
When the clients sends the OpenSecureChannel request (Frame 139 in wireshark file connect-certfailure3.pcapng), the server responds with Bad_CertificateInvalid. This error is shown in the client, as
The reason for the failure is also found in the wireshark log: Frame 139 OpenSecureChannel Message (client to server): ReceiverCertificateThumbprint: af00aa9711c28ee2ba053bdffa45dcc74cb6240a (hex) However, the correct thumbprint of the server certificate is (in my case) 74 64 eb 0b cc 76 96 14 6e 87 0f d2 2f 57 3b 78 7c c7 4a 34 (hex).
This thumbprint is not saved inside the certificate. Instead, it is calculated by the certificate viewing tool. I find that this thumbprint is shown by the Windows certificate info tool as well as by openssl, using the command
So the thumbprint calculated by the UA C++ SDK (which is set up to use openssl) seems to be correct, and the thumbprint calculated by the OPC Foundation Java Stack is wrong in this case, and that the UA SDK needs to deny the connection since it receives an incorrect thumbprint from the java client.
The Java Stack implements the relevant thumbprint handling in the class org.opcfoundation.ua.transport.security.Cert. The thumbprint is calculated as SHA-1 hash in the function
org.opcfoundation.ua.utils.CertificateUtils.createThumbprint(byte[])
and is stored in the field Cert.encodedCertificateThumbprint.
In my case, using Eclipse debugger on the test client, I find that
byte[] serverencodedCertificateThumbprint = [-81, 0, -86, -105, 17, -62, -114, -30, -70, 5, 59, -33, -6, 69, -36, -57, 76, -74, 36, 10] (dec) = [ af, 00, aa, 97, 11, c2, 8e, e2, ba, 05,3b, df, fa, 45, dc, c7, 4c, b6, 24, 0a ] (hex)
By debugging the OPC Foundation Java Stack, I found following problem. The thumbprint is sometimes incorrectly calculated as SHA-1 hash over the certificate chain instead of just the certificate - see commented code below, which fixes the issue.
connect-certfailure3b.zip