First commit

This commit is contained in:
Beu 2018-07-04 18:12:38 +02:00
commit 4743ae9ca3
2 changed files with 135 additions and 0 deletions

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# API of HTTPS+ Checker
It's a CGI API write in python3.
The only one dependance is **dnspython**

130
index.py Normal file
View File

@ -0,0 +1,130 @@
#!/usr/bin/python3
#-*- coding: utf-8 -*-
# IMPORTATION
import cgi
import json
import urllib.request
import ssl
import hashlib
import dns.query
import dns.message
import socket
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import Encoding
from cryptography.hazmat.primitives.serialization import PublicFormat
# MODULES
def dnssec_validation(DOMAIN):
qm = dns.message.make_query(DOMAIN, dns.rdatatype.A,want_dnssec=True)
response = dns.query.udp(qm,"1.1.1.1")
dnssec = dns.flags.to_text(response.flags)
if "AD" in dnssec:
return(True)
else:
return(False)
def tlsa_validation(DOMAIN):
def compute_hash(func, string):
"""compute hash of string using given hash function"""
h = func()
h.update(string)
return h.hexdigest()
qm = dns.message.make_query('_443._tcp.' + DOMAIN, dns.rdatatype.TLSA)
response = dns.query.udp(qm,"1.1.1.1")
if len(response.answer) is 0:
return(False)
else:
tlsaanswer = str(response.answer[-1])
tlsatable = tlsaanswer.split()
selector = str(tlsatable[5])
mtype = str(tlsatable[6])
hexdata1 = str(tlsatable[7])
conn = ssl.create_connection((DOMAIN , 443))
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
sock = context.wrap_socket(conn, server_hostname=DOMAIN)
cert = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))
cert = cert.encode('ascii')
if selector == "0":
certdata = cert.as_der()
elif selector == "1":
cert = x509.load_pem_x509_certificate(cert, default_backend())
certdata = cert.public_key().public_bytes(Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
else:
raise ValueError("selector type %d not recognized" % selector)
if mtype == "0":
hexdata2 = hexdump(certdata)
elif mtype == "1":
hexdata2 = compute_hash(hashlib.sha256, certdata)
elif mtype == "2":
hexdata2 = compute_hash(hashlib.sha512, certdata)
else:
raise ValueError("matchtype %d not recognized" % matchtype)
if hexdata1 == hexdata2:
return True
else:
return False
def headers_validation(DOMAIN):
url = "https://" + DOMAIN + "/"
try:
headers = urllib.request.urlopen(url,timeout=3).info()
except:
return("NO HTTPS")
if "public-key-pins" in str(headers).lower():
RESULT="HPKP_TRUE"
else:
RESULT="HPKP _FALSE"
if "strict-transport-security" in str(headers).lower():
RESULT = RESULT + " HSTS_TRUE"
else:
RESULT = RESULT + " HSTS_FALSE"
return(RESULT)
# MAIN
print("Content-Type: text/html")
print("")
fs = cgi.FieldStorage()
JSON_RESULT= '{"DNSSEC": false,"DANE": false,"HSTS": false,"HPKP": false}'
JSON_DATA = json.loads(JSON_RESULT)
if "domain" not in fs:
print("{ERROR}")
cgi.sys.exit(0)
domain = cgi.escape(fs["domain"].value)
if dnssec_validation(domain) is True:
JSON_DATA["DNSSEC"] = True
if tlsa_validation(domain) is True:
JSON_DATA["DANE"] = True
headers = headers_validation(domain)
if "HSTS_TRUE" in headers:
JSON_DATA["HSTS"] = True
if "HPKP_TRUE" in headers:
JSON_DATA["HPKP"] = True
JSON_RESULT = json.dumps(JSON_DATA)
print(JSON_RESULT)