diff --git a/bin/x509/ip-ssl-subject-api.py b/bin/x509/ip-ssl-subject-api.py index 0ce0319..90eeef6 100644 --- a/bin/x509/ip-ssl-subject-api.py +++ b/bin/x509/ip-ssl-subject-api.py @@ -1,7 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Lookup IP for known fingerprints and X.509 subjects via HTTP API +# Lookup IP or CIDR block for known fingerprints and X.509 subjects via HTTP API /query/149.13.30.0/24 +# Lookup fingerprint of certificate where seen /cquery/16c25d401f35dd52fb4aec85eb1f1a28ce16f961 # # Software is free software released under the GNU General Public License version 3 and later # @@ -21,6 +22,17 @@ import tornado.web from tornado.options import define, options define("port", default=8888, help="run on the given port", type=int) ipmaxsize = 512 #/23 +servername = 'SSL Certificate API - https://github.com/adulau/crl-monitor' + +def checksha1(value=False): + if value is False or len(value) != 40: + return False + try: + sha1int = int(value, 16) + except ValueError: + return False + + return True class SSLQueryHandler(tornado.web.RequestHandler): @@ -71,14 +83,40 @@ class SSLQueryHandler(tornado.web.RequestHandler): if not self._finished: self.set_header('Content-Type', 'application/json') - self.set_header('Server', 'https://github.com/adulau/crl-monitor') + self.set_header('Server', servername) self.write(json.dumps(out)) +class CertificateQueryHandler(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)') + + out = {} + out['certificate'] = fp + out['seen'] = [] + ips = r.smembers('s:{}'.format(fp)) + out['hits'] = len(ips) + for ip in ips: + out['seen'].append(ip) + + 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) ]) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port)