def main(argv): key = False pin = False parser = argparse.ArgumentParser(description='Gather') parser.add_argument('-s', '--server', dest="server", help="name of server") parser.add_argument('-k', action='store_true', dest='key', help='Indicates that you want the key of the server') parser.add_argument('-p', action='store_true', dest="pin", help='Indicate that you want extract pin') parser.add_argument('-a', '--algorithm', dest='algo', help='Hash algorithm to use') parser.add_argument('-f', '--file', dest='file', help="File to a certificate") parser.set_defaults(algo='sha256') options = parser.parse_args() if options.server is not None: server = options.server key = options.key pin = options.pin algo = options.algo if key is True: get_key(server, algo) if pin is True: (_id, issuer, b64_pki) = get_pin(server, algo) answer = raw_input("Do you want to include it in the DB (y/n): ") if answer == 'y' or answer == 'Y': db = PinDB(config.DB_NAME,"pinning") collection = db.collection pin = dict() pin["_id"] = _id pin["issuers"] = dict() pin["issuers"][issuer] = list() pin["issuers"][issuer].append(b64_pki) exist = collection.find_one({"_id" : pin["_id"]}) if exist is None: collection.insert(pin) else: exist = merge_dict(exist["issuers"], pin["issuers"]) collection.update({"_id" : pin["_id"]}, exist) print "Database updated" if options.file is not None: get_key_from_file(options.file, options.algo)
hash_t = cert.hash_spki(algorithm="sha256") name = cert.subject_common_name() algorithm = cert.get_cert_nss().subject_public_key_info.algorithm algorithm = algorithm.id_str _id = algorithm + ' - ' + name exist = db.get(_id) if exist is None: # That means that the certificate is not in the db, it's the # first time it was seen db.set_hash(hash_t, _id) debug_logger.debug("\t[+] Certificate %s first seen" % name) else: # Exist so we have to ensure that it is correct correct = db.compare(_id, hash_t) if correct is False: before = db.get(_id) debug_logger.debug("\t[-] Certificate %s has changed" % name) logger.info( "\t[-] Certificate {0} has changed from".format(name) + " \n{0}--->{1}\n ".format(before["_id"], before["hash"]) + "to \n{0}--->{1}".format(algorithm, hash_t)) MITMNotification.notify(title=self.name, message=name) else: debug_logger.debug("\t[+] Certificate %s has not changed" % name) # This db is shared by all the instance of keyContinuity. It is not necessary # create an instance each time that we use this class. db = PinDB(config.DB_NAME, KeyContinuity.name)
name = cert.subject_common_name() issuer_name = cert.issuer_common_name() query = db.get(name) if query is None: debug_logger.debug( "\t[-] You have not pinned this certificate %s" % name) return try: spki = cert.hash_spki(deep=1, algorithm="sha256") spki = base64.b64encode(spki) except: logger.error("Getting spki of the intermediate CA %s" % name) return try: issuers = query["issuers"] for i in issuers[issuer_name]: if spki == i: debug_logger.debug("\t[+] pin correct %s " % name) return logger.info("\t[-] Pin does not match %s" % name) debug_logger.debug("\t[-] Pin does not match %s" % name) MITMNotification.notify(title="Pinning", message=cert.subject_common_name()) except: MITMNotification.notify(title="Pinning", message="Issuer different") debug_logger.debug("\t[-] issuer with different name %s" % name) db = PinDB(config.DB_NAME, "pinning")
def drop(): db = PinDB(config.DB_NAME, "keycontinuity") db.drop_pinning()
"usage: %prog -f <folder with certificates> ") parser.add_option('-f', '--folder', dest='folder', help="Directory that holds certificates") (opts, args) = parser.parse_args() if opts.folder is None: parser.error("Specify the name of directory") path = os.path.expanduser(opts.folder) certdb_dir = os.path.expanduser(config.NSS_DB_DIR) nss.nss_init(certdb_dir) certdb = nss.get_default_certdb() db = PinDB("pfc", "keycontinuity") for i in os.listdir(path): file = os.path.join(path, i) if os.path.isfile(file): # f = open(file).readlines() # f = ''.join(f) try: a = M2Crypto.X509.load_cert(file, format=FORMAT_DER) except: # we should transform PEM encoding to DER cmdstr = [ "openssl", "x509", "-in", file, "-inform", "PEM", "-out", file, "-outform", "DER" ] subprocess.call(cmdstr)