Archived

This forum has been archived. Please start a new discussion on GitHub.

SSL without a client cert

Hi there,

I'm trying to set up an IceSSL connection from a client to a Glacier2 instance. I've set up SSL in the Glacier2 config file as shown below and I can tell from the trace messages that SSL is properly initialized:
Ice.Plugin.IceSSL=IceSSL:createIceSSL
IceSSL.DefaultDir=/etc/mumble-server
IceSSL.CertAuthFile=ca.pem
IceSSL.CertFile=server.pem
IceSSL.KeyFile=server.key

However, when I attempt to connect to the Glacier2 instance from my client, I get the follow error:
-- 11/08/13 18:01:31.738 glacier2router: Network: attempting to accept ssl connection
   local address = xx.xx.xx.xx:65431
   remote address = xx.xx.xx.xx:34401
-! 11/08/13 18:01:31.850 glacier2router: warning: connection exception:
   TransceiverI.cpp:234: Ice::ProtocolException:
   protocol exception:
   SSL error occurred for new incoming connection:
   remote address = <not available>
   error # = 336151576
   message = error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
   location = s3_pkt.c, 1256
   data = SSL alert number 48
   xx.xx.xx.xx:65431
I'm initializing the client like so:
pProps->setProperty("IceSSL.CertAuthFile", m_caCertPath);
where 'm_caCertPath' is the absolute path to the ca.pem on the client's side. I'm not setting CertFile or KeyFile since I don't need mutual auth.

What am I doing wrong?

Comments

  • mes
    mes California
    Hi,

    By default, IceSSL requires a client to provide a certificate otherwise the connection will fail. Take a look at the description of the IceSSL.VerifyPeer property in the manual. For a situation where the client does not have a certificate, you should set IceSSL.VerifyPeer=1 in the Glacier2 configuration. This setting will allow the connection to continue if the client does not supply a certificate.

    Give that a try and let us know if it solves the problem.

    Regards,
    Mark
  • Hi Mark,

    Thanks for the incredibly fast response.

    I just put in the IceSSL.VerifyPeer=1 setting, but I'm still getting the same error:
    message = error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
    

    Could this be an issue with my certs, I wonder?
  • mes
    mes California
    My best guess is that the server's error message is relaying the client's status. In other words, during the SSL handshake, the client informs the server that the client doesn't recognize the server's certificate authority (CA) certificate. This could have several causes:
    • The property being set in your client code doesn't have any effect (e.g., you set it after the communicator is already initialized)
    • The CA certificate referred to in your client doesn't match the server's
    You should also verify that the CA certificate has not expired, and that the client's system clock is correct.

    If you're still having trouble, I suggest doing some experiments with a simple example, such as the "hello" demo included in the Ice distribution. You can use the certificates included in the distribution, and then substitute your own to see if anything changes.

    For example, I get the same error (alert unknown ca) in the hello server when I run the client without any IceSSL configuration properties, aside from installing the plug-in. When I add a definition for IceSSL.CertAuthFile in the client, and make sure IceSSL.VerifyPeer=1 is set in the server, then everything works as expected.

    Regards,
    Mark
  • I'll give the demo project a shot to see if it makes a difference.
    mes wrote: »
    My best guess is that the server's error message is relaying the client's status. In other words, during the SSL handshake, the client informs the server that the client doesn't recognize the server's certificate authority (CA) certificate. This could have several causes:
    • The property being set in your client code doesn't have any effect (e.g., you set it after the communicator is already initialized)
    • The CA certificate referred to in your client doesn't match the server's
    You should also verify that the CA certificate has not expired, and that the client's system clock is correct.
    I'm positive the SSL properties are being set before I call Ice::initialize():
    // Enable IceSSL	
    	pProps->setProperty("Ice.Plugin.IceSSL", "IceSSL:createIceSSL");
    
    	// Set the path to the CA certificate so we can validate the SSL connection to Glacier2
    	pProps->setProperty("IceSSL.CertAuthFile", m_caCertPath);
    
    	Ice::InitializationData iceInit;
    	iceInit.properties = pProps;
    	m_pCommunicator = Ice::initialize(iceInit);
    	if (!m_pCommunicator)
    		throw "Failed to initialize Ice communicator";
    
    I don't need to initialize anything else on the client side, right?
  • Oh, hang on, I just enabled security tracing on the client side, and got this:
    -- 11/08/13 11:55:24.685 Security: certificate verification failure
       issuer = /C=US/ST=BLAHBLAH
       subject = /C=US/ST=BLAHBLAH
       depth = 0
       error = self signed certificate
       local address = 10.0.0.20:34411
       remote address = xx.xx.xx.xx:65431
    GroanConnectionFailed: TransceiverI.cpp:235: Ice::ProtocolException:
    protocol exception:
    SSL error occurred for new outgoing connection:
    remote address = xx.xx.xx.xx:65431
    error # = 336134278
    message = error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
    
    I thought self-signed certificates were fine as long as the CA certificate is passed along?
  • And here's the results when using the certs provided with the Ice distribution (in short: it works):
    -- 11/08/13 12:21:23.354 Security: IceSSL: ignoring certificate validation failure:
       peer certificate does not have `xx.xx.xx.xx' as its commonName or in its subjectAltName extension
       Subject DN: cn=127.0.0.1,emailaddress=info@zeroc.com,ou=ice,o=zeroc\, inc.,st=florida,c=us
       DNS names found in certificate: 127.0.0.1
       IP addresses found in certificate: 127.0.0.1
    -- 11/08/13 12:21:23.354 Security: SSL summary for outgoing connection
       cipher = DHE-RSA-AES256-SHA
       bits = 256
       protocol = TLSv1.1
       local address = 10.0.0.20:34412
       remote address = xx.xx.xx.xx:65431
    
    I guess that narrows it down to the self-signed issue I mentioned above although I'm not sure why verification fails when I pass the proper CA certificate to the client.

    I can successfully verify the certificate on the client machine using openssl:
    openssl verify -CAfile ca.pem server.pem
    server.pem: OK
    
  • mes
    mes California
    Your client code looks correct.

    A server can use a self-signed certificate, but if the client is configured to verify the server's certificate chain, then the client must install the CA certificate locally.

    If you set IceSSL.VerifyPeer=0 in the client, I suspect the connection will succeed because you're essentially telling the client to ignore certificate verification failures. The task is figuring out why verification is failing.

    Mark
  • Yep, setting IceSSL.VerifyPeer=0 ignores all errors and the connection is established:
    -- 11/08/13 12:31:05.329 Security: certificate verification failure
       issuer = /C=US/ST=BLAHBLAH
       subject = /C=US/ST=BLAHBLAH
       depth = 0
       error = self signed certificate
       local address = 10.0.0.20:34414
       remote address = xx.xx.xx.xx:65431
    -- 11/08/13 12:31:05.428 Security: IceSSL: ignoring certificate verification failure:
       self signed certificate
    -- 11/08/13 12:31:05.428 Security: IceSSL: ignoring certificate validation failure:
       peer certificate does not have `xx.xx.xx.xx' as its commonName or in its subjectAltName extension
       Subject DN: cn=BLAHBLAH
    -- 11/08/13 12:31:05.428 Security: SSL summary for outgoing connection
       cipher = DHE-RSA-AES256-SHA
       bits = 256
       protocol = TLSv1.1
       local address = 10.0.0.20:34414
       remote address = xx.xx.xx.xx:65431
     => nil
    
    I think the problem is that the certificate has depth 0, i.e. there is no root certificate. As far as I could tell when using the Ice distribution's CA cert, the depth was 1.

    I'll try regenerating the certs.
  • mes
    mes California
    Sounds like you're on the right track. If it helps, Ice includes a Python script that can handle generating CA & self-signed certificates.

    Mark