]> git.donarmstrong.com Git - ca-certificates.git/blob - mozilla/certdata2pem.py
d40b659d5cc059fa4af0b2dd0f7f682784f7f84b
[ca-certificates.git] / mozilla / certdata2pem.py
1 #!/usr/bin/python
2 # vim:set et sw=4:
3 #
4 # certdata2pem.py - splits certdata.txt into multiple files
5 #
6 # Copyright (C) 2009 Philipp Kern <pkern@debian.org>
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
22 import base64
23 import os.path
24 import re
25 import sys
26 import textwrap
27
28 objects = []
29
30 # Dirty file parser.
31 in_data, in_multiline, in_obj = False, False, False
32 field, type, value, obj = None, None, None, dict()
33 for line in open('certdata.txt', 'r'):
34     # Ignore the file header.
35     if not in_data:
36         if line.startswith('BEGINDATA'):
37             in_data = True
38         continue
39     # Ignore comment lines.
40     if line.startswith('#'):
41         continue
42     # Empty lines are significant if we are inside an object.
43     if in_obj and len(line.strip()) == 0:
44         objects.append(obj)
45         obj = dict()
46         in_obj = False
47         continue
48     if len(line.strip()) == 0:
49         continue
50     if in_multiline:
51         if not line.startswith('END'):
52             if type == 'MULTILINE_OCTAL':
53                 line = line.strip()
54                 for i in re.finditer(r'\\([0-3][0-7][0-7])', line):
55                     value += chr(int(i.group(1), 8))
56             else:
57                 value += line
58             continue
59         obj[field] = value
60         in_multiline = False
61         continue
62     if line.startswith('CKA_CLASS'):
63         in_obj = True
64     line_parts = line.strip().split(' ', 2)
65     if len(line_parts) > 2:
66         field, type = line_parts[0:2]
67         value = ' '.join(line_parts[2:])
68     elif len(line_parts) == 2:
69         field, type = line_parts
70         value = None
71     else:
72         raise NotImplementedError, 'line_parts < 2 not supported.'
73     if type == 'MULTILINE_OCTAL':
74         in_multiline = True
75         value = ""
76         continue
77     obj[field] = value
78 if len(obj.items()) > 0:
79     objects.append(obj)
80
81 # Read blacklist.
82 blacklist = []
83 if os.path.exists('blacklist.txt'):
84     for line in open('blacklist.txt', 'r'):
85         line = line.strip()
86         if line.startswith('#') or len(line) == 0:
87             continue
88         item = line.split('#', 1)[0].strip()
89         blacklist.append(item)
90
91 # Build up trust database.
92 trust = dict()
93 for obj in objects:
94     if obj['CKA_CLASS'] != 'CKO_NETSCAPE_TRUST':
95         continue
96     if obj['CKA_LABEL'] in blacklist:
97         print "Certificate %s blacklisted, ignoring." % obj['CKA_LABEL']
98     elif obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NETSCAPE_TRUSTED_DELEGATOR':
99         trust[obj['CKA_LABEL']] = True
100     elif obj['CKA_TRUST_EMAIL_PROTECTION'] == 'CKT_NETSCAPE_TRUSTED_DELEGATOR':
101         trust[obj['CKA_LABEL']] = True
102     elif obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NETSCAPE_UNTRUSTED':
103         print '!'*74
104         print "UNTRUSTED BUT NOT BLACKLISTED CERTIFICATE FOUND: %s" % obj['CKA_LABEL']
105         print '!'*74
106     else:
107         print "Ignoring certificate %s.  SAUTH=%s, EPROT=%s" % \
108               (obj['CKA_LABEL'], obj['CKA_TRUST_SERVER_AUTH'],
109                obj['CKA_TRUST_EMAIL_PROTECTION'])
110
111 for obj in objects:
112     if obj['CKA_CLASS'] == 'CKO_CERTIFICATE':
113         if not obj['CKA_LABEL'] in trust or not trust[obj['CKA_LABEL']]:
114             continue
115         fname = obj['CKA_LABEL'][1:-1].replace('/', '_')\
116                                       .replace(' ', '_')\
117                                       .replace('(', '=')\
118                                       .replace(')', '=')\
119                                       .replace(',', '_') + '.crt'
120         f = open(fname, 'w')
121         f.write("-----BEGIN CERTIFICATE-----\n")
122         f.write("\n".join(textwrap.wrap(base64.b64encode(obj['CKA_VALUE']), 64)))
123         f.write("\n-----END CERTIFICATE-----\n")
124