diff --git a/bin/x509/ip-ssl-subject-api.py b/bin/x509/ip-ssl-subject-api.py index 90eeef6..d118e48 100644 --- a/bin/x509/ip-ssl-subject-api.py +++ b/bin/x509/ip-ssl-subject-api.py @@ -13,6 +13,9 @@ import sys import netaddr import json import re +import os + +import M2Crypto import tornado.httpserver import tornado.ioloop @@ -21,6 +24,7 @@ import tornado.web from tornado.options import define, options define("port", default=8888, help="run on the given port", type=int) +certrepo = '/data/certs{}' ipmaxsize = 512 #/23 servername = 'SSL Certificate API - https://github.com/adulau/crl-monitor' @@ -34,6 +38,15 @@ def checksha1(value=False): return True +def bpath(ha=None, level=6): + if ha is None: + return False + fn = "" + for i in range(0, level*2, 2): + fn = fn + "/"+ ha[i:2+i] + return fn + + class SSLQueryHandler(tornado.web.RequestHandler): def get(self, input): @@ -112,11 +125,56 @@ class CertificateQueryHandler(tornado.web.RequestHandler): self.set_header('Server', servername) self.write(json.dumps(out)) +class FetchCertificateHandler(tornado.web.RequestHandler): + def get(self, input): + try: + r = redis.StrictRedis(host='127.0.0.1', port=8323) + except: + print "Unable to connect to the Redis server" + sys.exit(255) + + fp = input.lower() + if not checksha1(value=fp): + self.clear() + self.set_status(400) + self.finish('Incorrect format of the certificate fingerprint (expected SHA1 in hex format)') + + certpath = bpath(ha=fp) + certpath = os.path.join(certpath, fp) + certpath = certrepo.format(certpath) + if not os.path.exists(certpath): + self.clear() + self.set_status(400) + self.finish('Not existing certificate') + + cert = M2Crypto.X509.load_cert(certpath, M2Crypto.X509.FORMAT_DER) + out = {} + out['pem'] = cert.as_pem() + out['info'] = {} + out['info']['issuer'] = cert.get_issuer().as_text() + out['info']['subject'] = cert.get_subject().as_text() + out['info']['fingerprint'] = cert.get_fingerprint(md='sha1') + out['info']['keylength'] = cert.get_pubkey().get_rsa().__len__() + out['info']['key'] = cert.get_pubkey().get_rsa().as_pem() + out['info']['not_before'] = cert.get_not_before().get_datetime().isoformat() + out['info']['not_after'] = cert.get_not_after().get_datetime().isoformat() + out['info']['extension'] = {} + extcount = cert.get_ext_count() + + for i in range(0, extcount): + out['info']['extension'][cert.get_ext_at(i).get_name()] = cert.get_ext_at(i).get_value() + + if not self._finished: + self.set_header('Content-Type', 'application/json') + self.set_header('Server', servername) + self.write(json.dumps(out)) + if __name__ == "__main__": tornado.options.parse_command_line() app = tornado.web.Application(handlers=[ (r"/query/(.*)", SSLQueryHandler), - (r"/cquery/(.*)", CertificateQueryHandler) + (r"/cquery/(.*)", CertificateQueryHandler), + (r"/cfetch/(.*)", FetchCertificateHandler) ]) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port)