I have been struggling with this for days and have searched for days. I am trying to connect to api-3t.sandbox.paypal.com:443 from my AWS EC2 instance. The instance is Windows Server 2012 R2. I have installed openssl to try and debug. Under Trusted Root Certification Authority I can see VeriSign Class 3 Public Primary Certification Authority - G5 7/16/2036 in there. I also have openssl installed on my development machine.
If I run openssl s_client -connect api-3t.sandbox.paypal.com:443 in the development machine it returns with a Verify return code: 0 (ok). If I run that same line in the EC2 instance, it returns with a Verify return code: 20 (unable to get local issuer certificate)
I then downloaded the G5 certificate that reads:
-----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
And on the EC2 instance I ran the following: openssl s_client -CAfile g5.cer -connect api-3t.sandbox.paypal.com:443 and the response was Verify return code: 0 (ok)
So when I pass in the certificate to openssl, it works fine. But when it tries to find it in the keystore it fails.
I followed these instructions to install the certificate: http://www.sqlservermart.com/HowTo/Windows_Import_Certificate.aspx
Can anyone provide assistance to lead me in the right direction? Is there something specific I need to do with AWS?
--- Edit. Here is the output after attempting to change the policy
C:\>openssl s_client -connect api-3t.sandbox.paypal.com:443
Loading 'screen' into random state - done
CONNECTED(0000013C)
depth=1 C = US, O = Symantec Corporation, OU = Symantec Trust Network, CN = Symantec Class 3 Secure Server CA - G4
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=PayPal Production/CN=api-3t.sandbox.paypal.com
i:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 Secure Server CA - G4
1 s:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 Secure Server CA - G4
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
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGiDCCBXCgAwIBAgIQSmPFPGKFy6vVcS32CMWsdDANBgkqhkiG9w0BAQsFADB+
MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVj
IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MDExNDAwMDAwMFoX
DTE4MDExNDIzNTk1OVowgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9y
bmlhMREwDwYDVQQHDAhTYW4gSm9zZTEVMBMGA1UECgwMUGF5UGFsLCBJbmMuMRow
GAYDVQQLDBFQYXlQYWwgUHJvZHVjdGlvbjEiMCAGA1UEAwwZYXBpLTN0LnNhbmRi
b3gucGF5cGFsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANXB
QRl1wRXByqGLGt64dqkOJ8srJSPcqYwjA+KL3JuSmWKgvHUKg581H5p6/aX5BD92
ZmMLMrE3gtQnQU9cfatkw7+sFNtDDXh4gJhNAWz1Mw7VuDTRzk4N0YcO55Wy2WQ4
/Z2fYHfL6IoohXfqtYdFY1JzOXkqunPfhsSOKTb03Lf2k4hniwoMVsn8rOSBklNZ
6knC4iiaEOpo/EGtYylbpnoRg1aQP+1Oyc+bwG1LPT64XZA/4frcm1gKnFYBYtRM
RKBmQsF88SjSNUP9DiriHiD8tXryy2xAoQml+bfkslb5FJYLP7xmncQaXQRk/YUo
ehdW8Git3BQpwNZS9f0CAwEAAaOCAvEwggLtMCQGA1UdEQQdMBuCGWFwaS0zdC5z
YW5kYm94LnBheXBhbC5jb20wCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCBaAwHQYD
VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMGEGA1UdIARaMFgwVgYGZ4EMAQIC
MEwwIwYIKwYBBQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUF
BwICMBkaF2h0dHBzOi8vZC5zeW1jYi5jb20vcnBhMB8GA1UdIwQYMBaAFF9gz2GQ
Vd+EQxSKYCqy9Xr0QxjvMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9zcy5zeW1j
Yi5jb20vc3MuY3JsMFcGCCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYTaHR0cDov
L3NzLnN5bWNkLmNvbTAmBggrBgEFBQcwAoYaaHR0cDovL3NzLnN5bWNiLmNvbS9z
cy5jcnQwggF/BgorBgEEAdZ5AgQCBIIBbwSCAWsBaQB2AN3rHSt6DU+mIIuBrYFo
cH4ujp0B1VyIjT0RxM227L7MAAABUkI8Bj4AAAQDAEcwRQIhAIHuCBevjKTfgyu3
p69luk4DBTOJjBozTsnJIs+dVS7NAiASjAaBPD/bGWGXC8bayAREXvuPSr0W+xU0
l0T6Kaje9wB3AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABUkI8
Bn8AAAQDAEgwRgIhAPIWGT/KdSkWSlR3SzPA6O+sP16mpF9Mc/8BBKhAck0WAiEA
u/ie0GvZ8wctdK8OhOnOUUQvQ8njBqd7l5s2GfRWymMAdgBo9pj4H2SCvjqM7rko
HUz8cVFdZ5PURNEKZ6y7T0/7xAAAAVJCPAZmAAAEAwBHMEUCIHkB7wZfWQPm+ZCP
cUAOQwutIiMSXmKFUM9GiHzJ72VoAiEAh+44zz2mRc/NcwTvQsW1BQcjL12y8gji
UBJgtrlwZq4wDQYJKoZIhvcNAQELBQADggEBAEKkutMm4VqebHi49Zw35dFStnRb
RD9sUIpFvuvSCTnvM0uwFGHa01hoH6XCk0mQf7Hlv8eUjQCYEjq/yOy/qd1D/0FG
pG5QYXpiiB1rfJyGSTps6TMsSzhGJwZt6e7ZNJ29uGBvfaYi5S+qbxqUkEUIOoeE
+K77MUD5ouwN6mm3azvemVMoJEPwjbVUZZwfLlxBQbwX4C2Kdihrn/r+AkeYiLej
Q+1pdnXz9Hwj3SM+uZWpu8f7kbczSWsuQmSV4gparNkOTjk5TwJvyrS3z+DQW674
FdfkrYmxqiiaELhsMPhRyjKce5HA2ol1GsnJ0IJCPjJc2o40IiL1AL552eA=
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=PayPal Production/CN=api-3t.sandbox.paypal.com
issuer=/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 Secure Server CA - G4
---
No client certificate CA names sent
---
SSL handshake has read 3524 bytes and written 423 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 9E01CD86FA9CB07DAD505F17E34C099B2E4C8B85126C68DCF2946F8859FF6435
Session-ID-ctx:
Master-Key: 4BF94BD3EBEE701226ABD3B2344F6B325F21218761D755B02EA6B00FE90866396A9A317A59729D166A1B970AD8D3903B
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1455312915
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
---
Here is a screenshot of my settings:
If you're going to develop your app with OpenSSL lib, instead of using the trust store built into the Win Server OS (as the default trust store in a operating system may not always be up to date), there's an alternative to build the trust store from Curl project HERE (Curl provides a regularly-updated conversion in Privacy-Enhanced Mail (PEM) format from Mozilla, which you can use directly, and the Verisign Root package including G5-G4-G3 root certs are contained as well for this case)
A few more steps to check on your OpenSSL,
Check where your OpenSSL cert bundle is stored, run openssl version -a
, and it would report the directory used:
OpenSSL 1.0.2e 3 Dec 2015
built on: reproducible build, date unspecified
platform: Cygwin-x86_64
options: bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
...
OPENSSLDIR: "/usr/ssl"
Check the directory of OPENSSLDIR: "/usr/ssl" and look for certs dir under that
You may also check the version here to make sure 1.0.1e or above is installed to support TLSv1.2, which is another piece of the PayPal API endpoints upgrade requirements
Replace the tls-ca-bundle.pem with what you downloaded from Curl project (the Mozilla cert bundle)
your openssl returns the following:
depth=1 C = US, O = Symantec Corporation, OU = Symantec Trust Network, CN = Symantec Class 3 Secure Server CA - G4
verify error:num=20:unable to get local issuer certificate
that means you do not have Symantec Class 3 Secure Server CA - G4 installed in your certificate store, you can download the certificate from here and install it or just copy the following:
-----BEGIN CERTIFICATE-----
MIIFODCCBCCgAwIBAgIQUT+5dDhwtzRAQY0wkwaZ/zANBgkqhkiG9w0BAQsFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB+MQsw
CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVjIENs
YXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAstgFyhx0LbUXVjnFSlIJluhL2AzxaJ+aQihiw6UwU35VEYJb
A3oNL+F5BMm0lncZgQGUWfm893qZJ4Itt4PdWid/sgN6nFMl6UgfRk/InSn4vnlW
9vf92Tpo2otLgjNBEsPIPMzWlnqEIRoiBAMnF4scaGGTDw5RgDMdtLXO637QYqzu
s3sBdO9pNevK1T2p7peYyo2qRA4lmUoVlqTObQJUHypqJuIGOmNIrLRM0XWTUP8T
L9ba4cYY9Z/JJV3zADreJk20KQnNDz0jbxZKgRb78oMQw7jW2FUyPfG9D72MUpVK
Fpd6UiFjdS8W+cRmvvW1Cdj/JwDNRHxvSz+w9wIDAQABo4IBYzCCAV8wEgYDVR0T
AQH/BAgwBgEB/wIBADAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vczEuc3ltY2Iu
Y29tL3BjYTMtZzUuY3JsMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQjMCEw
HwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wawYDVR0gBGQwYjBgBgpg
hkgBhvhFAQc2MFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20v
Y3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vcnBhMCkG
A1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTUzNDAdBgNVHQ4E
FgQUX2DPYZBV34RDFIpgKrL1evRDGO8wHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnz
Qzn6Aq8zMTMwDQYJKoZIhvcNAQELBQADggEBAF6UVkndji1l9cE2UbYD49qecxny
H1mrWH5sJgUs+oHXXCMXIiw3k/eG7IXmsKP9H+IyqEVv4dn7ua/ScKAyQmW/hP4W
Ko8/xabWo5N9Q+l0IZE1KPRj6S7t9/Vcf0uatSDpCr3gRRAMFJSaXaXjS5HoJJtG
QGX0InLNmfiIEfXzf+YzguaoxX7+0AjiJVgIcWjmzaLmFN5OUiQt/eV5E1PnXi8t
TRttQBVSK/eHiXgSgW7ZTaoteNTCLD0IX4eRnh8OsN4wUmSGiaqdZpwOdgyA8nTY
Kvi4Os7X1g8RvmurFPW9QaAiY4nxug9vKWNmLT+sjHLF+8fk1A/yO0+MKcc=
-----END CERTIFICATE-----
Related
I am trying to explore AD integration and was able to succesfully complete the setup as described in AWS blog post, and verified that SSL connection is working fine from "Management box".
Based on my understanding, ldp.exe from Management box is working fine because management box is joined to this AD and certificates are propagated properly.
I have use case where another linux box (which can't be joined to AD) but should use LDAPS over SSL to do some user search. For this to work, I need to export SSL and install it on Linux box. I couldn't quite figure out how to find and export certificates in this example? Are those certificates are available on RootCA (or) SubordinateCA and how to export them? appreciate any help.
I'm assuming you generated the SSL cert in AWS via Amazon Certificate Services (ACS). Although ACS won't allow you to export the private key from ACS, you shouldn't need it. All you need to do is import the public certificate into the certificate trust store that your Linux box is using when it connects to the AD server. I can't tell you how to do that (not sure what the application is), but you should be able to extract the public cert using openssl. You'll point openssl to the ad server, and have it output the public cert.
I'm pretty sure this is the openssl command line that would do that:
openssl s_client -showcerts -connect activedirectory.yourdomain.com:636
You can download the certificate from the ldaps end point and install it as follows.
Install openldap client
sudo yum install -y openldap-clients
• Download and Add Server Certificate to the openldap cert path
openssl s_client -connect <LDAPSURL>:636 -showcerts </dev/null 2>/dev/null | openssl x509 -outform PEM > server.crt
• Configure LDAP Details
Vi /etc/openldap/ldap.conf
BASE dc=corp,dc=example,dc=com
URI ldaps://corp.example.com
TLS_CACERT /etc/openldap/certs/server.crt
I'm trying to get Ejabberd to work with letsencrypt certificates on centos7.
I keep getting errors about the certificates not being signed by a known CA.
I have created the certificates by certbot, and I joined the privkey and fullchain files to single file.
All c2s connections work fine, but s2s connections don't.
When starting Ejabberd I see the following relevant log entries:
[warning] <0.606.0>#ejabberd_pkix:check_ca_dir:386 CA directory /etc/ssl/certs doesn't contain hashed certificate files; configuring 'ca_path' option might help
[warning] <0.606.0>#ejabberd_pkix:mk_cert_state:240 certificate from /opt/ejabberd/conf/xxxx.pem is invalid: certificate is signed by unknown CA
Connections to for example draugr.de generate the following entries:
[info] <0.793.0>#ejabberd_s2s_in:handle_auth_failure:206 (tls|<0.792.0>) Failed inbound s2s EXTERNAL authentication draugr.de -> XXXXX.net (::FFFF:89.163.212.45): unable to get local issuer certificate
I hope someone can help me out, thanks!
[EDIT 2020 may]
It looks like ejabberd now has automatic acme support (meaning it can request the certificate on its own from letsencrypt). So what you read below is obsolete.
As of 2018 november,
Merely installing letsencrypt using certbot is enough click here to see how. Ejabberd uses the provided certificates.
Note that you may need to register multiple subdomains for some strict jabber clients to work properly.
conference.yourjabberdomain.com
pubsub.yourjabberdomain.com
upload.yourjabberdomain.com
yourjabberdomain.com
or install a wildcard certificate from letsencrypt
sudo certbot certonly --server https://acme-v02.api.letsencrypt.org/directory --manual --preferred-challenges dns -d *.yourjabberdomain.com
I think there is a rule in the ejabberd config file ejabberd.yml that allows this to happen
certfiles:
- "/etc/letsencrypt/live/*/*.pem"
I was able to solve it myself finally but i am out of office the next few days and can't get you the exact configuration to solve it.
But if I recall correctly I downloaded the CA bundle here https://curl.haxx.se/docs/caextract.html and there was some configuration parameter for ejabberd to use this CA bundle in stead of the default one.
Hope it helps you.
If it is working for c2s and not working for s2s then it looks like the s2s block in configuration file is not updated with certfile. I believe you have something like this for c2s:
port: 5222
ip: "::"
module: ejabberd_c2s
starttls: true
certfile: 'CERTFILE'
protocol_options: 'TLSOPTS'
Similarly your s2s block should have:
port: 5269
ip: "::"
module: ejabberd_s2s_in
starttls: true
certfile: 'CERTFILE'
protocol_options: 'TLSOPTS'
max_stanza_size: 131072
shaper: s2s_shaper
I want to make https tests using libcurl and openssl in c++.
I have the following code:
curl_easy_setopt(mEasyHandle, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(mEasyHandle, CURLOPT_SSL_VERIFYHOST, 2L);
result = curl_easy_setopt(mEasyHandle, CURLOPT_CAINFO , "ca.pem");
I have a Windows server that listens on 192.168.0.101:4443. When running the program from Visual Studio, the certificate verification works, but on Linux I get the error server certificate verification failed. CAfile: ca.pem CRLfile: none.
In ca.pem I have put the content generated in the server's certificate (testing on windows works, on Linux not).
* Trying 192.168.0.101...
* Connected to 192.168.0.101 (192.168.0.101) port 4443 (#0)
* found 1 certificates in ca.pem
* server certificate verification failed. CAfile: ca.pem CRLfile: none
* Closing connection 0
UPDATE:
I have a folder /etc/ssl/certs that contains a lot of ca certs files. I have copied ca.pem to /etc/ssl/certs and run update-ca-certificates which produced the output:
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d....done.
I have solved this. Was a certificate problem in fact. The code worked but the timestamp on the machine was before the certificate was generated.
This is the flow I use to setup my HTTPS server with SSL.
It works perfectly on Windows, OS X and Ubuntu 13. But it's failing to work on Ubuntu 14 only and I don't know why.
It's not the full code once it's very big, but I can complete with more details if necessary.
SSL_library_init();
m_sslContext = SSL_CTX_new( SSLv23_server_method() );
SSL_CTX_use_certificate_chain_file( m_sslContext, "path/to/certificate.crt" );
SSL_CTX_use_PrivateKey_file( m_sslContext, "path/to/privatekey.pem", SSL_FILETYPE_PEM );
m_mainSocket = ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ) );
...
::listen( m_mainSocket, SOMAXCONN );
...
SOCKET childSocketHandle;
while ( ( childSocketHandle = ::accept( m_mainSocket, ... ) ) > 0 )
{
sslChildSocket = SSL_new( m_sslContext );
SSL_set_fd( sslChildSocket, childSocketHandle );
SSL_set_accept_state( sslChildSocket );
...
SSL_read( sslChildSocket, bufferIn, sizeof( bufferIn ) );
...
SSL_write( sslChildSocket, bufferOut, sizeof( bufferOut ) ) );
}
The problem is: when I try to connect from a browser (Google Chrom), it says:
Unable to make a secure connection to the server. This may be a
problem with the server, or it may be requiring a client
authentication certificate that you don't have. Error code:
ERR_SSL_PROTOCOL_ERROR
Other browsers say similar messages...
When I try to connect from wget, I get:
wget https://example.com:443/
--2014-05-01 17:01:33-- https://example.com:443/
Resolving example.com (example.com)... 127.0.1.1
Connecting to example.com (example.com)|127.0.1.1|:443... connected.
ERROR: cannot verify example.com's certificate, issued by ‘/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=00000000’:
Unable to locally verify the issuer's authority.
To connect to example.com insecurely, use `--no-check-certificate'.
I just changed the serial of the certificate to 00000000.
So... If I finally follow the wget message and do...
wget https://example.com:443/ --no-check-certificate
... THEN the server works perfectly!
So, the conclusion I get is: the server itself IS working, but the handshake has some problem with the SSL certificate. The certificate is valid, used in other servers, Apache accepts it perfectly and as I told, once again, this same implementation works on Windows, OS X and Ubuntu 13. This problem is only happening on Ubuntu 14.
Things I tried to do:
I tried to update the OpenSSL [compiled it by myself] but nothing
happened.
I tried to try other methods instead of SSLv23_server_method(), nothing happened
I compiled in Ubuntu 13 and executed in Ubuntu 14 (AND THIS WORKED!)
Weard (item 3) is that if I compile in Ubuntu 13 and run on Ubuntu 14, it works! So maybe some Ubuntu 14 static library is with problem?
Is my SSL implementation correct? What else can be done so I can fix it for Ubuntu 14 and my server work everywhere?
--
I do openssl s_client -connect example.com:443 and get:
CONNECTED(00000003)
140735262471008:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 322 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
It works perfectly on Windows, OS X and Ubuntu 13. But it's failing to work on Ubuntu 14 only and I don't know why.
...
ERR_SSL_PROTOCOL_ERROR
ERR_SSL_PROTOCOL_ERROR indicates the client and server could not agree on a protocol - SSLv3, TLS 1.0, etc. I believe it corresponds to the protocol_version alert of TLS. See RFC 5246, Section 7.2.
OpenSSL has been TLS 1.2 since 1.0.1. See the OpenSSL CHANGELOG. However, Ubuntu prior to 14 disabled TLS 1.1 and TLS 1.2 for interop reasons. See Ubuntu 12.04 LTS: OpenSSL downlevel version and does not support TLS 1.2. Ubuntu 14 (and subsequent) enables TLS 1.1 and TLS 1.2. (And TLS 1.3 is around the corner: The Transport Layer Security (TLS) Protocol Version 1.3 (draft-ietf-tls-rfc5246-bis-00)).
There could be another issues if you have to go through a proxy. The problem is related to the ClientHello size. The ClientHello size increased with TLS 1.1 and TLS 1.2 because of additional cipher suites (more correctly, TLS 1.2 because TLS 1.1 did not add any cipher suites). Size should not matter except some proxies have fixed size buffer and other hard coded limits that simply break the exchange. It is an issue with some F5 and Ironport appliances.
You can test for TLS 1.2 and ClientHello size sensitivity with s_client:
openssl s_client -tls1_2 -connect <server>:<port> -servername <server> \
-cipher "SSL_RSA_WITH_3DES_EDE_CBC_SHA:TLS_RSA_WITH_3DES_EDE_CBC_SHA"
The above connects with TLS 1.2 and uses only 2 cipher suites (4 bytes). If it connects with 2 cipher suites, then drop the -cipher and see if it connects with the 80+ (over 160 bytes) that are builtin.
If it does not connect with TLS 1.2, then try either -tls1 or -ssl3.
EDIT: You problem is an ancient server and TLS 1.1 and TLS 1.2. See below on the steps to isolate the problem.
You have three potential fixes.
First
The first fix is to have the server upgrade to something that's not ancient. If its a proxy, then fix the proxy.
Second
If you need to modify the protocol versions, then perform the following to get SSLv3 or YLS 1.0 only:
m_sslContext = SSL_CTX_new( SSLv23_server_method() );
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
SSL_CTX_set_options(m_sslContext, flags);
Third
If you need to modify the cipher suite list:
m_sslContext = SSL_CTX_new( SSLv23_server_method() );
const char* const PREFERRED_CIPHERS = "kEECDH:kEDH:kRSA:AESGCM:AES256:AES128:3DES:"
"SHA256:SHA84:SHA1:!aNULL:!eNULL:HIGH:!RC4:!MD5:!SRP:!PSK:!ADH:!AECDH";
res = SSL_CTX_set_cipher_list(m_sslContext, PREFERRED_CIPHERS);
EDIT: You problem is an ancient server and TLS 1.1 and TLS 1.2. You need to use (1) from above, or (2) from above. Ideally, the ancient server would be fixed so everyone can benefit.
TLS 1.2 does not work:
$ openssl s_client -tls1_2 -connect www.example.com:443 -CAfile gd-class2-root.crt
CONNECTED(00000003)
140735211598300:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:337:
...
TLS 1.1 does not work:
$ openssl s_client -tls1_1 -connect www.example.com:443 -CAfile gd-class2-root.crt
CONNECTED(00000003)
140735211598300:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:337:
...
TLS 1.0 does work:
$ openssl s_client -tls1 -connect www.example.com:443 -CAfile gd-class2-root.crt
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
...
SSL v3 does work:
$ openssl s_client -ssl3 -connect www.example.com:443 -CAfile gd-class2-root.crt
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
...
When I try to connect from wget, I get:
...
Unable to locally verify the issuer's authority.
...
So... If I finally follow the wget message and do...
wget https://mydomain.com:443/ --no-check-certificate
... THEN the server works perfectly!
This is a different issue. wget is likely avoiding the issue by incorporating one of the fixes above. A Wirehsark trace would tell you.
Also, if you provided a real server name, we could help you identify the Root CA you should be using (to avoid Unable to locally verify the issuer's authority).
Here's what I am seeing with s_client:
$ openssl s_client -connect www.example.com:443
CONNECTED(00000003)
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certificates.godaddy.com/repository, CN = Go Daddy Secure Certification Authority, serialNumber = 07969287
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.example.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...
So you need Go Daddy Class 2 Certification Authority. You can get that from Go Daddy Repository, SSL Certificate Information. The file is gd-class2-root.crt, and you can pass it to s_client and the result is Verify return code: 0 (ok):
$ openssl s_client -connect www.example.com:443 -CAfile gd-class2-root.crt
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify return:1
depth=1 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", OU = http://certificates.godaddy.com/repository, CN = Go Daddy Secure Certification Authority, serialNumber = 07969287
verify return:1
depth=0 OU = Domain Control Validated, CN = *.example.com
verify return:1
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=*.example.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFRTCCBC2gAwIBAgIHKyKXfFXVZjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
ODcwHhcNMTQwMzIxMTYyMjU2WhcNMTUwMzIxMTYyMjU2WjA8MSEwHwYDVQQLExhE
b21haW4gQ29udHJvbCBWYWxpZGF0ZWQxFzAVBgNVBAMMDiouc3RheWZpbG0uY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyRsNuqBROD+6RsmkJk7S
KtTpFO5ke92AfWnEnZuKCbbRo/WjmtCPNLQC7fAQxPJb6i/cCt9cusQqlpFjHTg/
lD5Dqoqn/GXMe4hfKbV8VV3NAjWr8f0M/M1ftaL+zo5UtRjdAEIC9ysfbKqqBOxP
hqGPiL0QpkKQ5YZMiz3S4UZzwQ1Unjj43xH4IZFffsdwY5uJqfeoOl/6qBNAQIyg
1Hk00er/+1UlO2hpMe/qjiCZvGSRUat/O51AgyCPFGDmhSEi6rjyeLvEgpILzgR7
K1/BsCe2Kxi+SRIt8UK2jFjXSRnCQyjtgOitbk/sM0afhUUIb7ns95RWAiXt5CpD
0QIDAQABo4IBuzCCAbcwDwYDVR0TAQH/BAUwAwEBADAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQDAgWgMDQGA1UdHwQtMCswKaAnoCWG
I2h0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2RzMS0xMDYuY3JsMFMGA1UdIARMMEow
SAYLYIZIAYb9bQEHFwEwOTA3BggrBgEFBQcCARYraHR0cDovL2NlcnRpZmljYXRl
cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzCBgAYIKwYBBQUHAQEEdDByMCQGCCsG
AQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wSgYIKwYBBQUHMAKGPmh0
dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZF9pbnRl
cm1lZGlhdGUuY3J0MB8GA1UdIwQYMBaAFP2sYTKTbEXW4u6FX5q653aZaMznMCcG
A1UdEQQgMB6CDiouc3RheWZpbG0uY29tggxzdGF5ZmlsbS5jb20wHQYDVR0OBBYE
FOZLbPozya++C27Grhs5pPUut4WFMA0GCSqGSIb3DQEBBQUAA4IBAQBPv85UBt3g
1XGHwZ9ARxpG9InoHRQledSbRckchU35awnIXuXd6pE+kZ7RctR6BywiPRrQnmYm
0D7wHP+BVoN2cZIkTHHgx/hILGTYk47CKyVcL9+WyDd5UXkJYyfdMzfia6dnG4wZ
ucsdR8Ete2do35yZmCZHU5L9KwXarQRuNexbiOqb4kBjUaIhN79NZs1h812QWLLB
+uRhvHOfQuSleEx1ggou/rwaYKNGYrIJl4/kpCquDXbqebkR1B+ad49GD+yBMyOm
/AOfGSU6YTUfZRGjzS2yAozs+QZFUrZTDHyt6Z93OLD+4O07SSAfTD3AlQlG/V1M
KwHuBUl22QD4
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=*.example.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy Secure Certification Authority/serialNumber=07969287
---
No client certificate CA names sent
---
SSL handshake has read 2765 bytes and written 843 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID: 990D00002F519EEFC297CD4CB157B2F7...
Session-ID-ctx:
Master-Key: A4B16EA84F4CD1E8D56A0B601A678AEE...
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1399002932
Timeout : 300 (sec)
Verify return code: 0 (ok)
I want to know if Apache Tomcat supports TLS v1.2 protocol. I didn't find any documentation about this! Thanks!
I have a similar use case, which is to enable Tomcat 7 to strictly use only TLSv1.2, not to fall back to earlier SSL protocols such as TLSv1.1 or SSLv3. The following steps will answer how to enable Tomcat to support TLSv1.2.
I am using: C:\apache-tomcat-7.0.64-64bit and C:\Java64\jdk1.8.0_60.
Following this instruction: https://tomcat.apache.org/tomcat-7.0-doc/security-howto.html. Tomcat is relatively simple to setup SSL support.
From many references I tested many combination, finally I found 1 which will enforce Tomcat 7 to accept TLSv1.2 only. 2 places needed to touch:
1) In C:\apache-tomcat-7.0.64-64bit\conf\server.xml
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="ssl/.keystore" keystorePass="changeit"
clientAuth="false" sslProtocol="SSL" sslEnabledProtocols="TLSv1.2" />
where
keystoreFile = local self-signed trust store
org.apache.coyote.http11.Http11Protocol = JSSE BIO implementation.
We don't use org.apache.coyote.http11.Http11AprProtocol, because it is powered by openssl. The underlying openssl will fall back to support earlier SSL protocols.
2) When start up Tomcat, enable the following environment parameters.
set JAVA_HOME=C:\Java64\jdk1.8.0_60
set PATH=%PATH%;C:\Java64\jdk1.8.0_60\bin
set CATALINA_HOME=C:\apache-tomcat-7.0.64-64bit
set JAVA_OPTS=-Djdk.tls.client.protocols="TLSv1.2" -Dsun.security.ssl.allowUnsafeRenegotiation=false -Dhttps.protocols="TLSv1.2"
JAVA_OPTS restriction is required, otherwise Tomcat (which is powered by Java8) will fall back to support earlier SSL protocols.
Start up Tomcat C:\apache-tomcat-7.0.64-64bit\bin\startup.bat
We can see JAVA_OPTS appears in Tomcat startup log.
Oct 16, 2015 4:10:17 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Djdk.tls.client.protocols=TLSv1.2
Oct 16, 2015 4:10:17 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dsun.security.ssl.allowUnsafeRenegotiation=false
Oct 16, 2015 4:10:17 PM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dhttps.protocols=TLSv1.2
Then, we can use openssl command to verify our setup. First connect localhost:8443 with TLSv1.1 protocol. Tomcat refuses to reply with Server certificate.
C:\OpenSSL-Win32\bin>openssl s_client -connect localhost:8443 -tls1_1
Loading 'screen' into random state - done
CONNECTED(000001C0)
5372:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:.\ssl\s3_pkt.c:362:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 0 bytes
Connect localhost:8443 with TLSv1.2 protocol, Tomcat replies ServerHello with certificate:
C:\OpenSSL-Win32\bin>openssl s_client -connect localhost:8443 -tls1_2
Loading 'screen' into random state - done
CONNECTED(000001C0)
depth=1 C = US, ST = Washington, L = Seattle, O = getaCert - www.getacert.com
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
0 s:/C=SG/ST=SG/L=Singapore/O=Xxxx/OU=Development/CN=Myself
i:/C=US/ST=Washington/L=Seattle/O=getaCert - www.getacert.com
1 s:/C=US/ST=Washington/L=Seattle/O=getaCert - www.getacert.com
i:/C=US/ST=Washington/L=Seattle/O=getaCert - www.getacert.com
---
Server certificate
-----BEGIN CERTIFICATE-----
(ignored)
-----END CERTIFICATE-----
subject=/C=SG/ST=SG/L=Singapore/O=Xxxx/OU=Development/CN=Myself
issuer=/C=US/ST=Washington/L=Seattle/O=getaCert - www.getacert.com
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2367 bytes and written 443 bytes
This proves that Tomcat now strictly respond to TLSv1.2 request only.
TLS version 1.2 is supported by the Oracle JDK version 7, in the JSSE implementation. As Tomcat uses JSSE as underlying SSL library, it should be supported from JDK version 1.7 onwards. Also check your enabled SSL cipher suites in Tomcat.
If you are using Apache as a proxy, please check the Apache and underlying OpenSSL documentation.
Some links:
http://docs.oracle.com/javase/7/docs/technotes/guides/security/enhancements-7.html (Java SE 7 Security Enhancements)
http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html
http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
As mentioned by others, Tomcat supports TLSv1.2 via the JSSE in JDK 7+.
Tomcat does NOT support TLSv1.1 or TLSv1.2 when used with Tomcat Native (APR). See https://issues.apache.org/bugzilla/show_bug.cgi?id=53952.
Update: looks like TLSv1.2 will finally be supported in Tomcat Native 1.1.32 and Tomcat 8.0.15/7.0.57.
I was also looking to upgrade sslProtocol to TLSv1.1 and as mentioned in the below links on Java6 and Java7
Java6
http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html
Java7
http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html
The SSLContext supported in Java6 are SSL, TLSv1 and in Java7 SSL, TLSv1, TLSv1.1 and TLSv1.2 are supported.
So, to enable TLSv1.1 or TLSv1.2 in tomcat, just upgrade to Java7 and change the sslProtocol in Connector in server.xml of tomcat.