openssl how to check server name indication (SNI) - ssl

I'm trying to verify whether a TLS client checks for server name indication (SNI).
I'm trying at first to reproduce the steps using openssl.
I tried to connect to google with this openssl command
openssl version
openSSL 1.1.1b 26 Feb 2019
openssl s_client -connect google.com:443 -servername "ibm.com"
Purposely I set the TLS extension -servername to a wrong domain, and I expect that openssl refuses connection, but it proceeds.
I also tried specifiying a CA certificate but nothing happened.
What should I expect when choosing a wrong SNI?
Log
openssl s_client -connect www.google.com:443 -servername "ibm.com"
CONNECTED(000001BC)
depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
verify return:1
---
Certificate chain
0 s:C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
i:C = US, O = Google Trust Services, CN = GTS CA 1O1
1 s:C = US, O = Google Trust Services, CN = GTS CA 1O1
i:OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFiTCCBHGgAwIBAgIRAOojQokwkAg5AgAAAABSqVUwDQYJKoZIhvcNAQELBQAw
QjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczET
MBEGA1UEAxMKR1RTIENBIDFPMTAeFw0xOTEyMjAxMzEzNDNaFw0yMDAzMTMxMzEz
NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH
Ew1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgTExDMRcwFQYDVQQDEw53
d3cuZ29vZ2xlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdb
zkTc78UBXe8/rti2OxAGZQUQ1WnilkCSqRuMn/gmc1jeiIDeZCWFurFin9+RBB/K
ib5xQx2iZ1ifcV+DOvDT16LEa887TehETAADpBnTJmVi0Z6GXjQQ9pyLrv+1PDYI
3z9Slkw3ZGVeMUE31etonDRB9lPN9skF09s1LvitIi4XdPXgaTNCBEWNMs1Tlv8H
1+UlaQiamriyTii4pptXv+KKsunDC//OEv1pm0cZnEeop8USMHermBzYkaFXC3ae
2hvV7Bj7w8c6PqHcTQ+e7xhoKoIzFVtneNoEyQL1h9QGtPdTofs/sidgd//Wo7sB
0JV1zq2EtSsKlp/N+U0CAwEAAaOCAlIwggJOMA4GA1UdDwEB/wQEAwIFoDATBgNV
HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQiK5HMzk32
vjkQNky4VkFcyt/kQTAfBgNVHSMEGDAWgBSY0fhuEOvPm+xgnxiQG6DrfQn9KzBk
BggrBgEFBQcBAQRYMFYwJwYIKwYBBQUHMAGGG2h0dHA6Ly9vY3NwLnBraS5nb29n
L2d0czFvMTArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nL2dzcjIvR1RTMU8x
LmNydDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTAhBgNVHSAEGjAYMAgGBmeB
DAECAjAMBgorBgEEAdZ5AgUDMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9jcmwu
cGtpLmdvb2cvR1RTMU8xLmNybDCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1ALIe
BcyLos2KIE6HZvkruYolIGdr2vpw57JJUy3vi5BeAAABbyOoMvgAAAQDAEYwRAIg
Ba8Zw9vk29aITM7udOH9zPzytfh5vjTxz2JPuNQuF6gCIEcduOoMHCV9s3G9uEwV
KXwfjtYwYvVlfKlCMW4ilFujAHUAXqdz+d9WwOe1Nkh90EngMnqRmgyEoRIShBh1
loFxRVgAAAFvI6gzIgAABAMARjBEAiBRslW536auv4WHgspy1wNvLEwS2VH66MMV
MJUcgN6IvwIgepYRaAuSuiJeAla6KuAnPCeJvXlscWTnFbm85DIEaegwDQYJKoZI
hvcNAQELBQADggEBAKqExHCpU6rjr/XMezkzy+fp76TST2l39vqIJKDdkQPe8V0I
afWgkc/T3z4bZx/4plzW+iAvk4KTyvDWNbv2xh3njAB6FoJyZkf9/H6zahLSaS4z
qiI3axO3rSD6AW6G5u5cKIN8IaJzLc6CgW+NkxMulOM//u008jZIvp6qGwVfeMlc
1kDocDf8imLam7yM4BQKvOPb5w7e+SgKO6qxRkhFsL18xgh7HZk8F1fvFFhGyuYQ
WL0jORJvjomn/uMxiU9UFlAiVtsY0zmyuVIEp2rDpdfaG8AnVV4BLnR6Ey8TpHzR
w1b3ocoOJi0is55pSMwU8L9RE7cz9MP9krrb7zU=
-----END CERTIFICATE-----
subject=C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
issuer=C = US, O = Google Trust Services, CN = GTS CA 1O1
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 3018 bytes and written 389 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 20 (unable to get local issuer certificate)
---

The certificate you got back is not yours, it's Google's.
Google implements SNI. Your request states that it wants to establish a connection with the hostname "ibm.com" that Google does not know about. So it decides to answer with its own certificate.
If this was a browser, you would get a name mismatch warning of some kind.
So to answer your question, to test an invalid SNI, look for the hostname in the output. Here is a command I use:
echo -n | openssl s_client -connect google.com:443 -servername ibm.com | openssl x509 -noout -text | grep ibm.com
You won't get any hits, that means that either SNI is not supported or the server you are connecting to does not recognize it.

I am checking on a Mac and I had to make a modification by adding the -connect directive.
echo -n | openssl s_client -connect google.com:443 -servername ibm.com | openssl x509 -noout -text | grep ibm.com
Since we don't need to input anything, I'd update the command to close the openssl command by forcing input from /dev/null:
echo -n | openssl s_client -connect google.com:443 -servername ibm.com </dev/null | openssl x509 -noout -text | grep ibm.com

Related

Understanding openssl. Where is the cert file?

I am using the command ...
openssl s_client -showcerts -connect reds-cluster-01:443
And I get the output:
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1
verify return:1
depth=0 CN = *.my-co-example.com
verify return:1
CONNECTED(00000003)
---
Certificate chain
0 s:/CN=*.my-co-example.com
i:/C=US/O=DigiCert Inc/CN=RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1
-----BEGIN CERTIFICATE-----
MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ
...
I assume that means somewhere on the filesystem of my server there would be a file somewhere that has the string ...
MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ
... in it. How can I find that file without having to execute something like?
sudo grep -sr MIIGnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgkqhkiG9w0BAQsFADBZ /
I assume that means somewhere on the filesystem of my server there would be a file somewhere that has the string ...
This assumption is wrong. What you see is part of the server certificate, which need to be checked against a CA certificate located in the local trust store. The server certificate is typically not in the local trust store. See SSL Certificate framework 101: How does the browser actually verify the validity of a given server certificate? for more on certificates are checked.
You can see more with "CURL -W CERTS" from Daniel Stenberg (also on Stack Overflow), which works on curl for the past 25+ years.
When a client connects to a TLS server it gets sent one or more certificates during the handshake.
Those certificates are verified by the client, to make sure that the server is indeed the right one: the server the client expects it to be; no impostor and no man in the middle etc.
When such a server certificate is signed by a Certificate Authority (CA), that CA’s certificate is normally not sent by the server but the client is expected to have it already in its CA store.
(So no file to check on the filesystem)
Ever since the day SSL and TLS first showed up in the 1990s user have occasionally wanted to be able to save the certificates provided by the server in a TLS handshake.
The openssl tool has offered this ability since along time and is actually one of my higher ranked stackoverflow answers.
Now (for curl 7.88.0,to be shipped in February 2023), Daniel proposes:
Using the –write-out (-w) option and the new variables %{certs} and %{num_certs}, curl can now do what you want.
Get the certificates from a server in PEM format:
$ curl https://curl.se -w "%{certs}" -o /dev/null > cacert.pem
$ curl --cacert cacert.pem https://curl.se/
That is easier to parse than the openssl s_client -showcerts -connect current alternative.

TLS 1.2 with CloudFront default domain

I have created a CloudFront distribution to front some publicly accessible content from an S3 origin. This is all fine, but I need to set the minimum supported TLS version to 1.2.
It seems that the only way to do this is to import a custom SSL certificate and set the ViewerCertificate properties, specifically the MinimumProtocolVersion. I can have Certificate Manager issue a public cert but I don't want to have to register a domain. For the purpose of this content, I'm happy with the default cloudfront.net domain.
It seems like specifying the minimum TLS version should be supported by default. Am I missing something here?
Thanks,
John
This might not be supported forever, but it turns out you can import a bogus, self-signed certificate for the default domain. CloudFront will ignore it, but will enforce your TLS policy.
For example, I'm currently testing this on d2uwa7ugi8xf89.cloudfront.net -- configured with security policy TLSv1.2_2019. openssl s_client will show that it's vending the default certificate:
% openssl s_client -servername d2uwa7ugi8xf89.cloudfront.net -tls1_2 -connect d2uwa7ugi8xf89.cloudfront.net:443
CONNECTED(00000003)
depth=3 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Global CA G2
depth=0 C = US, ST = Washington, L = Seattle, O = "Amazon.com, Inc.", CN = *.cloudfront.net
---
Certificate chain
0 s:/C=US/ST=Washington/L=Seattle/O=Amazon.com, Inc./CN=*.cloudfront.net
i:/C=US/O=DigiCert Inc/CN=DigiCert Global CA G2
1 s:/C=US/O=DigiCert Inc/CN=DigiCert Global CA G2
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
---
...
Attempt to connect with TLS 1.0 or TLS 1.1? No go:
% openssl s_client -servername d2uwa7ugi8xf89.cloudfront.net -tls1_1 -connect d2uwa7ugi8xf89.cloudfront.net:443
CONNECTED(00000003)
139725480863648:error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:s3_pkt.c:1493:SSL alert number 70
139725480863648:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
...
This certificate was generated in the usual bogus self-signed certificate way:
openssl genrsa 2048 > cf.privkey
openssl req -new -subj /CN=d2uwa7ugi8xf89.cloudfront.net -key cf.privkey -out cf.csr
openssl x509 -in cf.csr -req -signkey cf.privkey -out cf.pem -days 99999

build.shibboleth.net gives wrong certificate for some regions

One of our Jenkins builds is failing trying to connect to build.shibboleth.net. So I did some analysis.
Please look at these openssl results from 2 regions.
In South Asia region: It gives the cert of test.shibboleth.net, which is wrong.
$ openssl s_client -host build.shibboleth.net -port 443 -prexit -showcerts
CONNECTED(00000005)
depth=1 C = US, ST = Ohio, O = Shibboleth Consortium, CN = Shibboleth Project Intermediate CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=Ohio/O=Shibboleth Consortium/CN=test.shibboleth.net
i:/C=US/ST=Ohio/O=Shibboleth Consortium/CN=Shibboleth Project Intermediate CA
...
...
In USA region: It gives the cert of shibboleth.net, which is correct.
$ openssl s_client -host build.shibboleth.net -port 443 -prexit -showcerts
CONNECTED(00000005)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = shibboleth.net
verify return:1
---
Certificate chain
0 s:CN = shibboleth.net
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
...
...
And resolveip build.shibboleth.net gives 3.213.250.186 from both regions.
Why is it giving a wrong certificate for one region? I have no clue how to fix this. Any ideas?
I'd speculate that the results above aren't caused by region dependence but instead that you're using a different version of openssl on the two client machines.
We used to run the different vhosts on different IP addresses. Now, one address is used for everything and we rely on SNI to distinguish requests so that the right certificate is returned.
If the openssl client doesn't present the server name then you might get a default certificate instead of the one you expected. Whether openssl does that or not depends on the version of openssl in use (openssl version 1.1.1 does, earlier versions don't).
You can try adding -servername build.shibboleth.net to your openssl command to see if that changes the behaviour.

How to verify certificate chain with openssl

I am trying to verify a certificate file with OpenSSL. Can you explain me why s_client connection succeeds, but verify file with the same certificate chain fails? How can I verify the file?
Note I compiled OpenSSL 1.0.1k myself, it shouldn't be using any distro-specific config. And I provided the same CAfile to both commands.
$ openssl s_client -CAfile /etc/pki/tls/certs/ca-bundle.crt -connect www.google.com:443
WARNING: can't open config file: /usr/local/ssl/openssl.cnf
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
...
Verify return code: 0 (ok)
---
If I run it with -showcerts argument, it outputs all three certificates sent from server. I concatenated them into file google.pem. But the chain can't be verified. See:
$ openssl verify -CAfile /etc/pki/tls/certs/ca-bundle.crt google.pem
WARNING: can't open config file: /usr/local/ssl/openssl.cnf
google.pem: C = US, ST = California, L = Mountain View, O = Google Inc, CN = www.google.com
error 20 at 0 depth lookup:unable to get local issuer certificate
Applying a patch suggested on https://stackoverflow.com/a/27606964/1823988 doesn't help.
I found it. openssl verify doesn't expect certificate file to contain its chain. Chain needs to be passed with -untrusted argument. It works with the same file, trust is still determined by finding a trusted root in -CAfile.
openssl verify -CAfile /etc/pki/tls/certs/ca-bundle.crt -untrusted google.pem google.pem

"verify error:num=20" when connecting to gateway.sandbox.push.apple.com

I am attempting to run the Ray Wenderlich tutorial found at Apple Push Notification Services in iOS 6 Tutorial: Part 1/2.
I created an AppID and SSL certificate and keys and PEM files in a local directory. Afterwards, I got to the step to test whether the certificate works, and I invoked the following command from this local directory:
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195
-cert PushChatCert.pem -key PushChatKey.pem
This produced a lot of output. In the middle of the output was the following:
verify error:num=20:unable to get local issuer certificate
verify return:0
Is this an error, or is this a test for an error? If its an error, what would be the cause or what would you suggest to resolve it?
Here is the complete output (less the certificate data):
Enter pass phrase for PushChatKey.pem:
CONNECTED(00000003)
depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
---
Server certificate
-----BEGIN CERTIFICATE-----
<Long string of data removed>
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
issuer=/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
---
No client certificate CA names sent
---
SSL handshake has read 2731 bytes and written 2215 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key: <removed>
Key-Arg : None
Start Time: 1398633302
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
The tutorial goes on to say that "If the connection is successful, you should be able to type a few characters. When you press enter, the server should disconnect." I was able to do this and the server disconnected.
But the tutorial goes on to say that you may have to look through the output to find an error. Hence the reason for this question.
This produced a lot of output. In the middle of the output was the following:
verify error:num=20:unable to get local issuer certificate
verify return:0
You are missing a root certificate, and it should be specified either with -CAfile or with -CApath.
However, you may encounter a handshake alert after you fix the root certificate issue. I believe its a client certificate issue caused by me not having one (hence you may not experience it). Below, 0x14094410 is the OpenSSL error, and the SSL error (from the TLS protocol) is simply SSL alert number 40. Alert 40 is the handshake alert, and there's no additional information.
First
Determine the root you need:
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195
CONNECTED(00000003)
depth=1 C = US, O = "Entrust, Inc.", OU = www.entrust.net/rpa is incorporated by reference, OU = "(c) 2009 Entrust, Inc.", CN = Entrust Certification Authority - L1C
verify error:num=20:unable to get local issuer certificate
verify return:0
140067272132264:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1257:SSL alert number 40
140067272132264:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
Certificate chain
0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
So you need Entrust.net Certification Authority (2048). You can download it from Entrust Root Certificates. Its named entrust_2048_ca.cer and it appears to be in PEM format.
Second
Now, run openssl s_client again, but this time with -CAfile entrust_2048_ca.cer. Notice it completes with a Verify return code: 0 (ok):
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -CAfile entrust_2048_ca.cer
CONNECTED(00000003)
depth=2 O = Entrust.net, OU = www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU = (c) 1999 Entrust.net Limited, CN = Entrust.net Certification Authority (2048)
verify return:1
depth=1 C = US, O = "Entrust, Inc.", OU = www.entrust.net/rpa is incorporated by reference, OU = "(c) 2009 Entrust, Inc.", CN = Entrust Certification Authority - L1C
verify return:1
depth=0 C = US, ST = California, L = Cupertino, O = Apple Inc., OU = iTMS Engineering, CN = gateway.sandbox.push.apple.com
verify return:1
140642906502824:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1257:SSL alert number 40
140642906502824:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
Certificate chain
0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
i:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
1 s:/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFGzCCBAOgAwIBAgIETBz90jANBgkqhkiG9w0BAQUFADCBsTELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9ycGEgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
KGMpIDIwMDkgRW50cnVzdCwgSW5jLjEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eSAtIEwxQzAeFw0xMjA1MjUyMzM3NDZaFw0xNDA1MzEw
NTA4NDhaMIGPMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTESMBAG
A1UEBxMJQ3VwZXJ0aW5vMRMwEQYDVQQKEwpBcHBsZSBJbmMuMRkwFwYDVQQLExBp
VE1TIEVuZ2luZWVyaW5nMScwJQYDVQQDEx5nYXRld2F5LnNhbmRib3gucHVzaC5h
cHBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/r1z4BRFu
DIU9/vOboVmd7OwaPPLRtcZiZLWxSyG/6KeRPpaeaC6DScvSDRoJuIeTDBup0bg4
08K0Gzh+lfKRlJOC2sma5Wgvk7oP4sty83My3YCZQv4QvgDhx+seONNs6XiA8Cl4
ingDymWGlzb0sTdfBIE/nWiEOtXQZcg6GKePOWXKSYgWyi/08538UihKK4JZIOL2
eIeBwjEwlaXFFpMlStc36uS/8oy+KMjwvuu3HazNMidvbGK2Z68rBnqnOAaDBtuT
K7rwAa5+i8GYY+sJA0DywMViZxgG/xWWyr4DvhtpHfUjyQgg1ixM8q651LNgdRVf
4sB0PfANitq7AgMBAAGjggFZMIIBVTALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYI
KwYBBQUHAwEGCCsGAQUFBwMCMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwu
ZW50cnVzdC5uZXQvbGV2ZWwxYy5jcmwwZQYIKwYBBQUHAQEEWTBXMCMGCCsGAQUF
BzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBggrBgEFBQcwAoYkaHR0cDov
L2FpYS5lbnRydXN0Lm5ldC9sMWMtY2hhaW4uY2VyMEAGA1UdIAQ5MDcwNQYJKoZI
hvZ9B0sCMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuZW50cnVzdC5uZXQvcnBh
MB8GA1UdIwQYMBaAFB7xq4kG+EkPATN37hR67hl8kyhNMB0GA1UdDgQWBBSgNiNR
qtTShi8PuJ7UNUEbeE71STAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUAA4IBAQAS
EDkUyBHVdRJnCLHY8w9ec92NWqBYqKiSGP0uVCvgpsJIWDBkCGIw1Olks6mQuS9+
R7VRJJFg7EhtufmoRIvjgntKpTe49sB/lrmiZVQGnhjd6YdyYm9+OBUWRvwketLM
v0S+nxZD0qLLJ9foVUB8zP8LtutqFJ5IZw1xb9eSNzhpKkQ9ylj8MCd4tpXZxICL
Gt327poTXwmjQ+31fz7HCQCowMHccP8kiKM5SeYC9q+nkmdaozHVvw4e1RsP+EWO
vPtcH1x1BCkTJajmrO7JuRPLuBEnZGSPUVFRKWP9jy0a28VnJek+oA7rRMRD8irU
fMGbLqkGn8YogdPqe5T1
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=iTMS Engineering/CN=gateway.sandbox.push.apple.com
issuer=/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
---
No client certificate CA names sent
---
SSL handshake has read 2683 bytes and written 338 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key: A2F375CC440179ADF831179C32A35AF4...
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1398721005
Timeout : 300 (sec)
Verify return code: 0 (ok)
Third
This is kind of the old way of doing things, back when SSLv3 was still popular. That is, the POODLE attack was unknown:
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -CAfile entrust_2048_ca.cer
You should probably switch to TLS 1.0 or above and use Server Name Indication (SNI). SNI is a TLS feature not present in SSL. You might need to force TLS 1.2 in 2016; and you can do so with -tls1_2.
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 \
-tls1 -servername gateway.sandbox.push.apple.com -CAfile entrust_2048_ca.cer
Below is information from other comments and answers. I'm gathering them up for convenience. You should upvote the comment or answer as appropriate.
Client Certificate
Korbbit provides additional information below. It addresses the statement I made, "alert handshake failure ... I believe its a client certificate issue caused by me not having one". You should provide feedback for Korbbit if its helpful to you:
if you look at the tutorial again you are meant to type...
-cert PushChatCert.pem -key PushChatKey.pem
With Korbbit's feedback, the answer becomes:
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 \
-tls1 -servername gateway.sandbox.push.apple.com \
-cert PushChatCert.pem -key PushChatKey.pem -CAfile entrust_2048_ca.cer
ca-certificates bundle and -CApath
From Timur Bakeyev, Entrust.net is a well-known Root Certificate Authority, so it's certificate comes in the common CA certificates bundle (ca-certificates in Debian). It is usually installed, among others, into the /etc/ssl/certs directory and, alternatively, can be referred with the -CApath /etc/ssl/certs/ option.
You can use -CApath in place of -CAfile as follows.
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -CApath /etc/ssl/certs/
I just did the same tutorial and the accepted answer might not be what you want. if you look at the tutorial again you are meant to type:
openssl s_client -connect gateway.sandbox.push.apple.com:2195
-cert PushChatCert.pem -key PushChatKey.pem
not just:
openssl s_client -connect gateway.sandbox.push.apple.com:2195
if you type it as one line it will work:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem