Verify SSL certificate from the custom path using python - python

I have installed apache web server. Generated SSL for the apache website. Got cert file and key. I wrote a python snippet to validate the ssl file for the website. The certificate file path is stored in cer_auth. My code will access file in the cer_auth,validates it and provide the result. But it is showing error. How to solve it?
Here's the code:
import requests
host = '192.168.1.27'
host1 = 'https://'+host
#cer_auth = '/etc/ssl/certs/ca-certificates.crt'
cer_auth = '/home/paulsteven/Apache_SSL/apache-selfsigned.crt'
print(host1)
try:
requests.get(host1, verify= cer_auth)
print("SSL Certificate Verified")
except:
print("No SSL certificate")
Error i got:
https://192.168.1.27
/home/paulsteven/.local/lib/python3.5/site-packages/urllib3/connection.py:362: SubjectAltNameWarning: Certificate for 192.168.1.27 has no `subjectAltName`, falling back to check for a `commonName` for now. This feature is being removed by major browsers and deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 for details.)
SubjectAltNameWarning
No SSL certificate

The old way of pointing certificates to hostnames was through the CommonName or CN field. This practice is rapidly changing due to changes in how browsers handle certificates. The current expectation is to have all hostnames and IPs in x509v3 extended fields in the certificate, named subjectAlternativeNames. The instructions you have followed were probably outdated.
Here's a mediocre guide into doing just that with OpenSSL
https://support.citrix.com/article/CTX135602
If you want to sign for some IP addresses, the field name is IP.1 instead of DNS.1 like in the link above.

Related

What's the function of `context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")` in python ssl coding?

I follow a tutorial written a Python ssl demo.
import ssl
import socket
HOSTNAME = "www.cloudflare.com"
context = ssl.create_default_context()
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
#context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=HOSTNAME)
conn.connect((HOSTNAME, 443))
# cert = conn.getpeercert()
#
# print(cert)
this line code I don't understand, what's the function?
context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
and I run it in my macOS, I don't know which path I can access the ca-bundle.crt, and don't know the ca-bundle.crt's function. Could you please help with these questions?
Do you know how certificates are verified? If no you can start with the Wikipedia page about PKI.
In brief. Certificates are signed by the certificate authorities. We trust those authorities in that they check all the claims in the certificated requests. As a resut, if a site provides a certificate for stackoverflow.com and signed by the trusted CA then we believe it is really Stackoverflow.
The set of trusted authorities is small. Several dozens. Theyr public keys are distributed as certificates with operating systems, browsers, openssl distro. Those certificates are called root certificates.
The call context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt") loads the list of root certificates of the CAs, that openssl maintaners trust. That list of certificates is stored in the file /etc/ssl/certs/ca-bundle.crt.
But in MacOS this call is not needed. Default OpenSSL distro loads the CA certificates from the operating sysem. The certificate for cloudflare.com is issued by DigiCert. This is a reputable CA that all browsers and operating systems trust. Their certificate is stored in MacOS and is loaded in your process when you intialize the default context.
FYI. The constant ssl.PROTOCOL_SSLv23 is a misnomer and was deprecated since python 3.6. Use ssl.PROTOCOL_TLS instead.

Python - Issue SSL: CERTIFICATE_VERIFY_FAILED

I'm trying to solve the problem
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:579)
when I connect to a handle server.
I also used
ssl._create_default_https_context = ssl._create_unverified_context
as some user suggested, but I'm not able to fix the issue.
Any other solution?
Thanks
Does your server have a valid certificate, signed by a Certification Authority?
If it uses a self-signed certificate I would suggest that you save a copy of the public certificate in your Python project and pass the certificate name in the verify parameter on requests.
You can save the certificate by accessing the server on Firefox, clicking on the Lock icon near to the address bar, selecting the Certificate, then More details, then View Certificate, then export.
You will get a .pem file, let's say: "my_server_certificate.pem".
Then when you create your Session object on requests you can pass the parameter:
session = requests.Session()
session.verify = "my_server_certificate.pem"
I had similar problems when using charles proxy with my Python scripts. I hope this helps you solve your problem as well.

Python - SSL: CERTIFICATE_VERIFY_FAILED

I have a python script that uses the VirusTotal API. It has been working with no problems, but all of a sudden when I run the script I am getting the following error:
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>
I believe it may be our web proxy that is causing the issue. Is there a way to prevent it from verifying the cert? Here is the portion of the code that uses the API:
json_out = []
url = "https://www.virustotal.com/vtapi/v2/file/report"
parameters = {"resource": my_list,
"apikey": "<MY API KEY>"}
data = urllib.urlencode(parameters)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
json_out.append (response.read())
I believe it may be our web proxy that is causing the issue. Is there a way to prevent it from verifying the cert?
If you assume that a SSL intercepting proxy is denying the connection then you have to fix the problem at the proxy, i.e. there is no way to instruct the proxy to not check the certificate from your application.
If instead you assume that there is a SSL intercepting proxy and thus the certificate you receive is not signed by a CA you trust then you should get the CA of the proxy and trust it in your application (see cafile parameter in the documentation). Disabling validation is almost never the right way. Instead fix it so that validation works.
There are two possibilities,
You are using a self-signed certificate. Browsers don not trust on such certificate, so be sure that you are using CA-signed trusted certificate.
If you are using CA-signed trusted the certificate that you should have to check for install CA chain certificates (Root and Intermediate certificate).
You can refer this article, it may help you. - https://access.redhat.com/articles/2039753

How to connect to a SOAP service (without WSDL) using SSL and authentication in Python?

I want to connect to a SOAP API that does not have WSDL in Python. To connect I need to a add a SSL certificate and authenticate afterwards.
from pysimplesoap.client import SoapClient, SimpleXMLElement
cacert = open(path, 'rb').read() # read the certificate
header = SimpleXMLElement('<Header/>')
credentials = header.add_child('Credentials')
credentials.marshall('Password', 'password')
credentials.marshall('Username', 'username')
client = SoapClient(
location="https://mytest.com/Services/",
cacert=cacert)
client['Header'] = header
client.action = "https://mytest.com/Services/Action1"
client.Action1() # gives SSL error
The result I receive is a SSL error:
SSLHandshakeError: [Errno 1] _ssl.c:510: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Can anyone, please, tell me how to solve this issue? Or can you advise any other library I can use. Most SOAP libraries I found offer connection only to WSDL.
Usually in a pfx file there is the client certificate with key, not the CA file. The libraries seems to expect the client certificate as PEM. You should extract the certificate and the key as show in https://stackoverflow.com/a/9516936/3929826.
Then hand it in to the SoapClient() initiation as cert and key_file argument:
client = SoapClient(location="https://mytest.com/Services/",
cert='mycert.pem',
key_file='mycert.key)
It should also be possible to put both into the cert file.
If that still does not work your have to add the CA certificate as the cacert parameter after you retrieved it as described in https://stackoverflow.com/a/7886248/3929826 .
For further reference see the source code of simplesoap: https://code.google.com/p/pysimplesoap/source/browse/pysimplesoap/client.py#75 .

imaplib python with ssl certificate

I'm trying to use imaplib.IMAP4_SSL function but I'm stuck with this error:
[Errno 336265225] _ssl.c:356: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
try:
mail = imaplib.IMAP4_SSL(host='imap.gmail.com', port="993", certfile="certIMAP.pem")
except Exception as e:
print e
sys.exit()
The certificate has been downloaded with:
echo | openssl s_client -connect imap.gmail.com:993 2>/dev/null | openssl x509 > certIMAP.pem
Permission on the file are ok.
If I use the keyfile option, they ask me the cert, and then the same error is obtained.
I could not find example for this function with cert specification.
Thank you.
While it is not obvious from the documentation I would suggest that the parameters certfile and keyfile are not used to verify the servers certificate (that's how you use it - and keyfile would not make any sense here) but are the optional certificate for the client and it's private key, which some server might require to identify the client (e.g. instead or additionally to password).
To verify the server you usually have something called CA file or CA path (CA = certificate agency) and you don't need a private key here. There seem to be no obvious way for given the CA certificates here, but Certificate Authority for imaplib and poplib python might help you with this.

Categories

Resources