curl: (56) OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 - ssl

I'm trying to access the API from internet however getting the error.
Trace of curl
λ curl -v https://api-tryitout-uat.hdfcbank.com/v1/ganapathi
% 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 103.120.106.197...
TCP_NODELAY set
Connected to api-tryitout-uat.hdfcbank.com (103.120.106.197) port 443 (#0)
ALPN, offering h2
ALPN, offering http/1.1
Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
successfully set certificate verify locations:
CAfile: C:/Users/tonmo/Downloads/cmder/vendor/git-for-windows/mingw64/ssl/certs/ca-bundle.crt
CApath: none
TLSv1.2 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [87 bytes data]
TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [3970 bytes data]
TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
{ [1 bytes data]
TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
ALPN, server did not agree to a protocol
Server certificate:
subject: jurisdictionC=IN; businessCategory=Private Organization; serialNumber=080618; C=IN; ST=Maharashtra; L=Mumbai; O=Hdfc Bank Limited; CN=api-tryitout-uat.hdfcbank.com
start date: Apr 1 00:00:00 2022 GMT
expire date: May 2 23:59:59 2023 GMT
subjectAltName: host "api-tryitout-uat.hdfcbank.com" matched cert's "api-tryitout-uat.hdfcbank.com"
issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=GeoTrust EV RSA CA 2018
SSL certificate verify ok.
} [5 bytes data]
GET /v1/ganapathi HTTP/1.1
Host: api-tryitout-uat.hdfcbank.com
User-Agent: curl/7.61.1
Accept: /
OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Closing connection 0
} [5 bytes data]
curl: (56) OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054
Please help to resolve this.

Related

Am I using 1 Way or 2 way SSL

root#XXXXXX:/var/tmp# curl --tlsv1.2 --tls-max 1.2 -v
https://example.com:8443/health --cacert Internal_Root_CA.cer
Trying 10.50.65.56...
TCP_NODELAY set
Connected to example.com (10.50.65.56) port 8443 (#0)
ALPN, offering h2
ALPN, offering http/1.1
successfully set certificate verify locations:
CAfile: Internal_Root_CA.cer CApath: /etc/ssl/certs
TLSv1.2 (OUT), TLS handshake, Client hello (1):
TLSv1.2 (IN), TLS handshake, Server hello (2):
TLSv1.2 (IN), TLS handshake, Certificate (11):
TLSv1.2 (IN), TLS handshake, Server key exchange (12):
TLSv1.2 (IN), TLS handshake, Server finished (14):
TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
TLSv1.2 (OUT), TLS change cipher, Client hello (1):
TLSv1.2 (OUT), TLS handshake, Finished (20):
TLSv1.2 (IN), TLS handshake, Finished (20):
SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
ALPN, server did not agree to a protocol
Server certificate:
subject: C=US; ST=ZZZ; L=CCC; O=Company; CN=example.com
start date: Sep 29 22:30:19 2022 GMT
expire date: Sep 27 22:30:49 2024 GMT
subjectAltName: host "example.com" matched cert's "example.com"
issuer: O=Company; CN= Issuing CA
SSL certificate verify ok.
GET /health HTTP/1.1
Host: example.com:8443
User-Agent: curl/7.58.0
Accept: /
< HTTP/1.1 200 < Content-Type: text/plain;charset=UTF-8 < Content-Length: 0 < Date: Wed, 12 Oct 2022 18:33:10 GMT <
Connection #0 to host mdm-dev.gcp.aexp.com left intact
Am I using 1 way or 2 way SSL? THe REST API is developed using Spring boot.
I have to pass in the Root CA for the Call to work.
This is 1-way SSL because a) you don't give a client certificate to use and b) the server does not even request one (no CertificateRequest message from server).

Removing DST_Root_CA_X3 in Archlinux

On 2021-09-30 the Lets Encrypt certificate DST_ROOT_CA_X3 expired. I have an older Archlinux build that is now failing basic https requests to Lets Encrypt domains.
For example: curl -sv https://serverfault.com yields:
* Rebuilt URL to: https://serverfault.com/
* Trying 151.101.193.69...
* TCP_NODELAY set
* Connected to serverfault.com (151.101.193.69) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [108 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [4487 bytes data]
* TLSv1.2 (OUT), TLS alert, Server hello (2):
} [2 bytes data]
* SSL certificate problem: certificate rejected
* Curl_http_done: called premature == 1
* Closing connection 0
} [5 bytes data]
* TLSv1.2 (OUT), TLS alert, Client hello (1):
} [2 bytes data]
I have found other posts that describe how to remove this certificate on Ubuntu based builds. I am unfamiliar with Archlinux - how do you go about doing the same?
There is a ca-certificates package which most likely just needs to be updated.
sudo pacman -Sy ca-certificates
or just update your entire system
sudo pacman -Syu

curl says OpenSSL SSL_connect: SSL_ERROR_ZERO_RETURN in connection to s3.ap-south-1.amazonaws.com:443

I am trying to download a file over https TLS from aws using libcurl.
I am using below options
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_CONTROL);
curl_easy_setopt(curl, CURLOPT_CAINFO, "cert.pem");
curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
and I get the below output when I try to connect.
* Trying 52.219.158.33...
* TCP_NODELAY set
* Connected to s3.ap-south-1.amazonaws.com (52.219.158.33) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* successfully set certificate verify locations:
* CAfile: cert.pem
CApath: /etc/ssl/certs
* OpenSSL SSL_connect: SSL_ERROR_ZERO_RETURN in connection to s3.ap-south-1.amazonaws.com:443
* stopped the pause stream!
* Closing connection 0*
but when I try to do the same thing using curl command line it works fine
$curl --cacert cert.pem -o final.bin -v
I get a detailed output below
% 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 52.219.66.33...
* TCP_NODELAY set
* Connected to s3.ap-south-1.amazonaws.com (52.219.66.33) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: cert.pem
CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [91 bytes data]
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [5304 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=*.s3.ap-south-1.amazonaws.com
* start date: Mar 26 00:00:00 2021 GMT
* expire date: Mar 5 23:59:59 2022 GMT
* subjectAltName: host "s3.ap-south-1.amazonaws.com" matched cert's "s3.ap-south-1.amazonaws.com"
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
} [5 bytes data]
> GET /<url> HTTP/1.1
> Host: s3.ap-south-1.amazonaws.com
> User-Agent: curl/7.58.0
> Accept: */*
>
{ [5 bytes data]
< HTTP/1.1 200 OK
< x-amz-id-2: g/Q+ZRBzQktcquk2elmt1j5fA6w+WCJtJert44SXh4oeEGIZ6y55OcClxQwN/P+QaznzcMjjo=
< x-amz-request-id: MF91MY53D47PST6
< Date: Mon, 29 Nov 2021 08:27:39 GMT
< Last-Modified: Fri, 26 Nov 2021 09:47:49 GMT
< ETag: "33fd329aa6dsf3cdfcf9d7e010c3485e2"
< Accept-Ranges: bytes
< Content-Type: binary/octet-stream
< Server: AmazonS3
< Content-Length: 6304448
<
{ [5 bytes data]
100 6156k 100 6156k 0 0 322k 0 0:00:19 0:00:19 --:--:-- 485k
* Connection #0 to host s3.ap-south-1.amazonaws.com left intact
How do I get the same output using libcurl APIs?
Any other configuration is missing as part of curl config?
There is no such cipher TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 for OpenSSL listed in the manual SSL Ciphers. This caused the attempt to use TLS with the empty list of ciphers. You would know it if you had checked the returned value of curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"). The curl dump shows you the correct cipher.
curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, "ECDHE-RSA-AES128-GCM-SHA256");
Additionally, curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_CONTROL) has no affect. CURLOPT_USE_SSL is for the protocols FTP, SMTP, POP3, IMAP.

AWS API Gateway MissingAuthenticationToken

I have an api called api-gateway-v1.
this api is a http_proxy.
The method_request authorization is set to NONE.
The method_execution is set to passthrough.
There are two custom domain names which call the same api (same stage).
custom-domain-name-1 has no mutual_tls works as expected.
custom-domain-name-2 has mutual_tls works as expected.
custom domain-1 curl verbose o/p:
curl -v --location --request POST 'https://custom-domain-name-1/v1' --header 'Content-Type: application/json' --data-raw {"email":"email#example.com","password":"mypassword"}'
TCP_NODELAY set
Connected to custom-domain-name-1 (1.2.3.5) port 443 (#0)
ALPN, offering h2
ALPN, offering http/1.1
successfully set certificate verify locations:
CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
TLSv1.3 (OUT), TLS handshake, Client hello (1):
TLSv1.3 (IN), TLS handshake, Server hello (2):
TLSv1.2 (IN), TLS handshake, Certificate (11):
TLSv1.2 (IN), TLS handshake, Server key exchange (12):
TLSv1.2 (IN), TLS handshake, Server finished (14):
TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
TLSv1.2 (OUT), TLS handshake, Finished (20):
TLSv1.2 (IN), TLS handshake, Finished (20):
SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
ALPN, server accepted to use h2
Server certificate:
subject: CN=custom-domain-name-1
start date: Mar 1 00:00:00 2021 GMT
expire date: Mar 30 23:59:59 2022 GMT
subjectAltName: host "custom-domain-name-1" matched cert's "custom-domain-name-1"
issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
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 0x55c4d244ae10)
POST /v1 HTTP/2
Host: custom-domain-name-1
user-agent: curl/7.68.0
accept: */*
content-type: application/json
content-length: 76
Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
We are completely uploaded and fine
HTTP/2 200
date: Tue, 10 Aug 2021 07:56:41 GMT
content-type: application/json
content-length: 1009
x-amzn-requestid: 8997bed9-b2d5-48fe-8cf2-0d9166ec489d
x-amzn-remapped-connection: keep-alive
x-ratelimit-remaining: 999
x-amz-apigw-id: abc=
cache-control: private, must-revalidate
x-amzn-remapped-server: nginx
x-ratelimit-limit: 1000
x-content-type-options: nosniff
expires: -1
pragma: no-cache
x-amzn-remapped-date: Tue, 10 Aug 2021 07:56:41 GMT
Connection #0 to host custom-domain-name-1 left intact
{"success":{"token":"XYZ"}}
custom domain-2 curl verbose o/p:
curl -v --key form.key --cert cert.pem https://custom-domain-name-2/v1 --header 'Content-Type: application/json' --data-raw '{"email":"email#example.com","password":"mypassword"}'
Note: Unnecessary use of -X or --request, POST is already inferred.
Trying 54.251.193.98:443...
TCP_NODELAY set
Connected to custom-domain-name-2 (1.2.3.4) port 443 (#0)
ALPN, offering h2
ALPN, offering http/1.1
successfully set certificate verify locations:
CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
TLSv1.3 (OUT), TLS handshake, Client hello (1):
TLSv1.3 (IN), TLS handshake, Server hello (2):
TLSv1.2 (IN), TLS handshake, Certificate (11):
TLSv1.2 (IN), TLS handshake, Server key exchange (12):
TLSv1.2 (IN), TLS handshake, Request CERT (13):
TLSv1.2 (IN), TLS handshake, Server finished (14):
TLSv1.2 (OUT), TLS handshake, Certificate (11):
TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
TLSv1.2 (OUT), TLS handshake, CERT verify (15):
TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
TLSv1.2 (OUT), TLS handshake, Finished (20):
TLSv1.2 (IN), TLS handshake, Finished (20):
SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
ALPN, server accepted to use h2
Server certificate:
subject: CN=custom-domain-name-2
start date: Aug 5 00:00:00 2021 GMT
expire date: Sep 3 23:59:59 2022 GMT
subjectAltName: host "custom-domain-name-2" matched cert's "custom-domain-name-2"
issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
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 0x555588810e10)
POST /v1 HTTP/2
Host: custom-domain-name-2
user-agent: curl/7.68.0
accept: */*
content-type: application/json
content-length: 66
We are completely uploaded and fine
Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
HTTP/2 403
x-amzn-requestid: abc-123
x-amzn-errortype: MissingAuthenticationTokenException
x-amz-apigw-id: 123-abc
content-type: application/json
content-length: 42
date: Wed, 11 Aug 2021 10:53:59 GMT
Connection #0 to host custom-domain-name-2 left intact {"message":"Missing Authentication Token"}
The connection seems to be fine but the HTTP code is changing.
Does anyone has insight into what's happening?
I solved it by Enabling CORS which was missing.

servers returns "Invalid Host header" inside alpine when connecting via ssl

First of all, this question is not about how to fix this, but rather about why it happens.
Exact same curl (exact same version curl/7.65.1) with exact same request produces different results.
Why the certificate chain is different?
How server response depends on ssl connection flow? (Alpine get response body "Invalid host header", host OS downloads file w/o any issues)?
Why http version is different? How do the server and client agree on protocol version? Running the same command with --http curl flag fixes the issue.
docker run -i -t alpine /bin/sh:
apk add curl
curl -kfSL https://nginx.org/download/nginx-1.15.3.tar.gz -o nginx.tar.gz -vvv
Output:
* Trying 95.211.80.227:443...
* TCP_NODELAY set
* Connected to nginx.org (95.211.80.227) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=localhost
* start date: Jul 8 19:13:11 2019 GMT
* expire date: Aug 7 19:13:11 2019 GMT
* issuer: CN=localhost
* SSL certificate verify result: self signed certificate (18), 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 0x55e3e4a37540)
> GET /download/nginx-1.15.3.tar.gz HTTP/2
> Host: nginx.org
> User-Agent: curl/7.65.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
< HTTP/2 200
< x-powered-by: Express
< content-type: text/html; charset=utf-8
< content-length: 19
< etag: W/"13-OxsTL6IB85fkJxv9HO8uum0slCI"
<
* Connection #0 to host nginx.org left intact
Invalid Host header
Same curl command works completely fine from my host machine (Archlinux bleeding edge) even without insecure (-k)option.
% 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 95.211.80.227:443...
* TCP_NODELAY set
* Connected to nginx.org (95.211.80.227) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [108 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2621 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=nginx.org
* start date: May 14 19:45:30 2019 GMT
* expire date: Aug 12 19:45:30 2019 GMT
* subjectAltName: host "nginx.org" matched cert's "nginx.org"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
} [5 bytes data]
> GET /download/nginx-1.15.3.tar.gz HTTP/1.1
> Host: nginx.org
> User-Agent: curl/7.65.1
> Accept: */*
>
{ [5 bytes data]
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.15.7
< Date: Wed, 10 Jul 2019 13:03:16 GMT
< Content-Type: application/octet-stream
< Content-Length: 1022881
< Last-Modified: Tue, 28 Aug 2018 15:40:55 GMT
< Connection: keep-alive
< Keep-Alive: timeout=15
< ETag: "5b856d07-f9ba1"
< Accept-Ranges: bytes
P.S. I'm aware of this response