First commit
This commit is contained in:
commit
4743ae9ca3
5
README.md
Normal file
5
README.md
Normal 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
130
index.py
Normal 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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user