SSL certificate verify result: unable to get local issuer certificate (20)
IngoWolf opened this issue · 13 comments
I'm using curl v3 version 4.2.2 (https://github.com/miyako/4d-plugin-curl-v3/releases/tag/4.2.2) to communicate with a remote host via htpps (the remote host is not apple.com, but api.certify.ubirch.com) on Windows 10 Pro (21H1) with 4D v19. The problem is that I can't get curl to verify the remote certificate via the windows certificate store. But this is demanded by the customer.
Here's the simplified 4D code:
C_OBJECT($vObj_Options;$vObj_Result)
C_BLOB($vx_Request; $vx_Response)
C_TEXT($vT_callback)
$vObj_Options:=New object
$vObj_Options.URL:="https://www.apple.com/test"
$vObj_Options.POST:=1
$vObj_Options.SSL_VERIFYPEER:=0
$vObj_Options.SSL_VERIFYHOST:=0
//$vObj_Options.CAPATH:=""
//$vObj_Options.CAINFO:=""
$vObj_Options.DEBUG:=Get 4D folder(Logs folder)
If (Application type#4D Server)
SHOW ON DISK(Get 4D folder(Logs folder); *)
End if
$vT_callback:=""
$vObj_Result:=cURL($vObj_Options; $vx_Request; $vx_Response; $vT_callback)
And here's the log:
Connection 3 seems to be dead!
Closing connection 3
TLSv1.3 (OUT), TLS alert, close notify (256):
Hostname in DNS cache was stale, zapped
Trying 2a02:26f0:fb:5b2::1aca:443...
connect to 2a02:26f0:fb:5b2::1aca port 443 failed: Network unreachable
Trying 2a02:26f0:fb:591::1aca:443...
connect to 2a02:26f0:fb:591::1aca port 443 failed: Network unreachable
Trying 104.89.44.72:443...
Connected to www.apple.com (104.89.44.72) port 443 (#4)
ALPN, offering h2
ALPN, offering http/1.1
TLSv1.3 (OUT), TLS handshake, Client hello (1):
TLSv1.3 (IN), TLS handshake, Server hello (2):
TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
TLSv1.3 (IN), TLS handshake, Certificate (11):
TLSv1.3 (IN), TLS handshake, CERT verify (15):
TLSv1.3 (IN), TLS handshake, Finished (20):
TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
TLSv1.3 (OUT), TLS handshake, Finished (20):
SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
ALPN, server accepted to use h2
Server certificate:
subject: businessCategory=Private Organization; jurisdictionC=US; jurisdictionST=California; serialNumber=C0806592; C=US; ST=California; L=Cupertino; O=Apple Inc.; OU=management:idms.group.1208920; CN=www.apple.com
start date: Sep 8 11:52:43 2021 GMT
expire date: Oct 8 11:52:42 2022 GMT
issuer: C=US; O=Apple Inc.; CN=Apple Public EV Server RSA CA 2 - G1
SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
Using HTTP2, server supports multi-use
Connection state changed (HTTP/2 confirmed)
Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
Using Stream ID: 1 (easy handle 0x2907bdd8)
TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
old SSL session ID is stale, removing
Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
Connection #4 to host www.apple.com left intact
how about you take a step back and find out how to connect with command line curl ?
Command line curl has no problem in verifying the remote certificate via the windows certificate store:
C:\Vertinex\curl-7.80.0-win64-mingw\bin>curl -v https://www.apple.com/test
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 104.125.23.242:443...
* Connected to www.apple.com (104.125.23.242) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* CAfile: C:\Vertinex\curl-7.80.0-win64-mingw\bin\curl-ca-bundle.crt
* CApath: none
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* TLSv1.2 (IN), TLS header, Certificate Status (22):
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.2 (IN), TLS header, Finished (20):
{ [5 bytes data]
* TLSv1.2 (IN), TLS header, Supplemental data (23):
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [29 bytes data]
* TLSv1.2 (IN), TLS header, Supplemental data (23):
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [3480 bytes data]
* TLSv1.2 (IN), TLS header, Supplemental data (23):
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [264 bytes data]
* TLSv1.2 (IN), TLS header, Supplemental data (23):
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.2 (OUT), TLS header, Finished (20):
} [5 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: businessCategory=Private Organization; jurisdictionC=US; jurisdictionST=California; serialNumber=C0806592; C=US; ST=California; L=Cupertino; O=Apple Inc.; OU=management:idms.group.1208920; CN=www.apple.com
* start date: Sep 8 11:52:43 2021 GMT
* expire date: Oct 8 11:52:42 2022 GMT
* subjectAltName: host "www.apple.com" matched cert's "www.apple.com"
* issuer: C=US; O=Apple Inc.; CN=Apple Public EV Server RSA CA 2 - G1
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
the idea is to pass the same arguments you do to curl.
if -v
is the only argument, you should do the same with the plugin.
in your posted code, you pass the options that correspond to -k
.
Here's the stripped down 4D code:
C_OBJECT($vObj_Options; $vObj_Result)
C_BLOB($vx_Request; $vx_Response)
C_TEXT($vT_callback)
$vObj_Options:=New object
$vObj_Options.URL:="https://www.apple.com/test"
$vObj_Options.DEBUG:=Get 4D folder(Logs folder)
If (Application type#4D Server)
SHOW ON DISK(Get 4D folder(Logs folder); *)
End if
$vT_callback:=""
$vObj_Result:=cURL($vObj_Options; $vx_Request; $vx_Response; $vT_callback)
and the log file content:
Trying 104.89.44.72:443...
Connected to www.apple.com (104.89.44.72) port 443 (#0)
ALPN, offering h2
ALPN, offering http/1.1
TLSv1.3 (OUT), TLS handshake, Client hello (1):
TLSv1.3 (IN), TLS handshake, Server hello (2):
TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
TLSv1.3 (IN), TLS handshake, Certificate (11):
TLSv1.3 (OUT), TLS alert, unknown CA (560):
SSL certificate problem: unable to get local issuer certificate
Closing connection 0
I get
Connected to www.apple.com (23.212.176.239) port 443 (#0)
ALPN, offering h2
ALPN, offering http/1.1
successfully set certificate verify locations:
CAfile: /etc/ssl/cert.pem
CApath: none
TLSv1.3 (OUT), TLS handshake, Client hello (1):
TLSv1.3 (IN), TLS handshake, Server hello (2):
TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
TLSv1.3 (IN), TLS handshake, Certificate (11):
TLSv1.3 (IN), TLS handshake, CERT verify (15):
TLSv1.3 (IN), TLS handshake, Finished (20):
TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
TLSv1.3 (OUT), TLS handshake, Finished (20):
SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
ALPN, server accepted to use h2
Server certificate:
subject: businessCategory=Private Organization; jurisdictionC=US; jurisdictionST=California; serialNumber=C0806592; C=US; ST=California; L=Cupertino; O=Apple Inc.; OU=management:idms.group.1208920; CN=www.apple.com
start date: Sep 8 11:52:43 2021 GMT
expire date: Oct 8 11:52:42 2022 GMT
subjectAltName: host "www.apple.com" matched cert's "www.apple.com"
issuer: C=US; O=Apple Inc.; CN=Apple Public EV Server RSA CA 2 - G1
SSL certificate verify ok.
Using HTTP2, server supports multi-use
Connection state changed (HTTP/2 confirmed)
Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
Using Stream ID: 1 (easy handle 0x7fcb6067ba00)
TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
old SSL session ID is stale, removing
Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
Connection #0 to host www.apple.com left intact
so is it a windows problem?
you can also google "SSL certificate problem: unable to get local issuer certificate"
Yes, all tests (and problems) on windows. Unfortunately all clients on windows, too.
your command line curl might be using a cacert.pem that came with it.
perhaps you can follow the instructions on https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate and specify cacert.crt ?
and specify cacert.crt:
I'll give it a try. After reading the documentation of curl I was under the impression, it would automatically use the windows certificate store, if neither CAPATH nor CACERT were given.
maybe this
OpenSSL does not support using the "CA certificate store" that Windows has on its own. If you want your curl build to use that cert store, you need to rebuild curl to use the schannel backend instead (aka "winssl"), which is the Windows native version that also uses the Windows cert store by default.
and
Starting with libcurl 7.71.0, due to ship on June 24, 2020, it will get the ability to use the Windows CA cert store when built to use OpenSSL. You then need to use the CURLOPT_SSL_OPTIONS option and set the correct bit in the bitmask: CURLSSLOPT_NATIVE_CA.
the plugin is libcurl-7.74.0-DEV
so maybe you can try the bitmask ?
Specifying cacert.crt
via
$vObj_Options.CAINFO:="C:\\Vertinex\\curl-ca-bundle.crt"
solved the problem.
Many thanks for your support.