verisign G5 root certificate checking - linux

Can somebody let me know how to check my server has VeriSign G5 root certificate installed. I have executed the following command
openssl s_client -connect api-3t.sandbox.paypal.com:443 -showcerts
and it return the following result
issuer=/C=US/O=GeoTrust Inc./CN=GeoTrust SSL CA - G3 . It means my server installed with VeriSign G3 root certificate?
Server : CentOS 5

Related

SSL: Servers certificate chain is incomplete

I bought a PositiveSSL Wildcard from https://www.ssls.com/
I have received 3 files a .ca-bundle a .crt and a .p7b.
I configured the certificates with NGINX but I'm getting an error:
"Servers certificate chain is incomplete"
https://www.ssllabs.com/ssltest/analyze.html?d=api.billgun.com
How can I fix this?
Servers certificate chain is incomplete
means you don't have intermediate certificates, certificates have expired or are in wrong order.
It looks like you don't have any intermediate certificates: https://www.sslshopper.com/ssl-checker.html#hostname=https://api.billgun.com/.
When you open your site in a browser you will get green padlock because browsers can download missing intermediate certificates but other tools won't be able to connect ie. curl:
curl -I 'https://api.billgun.com/'
curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
More details here: http://curl.haxx.se/docs/sslcerts.html
or openssl:
openssl s_client -connect api.billgun.com:443
CONNECTED(00000003)
depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.billgun.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.billgun.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.billgun.com
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
The fastest way to generate correct chain is to:
open your site in a browser
click on green padlock and display certificate properties
export every certificate in the chain (in your case, you should get 3 files: -billguncom.crt, COMODORSADomainValidationSecureServerCA.crt, COMODORSACertificationAuthority.crt)
combine the files in order from leaf to root cert:
cat -- -billguncom.crt COMODORSADomainValidationSecureServerCA.crt COMODORSACertificationAuthority.crt > billgun_com.crt
install new cert on server
test nginx cofiguration nginx -t
restart server service nginx restart
There is a tool to automate the procedure of producing a bundle of correctly chained certificates. https://github.com/zakjan/cert-chain-resolver (I'm the author.)
Usage:
cert-chain-resolver -o domain.bundle.pem domain.pem
domain.pem is your input certificate
domain.bundle.pem is the certificate bundle, that you can use in your web server configuration

How do I properly import a SSL certificate

I am trying to import a SSL certificate on Ubuntu 14.04. I have downloaded an SSL certificate using
openssl s_client -showcerts -connect pypi.python.org:443
Afterward, I copied the certificate to /etc/ssl/certs (this is where $SSL_CERT_DIR points to and where my working certificates are). However when I re-run the command
openssl s_client -showcerts -connect pypi.python.org:443
I still get
Verify return code: 20 (unable to get local issuer certificate)
What am I doing wrong?

Download SSL Corproate Proxy Cert via Linux CLI

How do I download a proxy's SSL cert and save it to a file using the Linux command line.
It's possible to download an ssl cert via the openssl tool: https://superuser.com/questions/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file. But this does not work when behind a corporate proxy that re-writes the SSL cert. I would like to download the proxy's ssl cert. Changing the HOST and PORT to my proxy's host and port does not work either.
Downloading the cert using my browser works but I need to do this in a bash script.
You can only extract certificates from the connection which actually get send inside the connection. Within a MITM proxy the root CA you want to have usually does not get send since it is expected to be installed locally as trusted, similar to a public root CA. And the reason you can extract this MITM CA within your browser is because the browser already has this CA as trusted in the CA store and can thus export it.
As mentioned here, openssl 1.1.0 and above support the -proxy argument so you can get the proxy's certificates with a command like (jcenter.bintray.com is just an example host to connect to)
openssl s_client -showcerts -proxy $https_proxy -connect jcenter.bintray.com:443
Also see this script for a more complete example how to import the certificate(s) to a JVM keystore and the system certificates.

Error "empty certificate chain" in a basic haskell app

I generated a certificate in the directory of my Haskell app:
openssl genrsa -out key.pem 2048
openssl req -new -key key.pem -out certificate.csr
openssl x509 -req -in certificate.csr -signkey key.pem -out certificate.pem
and then I ran my app:
import Network.Wai
import Network.Wai.Handler.Warp
import Servant
import Network.Wai.Handler.WarpTLS
startApp :: IO ()
startApp = do
let port = 3345
let tls = tlsSettings "certificate.csr" "key.pem"
runTLS tls (setPort port defaultSettings) app
And then went to https://localhost:3345 and I got an error "empty certificate chain"
What's wrong with it? Maybe I've put my certificate somewhere such as "/opt/...."?
For now all 3 files are in the root directory of my application: key.pem, certificate.csr and certificate.pem.
UPDATE:
It's arch linux, whereas on hosting I have Ubuntu, therefore I'll need a solution for both.
This certificate is self-signed, whereas on hosting it's issued by let's encrypt.
I've changed a code a bit: "csr" to pem:
let tls = tlsSettings "certificate.pem" "key.pem"
runTLS tls (setPort port defaultSettings) app
Here's another error:
$ curl -v https://localhost:3345
* Rebuilt URL to: https://localhost:3345/
* Trying ::1...
* connect to ::1 port 3345 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3345 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, Server hello (2):
* SSL certificate problem: self signed certificate
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, Client hello (1):
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
TL;DR: Handling certificates is hard. Use the self-signed .pem file (and the key) and add security exceptions to your browser or your operating system. The .csr file isn't something you can use. The server is fine (except for the .csr file), but you will end up with security warnings till you get your key signed by a CA (which isn't possible for local domain names).
What's wrong with it?
The server is (almost) fine. However, you want to send the .pem file. The .csr is a request for signing your certificate by a certificate authority (CA). A CA needs to get trusted by the user or another CA (that's trusted by the user). Let's have a look at your original commands:
openssl genrsa -out key.pem 2048
This will generate the private key, which will get used for the TLS handshake and other operations.
openssl req -new -key key.pem -out certificate.csr
This will generate the mentioned certificate sigining request. You would send this request to a CA, which checks your identity. For example, they would check whether the FQDN actually is yours. Otherwise, you could ask for a certificate for stackoverflow.com and use a MITM attack. This also concludes that you cannot ask a (non-local) CA for a certificate on a local name, like localhost or hostname.local.domain.name.
openssl x509 -req -in certificate.csr -signkey key.pem -out certificate.pem
This will take the original certificate request, use your own key to sign it, and generate a certificate (certificate.pem). Usually, this certificate contains a CA chain, e.g. who signed the CA's certificate, who signed the certificate of the one that signed the CA's certificate and so on, till we end up at a root certificate.
So, all you have to do is to use that certificate together with your private key. This will lead to security warnings though, since you cannot prove your own identity. That's why you need --insecure in curl and a security exception in most browsers. That aside, it will work. Note that the server doesn't know that its certificate is self-signed. It's just using two files to initiate the communication with the client.

Client/Server SSL certificate ignored/forbidden with Require SSL set in IIS 7.5

I have created a website that I want to be able to access using a smart card so I have enabled SSL on the site. When I am logged in remotely to the server and access the site on the https port using the smart card everything works fine. I receive my prompt and the site loads. However, if I try to access the same site, using the same card from a client pc then I receive the 403 Forbidden error.
Settings on the server(IIS 7.5) I have implemented or verified:
1) Site is bound to specific port (not 443) with a type of https and a certificate that has a friendly name.
2) SSL settings: Require SSL is checked, Require client certificates is selected (note: if I set it to accept, the site will load for the client but it never prompts for credentials)
3) I have verified that when Require client certificates is set to accept, that the certificate it recognizes in the browser is the correct one (e.g. myserver.com) but as I said then I don't receive the prompt for credentials
4) Anonymous Authentication is enabled, all others disabled
5) applicationhost.config file set the following in location -> system.webserver -> security:
a) sslFlags = "Ssl, SslNegotiateCert, SslRequireCert"
b) under authentication set iisClientCertificateMappingAuthentication to true
6) I have confirmed the necessary certificates exist in the Trusted Root and Personal folders for the Local Computer account.
Settings for the client:
1) I have confirmed the necessary certificates exist and match what the server has in the Trusted Root and Personal folders for the Local Computer account.
2) I have checked that the certificate chain in the browser does not show any errors going down the chain in both IE and Chrome
I created a self-signed certificate and added it to all the certificate stores on the server and the client and received the same behavior.
Using OpenSSL I have achieved the following results:
openssl s_client -connect myserver.com -CAfile c:\certs\godaddy.pem -servername myserver.com
Loading 'screen' into random state - done
CONNECTED(00000160)
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go D
addy Root Certificate Authority - G2
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http
://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate Authority - G
2
verify return:1
depth=0 OU = Domain Control Validated, CN = *.myserver.com
verify return:1
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.myserver.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certific
ate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
...29u1FZGXZnMUZCW5rlmZrkCAiBwDAB0/2t6BhyGh0JxydLWrRzJAZhW33KIem7IC...
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.myserver.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy
.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 2713 bytes and written 673 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: *** edited ***
Session-ID-ctx:
Master-Key: *** edited ***
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1439825381
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
read:errno=10054
The OpenSSL results has one section that says 'No client certificate CA names sent' and before I added the -CAfile option I was getting the Verify 20 error unable to get local issuer certificate.
UPDATE to OpenSSL results:
Figured out how to use the debug feature and from what I can see here, it seems to negotiate SSL correctly and with the correct certificate as long as I pass in the CAfile path.
openssl s_client -connect myserver.com:10168 -state -debug -CAfile c:\certs\godaddy.pem -servername myserver
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certs.godaddy.com/repository/, CN = Go Daddy Secure Certificate
Authority - G2
verify return:1
depth=0 OU = Domain Control Validated, CN = *.myserver.com
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.myserver.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.c
om/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certific
ate Authority - G2
---
Server certificate
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.myserver.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy
.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 2713 bytes and written 643 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: ***
Session-ID-ctx:
Master-Key: ***
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1439919398
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
read from 0x2dd5b0 [0x2f06d3] (5 bytes => -1 (0xFFFFFFFF))
read:errno=10054
write to 0x2dd5b0 [0x2f4c23] (37 bytes => -1 (0xFFFFFFFF))
Additional openssl command:
openssl s_client -connect yourip:443 -prexit
...found on this SO site here did prove that in the list of acceptable certificates names was the Go Daddy Class 2 Certification Authority CA; however, I did not see *.myserver.com. Since *.myserver.com is chained to the Go Daddy Class 2 Certification Authority CA it seems that might be a normal process as indicated by this site here. On my local pc and the server the Go Daddy certificate exists in both the Trusted Root and Intermediate CA folders.
UPDATE - netsh:
I also tried the netsh http add sslcert certhash= appid= clientcertnegotiation=enable which executed sucessfully but did not result in any success.
UPDATE TO WIRESHARK INFO:
If I use Wireshark on my local pc to look at the traffic specifically to the server (display filter is set to search for ip.addr or ssl) I don't see any traffic at all generated by SSL. There's no Client or Server Hello or Certificate entry. I did verify in the first three SYN, SYN/ACK, and ACK packets that the IP addresses and ports were the correct values.
When I run Wireshark on the server I don't see any SSL traffic either specifically coming from my IP address. However, if I run Wireshark and my SSL website directly on the server, the site does resolve, works and prompts for credentials like it should but I discovered that the Certificate id-at-commonName equals a certificate different than I assigned to the site (*.myserver.com) which is *.vo.msecnd.net and belongs according to my research to the Baltimore CyberTrust Root certificate from Microsoft.
UPDATE - Repaired Certificate
Followed the instructions on this site to repair the certificate and rule out it being faulty. I don't have an Entrust cert but the instructions at the bottom work the same.
Why am I not seeing a Client Hello? How can I troubleshoot lack of SSL handshake?
Some SO sites that I have used to try and resolve the issue include:
OpenSSL errno 10054,connection refused
OpenSSL: unable to get local issuer certificate
IIS 7.5 site with SSL fails, site without SSL works
RESOLUTION:
It appears the combination of certificate repair and setting the clientcertnegotiation did the trick but only after I rebooted the server.
The correct steps are:
Set IIS SSL bindings up correctly
netsh http show sslcert and copy the values
Remove server SSL certificate binding with netsh http delete sslcert
Added server SSL certificate binding with netsh http add sslcert ipport=0.0.0.0:443 certhash=.... appid=.... sslctlstorename=ClientAuthIssuer clientcertnegotiation=enable
Verified that settings were applied with netsh http show sslcert
(Windows 2012 R2 only) Set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\SendTrustedIssuerList to 1

Resources