]> git.ipfire.org Git - ipfire-3.x.git/blame - ca-certificates/certdata2pem.py
binutils: Update to 2.32
[ipfire-3.x.git] / ca-certificates / certdata2pem.py
CommitLineData
057303f8
SS
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
21# USA.
22
23import base64
24import os.path
25import re
26import sys
27import textwrap
28
29objects = []
30
31# Dirty file parser.
32in_data, in_multiline, in_obj = False, False, False
33field, type, value, obj = None, None, None, dict()
34for line in open('certdata.txt', 'r'):
35 # Ignore the file header.
36 if not in_data:
37 if line.startswith('BEGINDATA'):
38 in_data = True
39 continue
40 # Ignore comment lines.
41 if line.startswith('#'):
42 continue
43 # Empty lines are significant if we are inside an object.
44 if in_obj and len(line.strip()) == 0:
45 objects.append(obj)
46 obj = dict()
47 in_obj = False
48 continue
49 if len(line.strip()) == 0:
50 continue
51 if in_multiline:
52 if not line.startswith('END'):
53 if type == 'MULTILINE_OCTAL':
54 line = line.strip()
55 for i in re.finditer(r'\\([0-3][0-7][0-7])', line):
56 value += chr(int(i.group(1), 8))
57 else:
58 value += line
59 continue
60 obj[field] = value
61 in_multiline = False
62 continue
63 if line.startswith('CKA_CLASS'):
64 in_obj = True
65 line_parts = line.strip().split(' ', 2)
66 if len(line_parts) > 2:
67 field, type = line_parts[0:2]
68 value = ' '.join(line_parts[2:])
69 elif len(line_parts) == 2:
70 field, type = line_parts
71 value = None
72 else:
73 raise NotImplementedError, 'line_parts < 2 not supported.'
74 if type == 'MULTILINE_OCTAL':
75 in_multiline = True
76 value = ""
77 continue
78 obj[field] = value
79if len(obj.items()) > 0:
80 objects.append(obj)
81
82# Read blacklist.
83blacklist = []
84if os.path.exists('blacklist.txt'):
85 for line in open('blacklist.txt', 'r'):
86 line = line.strip()
87 if line.startswith('#') or len(line) == 0:
88 continue
89 item = line.split('#', 1)[0].strip()
90 blacklist.append(item)
91
92# Build up trust database.
93trust = dict()
94trustmap = dict()
95for obj in objects:
96
97 if obj['CKA_CLASS'] != 'CKO_NSS_TRUST':
98 continue
99 if obj['CKA_LABEL'] in blacklist:
100 print "Certificate %s blacklisted, ignoring." % obj['CKA_LABEL']
101 elif obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_TRUSTED_DELEGATOR':
102 trust[obj['CKA_LABEL']] = True
103 elif obj['CKA_TRUST_EMAIL_PROTECTION'] == 'CKT_NSS_TRUSTED_DELEGATOR':
104 trust[obj['CKA_LABEL']] = True
105 elif obj['CKA_TRUST_CODE_SIGNING'] == 'CKT_NSS_TRUSTED_DELEGATOR':
106 trust[obj['CKA_LABEL']] = True
107 elif obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_UNTRUSTED':
108 print '!'*74
109 print "UNTRUSTED BUT NOT BLACKLISTED CERTIFICATE FOUND: %s" % obj['CKA_LABEL']
110 print '!'*74
111 sys.exit(1)
112 else:
113 print "Ignoring certificate %s. SAUTH=%s, EPROT=%s" % \
114 (obj['CKA_LABEL'], obj['CKA_TRUST_SERVER_AUTH'],
115 obj['CKA_TRUST_EMAIL_PROTECTION'])
116 label = obj['CKA_LABEL']
117 trustmap[label] = obj
118 print " added cert", label
119
120def obj_to_filename(obj):
121 label = obj['CKA_LABEL'][1:-1]
122 label = label.replace('/', '_')\
123 .replace(' ', '_')\
124 .replace('(', '=')\
125 .replace(')', '=')\
126 .replace(',', '_')
127 label = re.sub(r'\\x[0-9a-fA-F]{2}', lambda m:chr(int(m.group(0)[2:], 16)), label)
128 serial = ".".join(map(lambda x:str(ord(x)), obj['CKA_SERIAL_NUMBER']))
129 return label + ":" + serial + ".crt"
130
131trust_types = {
132 "CKA_TRUST_DIGITAL_SIGNATURE": "digital-signature",
133 "CKA_TRUST_NON_REPUDIATION": "non-repudiation",
134 "CKA_TRUST_KEY_ENCIPHERMENT": "key-encipherment",
135 "CKA_TRUST_DATA_ENCIPHERMENT": "data-encipherment",
136 "CKA_TRUST_KEY_AGREEMENT": "key-agreement",
137 "CKA_TRUST_KEY_CERT_SIGN": "cert-sign",
138 "CKA_TRUST_CRL_SIGN": "crl-sign",
139 "CKA_TRUST_SERVER_AUTH": "server-auth",
140 "CKA_TRUST_CLIENT_AUTH": "client-auth",
141 "CKA_TRUST_CODE_SIGNING": "code-signing",
142 "CKA_TRUST_EMAIL_PROTECTION": "email-protection",
143 "CKA_TRUST_IPSEC_END_SYSTEM": "ipsec-end-system",
144 "CKA_TRUST_IPSEC_TUNNEL": "ipsec-tunnel",
145 "CKA_TRUST_IPSEC_USER": "ipsec-user",
146 "CKA_TRUST_TIME_STAMPING": "time-stamping",
147 "CKA_TRUST_STEP_UP_APPROVED": "step-up-approved",
148}
149
150openssl_trust = {
151 "CKA_TRUST_SERVER_AUTH": "serverAuth",
152 "CKA_TRUST_CLIENT_AUTH": "clientAuth",
153 "CKA_TRUST_CODE_SIGNING": "codeSigning",
154 "CKA_TRUST_EMAIL_PROTECTION": "emailProtection",
155}
156
157for obj in objects:
158 if obj['CKA_CLASS'] == 'CKO_CERTIFICATE':
159 print "producing cert file for " + obj['CKA_LABEL']
160 if not obj['CKA_LABEL'] in trust or not trust[obj['CKA_LABEL']]:
161 print " -> untrusted, ignoring"
162 continue
163 fname = obj_to_filename(obj)
164 f = open(fname, 'w')
165 trustbits = []
166 openssl_trustflags = []
167 tobj = trustmap[obj['CKA_LABEL']]
168 for t in trust_types.keys():
169 if tobj.has_key(t) and tobj[t] == 'CKT_NSS_TRUSTED_DELEGATOR':
170 trustbits.append(t)
171 if t in openssl_trust:
172 openssl_trustflags.append(openssl_trust[t])
173 f.write("# trust=" + " ".join(trustbits) + "\n")
174 if openssl_trustflags:
175 f.write("# openssl-trust=" + " ".join(openssl_trustflags) + "\n")
176 f.write("-----BEGIN CERTIFICATE-----\n")
177 f.write("\n".join(textwrap.wrap(base64.b64encode(obj['CKA_VALUE']), 64)))
178 f.write("\n-----END CERTIFICATE-----\n")
179 print " -> written as '%s', trust = %s, openssl-trust = %s" % (fname, trustbits, openssl_trustflags)
180
181
182