RabbitMQ Client TLS Peer Verification Failure when providing CA Cert

788 views
Skip to first unread message

ir.ta...@gmail.com

unread,
Nov 5, 2017, 7:16:15 PM11/5/17
to rabbitmq-users
Hi 

We enabled peer verification for rabbitmq ( server 3.6.1 erlang OTP 18.2.1 )  however we kept getting this exception. Googling suggested we should upgrade erlang.

RabbitMQ Exception RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The message received was unexpected or badly formatted
   --- End of inner exception stack trace ---
   at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, Func`2 selector)
   at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
   --- End of inner exception stack trace ---
   at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
   at RabbitMQ.Client.ConnectionFactory.CreateConnection()
   at TestTls.Program.Main(String[] args) in c:\users\thivankaa\documents\visual studio 2017\Projects\TestTls\TestTls\Program.cs:line 44
RabbitMQ Exception System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The message received was unexpected or badly formatted
   --- End of inner exception stack trace ---
   at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, Func`2 selector)

We eventually realised after much trial and error that this error thrown when we provided the CA cert that is used to sign the server certificate, for server certificate validation.

         Console.ReadLine();
         
ConnectionFactory factory = new ConnectionFactory();
         factory
.HostName = "localhost";
         factory
.Port = 5671;
         factory
.UserName = "guest";
         factory
.Password = "guest";
         factory
.Ssl.Enabled = true;
         factory
.Ssl.AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateChainErrors; // work around RemoteCertificateChainErrors
         factory
.Ssl.CertPath = "keycert.p12";
         factory
.Ssl.CertPassphrase = "passphrase";
         factory
.Ssl.ServerName = "Test";
         
// This code segment results in the SSPI Error
         
//factory.Ssl.Certs = new X509CertificateCollection( new[]
         
//{
         
//   X509Certificate.CreateFromCertFile("cacert.cer" ),
         
//} );
         
try
         
{
           
IConnection conn = factory.CreateConnection();
           
Console.WriteLine( conn.IsOpen );
         
}
         
catch (Exception ex)
         
{
           
while (ex != null)
           
{
               
Console.WriteLine( "RabbitMQ Exception " + ex.Message );
               ex
= ex.InnerException;
           
}
         
}
         
Console.ReadLine();
     
}

We want to pass in the default ca, cert because we want TLS connections to work without manually adding the CA Cert to the trusted root authorities in the OS. 

Other rabbitmq clients allow you to pass in the CA which is used to verify the server certificate. Is there a way we can do this for the .net client?

ir.ta...@gmail.com

unread,
Nov 5, 2017, 7:20:57 PM11/5/17
to rabbitmq-users
Edit:
I think factory.Ssl.Certs is a list of client certs. I assumed the argument was to list ca certs used to verify the server certificates. 
Message has been deleted
Message has been deleted
Message has been deleted

Michael Klishin

unread,
Nov 6, 2017, 11:33:44 AM11/6/17
to rabbitm...@googlegroups.com
And the right thing to do (if you have control over this at all) usually is to add your CAs to the list of trusted
certificates on the peer's end.

But overriding the policy in the client can work just fine, I just think it's a workaround and not how PKI/certificate management
were meant to be set up.

On Mon, Nov 6, 2017 at 5:14 AM, <ir.ta...@gmail.com> wrote:

         factory
.Ssl.CertificateValidationCallback = ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) =>
         
{
           
if (sslPolicyErrors == SslPolicyErrors.None)
               
return true;
           
if (chain == null)
               
return false;
            X509Certificate2 cert2
= new X509Certificate2( certificate );
            X509Certificate2 signerCert2
= new X509Certificate2( "cacert.pem");
            chain
.ChainPolicy.ExtraStore.Add( signerCert2 );
            chain
.Build( cert2 );
           
return chain.ChainStatus.All( chainStatus => chainStatus.Status == X509ChainStatusFlags.NoError || chainStatus.Status == X509ChainStatusFlags.UntrustedRoot);
         
};

Hi I resolved the problem by implementing the CertificateValidation callback, we add our custom ( untrustedCA ) to the list of ca certs used to verify the server cert. Note this cert is still an untrustedRootCA because has not been added to the list of trusted ca's in your OS. 

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
MK

Staff Software Engineer, Pivotal/RabbitMQ

ir.ta...@gmail.com

unread,
Nov 8, 2017, 10:22:08 PM11/8/17
to rabbitmq-users
Hi Michael 

I agree, it's a work around but we did not want manual steps for the default certs. 
The code I provided earlier is vulnerable to MITM attacks.
It would be safer to discard the provided chain and re-build the whole thing from the client. 

         factory
.Ssl.CertificateValidationCallback = ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors ) =>
         
{
            if (sslPolicyErrors == SslPolicyErrors.None)
               
return true;

            
chain = new X509Chain();

            X509Certificate2 cert2 = new X509Certificate2( certificate );
            X509Certificate2 signerCert2 
= new X509Certificate2( "cacert.pem");
            chain
.ChainPolicy.ExtraStore.Add( signerCert2 );
            chain
.Build( cert2 );
            
return chain.ChainStatus.All( chainStatus => chainStatus.Status == X509ChainStatusFlags.NoError || chainStatus.Status == X509ChainStatusFlags.UntrustedRoot);
         
};
// note our custom ca is still considered an untrusted root because it has not be added to the trusted CA list. Partial chains are not accepted. 
// wont work if there are intermediate certs. 

After we did the above, the peer verification still failed. We found out it was caused by erlang 19.1 https://bugs.erlang.org/browse/ERL-259

Thankfully, the fix is compiled into byte code so we built erlang 19.1.1 in linux and patch the sll lib in windows :) 

Michael Klishin

unread,
Nov 9, 2017, 5:51:37 AM11/9/17
to rabbitm...@googlegroups.com
Why not go straight to 19.3.6.3 or even 20.x? :)

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ir.ta...@gmail.com

unread,
Nov 16, 2017, 5:41:53 PM11/16/17
to rabbitmq-users
It will break the possibility of doing an incremental upgrade :) 

Michael Klishin

unread,
Nov 17, 2017, 2:55:14 PM11/17/17
to rabbitm...@googlegroups.com
Fair enough.

On Thu, Nov 16, 2017 at 10:41 PM, <ir.ta...@gmail.com> wrote:
It will break the possibility of doing an incremental upgrade :) 

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages