It may sound very simple but I can't get it to work. I want to connect to an ftp with ssl certificate on windows with command line.
So I generate my certificate with IIS, I export it to "cer" format and after a lot of try I end with this command line :
curl -3 -v --cacert "XX\XX\test_certif.cer" --disable-epsv --ftp-skip-pasv-ip --ftp-ssl ftp://XXXXXXX --user XXXX
and after entering my password, i have this error :
Enter host password for user 'XXXXXX':
* Rebuilt URL to: ftp://XXXX/
* Trying XX::XX:XX:XX...
* TCP_NODELAY set
* Connected to XXXXX (XX::XX:XX:XX:XX) port 21 (#0)
< 220 Microsoft FTP Service
> AUTH SSL
< 234 AUTH command ok. Expecting TLS Negotiation.
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: XX\XX\test_certif.cer
CApath: none
* SSLv3 (OUT), TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to XXX:21
* Closing connection 0
curl: (35) Unknown SSL protocol error in connection to XXX:21
And i out of idea to make it work.
To go a little further my ftp work when i change ssl parameter of the ftp from "Needed ssl connexion" to "allowed ssl connexion" so the matter is not this way.
And Windows firewall is disable.
update i still work on it and i have now this command line :
curl -v --cacert "XX\XX\test_certif.cer" --ftp-ssl ftp://XXX --user XXX
with this output
Enter host password for user 'XXX':
* Rebuilt URL to: ftp://XXX
* Trying XX::XX:XX:XX:XX...
* TCP_NODELAY set
* Connected to XXX (XX::XX:XX:XX:XX) port 21 (#0)
< 220 Microsoft FTP Service
> AUTH SSL
< 234 AUTH command ok. Expecting TLS Negotiation.
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: XX\XX\test_certif.cer
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* 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 (OUT), TLS alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, Client hello (1):
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
got any idea?
Feel free to ask more info if needed ill update the question.
Thx by advance
I solve my issue. The matter was with the certificat générate by IIS not working with curl.
So i use OpenSSl to générate a key :
openssl genrsa -des3 -out key.pem -passout pass:password 1024
Then still use OpenSSL to générate a certificat with the key :
req -x509 -new -key key.pem -passin pass:password -days 3650 -out certificat.cer -config "C:\Program Files (x86)\GnuWin32\share\openssl.cnf"
-config is not necessary needed and is located on the folder of your openssl install
Now still with OpenSSL, convert key+certificat to pfx
pkcs12 -inkey key.pem -in certificat.cer -export -out iis_certificate.pfx
Now you can import the pfx certificate to IIS and use it to configure your FTP connection.
Create a pem file and copy past the content of certificat.cer inside him or just convert the file to pem. Lets name it "cacer.pem"
Now use curl to connect :
curl -v ftp://"IP or server name" --user « username » --ftp-ssl --cacert « Path of cacer.pem file »
Here is a little bonus, the command line to upload a file and set passord in the command line :
curl -upload-file “Path of file to transfert” ftp://"IP or server name" --user « user »: « password » --ftp-ssl --cacert " Path of cacer.pem file "
Related
I have been given the following files for setting up TLS for a website running on the domain example.com:
example.com.key (containing the private key)
example.com.cer (containing one certificate)
intermediate_example.com.crt (containing two certificates)
example.com.csr (containing one certificate request)
I'm using Traefik to host the site, and I've configured Traefik like so in the dynamic.yml config:
tls:
certificates:
- certFile: "certs/example.com.cer"
keyFile: "certs/example.com.key"
stores:
- default
Doing so resulted in a website I could access via Chrome and Firefox, but whenever trying a request with curl (or any program using its libraries), I get the following error:
➜ ~ curl -v https://test.example.com/
* Trying xxx.xxx.xxx.xxx:443...
* Connected to test.example.com (xxx.xxx.xxx.xxx) 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.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
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html
Why is this working in browsers, but not via curl?
I have ensured that the ca-certificates package is installed on the host, and even when I download the most recent CA bundle and use curl --cacert cacert.pem …, it does not work.
What am I missing here?
The reason it does not work is that the intermediate certificate is missing in what Traefik is sending to the client.
The browsers can work around this using the Authority Information Access mechanism, and even macOS does this, fetching the missing information out-of-band, thereby allowing you to access the site normally. Some background is given here.
This is obviously a configuration error on the server. To fix it, at least for Traefik, you can concatenate everything into one .pem file. You don't need to add the CSR file here:
cat example.com.key example.com.cer intermediate_example.com.crt > cert.pem
Then, specify the same file twice in Traefik's config:
tls:
certificates:
- certFile: "certs/cert.pem"
keyFile: "certs/cert.pem"
stores:
- default
This is also mentioned in this discussion on the Traefik community board.
I have created a self signed certificate using keytool. Full command is
keytool -keystore server.p12 -alias server_key -keyalg rsa -ext ku=DigitalSignature,keyEncipherment,dataEncipherment
I added this keystore to my web server as well. There was no there. My question is about how to curl to the server without skipping verification. (I don't want to use -k option). I exported the server certificate using the following command
keytool -export -keystore server.p12 -alias server_key -file server.crt
With curl -v --cacert server.crt https://host:port, the following is the error even though server certificate is provided for curl.
* Rebuilt URL to: https://localhost:5443/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /home/innsh/Downloads/cacert.pem
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS Unknown, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* stopped the pause stream!
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
I need to do curl uploading behind company proxy. and I've getting the following two type of problems depending on the site that I try,
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
curl: (60) SSL certificate problem: unable to get local issuer certificate
Here are the details:
Case 1:
. . .
< HTTP/1.1 200 Connection established
< Proxy-agent: CCProxy
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* 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):
* CONNECT phase completed!
* CONNECT phase completed!
* error:1408F10B:SSL routines:ssl3_get_record:wrong version number
* Closing connection 0
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
Case 2:
$ curl -vX POST -d "userId=5&title=Hello World&body=Post body." https://jsonplaceholder.typicode.com/posts
Note: Unnecessary use of -X or --request, POST is already inferred.
* Uses proxy env variable https_proxy == 'http://10.xx.xx.xx:808/'
* Trying 10.xx.xx.xx:808...
* TCP_NODELAY set
* Connected to 10.xx.xx.xx port 808 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to jsonplaceholder.typicode.com:443
> CONNECT jsonplaceholder.typicode.com:443 HTTP/1.1
> Host: jsonplaceholder.typicode.com:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
< Proxy-agent: CCProxy
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* 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):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
The problem is not the above CCProxy, but our company is using the Zscaler transparent proxy which is intercepting SSL requests with its own certificate.
Is there any way to fix it pls?
$ curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1g zlib/1.2.11 brotli/1.0.7 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.8.0 nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux bullseye/sid
Release: testing
Codename: bullseye
Step 1 in both options will extract the Zscaler certificates.
OPTION 1 Direct curl
Download the certificates (all certificates are included in a single file)
Execute the curl command passing the certificateS you want to use.
# 1
openssl s_client -showcerts \
-connect jsonplaceholder.typicode.com:443 </dev/null 2>/dev/null \
| sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > typicode.crt
# 2
curl --cacert typicode.crt -v \
-d "userId=5&title=Hello World&body=Post body." \
https://jsonplaceholder.typicode.com/posts
OPTION 2 (installer script)
In case the curl command is executed by an installer you don't have control, then, update your certificates:
Extract the certificates from server (use the FQDN or IP and PORT, i.e: jsonplaceholder.typicode.com:443)
Move the XXX.crt certificate to your certificates directory
Update certificates
Execute installation script
# 1
openssl s_client -showcerts \
-connect jsonplaceholder.typicode.com:443 </dev/null 2>/dev/null \
| sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > typicode.crt
# 2
sudo mv typicode.crt /usr/local/share/ca-certificates/
# 3
sudo update-ca-certificates
# 4 execute your installer script
Bonus
In case you need/want to get the Zscaler certificates only, get the IP from: https://ip.zscaler.com
openssl s_client -showcerts -servername server -connect 165.225.216.33:443 > </dev/null 2>/dev/null | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' | grep -m1 -B-1 -- '-----END CERTIFICATE-----' > zscaler.crt
UPDATED (11/19/21):
Adding option 1, when is a direct curl and no need of install the certificates.
Optimized the command for extracting the certificates (creating the file)
Bonus: Getting the Zscaler IP
Tested on Ubuntu 20 and 18 behind Zscaler proxy.
Without certificate
With certificate
References:
How to install certificates for command line
unable to connect to server: x509: certificate signed by unknown authority
The answer is to "add that proxy's certificate to the CA bundle", thanks to Daniel Stenberg's answer. Then I guess I am suppose to fill in the rest. So here it is my attempt solving the remaining of the problems/questions --
Q: What is the easiest way to get that Zscaler certificate?
A: From here:
Go to Policy > SSL Inspection. In the Intermediate Root Certificate Authority for SSL Interception section, click Download Zscaler Root Certificate. Navigate to the ZscalerRootCerts. zip file and unzip it.
Q: How to add that certificate to the CA bundle?
A: See How to install company proxy certificate:
You can use curl --cacert <CA certificate> to supply your company CA cert.
Or you can add your company CA cert to /etc/pki/tls/certs/ and run make there to make it available system-wide.
This error (SSL certificate problem) means that the CA store that curl uses to verify the server's peer did not contain the cert and therefore the server couldn't be verified.
If want curl to work with a transparent proxy that terminates TLS you must add that proxy's certificate to the CA bundle or completely ignore the certificate check (which I recommend against).
A transparent proxy for TLS will of course make the connection completely unreliable and have broken security properties.
I've been asked to setup an FTPS connection, using a Client Authentication certificate. I'm the client, connecting to the server. I'm on a Windows7 workstation, behind a firewall. Some other info:
TLS 1.2 only
Passive mode only
My WAN IP is whitelisted
I'm connecting to a test URL, for now
There is no outbound firewall (only inbound rules)
Key should be sent in PEM format
I bought the certificate from Comodo, and generated the certificate with IE10. I exported the complete certificate from IE, with private key and extended properties, in the .pfx format.
I wrote a little batch file to extract the necessary parts from the .pfx, using OpenSSL:
::Extract the private key from the PFX
openssl pkcs12 -in comodo.pfx -nocerts -out encrypted.key
::Extract unencrypted private key
openssl rsa -in encrypted.key -out decrypted.key
::Extract the public cert in Base64 from the PFX
openssl pkcs12 -in comodo.pfx -clcerts -nokeys | openssl x509 -out comodo.cer
::Extract the chain bundle from the PFX
openssl pkcs12 -in comodo.pfx -nodes -nokeys -cacerts | openssl x509 -out comodo.crt
Using the extracted key parts, I have been trying various cURL (v7.46.0) commands to connect to the FTPS server. The connection keeps failing. My latest attempt is below. The error is almost always the same.
curl -3 -k -v --ftp-ssl --tlsv1.2 --ftp-ssl-reqd --ftp-pasv --key decrypted.key --cacert comodo.crt --cert comodo.cer --user REMOVED:REMOVED ftp://ftps.REMOVED/
An example of the output is:
> curl -3 -v -k --user REMOVED:REMOVED --ftp-ssl --tlsv1.2 --ftp-ssl-reqd --ftp-skip-pasv-ip --cert comodo.cer --key priv.pem ftp://ftps.REMOVED/
* Trying REMOVED_IP.
* Connected to ftps.REMOVED (REMOVED_IP) port 21 (#0)
< 220 Service ready for new user.
> AUTH SSL
< 234 Command AUTH okay; starting SSL connection.
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to ftps.REMOVED:21
* Closing connection 0 curl: (35) Unknown SSL protocol error in connection to ftps.REMOVED:21
>pause
Press any key to continue . . .
Strangely, if I connect with FileZilla, i can seem to get past the TLS handshake, but then I get different errors when I try to upload a file. As this connection will ultimately be made with cURL, I've concentrated on using cURL.
I've been trying this for over a week. The server admin has bought a certificate from my provider, and can connect without issue. I'm stumped on this one. Any help would be greatly appreciated.
Moved this question to ServerFault, as there seemed to be quite a lot of similar topics on that community:
https://serverfault.com/questions/820851/debugging-curl-ftps-connection-using-client-authentication-certificates-openss
I'm trying to connect to a service that requires a certificate for authorization. The process is that I send the service a CSR file. The service signs the CSR and sends me a certificate that I use for connection.
I generated the CSR by the following command line:
openssl req -new -nodes -newkey rsa:2048 -keyout cert.key -out cert.csr
I took the content of the cert.csr and sent to them. They generate the client certificate and I got a PEM file back.
I now try to connect using their certificate file in SSLCERT for curl() and providing the private key from cert.key as CURLOPT_SSLKEY - (which I got at step 1).
Fails with: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
What am I doing wrong in this process?
It works when I try with a received a test certificate including a private key from the service (self signed certificate). But when I use a certificate they generated from my CSR and then use my private key as key, it errors with handshake failure.
So I know it does not have something to do with that openssl / curl doesn't support v3/TLS etc. that others when researching for a solution found out their problem was.
Here is what I run:
curl -i -v --request POST https://service.com/ --cert clientcert.pem --key private_key.pem --cert-type pem --tlsv1.1 --insecure
* Connected to service.com (1xx.xxx.xxx.xx) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Request CERT (13):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS handshake, CERT verify (15):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS alert, Server hello (2):
* error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
* Closing connection 0
Running following versions: curl 7.35.0 (x86_64-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3
Not a definite answer but too much to fit in comments:
I hypothesize they gave you a cert that either has a wrong issuer (although their server could use a more specific alert code for that) or a wrong subject. We know the cert matches your privatekey -- because both curl and openssl client paired them without complaining about a mismatch; but we don't actually know it matches their desired CA(s) -- because your curl uses openssl and openssl SSL client does NOT enforce that a configured client cert matches certreq.CAs.
Do openssl x509 <clientcert.pem -noout -subject -issuer and the same on the cert from the test P12 that works. Do openssl s_client (or check the one you did) and look under Acceptable client certificate CA names; the name there or one of them should match (exactly!) the issuer(s) of your certs. If not, that's most likely your problem and you need to check with them you submitted your CSR to the correct place and in the correct way. Perhaps they have different regimes in different regions, or business lines, or test vs prod, or active vs pending, etc.
If the issuer of your cert does match desiredCAs, compare its subject to the working (test-P12) one: are they in similar format? are there any components in the working one not present in yours? If they allow it, try generating and submitting a new CSR with a subject name exactly the same as the test-P12 one, or as close as you can get, and see if that produces a cert that works better. (You don't have to generate a new key to do this, but if you choose to, keep track of which certs match which keys so you don't get them mixed up.) If that doesn't help look at the certificate extensions with openssl x509 <cert -noout -text for any difference(s) that might reasonably be related to subject authorization, like KeyUsage, ExtendedKeyUsage, maybe Policy, maybe Constraints, maybe even something nonstandard.
If all else fails, ask the server operator(s) what their logs say about the problem, or if you have access look at the logs yourself.
What SSL private key should be sent along with the client certificate?
None of them :)
One of the appealing things about client certificates is it does not do dumb things, like transmit a secret (like a password), in the plain text to a server (HTTP basic_auth). The password is still used to unlock the key for the client certificate, its just not used directly to during exchange or tp authenticate the client.
Instead, the client chooses a temporary, random key for that session. The client then signs the temporary, random key with his cert and sends it to the server (some hand waiving). If a bad guy intercepts anything, its random so it can't be used in the future. It can't even be used for a second run of the protocol with the server because the server will select a new, random value, too.
Fails with: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
Use TLS 1.0 and above; and use Server Name Indication.
You have not provided any code, so its not clear to me how to tell you what to do. Instead, here's the OpenSSL command line to test it:
openssl s_client -connect www.example.com:443 -tls1 -servername www.example.com \
-cert mycert.pem -key mykey.pem -CAfile <certificate-authority-for-service>.pem
You can also use -CAfile to avoid the “verify error:num=20”. See, for example, “verify error:num=20” when connecting to gateway.sandbox.push.apple.com.
The solution for me on a CentOS 8 system was checking the System Cryptography Policy by verifying the /etc/crypto-policies/config reads the default value of DEFAULT rather than any other value.
Once changing this value to DEFAULT, run the following command:
/usr/bin/update-crypto-policies --set DEFAULT
Rerun the curl command and it should work.
In my case the cause of the error was that I only imported the certificate (e.g., cert1.pem) and the private key (e.g., privkey1.pem) into the keystore and to solve the issue, I had to import the full chain of certificates as well.
I got the following files from "Let's Encrypt" certification authority:
privkey1.pem
fullchain1.pem
chain1.pem
cert1.pem
So I did the following:
Join the content of three certificate files together into a file named all.pem:
cat cert1.pem chain1.pem fullchain1.pem > all.pem
Create my keystore containing the full certificate chain:
openssl pkcs12 -export -in all.pem -inkey privkey1.pem -out my_keystore.p12 -name mycertalias -CAfile chain1.pem -caname root