How to Grab SSL Certificate in OpenSSL - c++

So I have been searching high and low for how to validate my server's certificate from within OpenSSL in a C++ application I am developing, and I finally got a hint. However, I am still missing a few steps.
So I found out that OpenSSL has a ssl client application called s_client. When I use the following command:
echo -n | openssl s_client -connect mywebsite.me:443 -debug | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > my.cert
I receive this error as I do within my application:
verify error:num=20:unable to get local issuer certificate
It's not until I did some more searching that I found out what the error meant and that I had to do the following:
echo -n | openssl s_client -connect mywebsite.me:443 -debug | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > my.cert
echo -n | openssl s_client -connect mywebsite.me:443 -debug -CAfile my.cert
The first command connects, receives a response, saves it to a file, but fails to validate the response. The second reconnects sending the saved file and allows the certificate to be properly verified.
My question is, how can I grab the stream that is being send to sed and send "my.cert" in c/c++ preferably in one connect? I have been walking the s_client code but can't seem to find it.

openssl s_client -connect mywebsite.me:443 -debug
...
I receive this error as I do within my application:
verify error:num=20:unable to get local issuer certificate
mywebsite.me is certifed by Go Daddy. In particular, Go Daddy Class 2 Certification Authority.
$ openssl s_client -connect mywebsite.me:443
CONNECTED(00000003)
depth=2 C = US, O = "The Go Daddy Group, Inc.", OU = Go Daddy Class 2 Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/O=breezi.com/OU=Domain Control Validated/CN=breezi.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
2 s:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...
Navigate to Go Daddy Repository, SSL Certificate Information and fetch Go Daddy Class 2 Certification Authority Root Certificate. You can't do a simple wget with a URL because GoDaddy has f**k'd up the download with javascript (it fetches a web page rather then the certificate). The GoDaddy root is saved as gd-class2-root.crt.
Then, run openssl s_client again with the -CAfile option. The certificate is expired, so you'll receive Verify return code: 10 (certificate has expired). But it clears the trust issue.
$ openssl s_client -CAfile gd-class2-root.crt -connect mywebsite.me:443
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 O = breezi.com, OU = Domain Control Validated, CN = breezi.com
verify error:num=10:certificate has expired
notAfter=Sep 29 02:23:46 2013 GMT
verify return:1
depth=0 O = breezi.com, OU = Domain Control Validated, CN = breezi.com
notAfter=Sep 29 02:23:46 2013 GMT
verify return:1
---
Certificate chain
0 s:/O=breezi.com/OU=Domain Control Validated/CN=breezi.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
2 s:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFUzCCBDugAwIBAgIHJ84NzOXfzDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
ODcwHhcNMTIwOTI5MDIyMzQ2WhcNMTMwOTI5MDIyMzQ2WjBNMRMwEQYDVQQKEwpi
cmVlemkuY29tMSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0ZWQxEzAR
BgNVBAMTCmJyZWV6aS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDVdxshW9y7VRrN8VtPeKqfC2PXdBnxSH2Lh3jzu6ESOuQw3Jn4oFHTVNJBGxA6
v3dh607UroG9LfjN3rz+qvfmN8A7+gKtJOVM7Grc+IlTU/gy+1Ks8cs84Gsn6cq9
3yM3Qix3POf//T8q6jsYuthmzKpAcrqZizF4OFT2bDnHr2WHDDIL+BXVSBbVRgQM
r8TOtPAagiEgpjpgtSTDMTuk4fDnWolyLMW8HhBKMq2HkfoV/fD3osS0ZGgqTbwm
KnPbdAXmonMWztEr8tJe2SRdQx5HlJ5VDNgH5/ckpFnebSo0pUmthHAI5tAMiBRB
jShnAHu+GVczKuc03gYTNSQXAgMBAAGjggG4MIIBtDAPBgNVHRMBAf8EBTADAQEA
MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCBaAw
MwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9nZHMxLTc3
LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcBMDkwNwYIKwYBBQUHAgEWK2h0
dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8wgYAGCCsG
AQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20v
MEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3Jl
cG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9rGEyk2xF
1uLuhV+auud2mWjM5zAlBgNVHREEHjAcggpicmVlemkuY29tgg53d3cuYnJlZXpp
LmNvbTAdBgNVHQ4EFgQUPbIjjMZfa7Cmna7cApwl4ltIWIgwDQYJKoZIhvcNAQEF
BQADggEBAAbv7E5Gg/s0+2u4hvxHvFs5fNCT/x3QKw2AjECYM5e/jdzIBPPzA9us
zT20mDWGj/2uxoxpYg8Yjh82G68eCQ/DykKVskiR4Fiud4q9+5S+ZBsZsozNb6F8
GO2ckdhR4mDI/6xaSCzoCZljlpNXLuhOjvK3/1frxVgzbNxwERIIT8eVhBbPh7KG
3r+AQi3bbtcLJP4j0cNMHWup8FcTeRJyobjAwfOB/ot62ZeDuhtDM37wmL6XWAfw
0a0JjAD1xb8iYeKQ+aOqKTTcExdlckQFPnjfJwqk+xbXoXZGWI6pTdtTTYOOeJGu
ZXKr/ICABK8DviHq0RfVp3lnbVgfwkQ=
-----END CERTIFICATE-----
subject=/O=breezi.com/OU=Domain Control Validated/CN=breezi.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 4497 bytes and written 518 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 41C9F384CAB44419C20452CCBD7B7346A224F55906F943DD977198B48B44FC33
Session-ID-ctx:
Master-Key: BAD61F7C0883D5C3918DCB766C83A85FFF4C533823C5CA41C62617701E87C66C6D1351C30521B337267753B16C830BBD
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket:
0000 - 77 82 b3 42 d2 32 f9 4f-32 55 ea 03 0a 0f 66 16 w..B.2.O2U....f.
0010 - 97 8f 93 2e 47 4e ae cc-d2 a8 c0 ee 81 47 63 be ....GN.......Gc.
0020 - 07 40 fc c4 a0 28 78 e6-a2 97 22 73 87 28 77 f2 .#...(x..."s.(w.
0030 - a2 80 a3 6f d3 3c 50 cc-82 a8 0c 8e 9b 04 f0 7e ...o.<P........~
0040 - 12 24 d2 2a 9c 6b ef b8-49 d7 16 f1 45 80 e1 44 .$.*.k..I...E..D
0050 - fe d4 87 0e 92 80 b3 63-98 36 5e 9b 39 91 a3 76 .......c.6^.9..v
0060 - 3a 37 dc 1b 4d de 7e 01-22 d0 cd c0 7a 4c cf f8 :7..M.~."...zL..
0070 - ae d4 a5 fe 74 19 03 db-99 28 b7 09 ce 08 35 dd ....t....(....5.
0080 - 33 ff cd 9f 88 63 05 8a-f4 d1 f7 32 16 0b ed b9 3....c.....2....
0090 - 9f b4 ee 53 2d 8b b4 c2-27 bd b5 4d e3 19 a3 72 ...S-...'..M...r
Compression: 1 (zlib compression)
Start Time: 1393884832
Timeout : 300 (sec)
Verify return code: 10 (certificate has expired)
It's not until I did some more searching that I found out
what the error meant and that I had to do the following:
echo -n | openssl s_client -connect mywebsite.me:443 -debug | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > my.cert
echo -n | openssl s_client -connect mywebsite.me:443 -debug -CAfile my.cert
No, this is not the way to do things.
If you own the mywebsite.me domain, then you can get a free Class 1 certificate from StartCom. Their certifcates are trusted by most mobile and desktop browsers.
While StartCom does not charge to issue the certificate, they do charge for revocation because that's what costs money. (Other CAs charge you for the revocation up front and then pocket the money if not needed).

Related

Using Boost-Beast (Asio) http client with SSL (HTTPS)

I am new to SSL and the Boost-Beast library, and also C++, but that's a different story.
I have a question regarding using HTTPS (SSL) with Beast. I am going to use the library to connect to a REST service and post JSON to a server where I do not control the certificates, the API etc.
And it kind of works.
The thing is that I do not clearly understand HOW it works. In the example that comes with Beast it is referenced to a file example/common/root_certificates.hpp where it is two certificates in base64 format or something like that.
When I tried the example, I got it to work with POST a JSON string to a server, let's call it "exampleserver.com". Connected to both port 80 and 443. Even though I commented out the line where it calls the root certificate function, load_root_certificates(ctx);. No errors from handshaking or anything else showed up. And the server responded correctly.
So, my questions are then:
1) Did the Beast library get the certificate from exampleserver.com or did I already have it installed and that's why it worked? If so what happens when it expires? Do I have to reinstall a new one on every client that uses my application?
I would prefer to not have any hardcoded certificates in my code to check it upon. The certificate says DigiCert Global Root CA -> DigiCert SHA2 Secure Server CA is that a standard certificate maybe that comes with the browser?
2) Did it just use plain HTTP over port 443 (no SSL)? Don know if this is possible at all...
Even though I commented out the line where it calls the root certificate funtion, "load_root_certificates(ctx);"
In that case, openssl uses the systemwide default certificate store (e.g. on linux /etc/ssl/certs), so the "usual" authorities will be trusted (just like e.g. your browser does).
1) Did the Beast library get the certificate from "exampleserver.com" or did I already have it installed and thats why it worked?
Yes.
If so what happens when it expires?
It will fail to verify. Test it, if you want: https://expired.badssl.com/
That site has many excellent SSL tests (https://badssl.com)
The certificate says "DigiCert Global Root CA -> DigiCert SHA2 Secure Server CA" is that a standard certificate maybe that comes with the browser?
The browser's trusted certificates aren't relevant (you're not using the browser). However, you can see openssl's (see above), or you can test using something like
openssl s_client -connect exampleserver.com:443 -verify -showcerts
Which prints something similar to
verify depth is 0
CONNECTED(00000003)
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = US, ST = TX, L = Houston, O = "cPanel, Inc.", CN = "cPanel, Inc. Certification Authority"
verify return:1
depth=0 CN = tradingfleet.com
verify return:1
---
Certificate chain
0 s:/CN=tradingfleet.com
i:/C=US/ST=TX/L=Houston/O=cPanel, Inc./CN=cPanel, Inc. Certification Authority
1 s:/C=US/ST=TX/L=Houston/O=cPanel, Inc./CN=cPanel, Inc. Certification Authority
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFUjCCBDqgAwIBAgIQPI9I0oyjgNMrudesOYyqgDANBgkqhkiG9w0BAQsFADBy
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCVFgxEDAOBgNVBAcTB0hvdXN0b24xFTAT
BgNVBAoTDGNQYW5lbCwgSW5jLjEtMCsGA1UEAxMkY1BhbmVsLCBJbmMuIENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MDIxODAwMDAwMFoXDTE4MDUxOTIzNTk1
OVowGzEZMBcGA1UEAxMQdHJhZGluZ2ZsZWV0LmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANe5zu81biDwwIloBMFHWc2OvoiGTNBr2aya8auWrzRm
rmbOfugZOaIAms79jnINCQ7jy0Qk2xwblgCifCg7y/UfSXvv7IWUWcEDywsAoyz/
sUc9myvQbot+kD1DaxVoyN85LnDehaYF5+myDznJISQe1ei01n/aIF8gwOz4k3Gn
R07Zh0sDRBjIiRsAL6ZljrPRk47cul2+8pD0qNJHHN0QX6hz/KPOugTiivI1+ymo
onSeeN29oh5oTtCHP2yj9+RNsCNcPAnbDawy0RAgFi2W5GyHiIo/NkUxBXN8tQxH
2xrPnY+MQJHUcKXJd//DTX6tWoQqo4xisN6Q9iZ3+R8CAwEAAaOCAjkwggI1MB8G
A1UdIwQYMBaAFH4DWmVBa6d+CuG4nQjqHY4dasdlMB0GA1UdDgQWBBQKTFmhmBNx
pS9uBbXjqE1ZjCOiFjAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA6BgsrBgEEAbIx
AQICNDArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29tL0NQ
UzAIBgZngQwBAgEwTAYDVR0fBEUwQzBBoD+gPYY7aHR0cDovL2NybC5jb21vZG9j
YS5jb20vY1BhbmVsSW5jQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwfQYIKwYB
BQUHAQEEcTBvMEcGCCsGAQUFBzAChjtodHRwOi8vY3J0LmNvbW9kb2NhLmNvbS9j
UGFuZWxJbmNDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNydDAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuY29tb2RvY2EuY29tMIGXBgNVHREEgY8wgYyCEHRyYWRpbmdm
bGVldC5jb22CF2NwYW5lbC50cmFkaW5nZmxlZXQuY29tghVtYWlsLnRyYWRpbmdm
bGVldC5jb22CGHdlYmRpc2sudHJhZGluZ2ZsZWV0LmNvbYIYd2VibWFpbC50cmFk
aW5nZmxlZXQuY29tghR3d3cudHJhZGluZ2ZsZWV0LmNvbTANBgkqhkiG9w0BAQsF
AAOCAQEAPFIZv1oHXm79+uoLnP9Sya2qEghOn/uPpNtappgUSrh2Pb0MueX84C0P
4HRS4yHRO1TD9ZOfCuPsguzXhl+RUB7Asl2iAhwthoZGMLhv6uaUnAUHZbpdkJY3
r/quuWHXDGNoe2quAOxGLPDO7WMvrDh1hFi7x7AGshkRSZ4DREBnCS7iprKzKL6H
BaNqtAlWgoXcSSg1RpnbU2o4bWIv8mZG0ATr7Cc8VSf04SjBLZnLTNeqo6Z+ALQ3
yrFsAytim6857FB231V5NEvLh+iZjSOuBG9xv+4Nw46bVz9z8QxB3czAodrDGXbB
lgH1s5f486lRq45dRn/hGY+DZjJXgg==
-----END CERTIFICATE-----
subject=/CN=tradingfleet.com
issuer=/C=US/ST=TX/L=Houston/O=cPanel, Inc./CN=cPanel, Inc. Certification Authority
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4988 bytes and written 431 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 24CB439538212A23E0391887F856E369858AB6864B25DA5F1FD618550C41EB92
Session-ID-ctx:
Master-Key: 1B8A3028923478527196B429D10F3584C5FA5DE4175C834CBBEF9EB19013FBFE58E7668CED9C0877E15F4F214A61F80C
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - ca 83 5a 76 c2 51 7b c7-68 15 12 a7 cb c9 f5 35 ..Zv.Q{.h......5
0010 - 0a dc c1 2a 90 fd 61 69-0a d9 89 09 f0 c4 b3 40 ...*..ai.......#
0020 - 79 dc 97 8a c5 0d a1 67-85 5e b4 25 47 94 ed 23 y......g.^.%G..#
0030 - 42 df b2 99 25 ec b1 fa-d7 3e 3e 24 37 ef 67 ef B...%....>>$7.g.
0040 - 56 f4 d2 57 cd 47 48 bd-d7 86 b1 2f b5 76 d6 db V..W.GH..../.v..
0050 - 12 9d 7a d3 94 b0 58 bf-c5 c4 3e 7d 05 98 75 1d ..z...X...>}..u.
0060 - 31 bc 9b 23 4f a7 ce 37-af 77 8a 96 89 20 20 64 1..#O..7.w... d
0070 - 3d bf de 25 b2 09 02 20-49 09 b5 57 a1 c3 75 ed =..%... I..W..u.
0080 - 97 ec 51 d2 46 f7 c6 b7-4a d8 b2 db 95 eb ac d6 ..Q.F...J.......
0090 - be 76 14 80 ca 08 dc b7-b6 cb e9 c9 cc 8b 45 bd .v............E.
00a0 - d7 1d a7 88 9b a4 91 33-aa 23 fe 23 65 b8 e1 d9 .......3.#.#e...
00b0 - 98 f6 55 1e 25 32 97 b5-22 ac d0 58 01 a6 42 60 ..U.%2.."..X..B`
Start Time: 1522150150
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
^C
2) Did it just use plain http over port 443 (no SSL)? Don know if this is possible at all...
No it didn't.
It's possible only given a whacky server config, but usually if your server connects https from a browser, it will be impossible to connect plain:
https://askubuntu.com/questions/860511/is-it-possible-to-set-same-port-work-with-http-and-https
on whacky configs: Nodejs HTTP and HTTPS over same port
As suggested by Vinnie Falco, in the file example/common/root_certificates.hpp, use the following header only library https://github.com/djarek/certify
In your code add the following includes
#include <boost/certify/extensions.hpp>
#include <boost/certify/https_verification.hpp>
And replace the initial code:
// This holds the root certificate used for verification
load_root_certificates(ctx);
// Verify the remote server's certificate
ctx.set_verify_mode(ssl::verify_peer);
by this:
ctx.set_verify_mode(ssl::context::verify_peer );
boost::certify::enable_native_https_server_verification(ctx);
Tested quickly with site badssl.com and sites with good ssl certificate. And it's work like a charm.
Possibly, you already figured it out by now.
I tried the same beast sample (Boost libraries 1.70) and had to make the following change to the ctor of session (I did it there it may be possible to make the change at some other place in code as well):
ws_.next_layer().set_verify_mode(boost::asio::ssl::verify_peer);
ws_.next_layer().set_verify_callback(std::bind(&session::verify_certificate, this, _1, _2));
and added a method (that I copied as is from the Asio client sample):
bool verify_certificate(bool pverified_ok, ssl::verify_context& ctx)
{
char subject_name[256];
X509 *cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
std::cout << "Verifying " << subject_name << std::endl;
return pverified_ok;
}
This change causes the verification to fail (I had removed the hard-coded certificates since I did not want to use those). The callback assists in logging that the server certificate was actually being verified.
Just like the Asio sample adding a CA certificate to the ssl::context e.g.
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
ctx.load_verify_file("ca.pem"); // CA certificate
Causes the verification to pass.
You need to create the self-signed CA certificate and server certificate signed by it and place it in the server code (again from Asio sample) e.g.
context_.use_certificate_chain_file("..\\sample-server1.pem");
context_.use_private_key_file("..\\sample-server1-key.pem", boost::asio::ssl::context::pem);
context_.use_tmp_dh_file("..\\dh2048.pem");

Using JAX-WS in Weblogic 10.3.6 combining 2waySSL and Proxy

I have implemented a connector to different kinds of webservice with JAX-WS in weblogic 10.3.6, the connector can be configured with 2waySSL, proxy and combine both of them.
The implementation to use proxy works properly using ClientProxyFeature.
In the same way with 2waySSL using a custom SSLSocketFactory as Oracle says in the documentation. Persisting the State of a Request over SSL (JAX-WS Only)
((BindingProvider) port).getRequestContext().put(
JAXWSProperties.SSL_SOCKET_FACTORY,
SSLClientUtil.getSSLSocketFactoryFromSysProperties());
The issue occurs when combine both features. The handshake does not happend (ClientHello)
The error is:
ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', READ: TLSv1.2 Alert, length = 64
Padded plaintext after DECRYPTION: len = 64
0000: F0 E5 6E 9F 6F F4 BB 2E 07 29 56 FE 34 0A 10 0B ..n.o....)V.4...
0010: 02 28 7E 75 92 F7 03 4E CD 3A 7E 0B E2 6A 7C 8E .(.u...N.:...j..
0020: 3B F8 4E F5 98 A3 D3 B4 67 76 20 49 1B 77 07 5E ;.N.....gv I.w.^
0030: 9D 66 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D .f..............
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', RECV TLSv1.2 ALERT: fatal, handshake_failure
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
<13-sep-2017 09H32' CEST> <Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]weblogic.security.SSL.jsseadapter: SSLENGINE: Exception occurred during SSLEngine.unwrap(ByteBuffer,ByteBuffer[]).
javax.net.ssl.SSLException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:188)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1614)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1582)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1751)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1043)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:865)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:740)
Debuging and decompiling weblogic source I can see that the HttpsClient when use proxy does not use the custom SSLSocketFactory.
1) In the transport class weblogic.wsee.jaxws.transport.http.client.HttpClientTransport weblogic opens the connection:
protected HttpURLConnection openConnection(Packet paramPacket)
…
localSSLSocketFactory = (javax.net.ssl.SSLSocketFactory)this.context.invocationProperties.get("com.sun.xml.ws.transport.https.client.SSLSocketFactory");
if ((localSSLSocketFactory != null) && ((localSSLSocketFactory instanceof javax.net.ssl.SSLSocketFactory)))
{
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("set (jdk) ssl socketfactory to wls socketfactory");
}
((weblogic.net.http.HttpsURLConnection)localObject3).setSSLSocketFactory(new MySSLSocketFactory((javax.net.ssl.SSLSocketFactory)localSSLSocketFactory));
}
…
As you can see, set the custom SSLSocketFactory.
2) Without a proxy, the weblogic.net.http.HttpsClient uses the custom SSLSocketFactory to create the socket
this.serverSocket = localSocketFactory.createSocket(arrayOfInetAddress[i], paramInt);
The localSocketFactory is the custom SSLSocketFactory.
3) But if uses proxy then create a new SSLSocketFactory
private void makeConnectionUsingProxy(String s, int i, boolean flag)
throws IOException
{
javax.net.ssl.SSLSocketFactory sslsocketfactory;
int j;
SSLContextWrapper sslcontextwrapper = SSLSetup.getSSLContext(sslInfo);
sslcontextwrapper.getHostnameVerifier().setProxyMapping(s, host);
sslcontextwrapper.getTrustManager().setProxyMapping(s, host);
sslsocketfactory = sslcontextwrapper.getSSLSocketFactory();
The sslInfo is an object without the keystore or truststore informed in the SSLSocketFactory. I haven't seen any way to inform the object sslInfo (weblogic.security.SSL.SSLClientInfo)
The variables to start the weblogic are the next:
-Dweblogic.security.SSL.nojce=true -Djavax.net.debug=all -Dssl.debug=true
-Djavax.net.ssl.keyStore=XXXXXs -Djavax.net.ssl.keyStorePassword=XXXXX
-Djdk.tls.enableRC4CipherSuites=true -Djsse.enableSNIExtension=false -Dweblogic.ssl.JSSEEnabled=true -Dweblogic.security.SSL.enableJSSE=true -Dweblogic.security.SSL.nojce=true -Dweblogic.security.SSL.ignoreHostnameVerification=true
The custom SSLSocketFactory is create with this params and with the default trustore. When no proxy is used everything works propertly.
I don't understand why to make the connection with a proxy weblogic does not use the same SSLSocketFactory.
Any ideas?
Oracle people have confirm us that is a "bug" in this implementation, it is only possible to solve with the property -DUseSunHttpHandler=true.
In Oracle 12 you can use the setter method setUseSunHttpHandler of the ClientProxyFeature. But with the weblogic implementation is not possible to solve.

Build a certificate context from a .pem file containing certificate and private key

I'm developing a C++/Windows TLS client.
I can build a certificate context for the server certificate in this way:
ReadFile(hFile, cert, 8192, &len, NULL);
CryptStringToBinary(cert, readLen, CRYPT_STRING_BASE64_ANY, binCert, &binLen, NULL, NULL);
PCCERT_CONTEXT pContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE*)binCert, binLen);
but if I try do to the same with a client certificate (.pem file containing certificate and private key) I got a fail.
I think this is due to the fact that server as only one base64 section
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
while the client has two:
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY----
-----END PRIVATE KEY----
But that's just my guess.
Can someone provide a code snip that builds a certificate context from this kind of .pem file?
Acceptable code must not parse directly the file, I mean I don't want to parse the file to separate certificate from key.
Thanks!
Let me include an example of pem I would like to use:
Bag Attributes
friendlyName: client
localKeyID: 54 69 6D 65 20 31 34 38 34 38 33 33 35 35 39 31 30 39
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMuupRTZX52zM2
1xt/3X3JhPtjtV5k4Ua+t/KFMOa0GERyJfzYFvgaKPUQWmNCkfK+oflG8IeNhoPl
+axvWckGb9Hy78M/BPyj19h96q09KpgRtPzl7QPhQUigFe7a+k6kb+unH+21bv1X
u3btN36Q/hTMHziq+EgYSuuWhDau2NQ2xgCSrJdMOox84BPaI8RqRQhL9Ob3Q5vC
ZS936NABYkBstSIMx+w9gsP6aLh+99okBa30EY9hriP8hPJ3UfIL/0ZcamCxhFOt
p3NZlI5WNz+7Gxt0Z1JtGF86fXIj65qntLDC+J2E8/6imUTA7G0KLDbgngGga2Vm
IYtckCnLAgMBAAECggEAcnJa4rBYkqAy9Qky2jvbQXgRgB+3cPVuMtdpv4MitLKM
MLODsNjGQPl8ZXPh4SjtZhvt2fZEEJ2NxlXYSzcJ5YtE9mWJ5ATJpl3XLCywQ204
LU3bwjzI2ndAPh2EtO0QYWQffAGhRLeS8CRfyyQmoK8ouSMK7qh0xP+8yxuF5h9X
1TW9wLeB3UEI0OtpaBGtOBHq06iX0BLdaszDB3cpaH3v8RCXtrtdaB2oPvMuooKf
gQFVNik7lgahMLBEXnc8BR5/LM/lxABODADU+PUvT0c8xrpi6BmOT8V5qWWsZnZC
LWTnOKSUbHz7HdTVHL1q0qMIELI7sVjL/CA4A7kRgQKBgQDxG6hfx/OYdXQaaFm5
uWexlrVNkOirwuO4Qq46rzzYnn0mSje5btBLo872sF2/5Hfkp+4PqcI+r1qM+hGe
xYl8OH1ZELXAhPVDoix9spunh7Kyaf4cxldHVh0S+aJkKuoIu8bx3UwnDjFu55zp
z8FfI7IvKziIv5cYXyG10zFtkQKBgQDZYA8Z219W9kiDc6rPuEocGATEOQ2pEu1H
1IBwjDolLAEiMQU+TfN2M/DJpsJYIIOws2aXY9bykGEC/NmlmUXp0aUrr7gvcyXQ
bVC/Tb0c//HWs5bZJx0bfM6tuaKU6t9anBSCShLk+Sr84tDX7SdP3Qtax6HQnkZ/
eMj3TSgjmwKBgQDEy4Jey2G0qwmdFFdIFGDivtQ0/3Yp2+Tq3OJA3A+Z76LOwf1B
yYUSeB3RlJqwqdaCN99DwZfeelo6f1IqeamCTslhDRaMkPlvvsr5vfL2hvgAUCst
aWaLv2nztvYpNC3Z+wqjF7G0nw0SLNIStZRsB0LE5U47r8WwCtYFBuBtQQKBgCUK
2YfuejC3h2PfMhxzqy1eanGFx24oa4byD3EedEohVZAeCmazoelisIWshTG/WLGj
4Lerq9VqBR4dOHmfxOozb5IiP6DWXntGJZx0AuYON4f+0pXutGcavZ2dJLd7ztQC
BPyu4sliLJErlas2HpzdbjHqEwkZ76mJS7XY0B5BAoGBAMiH9bMvVneJ9IOJyS0i
rosw53t9GW9m9jIKvkMyFxlyBTyrIyqOCFhnbku7wyAT8LIWqaLEWoUU1aA1Jdki
0xjnhK/3hkN1jVq66a0Oc6sOS9RY0Nobpc9sRJxbRIaunjUV/nmGqrtgQhIoOYhg
KW8xlDPBCuTaJ61PjgpFssKG
-----END PRIVATE KEY-----
Bag Attributes
friendlyName: client
localKeyID: 54 69 6D 65 20 31 34 38 34 38 33 33 35 35 39 31 30 39
subject=/C=it/ST=mi/L=milan/O=hat/OU=red/CN=clientzilla
issuer=/C=it/ST=mi/L=milan/O=hat/OU=red/CN=clientzilla
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIERNkHRjANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJp
dDELMAkGA1UECBMCbWkxDjAMBgNVBAcTBW1pbGFuMQwwCgYDVQQKEwNoYXQxDDAK
BgNVBAsTA3JlZDEUMBIGA1UEAxMLY2xpZW50emlsbGEwHhcNMTcwMTE4MTczMjQz
WhcNMTcwNDE4MTczMjQzWjBcMQswCQYDVQQGEwJpdDELMAkGA1UECBMCbWkxDjAM
BgNVBAcTBW1pbGFuMQwwCgYDVQQKEwNoYXQxDDAKBgNVBAsTA3JlZDEUMBIGA1UE
AxMLY2xpZW50emlsbGEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDM
uupRTZX52zM21xt/3X3JhPtjtV5k4Ua+t/KFMOa0GERyJfzYFvgaKPUQWmNCkfK+
oflG8IeNhoPl+axvWckGb9Hy78M/BPyj19h96q09KpgRtPzl7QPhQUigFe7a+k6k
b+unH+21bv1Xu3btN36Q/hTMHziq+EgYSuuWhDau2NQ2xgCSrJdMOox84BPaI8Rq
RQhL9Ob3Q5vCZS936NABYkBstSIMx+w9gsP6aLh+99okBa30EY9hriP8hPJ3UfIL
/0ZcamCxhFOtp3NZlI5WNz+7Gxt0Z1JtGF86fXIj65qntLDC+J2E8/6imUTA7G0K
LDbgngGga2VmIYtckCnLAgMBAAGjITAfMB0GA1UdDgQWBBTOFmnZVt304ZpmU2Ny
eTpalYJLZDANBgkqhkiG9w0BAQsFAAOCAQEAVquQQWQpjz4ISWdMkdHHi5zN0MzB
75PbxUKcGRx9f63sIGYlCEQ0n/GTW9ycgeF0FPxAmTxozU3G+f+cA36TRyXRzqpa
prSjWi2acfOydiI3msPohMbOkllqvmPez3sRbU8UTLL3jQX068qteLLwy0zs8plg
SRCdD87cukOjQ3PNox/88FUTAr+zVMSWfxsJ7miOxYbOFy1CVTWLpha57vP5FmA/
TkXMo3O+GLdWqWHiTDZjR84YWg9xco5NXQCETwz/LajSos2Sl2eqWAkOp7QljXs9
pu8UrmGJTO1S0Ipp5MzkmZpWx2T6E7c9zzdMzKjxjuM9f5ZEXR3tMzovvA==
-----END CERTIFICATE-----

Poco + OpenSSL + CA PEM : "Unacceptable certificate" error for 1 out of 2 identical sites

I am trying to do a SSL handshake with www1.filemail.com. I am using cURL's cacert.pem, but I am getting this error:
Unacceptable certificate from 188.138.81.30: application verification failure
Making the handshake against any other HTTPS website works - including www2.filemail.com. www1 and www2 should be identically configured - and they both work fine in all browsers. They also test fine here (identical certificates and intermediary certificates are sent out for both sites):
SSL Labs www1.filemail.com
SSL Labs www2.filemail.com
Why am I getting this problem with www1 using OpenSSL and the cacert.pem file?
There has to be a difference in the certificate setup of www1 and www2. I have tested with a myriad of tools (openssl, ssllabs etc.) to try to pinpoint the difference - but I always get the exact same results for both sites (except when running my code)
What am I missing here? What's the difference between the sites?
(It should be noted that we are using a relatively cheap wildcard certificate provided by RapidSSL - so I'm guessing it has something to do with intermediate or cross-root certificates - but everything seems to be in order when testing with the tools mentioned above.)
Code:
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> pCert = new Poco::Net::ConsoleCertificateHandler(false);
Poco::Net::Context::Ptr pContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "C:\\cacert.pem", Poco::Net::Context::VERIFY_RELAXED, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:#STRENGTH");
Poco::Net::SSLManager::instance().initializeClient(0, pCert, pContext);
URI uri("https://www1.filemail.com");
Poco::Net::SecureStreamSocket ss(Poco::Net::SocketAddress(uri.getHost().c_str(), uri.getPort()));
ss.completeHandshake();
www1 and www2 should be identically configured - and they both work fine in all browsers...
Here are the certificates. A diff shows they are the same end-entity (server) certificate:
$ diff www1.txt www2.txt
$
Each server is could be a sending a different chain. Use openssl s_client with openssl x509 and -showcerts to get the chain.
www1
$ openssl s_client -connect www1.filemail.com:443 -tls1 -servername www1.filemail.com | openssl x509 -text -noout > www1.txt
depth=1 C = US, O = GeoTrust Inc., CN = RapidSSL SHA256 CA - G3
verify error:num=20:unable to get local issuer certificate
^C
riemann:~$ cat www1.txt
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 15955 (0x3e53)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = GeoTrust Inc., CN = RapidSSL SHA256 CA - G3
Validity
Not Before: Oct 14 20:14:57 2014 GMT
Not After : Aug 4 13:09:28 2018 GMT
Subject: OU = GT83551982, OU = See www.rapidssl.com/resources/cps (c)14, OU = Domain Control Validated - RapidSSL(R), CN = *.filemail.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c5:38:89:72:40:74:77:e2:76:f0:20:ae:d9:91:
26:ac:42:85:03:86:ff:2f:a1:94:b7:f3:86:4c:f7:
ce:63:46:47:e6:03:73:95:01:07:0b:e0:60:9a:93:
c3:b4:14:bc:4e:16:f2:50:12:89:11:42:f5:58:51:
74:15:81:d0:ce:6e:e2:85:e8:d2:3a:38:48:a3:02:
80:e0:a1:fa:ea:8f:ca:ee:bc:00:b3:b2:64:7f:9c:
da:ca:e8:3f:a7:48:af:5c:ed:8e:2f:27:95:19:52:
85:d1:15:9b:f5:4d:b7:21:44:89:05:6f:06:92:7b:
ab:9e:10:63:be:7e:ce:3b:58:10:68:ae:7a:52:6e:
e5:62:bf:ff:56:33:06:51:e5:61:a0:bd:6b:3c:c9:
f3:55:54:02:16:f2:56:27:81:be:83:82:53:25:1e:
c4:1c:1d:65:da:9f:2c:f7:97:49:3c:e1:03:35:1c:
da:c3:02:6d:93:1a:4a:89:53:4c:f5:3e:e7:f9:b9:
c0:10:e0:80:77:3a:d9:5d:ed:b1:46:9e:92:7e:86:
46:d7:be:fe:af:5a:af:02:b4:1b:d2:2b:08:1d:bc:
b5:93:8c:48:45:27:ba:26:69:a9:a8:9f:98:d3:de:
2d:f5:70:f5:39:6a:30:3b:8c:01:6c:85:19:a2:a6:
9a:65
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
keyid:C3:9C:F3:FC:D3:46:08:34:BB:CE:46:7F:A0:7C:5B:F3:E2:08:CB:59
Authority Information Access:
OCSP - URI:http://gv.symcd.com
CA Issuers - URI:http://gv.symcb.com/gv.crt
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Alternative Name:
DNS:*.filemail.com, DNS:filemail.com
X509v3 CRL Distribution Points:
Full Name:
URI:http://gv.symcb.com/gv.crl
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Certificate Policies:
Policy: 2.16.840.1.113733.1.7.54
CPS: https://www.rapidssl.com/legal
Signature Algorithm: sha256WithRSAEncryption
77:7e:54:47:93:6c:b0:4e:9c:dc:01:47:1f:76:54:9d:f2:42:
94:c1:94:f8:7b:b4:68:82:fe:6d:66:45:68:e1:bd:df:ba:6d:
15:a1:6c:b0:79:9e:d7:99:d9:11:7e:84:e9:f1:63:7c:92:25:
c3:fe:cc:02:1a:61:b9:a3:29:59:18:c2:f1:d2:d7:84:dc:8d:
28:2e:b5:6e:91:d9:68:65:37:5a:b9:b3:d5:f4:d1:1f:b2:ec:
2b:0f:e1:50:30:72:f7:04:70:68:26:b0:61:47:44:49:d0:62:
31:81:53:fa:cc:3a:7b:a1:3b:74:da:c2:3b:7b:5d:9c:23:de:
69:92:51:fc:ff:8d:7a:ea:fd:b2:68:5f:38:3d:22:f6:a6:4a:
d7:a0:88:97:06:54:fd:ba:dc:b9:3a:69:25:89:99:0e:81:82:
c8:63:5c:87:98:bf:70:08:0a:89:20:a1:17:63:31:26:7b:af:
b3:83:f3:9c:b6:7e:64:52:08:bf:a3:74:d5:0c:26:f6:25:7c:
b9:cb:27:57:88:7f:af:1c:b5:99:08:4a:fd:c2:b4:ec:7a:40:
ea:80:ac:e8:88:84:33:53:ab:90:af:bc:bc:ea:6f:88:fe:a8:
f9:c7:63:a3:74:2c:0b:37:5c:90:39:ad:85:82:6a:e9:ea:a7:
e1:55:c2:dd
www2
$ openssl s_client -connect www2.filemail.com:443 -tls1 -servername www2.filemail.com | openssl x509 -text -noout > www2.txt
depth=1 C = US, O = GeoTrust Inc., CN = RapidSSL SHA256 CA - G3
verify error:num=20:unable to get local issuer certificate
^C
riemann:~$ cat www2.txt
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 15955 (0x3e53)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = GeoTrust Inc., CN = RapidSSL SHA256 CA - G3
Validity
Not Before: Oct 14 20:14:57 2014 GMT
Not After : Aug 4 13:09:28 2018 GMT
Subject: OU = GT83551982, OU = See www.rapidssl.com/resources/cps (c)14, OU = Domain Control Validated - RapidSSL(R), CN = *.filemail.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c5:38:89:72:40:74:77:e2:76:f0:20:ae:d9:91:
26:ac:42:85:03:86:ff:2f:a1:94:b7:f3:86:4c:f7:
ce:63:46:47:e6:03:73:95:01:07:0b:e0:60:9a:93:
c3:b4:14:bc:4e:16:f2:50:12:89:11:42:f5:58:51:
74:15:81:d0:ce:6e:e2:85:e8:d2:3a:38:48:a3:02:
80:e0:a1:fa:ea:8f:ca:ee:bc:00:b3:b2:64:7f:9c:
da:ca:e8:3f:a7:48:af:5c:ed:8e:2f:27:95:19:52:
85:d1:15:9b:f5:4d:b7:21:44:89:05:6f:06:92:7b:
ab:9e:10:63:be:7e:ce:3b:58:10:68:ae:7a:52:6e:
e5:62:bf:ff:56:33:06:51:e5:61:a0:bd:6b:3c:c9:
f3:55:54:02:16:f2:56:27:81:be:83:82:53:25:1e:
c4:1c:1d:65:da:9f:2c:f7:97:49:3c:e1:03:35:1c:
da:c3:02:6d:93:1a:4a:89:53:4c:f5:3e:e7:f9:b9:
c0:10:e0:80:77:3a:d9:5d:ed:b1:46:9e:92:7e:86:
46:d7:be:fe:af:5a:af:02:b4:1b:d2:2b:08:1d:bc:
b5:93:8c:48:45:27:ba:26:69:a9:a8:9f:98:d3:de:
2d:f5:70:f5:39:6a:30:3b:8c:01:6c:85:19:a2:a6:
9a:65
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
keyid:C3:9C:F3:FC:D3:46:08:34:BB:CE:46:7F:A0:7C:5B:F3:E2:08:CB:59
Authority Information Access:
OCSP - URI:http://gv.symcd.com
CA Issuers - URI:http://gv.symcb.com/gv.crt
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Alternative Name:
DNS:*.filemail.com, DNS:filemail.com
X509v3 CRL Distribution Points:
Full Name:
URI:http://gv.symcb.com/gv.crl
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Certificate Policies:
Policy: 2.16.840.1.113733.1.7.54
CPS: https://www.rapidssl.com/legal
Signature Algorithm: sha256WithRSAEncryption
77:7e:54:47:93:6c:b0:4e:9c:dc:01:47:1f:76:54:9d:f2:42:
94:c1:94:f8:7b:b4:68:82:fe:6d:66:45:68:e1:bd:df:ba:6d:
15:a1:6c:b0:79:9e:d7:99:d9:11:7e:84:e9:f1:63:7c:92:25:
c3:fe:cc:02:1a:61:b9:a3:29:59:18:c2:f1:d2:d7:84:dc:8d:
28:2e:b5:6e:91:d9:68:65:37:5a:b9:b3:d5:f4:d1:1f:b2:ec:
2b:0f:e1:50:30:72:f7:04:70:68:26:b0:61:47:44:49:d0:62:
31:81:53:fa:cc:3a:7b:a1:3b:74:da:c2:3b:7b:5d:9c:23:de:
69:92:51:fc:ff:8d:7a:ea:fd:b2:68:5f:38:3d:22:f6:a6:4a:
d7:a0:88:97:06:54:fd:ba:dc:b9:3a:69:25:89:99:0e:81:82:
c8:63:5c:87:98:bf:70:08:0a:89:20:a1:17:63:31:26:7b:af:
b3:83:f3:9c:b6:7e:64:52:08:bf:a3:74:d5:0c:26:f6:25:7c:
b9:cb:27:57:88:7f:af:1c:b5:99:08:4a:fd:c2:b4:ec:7a:40:
ea:80:ac:e8:88:84:33:53:ab:90:af:bc:bc:ea:6f:88:fe:a8:
f9:c7:63:a3:74:2c:0b:37:5c:90:39:ad:85:82:6a:e9:ea:a7:
e1:55:c2:dd
I am trying to do a SSL handshake towards www1.filemail.com - but I am
getting this error:
Unacceptable certificate from 188.138.81.30: application verification failure
RapidSSL SHA256 CA - G3 is a CA; it issued the server's certificate. The server is called the subject. As you work up a chain, the former issuer becomes the current subject. At the top of the chain is the self signed root. At the root, the issuer==subject.
The RapidSSL G3 CA is either (1) self-signed, so its a root CA; or (2) signed by another CA higher in the chain, so its a subordinate CA (i.e., it has an issuer). In this case, the G3 CA is a subordinate and it has an issuer.
It sounds like one server is sending the complete chain needed to validate the server's certificate; and the other server is not. Servers are supposed to send the complete chain to avoid the "which directory" problem in PKI. The "complete chain" is every certificate except the self-signed root (but many send the root, too).
The client must trust the self-signed root a priori, and its why it should not be sent (otherwise, a bad guy can swap-in his own chain). Or, instead of using cacert.pem:
Poco::Net::Context::CLIENT_USE, "", "", "C:\\cacert.pem", ...
You can load RapidSSL SHA256 CA - G3 and use that as the root of the trust. You will avoid the other 300 or so CA's in cacert.pem that are not needed to validate the server chain. Its good security engineering.
You can fetch RapidSSL SHA256 CA - G3 from rapidSSL's site at Intermediate CA Certificate: RapidSSL with SHA-2 (under SHA-1 Root).
UPDATE using RapidSSL SHA256 CA - G3:
Here's the signer's certificate:
$ cat rapidssl.pem
-----BEGIN CERTIFICATE-----
MIIEJTCCAw2gAwIBAgIDAjp3MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMTQwODI5MjEzOTMyWhcNMjIwNTIwMjEzOTMyWjBHMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXUmFwaWRTU0wg
U0hBMjU2IENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
VJvZWF0eLFbG1eh/9H0WA//Qi1rkjqfdVC7UBMBdmJyNkA+8EGVf2prWRHzAn7Xp
SowLBkMEu/SW4ib2YQGRZjEiwzQ0Xz8/kS9EX9zHFLYDn4ZLDqP/oIACg8PTH2lS
1p1kD8mD5xvEcKyU58Okaiy9uJ5p2L4KjxZjWmhxgHsw3hUEv8zTvz5IBVV6s9cQ
DAP8m/0Ip4yM26eO8R5j3LMBL3+vV8M8SKeDaCGnL+enP/C1DPz1hNFTvA5yT2AM
QriYrRmIV9cE7Ie/fodOoyH5U/02mEiN1vi7SPIpyGTRzFRIU4uvt2UevykzKdkp
YEj4/5G8V1jlNS67abZZAgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7
qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUw5zz/NNGCDS7zkZ/oHxb8+IIy1kwEgYD
VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig
JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF
BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARF
MEMwQQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3Ry
dXN0LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQCjWB7GQzKs
rC+TeLfqrlRARy1+eI1Q9vhmrNZPc9ZE768LzFvB9E+aj0l+YK/CJ8cW8fuTgZCp
fO9vfm5FlBaEvexJ8cQO9K8EWYOHDyw7l8NaEpt7BDV7o5UzCHuTcSJCs6nZb0+B
kvwHtnm8hEqddwnxxYny8LScVKoSew26T++TGezvfU5ho452nFnPjJSxhJf3GrkH
uLLGTxN5279PURt/aQ1RKsHWFf83UTRlUfQevjhq7A6rvz17OQV79PP7GqHQyH5O
ZI3NjGFVkP46yl0lD/gdo0p0Vk8aVUBwdSWmMy66S6VdU5oNMOGNX2Esr8zvsJmh
gP8L8mJMcCaY
-----END CERTIFICATE-----
Notice OpenSSL finished with Verify return code: 2 (unable to get issuer certificate). That's fine because you don't care about the issuer. You've rooted your trust at GeoTrust Inc., CN = RapidSSL SHA256 CA - G3, and RapidSSL SHA256 CA - G3 certified/signed the server's certificate.
$ openssl s_client -connect www1.filemail.com:443 -tls1 -servername www1.filemail.com -CAfile rapidssl.pem
CONNECTED(00000003)
depth=1 C = US, O = GeoTrust Inc., CN = RapidSSL SHA256 CA - G3
verify error:num=2:unable to get issuer certificate
issuer= C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
Server did acknowledge servername extension.
---
Certificate chain
0 s:/OU=GT83551982/OU=See www.rapidssl.com/resources/cps (c)14/OU=Domain Control Validated - RapidSSL(R)/CN=*.filemail.com
i:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G3
1 s:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G3
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEsDCCA5igAwIBAgICPlMwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCVVMx
FjAUBgNVBAoTDUdlb1RydXN0IEluYy4xIDAeBgNVBAMTF1JhcGlkU1NMIFNIQTI1
NiBDQSAtIEczMB4XDTE0MTAxNDIwMTQ1N1oXDTE4MDgwNDEzMDkyOFowgZIxEzAR
BgNVBAsTCkdUODM1NTE5ODIxMTAvBgNVBAsTKFNlZSB3d3cucmFwaWRzc2wuY29t
L3Jlc291cmNlcy9jcHMgKGMpMTQxLzAtBgNVBAsTJkRvbWFpbiBDb250cm9sIFZh
bGlkYXRlZCAtIFJhcGlkU1NMKFIpMRcwFQYDVQQDDA4qLmZpbGVtYWlsLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMU4iXJAdHfidvAgrtmRJqxC
hQOG/y+hlLfzhkz3zmNGR+YDc5UBBwvgYJqTw7QUvE4W8lASiRFC9VhRdBWB0M5u
4oXo0jo4SKMCgOCh+uqPyu68ALOyZH+c2sroP6dIr1ztji8nlRlShdEVm/VNtyFE
iQVvBpJ7q54QY75+zjtYEGiuelJu5WK//1YzBlHlYaC9azzJ81VUAhbyVieBvoOC
UyUexBwdZdqfLPeXSTzhAzUc2sMCbZMaSolTTPU+5/m5wBDggHc62V3tsUaekn6G
Rte+/q9arwK0G9IrCB28tZOMSEUnuiZpqaifmNPeLfVw9TlqMDuMAWyFGaKmmmUC
AwEAAaOCAVgwggFUMB8GA1UdIwQYMBaAFMOc8/zTRgg0u85Gf6B8W/PiCMtZMFcG
CCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYTaHR0cDovL2d2LnN5bWNkLmNvbTAm
BggrBgEFBQcwAoYaaHR0cDovL2d2LnN5bWNiLmNvbS9ndi5jcnQwDgYDVR0PAQH/
BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAnBgNVHREEIDAe
gg4qLmZpbGVtYWlsLmNvbYIMZmlsZW1haWwuY29tMCsGA1UdHwQkMCIwIKAeoByG
Gmh0dHA6Ly9ndi5zeW1jYi5jb20vZ3YuY3JsMAwGA1UdEwEB/wQCMAAwRQYDVR0g
BD4wPDA6BgpghkgBhvhFAQc2MCwwKgYIKwYBBQUHAgEWHmh0dHBzOi8vd3d3LnJh
cGlkc3NsLmNvbS9sZWdhbDANBgkqhkiG9w0BAQsFAAOCAQEAd35UR5NssE6c3AFH
H3ZUnfJClMGU+Hu0aIL+bWZFaOG937ptFaFssHme15nZEX6E6fFjfJIlw/7MAhph
uaMpWRjC8dLXhNyNKC61bpHZaGU3Wrmz1fTRH7LsKw/hUDBy9wRwaCawYUdESdBi
MYFT+sw6e6E7dNrCO3tdnCPeaZJR/P+Neur9smhfOD0i9qZK16CIlwZU/brcuTpp
JYmZDoGCyGNch5i/cAgKiSChF2MxJnuvs4PznLZ+ZFIIv6N01Qwm9iV8ucsnV4h/
rxy1mQhK/cK07HpA6oCs6IiEM1OrkK+8vOpviP6o+cdjo3QsCzdckDmthYJq6eqn
4VXC3Q==
-----END CERTIFICATE-----
subject=/OU=GT83551982/OU=See www.rapidssl.com/resources/cps (c)14/OU=Domain Control Validated - RapidSSL(R)/CN=*.filemail.com
issuer=/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G3
---
No client certificate CA names sent
Server Temp Key: ECDH, P-521, 521 bits
---
SSL handshake has read 2834 bytes and written 338 bytes
Verification error: unable to get issuer certificate
---
New, SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : ECDHE-RSA-AES256-SHA
Session-ID: 27390000AF3638FDEA75DDF52B9D937F290593304123134062F049306BBDE87F
Session-ID-ctx:
Master-Key: E8E2613F6267C705CA82EEE4C8A992880A2ABDA9E8D477A10C952764B1F4DD3D39244D3F0AD915B8FEB7E5FA1E8D55FD
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1473889933
Timeout : 7200 (sec)
Verify return code: 2 (unable to get issuer certificate)
Extended master secret: yes
----
Günter Obiltschnig helped me out via POCO#Github and got it working by replacing
Poco::Net::SecureStreamSocket ss(Poco::Net::SocketAddress(uri.getHost().c_str(), uri.getPort()));
with
Poco::Net::SecureStreamSocket ss(Poco::Net::SocketAddress(uri.getHost().c_str(), uri.getPort()), uri.getHost());
(including the host name in the constructor of SecureStreamSocket - it is used for certificate verification)
From the POCO documentation:
SecureStreamSocket(
const SocketAddress & address,
const std::string & hostName
);
//Creates a secure stream socket using the default client SSL context and connects it to the socket specified by address.
//The given host name is used for certificate verification <=======
I still do not know the exact difference in config between www1 and www2 are, would love if someone could enlighten me on this.

Cannot find the X.509 certificate using the following search criteria ----

I created custom authentication by Wcf after that I created self-sign ssl in IIS 7.5
and use below code in web.config
<serviceCertificate findValue="CN = srv-erp"/>
and this one too
<serviceCertificate findValue="CN = srv-erp"
storeLocation="LocalMachine"
x509FindType="FindBySubjectName"
storeName="My"/>
and I used FindBySerialNumber too.
but they didn't work and I get this error
Cannot find the X.509 certificate using the following search criteria:
StoreName 'My', StoreLocation 'LocalMachine', FindType
'FindBySubjectDistinguishedName', FindValue 'CN = srv-erp'.
Your help is appreciated
it seems that problem in the findValue property try to change it to serv-erp. You don't need to place key of property in findValue when you use x509FindType.
<serviceCertificate findValue="srv-erp"
storeLocation="LocalMachine"
x509FindType="FindBySubjectName"
storeName="My"/>
Also you may try to find you certificate by another type (see X509FindType reference) For instance, by thumbprint
<serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"
findValue="b5 ca b7 d0 b8 da fd 20 b7 bb 14 5d 66 2b 53 f3 0c 20 ca f2"/>
Finally, ensure that your certificate is exist. Type Run in Search Windows and copy and paste certmgr.msc. Then on the menu click on Action -> Find certificates...