Monday, April 11, 2016

Curl, OpenSSL, NSS, and secure web servers.

TL;DR

Upgrade curl and NSS on the Fedora Box
Don't use -k if you need SNI from a Mac
Send an x.509 certificate with your curl request?
  • Fedora: curl --cert mycert.pem  --key mycert.key
  • Mac: curl -v --cert "mycert.pfx:password" (To merge a PEM file and a Key, see the instructions here)
Final commands:
  • Fedora: curl -v --cert ~/mycert.pem --key ~/mycert.key --tlsv1.2 https://test.mydomain.net/ping
  • Mac: curl -v --cert "mycert.pfx:password" https://test.mydomain.net/ping
Another fun option:
  • You haven't migrated DNS for your Host-header content site?  
    • curl -v --resolve test.mydomain.com:443:4.5.6.7 https://test.mydomain.com

Back story

For the past couple months, I have been building a secure web server using Apache HTTPD and chef. The cookbook went to UAT and we were having a client problem. So, we started digging deeply into the cookbook. Client requests are authenticated using an x.509 certificate. So, I needed to include my test certificate in the curl request. And off I go, right???

Wrong

First request:
$ curl -v --cert ~/mycert.pem --key ~/mycert.key --tlsv1.2 https://test.mydomain.net/ping
* Trying 1.2.3.4...
* Connected to test.mydomain.net (1.2.3.4) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* NSS error -12286 (SSL_ERROR_NO_CYPHER_OVERLAP)
* Cannot communicate securely with peer: no common encryption algorithm(s).
* Closing connection 0 curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).

WHAT?? How can I have "NO_CYPHER_OVERLAP"? So, my boss tries it from his Mac OS laptop. Maybe I have done something dumb on my laptop... Not likely, but possible. His request fails. What's going on? We check the logs on the server, and they show successful transactions by other client. Good, the server is not broken... My requests are getting logged at all (No surprise. You can't send an HTTP request if you can't negotiate SSL) His requests are getting logged, but no x.509 signature in the log (We use a custom log format that includes some x.509 stuff for this type of troubleshooting). What command are you using and what output do you get?

$ curl -v -k --cert "mycert.pfx:password" "https://test.mydomain.net/ping"
* Trying 1.2.3.4... * Connected to test.mydomain.net (1.2.3.4) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
* Server certificate: *.testdomain2.com
* Server certificate: GeoTrust SSL CA - G2
* Server certificate: GeoTrust Global CA
Wait... Why are you getting *.testdomain2.com's certificate? We use a single IP address with SNI support. With curl and Mac OS, if you add -k to your curl command, it disables SNI support. Who knew???

So, I figure I'll upgrade curl. There have been some high profile bugs found in SSL implementations (POODLE and BEAST to name a couple). Yeah! New version of curl. More testing and get the same results. Finally, I read the error message again...
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* NSS error -12286 (SSL_ERROR_NO_CYPHER_OVERLAP) 
NSS???? I thought I was using OpenSSL... Let's upgrade NSS.
[thad.scalf@EDOLINUX-FS1 edo-httpd]$ curl -v --cert mycert.pem  --key mykey.key --tlsv1.2 https://test.mydomain.net/ping
*   Trying 1.2.3.4...
* Connected to uatrest.edocard.net (1.2.3.4) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=*.mydomain.net,O=myOrg,L=Nashville,ST=Tennessee,C=US
* start date: Mar 29 00:00:00 2016 GMT
* expire date: Apr 12 23:59:59 2017 GMT
* common name: *.mydomain.net
* issuer: CN=GeoTrust SSL CA - G3,O=GeoTrust Inc.,C=US
> GET /ping HTTP/1.1
> User-Agent: curl/7.40.0
> Host: uatrest.edocard.net
> Accept: */*
>
* NSS: client certificate from file
* subject: CN=mycert,OU=myOU,O=myOrg
* start date: Jun 02 21:31:27 2014 GMT
* expire date: Jun 01 21:31:27 2017 GMT
* common name: mycert
* issuer: CN=myOrg,OU=myOU,O=myOrg
< HTTP/1.1 200 OK
HA!! It works! And after removing the -k from my boss's Mac command, his works too!! It's like magic. 

No comments:

Post a Comment