diff --git a/bin/x509/ip-ssl-subject-api.py b/bin/x509/ip-ssl-subject-api.py new file mode 100644 index 0000000..939c44d --- /dev/null +++ b/bin/x509/ip-ssl-subject-api.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Lookup IP for known fingerprints and X.509 subjects via HTTP API +# +# Software is free software released under the GNU General Public License version 3 and later +# +# Copyright (c) 2015 Alexandre Dulaunoy - a@foo.be + +import redis +import sys +import netaddr +import json + +import tornado.httpserver +import tornado.ioloop +import tornado.options +import tornado.web + +from tornado.options import define, options +define("port", default=8888, help="run on the given port", type=int) +ipmaxsize = 512 #/23 + +class SSLQueryHandler(tornado.web.RequestHandler): + + def get(self, input): + try: + #Redis structure Set of (FP) per IP + r = redis.StrictRedis(host='127.0.0.1', port=6381) + except: + print "Unable to connect to the Redis server" + sys.exit(255) + subnets = [input] + out = {} + for subnet in subnets: + try: + iplist = netaddr.IPNetwork(subnet) + except: + self.clear() + self.set_status(400) + self.finish('Incorrect format') + continue + + if iplist.size > ipmaxsize: + self.clear() + self.set_status(400) + self.finish('Maximum CIDR block size reached >/23') + + if not self._finished: + self.finish() + for ip in iplist: + s = r.smembers(ip) + if s: + out[str(ip)] = [] + for fingerprint in s: + subjects = r.smembers(fingerprint) + if subjects: + for subject in subjects: + out[str(ip)].append(subject) + else: + out[str(ip)].append(fingerprint) + + if not self._finished: + self.set_header('Content-Type', 'application/json') + self.set_header('Server', 'https://github.com/adulau/crl-monitor') + self.write(json.dumps(out)) + + +if __name__ == "__main__": + tornado.options.parse_command_line() + app = tornado.web.Application(handlers=[ + (r"/query/(.*)", SSLQueryHandler), + ]) + http_server = tornado.httpserver.HTTPServer(app) + http_server.listen(options.port) + tornado.ioloop.IOLoop.instance().start() +