I am working on a website that exposes an xml gateway that clients can submit an xml request to and get an xml response in return. The website/company has been purchased by a larger organization and has been migrated into their infrastructure. The existing production site is using an ssl certificate by a particular certificate authority but the larger organization uses certificates issued by a different certificate authority. We have tried run a test with one of their clients and they are getting an SSL handshake error. The original developer says that the only way to get it to work is to restore the original SSL certificate and not to use the new ones. I am looking for some guidance or direction to diagnose this issue, so any help would be appreciated.
What the developer says, from the description is sensible to me, but the problem is theirs.
To verify that this is exactly what is happening you can do a wireshark capture and then decode the flow as SSL. If the problem is that the client do not trust the certificate send by the server and reject the connection you will see it in the handshake in the wireshark.
If you use a java client you could run it with -Djavax.net.debug=ssl to see the ssl messages from within java.
If this is indeed the problem then you must configure the client's truststore to have the certificate send by the server (which is the original one).
If this configuration is possible of course... This depends on the application
UPDATE:
Well if you migrated to a new CA, i.e. you deploy a new certificate in your interface, then sorry to say, it is "your" -meaning the server side- error.
IMHO, if it is possible, you should redeploy the old certificate for a prespecified period, communicating to all the stakeholders that you plan to migrate to a new certificate signed by a new CA, so that the clients don't break
Then it is their responsibility, within that period, to "fix" their client apps to be able to accept the new certificate. This can be as simple as configuration i.e. importing the certificate to a truststore, to as "complicated" as to change code and rebuild the client app (e.g. if the new issued certificate does not have extensions that the code is verifying or the CN has changed etc).
If it is not possible to redeploy the old certificate then, you just have to communicate the change to all stakeholders and then, they should "fix" it accordingly (as mentioned above)
Related
(This is for a new project, so I'm still considering options.)
I've got a server and client (phone app) communicating via gRPC, and now I'm looking into securing that connection. A common recommendation I see is to just use a self-signed server key, and embed the server's certificate directly within the client. This lets the app trust the server without requiring a cert download or third party CAs.
However, my understanding is that these certificates are only good for a year (per the openssl command to generate them). Wouldn't there be a problem in trying to renew the cert, when the old version is directly embedded in the client? I don't see how you could prepare the client for the new cert either, as both server and client would have to use the same cert for every request, right?
Given how often I see this method suggested, how do you get around the expiration problem?
Situation: we can't update der file on the client's device. And the SSL certificate on our web server expires soon.
Is it possible to renew the server's SSL certificate without replacing the client's certificate?
We want to follow this guide: https://www.smashingmagazine.com/how-to-issue-a-new-ssl-certificate-with-an-old-ssl-key/
However, we are not sure if it helps.
The question is:
Does the der file (on the client side) contain only public key and it is safe to renew SSL certificate using the technique described in the link above (keeping same pub/private keys).
Will it work on client's device without replacing der file? Or der file contains not only the public key for SSL certificate but also some other information?
I'm afraid, but based on your original post and clarifications, client will expect from web server the same server certificate as stored in DER file on client device. Client performs exact binary copy comparison (not only public keys).
Any attempts to replace server certificate will result in a connection failure on client. If you plan to replace the certificate on web server, you will have to update client devices as well.
Unfortunately, there are a lot of flawed HPKP implementations (to be honest, didn't see any reliable implementation) that work fine until server certificate is changed. In order to properly handle server certificate replacement, client MUST be able to store at least two server certificates, existing and new one. Here is the high-level server certificate replacement process:
acquire new server certificate from CA in advance.
make application update by including new certificate side-by-side. When client updates the application on their device, client app will trust both, existing and new certificate.
give clients a time to make app update on their devices. Ideally, you should wait until all clients have updated app version with updated certificate.
change SSL certificate in server bindings.
after aa time you can make another update for client certificate by removing expired certificate from trust store.
only this step sequence may guarantee uninterrupted certificate pinning renewal.
I'm have an application deployed to salesforce on the force.com platform,
which I'm trying to configure a 2 way SSL for.
I.e.
I want that for each request sent to from SF to my server, a client certificate will be sent.
I did the necessary configurations on SF for the certificate to be sent, but I'm still getting 403.7 from the server, which means: forbidden, client certificate required.
I installed wireshark on the server, captured traffic to see the 2 way ssl handshake, and I'm trying to find in the server hello message where it tells the client the trusted CAs from which a client certificate should correspond, but I'm having difficulties finding it.
I suspect that's why the client does not send the certificate.
Can anyone point me to where in the server hello I should look? Or perhaps in another packet capture?
Thanks in advance.
Client Key Exchange record:
Here, the server sends its Certificate Request message and the client sends its Certificate message in response, but that message contains 0 certificates.
Typically, this happens when the client was unable to select a client certificate to use. Either it's not configured properly to make use of any certificate, or it can't find one that is issued by one of the acceptable CAs.
Look at the Certificate Request packet and check its certificate_authorities list. This is a list of the CA Distinguished Names (DNs) that the server is willing to accept.
One way or another, the client will need to find a client certificate with which it can build a chain towards of those DNs. In the simplest case, a client certificate issued by such a DN is available. Otherwise, the client could have to build a chain from a client cert to such a DN, it would need to have the necessary intermediate CA certificates to do so. (How this is done depends on the client's configuration mechanisms.)
If intermediate CA certificates are necessary and not available on the client side, you may need to configure your server to accept them and advertise them in the Certificate Request too.
Added a screenshot of the handshake captures. can you please point me to where I should be looking? –
See packet #31. It contains the Certificate Request. Also packet #33 contains the certificate from the client, so the reason is not the client does not send the certificate, but instead that the server either does not like the certificate because the validation failed or because the certificate is not sufficient as authorization for the requested resource. You might get more information from the servers log.
Not sure if this will help anyone else, but for our case of this issue everything was working when running locally in Visual Studio and in IIS, but when deployed to a real server, we were hitting a certificate issue during 2-way SSL as described above and verified in Wireshark.
Anyway, on that server we have also have a .NET 4.7.2 Console application which was calling the same API and everything was working fine.
But, our .NET 4.7.2 web API calls were failing. It appears that when the same code was running inside IIS the cert was not available during the SSL negotiation. (although it loaded fine)
Our solution at this point was to modify the following call to include the 3rd parameter.
certificate = new X509Certificate2(certificatepath, Password, X509KeyStorageFlags.MachineKeySet);
By default X509Certificate2 uses the UserKeySet option, so perhaps the application pool user or another thread in IIS (?) was having trouble accessing the cert for the negotiation.
Here are a couple of the related pages that I found useful during my research:
https://paulstovell.com/x509certificate2/
https://github.com/dotnet/runtime/issues/23437
Currently I am having a problem connecting to the server due to the following issue:
When I tried to connect to the server, it returned an error: MQRC_SSL_INITIALIZATION_ERROR
Upon closer analysis via WireShark, I found that the Client is attempting to connect to the server using SSL v2, while the server can only accept SSL V3, thus rejecting the connection.
I checked through the document, but am not able to find any information on
what SSL version the .Net client supports.
I would like to check whether the SSL version is controlled from the .Net MQ
client, and if so, how can we configure to make it connect via SSL v3?
Thanks.
I'm not sure I agree with your conclusion since WMQ has supported SSL V3.0 and TLS V1.0 since at least V6.0 and possibly earlier. This is more likely a mismatch of configurations between the client and server. The procedure I recommend to resolve SSL/TLS issues is as follows:
My method for debugging SSL connections on WMQ is to progress through the following sequence making sure each step works before advancing to the next:
Get the channel running without SSL. This validates that the channel names are spelled correctly, that a network route exists between the endpoints, that the QMgr's listener is running and that the client points to the right port. You'd be surprised how many times someone mis-keys a port or channel name.
Get the channel running with the SVRCONN definition set to SSLCAUTH(OPTIONAL). This performs an anonymous SSL connection similar to what your browser does. The QMgr presents a certificate to the client but the client is not obligated to send one back. This validates that the QMgr can find its certificate and that the client can find its trust store and properly validates the QMgr's cert. (Note: the QMgr will always request the client cert and the client will always send it if one is present. To perform this test, use a copy of the client's keystore that has the signer cert(s) but not the application's personal cert. Copy the keystore and delete the personal cert from the copy. Do NOT delete the original!)
Set the SVRCONN channel to SSLCAUTH(REQUIRED). This now requires the client to find its keystore (in the last step it required only its trust store) and to be able to find its certificate. It also requires the QMgr to be able to validate the client's cert.
Set up SSLPEER or CHLAUTH mapping rules to narrow the population of validated certificates that will be accepted on the channel.
The difference between steps #2 and #3 helps to isolate the problem by testing the SSL credential exchange in only one direction at a time. This allows you to identify whether the problem exists in the personal cert or the public cert and on which side of the channel. Nearly all problems are sorted out in these two steps.
UPDATE
Notes to respond to questions. There are two types of certificate used with SSL/TLS. The personal certificate contains the private key and is the one that doesn't get passed around. The public certificate is the one that contains the public key and can be given out freely. The private key is held in a keystore. The public keys (usually these are the CA's root and intermediate certs) are stored in a trust store. In some cases, these are separate files. For example, in Java and JMS the JSSE provider looks in the environment for variables that point to the keystore and to the trust store. It is possible in Java and JMS that the keystore and trust store variables point to the same file.
In the case of WebSphere MQ servers and clients other than Java, the keystore and trust store are combined into a single location. Often referred to as a kdb file, it is actually a CMS key database comprised of several files of which one is the KDB. In this case "keystore" is actually shorthand for a combined keystore and trust store. For the .Net client, set the keystore location and other SSL properties in the MQEnviornment.
In the SSL/TLS handshake, the server always sends its public certificate in response to a connections request. The client then must validate that certificate by first checking the signature and validity date, then looking in its trust store for the thing that signed the certificate. If the thing that signed the certificate is an intermediate signer cert (it has itself been signed by something) then the search continues up the signer cert chain until the root cert is reached. Assuming that the server is authenticated, the same procedure is applied in reverse by having the client present a cert and the server validating it.
When the process fails in Step #2 we can debug using knowledge of the process above. The QMgr must first find its cert in its keystore and present it to the client. If the QMgr cannot find its cert, the result is errors in the AMQERR01.LOG file stating this. Always look on the QMgr side first when things die in Step #2!
If the QMgr does find its cert then the next step is that client must be able to find its trust store and then within that trust store must find the necessary signer cert chain. If this fails, there should be errors on the client side to indicate that. For example, a common error when setting the client environment is to specify the entire file name, including the .kdb extension. When this happens the QMgr looks for [keystorename].kdb.kdb which doesn't exist. Another common error is that the personal certificate exists in the keystore but with the wrong label. Non-Java WMQ clients look for the certificate by label name constructed from the literal string ibmwebspheremq followed by the user ID in lower case. For example, if my user ID is TRob then my certificate label would be ibmwebspheremqtrob. Note that this is the certificate's label in the keystore and NOT the certificates Common Name or other field in the Distinguished Name.
Depending on the type of client in use, these may be in the Windows error log, local MQ error logs or other location. If you can't find client-side errors, WMQ tracing is also an option.
I have a WCF Server Deployed through IIS. I want to Create a Certificate for it. I could do this by making the server a certificate server.
But then when the client connects to that server I want the client to automatically trust the certificate without having to register that the server as a "trusted authority".
Is this possible?
All this seems a lot of work to put username password protection on a WCF Service!
The short answer is no the client will need to add the server cert root as a trusted authority.
The slightly longer answer is that there is a workaround for needing to implement transport security in WCF when using message based authentication - this workaround is usually used when you want to rely upon another security mechanism that the WCF server is not aware of, like an ISA server providing SSL.
Have a look at Yaron Naveh's post. The essential idea is that you create a transport binding that pretends that it is secure.
With all that, you still need security (you don't want to send your creds in the clear) and so will still need a trust chain for your cert. So, it may not actually help you, but hopefully it gives you some options to consider.
Edit
Sorry if my answer was misleading. The server certificate root cert must by in the client trusted store. My additional detail was giving another option for providing the security (you can use an ISA server with a trusted cert to give your SSL connection)
In a similar situation to yours (needing secure communication when pushing client applicaitons to non technical customers) I have programatically installed the needed root certs.
Here is an SO post that details how to do that: How can I install a certificate into the local machine store programmatically using c#?
You can if you add this to your code but be aware of what you are doing!
System.Net.ServicePointManager.ServerCertificateValidationCallback += ( se, cert, chain, sslerror ) => { return true; };
Well if there would be such a way, it would be a security hole.
If a certificate is not linked to a trusted authority it is easily forged. So your choice is either to link it one way or another (directly or through a parent certificate you control), or configure your client so that it does not require the certificate i.e. using http rather than https.
Just keep in mind that it leaves your clients open to a variety of attacks
Edit
One of the possible attack scenarios is a man in the middle attack - a program inserts itself between your service and the client and channels the information though itself. This way the intruder has complete control over the information flow.
It can make copies of passwords or it can "adjust" the results in both directions any way it wants. The only thing which prevents this from happening is the certificates. But if they are not rooted, they can be forged.