Search code examples
dockeropenshiftibm-mq

How to refer to the certificate from windows certificate store for MQ managed client in docker image?


I am trying to connect to MQ using MQ managed client which refers to the certificate from certificate store. I have created the docker image for the code and now wondering how to push the certificate along with it.

End goal is to deploy the image to the openshift pod.

Hashtable properties = new Hashtable();
properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
properties.Add(MQC.HOST_NAME_PROPERTY, "XXXXXXXXXXXX");
properties.Add(MQC.PORT_PROPERTY, "XXXX");
properties.Add(MQC.CHANNEL_PROPERTY, "XXXXX");

//SSL
properties.Add(MQC.SSL_CERT_STORE_PROPERTY, "*USER");
properties.Add(MQC.SSL_CIPHER_SPEC_PROPERTY, "TLS_RSA_WITH_AES_256_CBC_SHA256");
properties.Add(MQC.SSL_PEER_NAME_PROPERTY,"XXXXXX");
properties.Add(MQC.SSL_RESET_COUNT_PROPERTY, 0);

queueManager = new MQQueueManager(QueueManagerName, properties);

The code is working fine directly without any issues but I am not aware of how to proceed with docker image.

UPDATE-1 Client Logs: SSL Server Certificate validation failed -

RemoteCertificateNameMismatch, RemoteCertificateChainErrors
0000016A 08:51:43.609321   54.1       ------------}  MQEncryptedSocket.ClientValidatingServerCertificate(Object,X509Certificate,X509Chain,SslPolicyErrors) rc=OK
0000016B 08:51:43.610594   54.1        System.Security.Authentication.AuthenticationException: The remote certificate was rejected by the provided RemoteCertificateValidationCallback.
   at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception)
   at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
   at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
   at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   at IBM.WMQ.Nmqi.MQEncryptedSocket.MakeSecuredConnection()
0000016C 08:51:43.610655   54.1       -----------}  MQEncryptedSocket.MakeSecuredConnection() rc=OK
0000016D 08:51:43.610803   54.1        System.Security.Authentication.AuthenticationException: The remote certificate was rejected by the provided RemoteCertificateValidationCallback.
   at IBM.WMQ.Nmqi.MQEncryptedSocket.MakeSecuredConnection()
   at IBM.WMQ.Nmqi.MQEncryptedSocket..ctor(NmqiEnvironment env, MQTCPConnection conn, Socket socket, MQChannelDefinition mqcd, MQSSLConfigOptions sslConfigOptions)
   at IBM.WMQ.MQTCPConnection.ConnectSocket(String localAddr, String connectionName, Int32 options) 

Solution

  • Finally, I was able to resolve the issue with the below steps:

    1. Add the root CA and sub CA certs to the CA certificate folder of the container and run the update-ca-certificates. (Make sure you copy all the CA and intermediate certificates to the ca-certificates folder)
    docker cp "<<CertLocation>>\<<CertName>>.crt" <<ContainerName>>:/usr/local/share/ca-certificates/<<CertName>>.crt
    update-ca-certificates --fresh --verbose
    
    1. Install the certificate used for SSL authentication of MQ to the personal store of the Current User using the below code.
    private static void InstallCertificate(string cerFileName, string friendlyName)
            {
                X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                store.Open(OpenFlags.ReadOnly);
                try
                {
                    X509Certificate2 certificate = new X509Certificate2(cerFileName, "<<CertificatePassword>>");
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !string.IsNullOrEmpty(friendlyName))
                    {
                        certificate.FriendlyName = friendlyName;
                    }
                    store.Open(OpenFlags.ReadWrite);
                    store.Add(certificate);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error in adding cert: {ex.Message}");
                }
                store.Close();
            }
    
    1. Update the cipherstring in the container to match with the required Cipherstring for the MQ. In my case it was TLS_RSA_WITH_AES_256_CBC_SHA256
    /etc/ssl/openssl.cnf
    CipherString = AES256-SHA256
    

    Thanks @JoshMc for providing the helpful links. Hope this helps!