API Python connection error occurrence, [SSL socket programming inquiry] - ssl

An SSL handshake error occurred in the process of making an API call with Python.
The reason for the SSL handshake error is that information such as client certificate, CA certificate, and client private key should be used as options.
Query curl -k --tlsv1.2 --cacert ./ca-chain.crt --cert ./client.crt --key ./client.key -H
You should have the above settings.
I found the tlsv1.2 part at the beginning through an internet search,
import ssl
I learned that I just need to add the syntax context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) .
Then cacert ./ca-chain.crt --cert ./client.crt --key ./client.key did not know how to implement this part in Python code, so I asked a question.
The client certificate, CA certificate, and client private key are in the state that I extracted and kept with openssl.
Query: curl -k --tlsv1.2 --cacert ./ca-chain.crt --cert ./client.crt --key ./client.key -H I would like to know how to implement this in python code.
Thanks for reading this long post.

Then cacert ./ca-chain.crt --cert ./client.crt --key ./client.key did not know how to implement this part in Python code, so I asked a question.
ctx.load_verify_locations('./ca-chain.crt')
ctx.load_cert_chain('./client.crt', './client.key')
For more see the documentation.

Related

curl failing with --insecure(-k) and missing --cacert

I have a client server interface.
The case is unusual, because the server authenticates client and not vice versa.
The client sends client cert to the server. The server authenticates the client cert with its root ca cert. There is also an intermediate cert being used, but I dont need that on server to authenticate the client.
The commands go as follows.
"curl -k --cert client-cert.pem --key client-key.pem https://server.com:443/endpoint" (FAIL)
But if I pass the intermediate cacert as argument to curl, its successful.
"curl -k --cert client-cert.pem --key client-key.pem --cacert intermediates.pem https://server.com:443/endpoint" (PASS)
Even if I pass in the root ca(same between client and server) it fails.
"curl -k --cert client-cert.pem --key client-key.pem --cacert root-ca.pem https://server.com:443/endpoint" (FAIL)
PS:
(FAIL) means, Server says authentication failure!
My Question is:
Why should a server care about the --cacert option at all. curl shouldn't be sending over the ca cert regardless. Correct?
Why do things work when I only pass intermediates file.
Thanks in advance for the response.
PS:
The client-cert.pem is signed by intermediate ca and intermediate ca is signed by root ca.

Certificate issues with centOS7 with curl

I have an issue when using certificate when using curl. I'm running centOS7. We managed to get the curl going in other places, but not our dev machine:
What we are trying to do:
sudo curl -X 'GET' 'https://webpage/document' --cert '/localization.crt.pem' --key '/localization.key.pem' -H 'accept: */*' -k
Im getting this error:
curl: (58) SSL peer cannot verify your certificate.
What I tried to do?(from centOS documentation)
https://access.redhat.com/documentation/en-us/red_hat_certificate_system/9/html/administration_guide_common_criteria_edition/importing_certificate_into_nssdb
# PKICertImport -d . -n "client name" -t ",," -a -i certificate.crt.pem -u C
after echo $? we get a 0, so i think it is installed properly?
Any idea on whats wrong would be great.
I have run into this recently on our linux environments. I've found that this tends to happen if you have an SSL Certificate issued that also includes a chain certificate. If that chain is not also configured on your server OpenSSL considers the certificate invalid.
I would test this using this command:
openssl s_client -showcerts -verify 5 -connect website.com:443
If you see a block like this that means you are missing the certificate chain in your server configuration:
---
SSL handshake has read 2162 bytes and written 401 bytes
Verification error: unable to verify the first certificate
---
Windows fills in the gaps and doesn't mind this type of configuration, but openssl is very particular.
I managed to solve the issue. Recompiled curl with openSSL with following tutorial:
Install curl with openssl
Works like a charm :)

using mosquitto_sub with --insecure

Right now I have to do an initial test of a mqtt broker (ssl).
However right now I don't have the valid truststore certificates, however I would like to test the basic connectivity, ignoring SSL errors regarding hostname verification, certificate validation etc.
Unfortunately I am not successful, even with a broker I know it's working.
What I'm doing:
mosquitto_sub -h the_host -p 8883 -t '#' -v -u myUser -P myPass --insecure -d --capath /etc/ssl/certs
According to the manpage I just use the --capath to identify it's a TLS connection, well knowing that the necessary root certificate is not available here.
What I get is this:
Client mosqsub|11262-csbox sending CONNECT
Error: A TLS error occurred.
Any idea what I'm doing wrong?
Using --insecure just disables the verification of the hostname in the certificate presented by the broker. It does not remove the need to have a copy of the CA certificate that signed the brokers certificate.
So if /etc/ssl/certs doesn't contain a matching CA certificate then the connection will fail.
If needed you should be able to use something like openssl s_client to download the certificate chain directly from the broker, you can then point to that file with the --cafile option instead of the --capath option.

client certificate not found

What can I do to troubleshoot/fix why my curl command cannot find my certificate when referencing to it by its nickname
I am trying to get a secure connection to a bank server, that is handling our online payments, using curl. The server is using NSS protocol. I installed the certificate from the bank into the nssdb with a nickname "foo" using:
certutil -A -d sql:/etc/pki/nssdb -i ccapi.pem -n "foo" -t "P,P,P"
Listing the cert to check that it has been created, I use
certutil -L -d sql:/etc/pki/nssdb/
with the output confirming a nickname "foo" for the cert.:
Certificate Nickname Trust Attributes
SSL,S/MIME,JAR/XPI
foo P,P,P
When I am trying to connect using curl referencing to the nickname foo for the certificate like this:
curl -k -v --cert "foo" https://ccapi.client.qvalent.com/payway/ccapi
This is PART of the output:
Connected to proxy.ourdomain.com.au (172.21.0.58) port 3128 (#0)
Establish HTTP proxy tunnel to ccapi.client.qvalent.com:443
CONNECT ccapi.client.qvalent.com:443 HTTP/1.1
Host: ccapi.client.qvalent.com:443
User-Agent: curl/7.37.0
Proxy-Connection: Keep-Alive
HTTP/1.1 200 Connection established
Proxy replied OK to CONNECT request
Initializing NSS with certpath: sql:/etc/pki/nssdb
skipping SSL peer certificate verification
NSS: client certificate not found: foo
The last line: certificate not found: foo, is my problem. I seem to be doing everything right when creating the cert in the nssdb with a nickname but when using a curl command to connect it cannot find the certificate. If I link to the actual cert like this and not the nickname:
curl -k -v --cert "./ccapi.pem" https://ccapi.client.qvalent.com/payway/ccapi
Then the certificate is recognized but I cannot connect to bank server. This could be because I need to use NSS but this is irrelevant for what I am trying to get an answer to. I have found similar questions on stackoverflow eg. CURL NSS client certificate not found myCert but they fall short of answering the question. I do not have/use PKCS #12 certificate.
What can I do to troubleshoot/fix why my curl command cannot find my certificate when referencing to it by its nickname.
Appreciate any help
-M

Using curl with certificate that has no password

I have my own CA and client certificate that I have been using successfully with cURL using the normal format:
curl --cacert /etc/myca.crt --cert /etc/myclient.pem:mypassword --cert-type PEM --get https://myhost.com
Now, for reasons outside the scope of this question, I have the same client certificate but the password has been removed using openssl. Using openssl I have verified that the new certificate is correct and I can use it to make SSL connections using applications other than cURL, but I cannot get it to work with cURL.
If I don't enter a password:
curl --cacert /etc/myca.crt --cert /etc/myclient.pem --cert-type PEM --get https://example.com
I get an error saying "curl: (58) unable to use client certificate (no key found or wrong pass phrase?)"
I have also tried:
curl --cacert /etc/myca.crt --cert /etc/myclient.pem: --cert-type PEM --get https://example.com
but I get the same error.
I am making the call to cURL from within a Perl script, so I need to find a way that will not prompt me for the password. I am using cURL 7.15.5 on RHEL 5.
Thank you.
You can make use of the --pass switch:
--pass <phrase> (SSL/SSH) Passphrase for the private key
To pass an empty passphrase you can use:
--pass ''