summaryrefslogtreecommitdiff
path: root/tools/validatestore.py
blob: a1077680ddaaa26d3b0f07d8bd1d7d623de00fd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python

# Copyright (c) 2015, NORDUnet A/S.
# See LICENSE for licensing information.

import argparse
import urllib2
import urllib
import json
import base64
import sys
import struct
import hashlib
import itertools
from certtools import *
try:
    from precerttools import *
except ImportError:
    pass
import os
import signal
import select
import zipfile
import traceback

parser = argparse.ArgumentParser(description='')
parser.add_argument('--store', default=None, metavar="dir", help='Get certificates from directory dir')
parser.add_argument('--parallel', type=int, default=1, metavar="n", help="Number of parallel workers")
args = parser.parse_args()

from multiprocessing import Pool

certfilepath = args.store

if certfilepath[-1] == "/":
    certfiles = [certfilepath + filename for filename in sorted(os.listdir(certfilepath)) if os.path.isfile(certfilepath + filename)]
else:
    certfiles = [certfilepath]

def submitcert((certfile, cert)):
    try:
        certchain = get_certs_from_string(cert)
        if len(certchain) == 0:
            return True
        precerts = get_precerts_from_string(cert)
        hash = get_hash_from_certfile(cert)
        timestamp = get_timestamp_from_certfile(cert)
        assert len(precerts) == 0 or len(precerts) == 1
        precert = precerts[0] if precerts else None
        if precert:
            if ext_key_usage_precert_signing_cert in get_ext_key_usage(certchain[0]):
                issuer_key_hash = get_cert_key_hash(certchain[1])
                issuer = certchain[1]
            else:
                issuer_key_hash = get_cert_key_hash(certchain[0])
                issuer = None
            cleanedcert = cleanprecert(precert, issuer=issuer)
            mtl = pack_mtl_precert(timestamp, cleanedcert, issuer_key_hash)
            leaf_hash = get_leaf_hash(mtl)
        else:
            mtl = pack_mtl(timestamp, certchain[0])
            leaf_hash = get_leaf_hash(mtl)
        if leaf_hash == hash:
            return True
        else:
            print certfile, repr(leaf_hash), repr(hash), precert != None
            return None
    except Exception, e:
        print certfile
        traceback.print_exc()
        raise e

def get_all_certificates(certfiles):
    for certfile in certfiles:
        if certfile.endswith(".zip"):
            zf = zipfile.ZipFile(certfile)
            for name in zf.namelist():
                yield (name, zf.read(name))
            zf.close()
        else:
            yield (certfile, open(certfile).read())

p = Pool(args.parallel, lambda: signal.signal(signal.SIGINT, signal.SIG_IGN))

certs = get_all_certificates(certfiles)

try:
    for result in p.imap_unordered(submitcert, certs):
        if result == None:
            print "error"
            p.terminate()
            p.join()
            sys.exit(1)
except KeyboardInterrupt:
    p.terminate()
    p.join()