summaryrefslogtreecommitdiff
path: root/startcom-sha2.py
blob: ea09710b103bf211013cda6b5d30510412e8fdd1 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
#!/usr/bin/env python
'''
This program scans for StartCom's intermediate SHA256 certificate files which
have known compatibility issues with some Windows clients due to a cached SHA-1
certificate. It can also fix these certificate files.

Note that the new certificates **expire on 24 October 2017** while the
recommended (but problematic certs) expire on **14 October 2022**. Supported
intermediate CAs with their old and new serial number.

    StartCom Class 1 Primary Intermediate Server CA
    0x17153d9eab3fbf -> 0x19
    StartCom Class 2 Primary Intermediate Server CA
    0x1cab36472d9c51 -> 0x1b
    StartCom Class 3 Primary Intermediate Server CA
    0x15a85b7110adcf -> 0x1d

More details are available at
https://forum.startcom.org/viewtopic.php?p=21826#p21826
'''

class1 = (
# https://www.startssl.com/certs/class1/sha2/pem/sub.class1.server.sha2.ca.pem
b'''
-----BEGIN CERTIFICATE-----''' + b'''
MIIF2TCCA8GgAwIBAgIHFxU9nqs/vzANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQG
EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDE0MjA1NDE3WhcNMjIxMDE0MjA1
NDE3WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzAp
BgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNV
BAMTL1N0YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVy
IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtonGrO8JUngHrJJj
0PREGBiEgFYfka7hh/oyULTTRwbw5gdfcA4Q9x3AzhA2NIVaD5Ksg8asWFI/ujjo
/OenJOJApgh2wJJuniptTT9uYSAK21ne0n1jsz5G/vohURjXzTCm7QduO3CHtPn6
6+6CPAVvkvek3AowHpNz/gfK11+AnSJYUq4G2ouHI2mw5CrY6oPSvfNx23BaKA+v
WjhwRRI/ME3NO68X5Q/LoKldSKqxYVDLNM08XMML6BDAjJvwAwNi/rJsPnIO7hxD
KslIDlc5xDEhyBDBLIf+VJVSH1I8MRKbf+fAoKVZ1eKPPvDVqOHXcDGpxLPPr21T
Lwb0pwIDAQABo4IBTDCCAUgwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E
BAMCAQYwHQYDVR0OBBYEFOtCNNCYsKuf9BtrCPfMZC7vDixFMB8GA1UdIwQYMBaA
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGkGCCsGAQUFBwEBBF0wWzAnBggrBgEFBQcw
AYYbaHR0cDovL29jc3Auc3RhcnRzc2wuY29tL2NhMDAGCCsGAQUFBzAChiRodHRw
Oi8vYWlhLnN0YXJ0c3NsLmNvbS9jZXJ0cy9jYS5jcnQwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMEMGA1UdIAQ8MDow
OAYEVR0gADAwMC4GCCsGAQUFBwIBFiJodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9w
b2xpY3kucGRmMA0GCSqGSIb3DQEBCwUAA4ICAQCBnsOw7dxamNbdJb/ydkh4Qb6E
qgEU+G9hCCIGXwhWRZMYczNJMrpVvyLq5mNOmrFPC7bJrqYV+vEOYHNXrzthLyOG
FFOVQe2cxbmQecFOvbkWVlYAIaTG42sHKVi+RFsG2jRNZcFhHnsFnLPMyE6148lZ
wVdZGsxZvpeHReNUpW0jh7uq90sShFzHs4f7wJ5XmiHOL7fZbnFV6uE/OoFnBWif
CRnd9+RE3uCospESPCRPdbG+Q4GQ+MBS1moXDTRB6DcNoHvqC6eU3r8/Fn/DeA9w
9JHPXUfrAhZYKyOQUIqcfE5bvssaY+oODVxji6BMk8VSVHsJ4FSC1/7Pkt/UPoQp
FVh38wIJnvEUeNVmVl3HHFYTd50irdKYPBC63qi2V/YYI6bJKmbrjfP9Vhyt9uNr
y3Kh4W22ktDuCCvWC7n/gqerdq+VlTRfNt7D/mB0irnaKjEVNCXBXm9V/978J+Ez
8aplGZccQ9jnc9kiPtUp5dj45E3V8vKqzp9srSSI5Xapdg+ZcPY+6HNuVB+MadRp
ZW2One/Qnzg9B4GnVX7MOETImdoP4kXpostFuxoY/5LxCU1LJAIENV4txvT50lX2
GBXCkxllRLWOgdyll11ift/4IO1aCOGDijGIfh498YisM1LGxytmGcxvbJERVri+
gGpWAZ5J6dvtf0s+bA==
-----END CERTIFICATE-----
''',
# https://class3.test.itk98.net/class1.ca.pem
b'''
-----BEGIN CERTIFICATE-----''' + b'''
MIIGNDCCBBygAwIBAgIBGTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJ
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20g
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NDE3WhcNMTcx
MDI0MjA1NDE3WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29t
IEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNp
Z25pbmcxODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRl
cm1lZGlhdGUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAtonGrO8JUngHrJJj0PREGBiEgFYfka7hh/oyULTTRwbw5gdfcA4Q
9x3AzhA2NIVaD5Ksg8asWFI/ujjo/OenJOJApgh2wJJuniptTT9uYSAK21ne
0n1jsz5G/vohURjXzTCm7QduO3CHtPn66+6CPAVvkvek3AowHpNz/gfK11+A
nSJYUq4G2ouHI2mw5CrY6oPSvfNx23BaKA+vWjhwRRI/ME3NO68X5Q/LoKld
SKqxYVDLNM08XMML6BDAjJvwAwNi/rJsPnIO7hxDKslIDlc5xDEhyBDBLIf+
VJVSH1I8MRKbf+fAoKVZ1eKPPvDVqOHXcDGpxLPPr21TLwb0pwIDAQABo4IB
rTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
BBYEFOtCNNCYsKuf9BtrCPfMZC7vDixFMB8GA1UdIwQYMBaAFE4L7xqkQFul
F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0
cDovL29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8v
d3d3LnN0YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4Yh
aHR0cDovL3d3dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRw
Oi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYL
KwYBBAGBtTcBAgEwZjAuBggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNz
bC5jb20vcG9saWN5LnBkZjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFy
dHNzbC5jb20vaW50ZXJtZWRpYXRlLnBkZjANBgkqhkiG9w0BAQsFAAOCAgEA
UiVivr7DGl0kxETnJMnlpLWn6AXQE+XSL2TdMkbS3wY40tqEo2O/MJ54cf1W
QgZilw659qpXYmxMNX2VGo8rz2HxPcBMaU2mjRnVAyFXn2uLvTKUcBIu0Gs1
qA75FBUOYxKudcreUaeWD2LlPgtdMX48mEU1VmjtDAHs1X7/z5j6c75c2VZ6
9xx05z1MKm4+32xsntq3EdcmskUBc2VZNqs6iz1+cCBTQBdeP56f+1hFQ5Hi
isQ8bDVdeENoFO99kHAAtjv4pkmj4BYqBUVWJy3VXxJcOk3QWyn5zwUps6EA
JCAkY6u7rUiEhF4a3y7IV3llMx7V+lpkACGAKOlO2CVRohy+SDOiVGkzF+dz
n+dx8Dzk+XX8ttFMh7G/IkbOBXLUOEuIDshnupkJZZdIFznMWAWN0iOj6qyb
3+FwZAA5AZua5nrZrLeqK8ssn8L5sFQOfO9mwcgszBLr63VfH+y4WqSDyVj9
mVv3yh6zTKYoXOMjH722m0oPwmgFsNLVrRSMtGt3Vvh0oSoDCjOi594tqTwa
emktFyGcXud7db/MkwC2MU0DC1QZX3YQpjuP/keRY/U46/oOwaqI8JnhNd6x
yn4H4ufzUAgl+Pu/aphb4RlClRuEL38a/Kq70wujW77vBXiEmjVOKnIkI2OE
lZ/AyIQS/jZfAJX+NnYi6tU=
-----END CERTIFICATE-----
'''
)

class2 = (
# https://www.startssl.com/certs/class2/sha2/pem/sub.class2.server.sha2.ca.pem
b'''
-----BEGIN CERTIFICATE-----''' + b'''
MIIF2TCCA8GgAwIBAgIHHKs2Ry2cUTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQG
EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDE0MjA1NzA5WhcNMjIxMDE0MjA1
NzA5WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzAp
BgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNV
BAMTL1N0YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVy
IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4k85L6GMmoWtCA4I
PlfyiAEhG5SpbOK426oZGEY6UqH1D/RujOqWjJaHeRNAUS8i8gyLhw9l33F0NENV
sTUJm9m8H/rrQtCXQHK3Q5Y9upadXVACHJuRjZzArNe7LxfXyz6CnXPrB0KSss1k
s3RVG7RLhiEs93iHMuAW5Nq9TJXqpAp+tgoNLorPVavD5d1Bik7mb2VsskDPF125
w2oLJxGEd2H2wnztwI14FBiZgZl1Y7foU9O6YekO+qIw80aiuckfbIBaQKwn7UhH
M7BUxkYa8zVhwQIpkFR+ZE3EMFICgtffziFuGJHXuKuMJxe18KMBL47SLoc6PbQp
Z4rEAwIDAQABo4IBTDCCAUgwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E
BAMCAQYwHQYDVR0OBBYEFBHbI0X9VMxqcW+EigPXvvcBLyaGMB8GA1UdIwQYMBaA
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGkGCCsGAQUFBwEBBF0wWzAnBggrBgEFBQcw
AYYbaHR0cDovL29jc3Auc3RhcnRzc2wuY29tL2NhMDAGCCsGAQUFBzAChiRodHRw
Oi8vYWlhLnN0YXJ0c3NsLmNvbS9jZXJ0cy9jYS5jcnQwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMEMGA1UdIAQ8MDow
OAYEVR0gADAwMC4GCCsGAQUFBwIBFiJodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9w
b2xpY3kucGRmMA0GCSqGSIb3DQEBCwUAA4ICAQBSyb3zvcv566LEMsqGcvzPv6cw
tf2R99WB4SEErQBM/+mLJ9r/8iTN/B8Pf9LR5YGSI3gW7msDLp0ASE+ugmUuh2/u
agdfS1Zu95ZGQebd/kW5Yiqainbprb3Wc7O8MSvQLNVsa7xqOiWHqailDdeF8Wxs
BQ70wWjLuyqBWKU+mcSf9x+EjqB60U3buAGcDYE0yoL+I2JNP22kUsBMXvJpSLHy
36xEZGmwRinHrfDywJ1oI4qoZ3EiF77OiXp2vlRsk1yL8Bpuru2OrsIFrhNX5rnn
cMgzuJ79SjDjmNQTa+5Ouebs387qoJ52apeq6t80RUL12k3Wh3Zt/85phnqBX9uy
T86w4GdgOUSwRRCFZZcSed/Ul9h4IQyEmM67T2sPGdqFaZFBbBccxrn2FK7yoYB6
4umV7yKKzP842/whVuyA/W2ihZEpA+qrA70sYESCADXnFGx2O0CDVdVc38coo1nV
iXg+D+AG/dVXiiQcp2I4HYWTS/mTf/NE+mOYnu0miZ32/vhDbCX/B/kSPJ4RsNOA
7uyrOwykcgOSFDbpvuaKOpGLrQwGqLODgm+p9TY5giMMjur9XH7TS1wz02dIz07u
y2NwYWdV67vcnAt6QxRISap5RbaPviyQZxz4nFaSlTAwHoPaW1yuVS11tmsROMlR
RNvbaAxIU4U67YaZSw==
-----END CERTIFICATE-----
''',
# https://class3.test.itk98.net/class2.ca.pem
b'''
-----BEGIN CERTIFICATE-----''' + b'''
MIIGNDCCBBygAwIBAgIBGzANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJ
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20g
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NzA5WhcNMTcx
MDI0MjA1NzA5WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29t
IEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNp
Z25pbmcxODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRl
cm1lZGlhdGUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA4k85L6GMmoWtCA4IPlfyiAEhG5SpbOK426oZGEY6UqH1D/RujOqW
jJaHeRNAUS8i8gyLhw9l33F0NENVsTUJm9m8H/rrQtCXQHK3Q5Y9upadXVAC
HJuRjZzArNe7LxfXyz6CnXPrB0KSss1ks3RVG7RLhiEs93iHMuAW5Nq9TJXq
pAp+tgoNLorPVavD5d1Bik7mb2VsskDPF125w2oLJxGEd2H2wnztwI14FBiZ
gZl1Y7foU9O6YekO+qIw80aiuckfbIBaQKwn7UhHM7BUxkYa8zVhwQIpkFR+
ZE3EMFICgtffziFuGJHXuKuMJxe18KMBL47SLoc6PbQpZ4rEAwIDAQABo4IB
rTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
BBYEFBHbI0X9VMxqcW+EigPXvvcBLyaGMB8GA1UdIwQYMBaAFE4L7xqkQFul
F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0
cDovL29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8v
d3d3LnN0YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4Yh
aHR0cDovL3d3dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRw
Oi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYL
KwYBBAGBtTcBAgEwZjAuBggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNz
bC5jb20vcG9saWN5LnBkZjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFy
dHNzbC5jb20vaW50ZXJtZWRpYXRlLnBkZjANBgkqhkiG9w0BAQsFAAOCAgEA
bQjxXHkqUPtUY+u8NEFcuKMDITfjvGklLgrTuBW63grW+2AuDAZRo/066eNH
s6QV4i5e4ujwPSR2dgggY7mOIIBmiDm2QRjF5CROq6zDlIdqlsFZICkuONDN
FpFjaPtZRTmuK1n6gywQgCNSIrbzjPcwR/jL/wowbfwC9yGme1EeZRqvWy/H
zFWacs7UMmWlRk6DTmpfPOPMJo5AxyTZCiCYQQeksV7xUAeY0kWa+y/FV+ee
rOPUl6yy4jRHTk7tCySxrciZwYbd6YNLmeIQoUAdRC3CH3nTB2/JYxltcgyG
HMiPU3TtafZgLs8fvncv+wIF1YAF/OGqg8qmzoJ3ghM4upGdTMIu8vADdmuL
C/+dnbzknxX6QEGlWA8zojLUxVhGNfIFoizu/V/DyvSvYuxzzIkPECK5gDoM
oBTTMI/wnxXwulNPtfgF7/5AtDhA4GNAfB2SddxiNQAF7XkUHtMZ9ff3W6Xk
FldOG+NlLFqsDBG/KLckyFK36gq+FqNFCbmtmtXBGB5L1fDIeYzcMKG6hFQx
hHS0oqpdHhp2nWBfLlOnTNqIZNJzOH37OJE6Olk45LNFJtSrqIAZyCCfM6bQ
goQvZuIaxs9SIp+63ZMk9TxEaQj/KteaOyfaPXI9778U7JElMTz3Bls62msl
V2I1C/A73ZyqJZWQZ8NU4ds=
-----END CERTIFICATE-----
'''
)

class3 = (
# https://www.startssl.com/certs/class1/sha2/pem/sub.class3.server.sha2.ca.pem
b'''
-----BEGIN CERTIFICATE-----''' + b'''
MIIF2TCCA8GgAwIBAgIHFahbcRCtzzANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQG
EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDE0MjA1ODI0WhcNMjIxMDE0MjA1
ODI0WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzAp
BgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNV
BAMTL1N0YXJ0Q29tIENsYXNzIDMgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVy
IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxtTlmqySw6jNfvAT
GV+1Z3tzCryzboJMuKv++wEh3XwM+fi1gAH9j8X6ORJYdCJcqWOA/D+E4Sh37S7x
JR9JDCfpPo+6yS9G0D/pOuQjUZVCdBfGym0DOFrHfgaAtN+wy/rvVULObi1AYw7c
F/a59olLMt5B41FNcbMCmJEBzmhc6iqttRqI0lGX72VDfcdEvOLw7rdEetvTl6hx
/s/2B58j/NxVY5M3J/oeqY0sPOSc3RMrH1mWZ1xgS96FgeblRRxdNfRbDn1/qdrE
Vxxc2jWHRyUUbpdevcgeTynGfBLcLsW9QUREZP2wGbeJL1TkbkMfxb/MKdQQzheL
/9Gc2QIDAQABo4IBTDCCAUgwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E
BAMCAQYwHQYDVR0OBBYEFIn4QqYcYurH8TIJK0E+e6JcrsVLMB8GA1UdIwQYMBaA
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGkGCCsGAQUFBwEBBF0wWzAnBggrBgEFBQcw
AYYbaHR0cDovL29jc3Auc3RhcnRzc2wuY29tL2NhMDAGCCsGAQUFBzAChiRodHRw
Oi8vYWlhLnN0YXJ0c3NsLmNvbS9jZXJ0cy9jYS5jcnQwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMEMGA1UdIAQ8MDow
OAYEVR0gADAwMC4GCCsGAQUFBwIBFiJodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9w
b2xpY3kucGRmMA0GCSqGSIb3DQEBCwUAA4ICAQAthLawLWmq9RJIhpczAyq3ep7T
ccmBd50ifXNehjyJ5d90C/uflhRHe/tzGQKHGhgb/3jhW8k0HDfdqsGTZI6jkC+a
Rld1X0cQMj/1NAXnOuMqhDXc5kANit9TdvtGlWZHVFvEk75JPYDD0D7ZXTQ3ccRn
1CzQM9pX5uxp3eiVHh8zHVwbrVyxBi3zXTSD1sUP/Ze/aXPP/OYZl8y3Iy8cQpiq
ie7OiiB1gOqp42Vb9lWnoH6jBLVpmtmkpcbH2wgClEmjgGTxmlILhD8BlrKF31vX
j6KdlRwn+jA0Uz6DCD+1IWMaADMOzeG9P41upK5uESwvVUXImboBR/OXBMc8Jyg8
WmPTG5rEwqkhGfsedq05kxg7MXmI7M2aaxXYwedkIGzhqrv6h3tLH/o8X9Ff7d0B
SLK8wwGstLZ7vNv6K7q2bMv4g5mKaesPNg/hoTri4yJEbYVBL9xgvTLhvNGp46IY
UEzn3vnFE6gnhne4jFQWqV4zjA9JveC8LtMqoAE8Z4HJbSNurfokLEm1MS3qIVHN
po3bgKCaTKJhsOcWY3a38jb8GalRiqKJE5lKqvKvZ/gPWZVOl78qROiDfdWvBT00
7p6y48YVkRW8Q1+M45w8cRaXfoRXbMJVCD9KvDrL2kDobaTvtIZxK0PUbKCXubPw
0N8NcSQMxAONGPkXWw==
-----END CERTIFICATE-----
''',
# https://class3.test.itk98.net/class3.ca.pem
b'''
-----BEGIN CERTIFICATE-----''' + b'''
MIIGNDCCBBygAwIBAgIBHTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJ
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp
Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20g
Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1ODI0WhcNMTcx
MDI0MjA1ODI0WjCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29t
IEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNp
Z25pbmcxODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDMgUHJpbWFyeSBJbnRl
cm1lZGlhdGUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAxtTlmqySw6jNfvATGV+1Z3tzCryzboJMuKv++wEh3XwM+fi1gAH9
j8X6ORJYdCJcqWOA/D+E4Sh37S7xJR9JDCfpPo+6yS9G0D/pOuQjUZVCdBfG
ym0DOFrHfgaAtN+wy/rvVULObi1AYw7cF/a59olLMt5B41FNcbMCmJEBzmhc
6iqttRqI0lGX72VDfcdEvOLw7rdEetvTl6hx/s/2B58j/NxVY5M3J/oeqY0s
POSc3RMrH1mWZ1xgS96FgeblRRxdNfRbDn1/qdrEVxxc2jWHRyUUbpdevcge
TynGfBLcLsW9QUREZP2wGbeJL1TkbkMfxb/MKdQQzheL/9Gc2QIDAQABo4IB
rTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
BBYEFIn4QqYcYurH8TIJK0E+e6JcrsVLMB8GA1UdIwQYMBaAFE4L7xqkQFul
F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0
cDovL29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8v
d3d3LnN0YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4Yh
aHR0cDovL3d3dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRw
Oi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYL
KwYBBAGBtTcBAgEwZjAuBggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNz
bC5jb20vcG9saWN5LnBkZjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFy
dHNzbC5jb20vaW50ZXJtZWRpYXRlLnBkZjANBgkqhkiG9w0BAQsFAAOCAgEA
SGTXnpQAUrMhzFcGLy/B/gNWS1zJ2j72py8ncV/rMxwBZdPwt6EUim63VwUA
29wXrH6ANWF0UOBoaYJWyqkObaHY8cJuqbNhEl+WXGTZSqgjtgdqdICdIYvq
Yya0rEj1Rr4tA9MoyG+1Xp4fPClHyMPAHcED5hWZ9wV0B2Rn8NOlbvmOj1dA
QMfubRvxbKrWfAJ/J9KP+CntK/jh+v3EKSe1Jeyzn1pf0bz3pInkzfcxM53R
6BWO24M3iVmAm3tY8uwwXFxv/3HVVgnorPXUFOxGujXPWv4m2LBtth7JH9CO
vQwFCqYZut9vWb+0efgp3PkY2PgZtf3HEu7l51VedulrcVEiljno8cpDjagd
b50YxNPvp6aAwxkV7wd3cgcGzS8YmbmQ8GLBCDTCcSmSIYKFIy9dTAu6C5s6
0E6WeFHEtgNUoqzAXQ1zJLyQNRadhcM6f9lbjVCmv0/BvACOpGgAEEvjm4CY
hKxZ+ob+KsEwXXQTT2HMa+bjBKopgj6VWTnf5j295YWP+3b0921AvZSzXDTi
WIld8wrW3d89JxX69FuP3+CE85ryMxFwbuyITBYjnxDF9aFAlJOi5w7saXeB
w1TvmYsilX3+fwnn5Nu4PZqw4MjxRcip15q6pz+SPjdhpYqFDQ3mgrvf4dMH
ImruS2dA4t8bY/h8BARHrec=
-----END CERTIFICATE-----
'''
)

startcom_ca_certificates = (
    ('class1', class1),
    ('class2', class2),
    ('class3', class3)
)

import argparse, os, logging, subprocess, sys
_logger = logging.getLogger(__name__)

def find_updated_cert(filename, ca_certificates):
    '''
    Returns None if the file contents do not contain the problematic
    certificate, and the new file contents otherwise.
    '''
    contents = open(filename, 'rb').read()
    if b'-----BEGIN CERTIFICATE-----' not in contents:
        _logger.info('%s: not a certificate, skipping', filename)
        return None
    orig_contents = contents
    for name, (old_cert, new_cert) in ca_certificates:
        if not old_cert in contents:
            continue
        _logger.warning('%s: certificate needs update: %s', filename, name)
        contents = contents.replace(old_cert, new_cert)

    if orig_contents != contents:
        return contents

    _logger.info('%s: no changes needed', filename)

def get_filenames(filenames, recursive):
    '''
    Discovers all files from the given set of filenames, optionally recursing
    into directory items.
    '''
    while filenames:
        item = filenames[0]
        filenames = filenames[1:]
        if os.path.isdir(item) and recursive:
            try:
                diritems = [os.path.join(item, filename)
                    for filename in os.listdir(item)]
            except EnvironmentError as e:
                _logger.warning('%s: %s', item, e)
                continue
            filenames = diritems + filenames
        else:
            yield item

def main(args):
    logLevel = logging.INFO if args.verbose else logging.WARNING
    logging.basicConfig(format='%(message)s', level=logLevel)

    if args.reverse:
        ca_certificates = (
            (name, (new_cert, old_cert))
            for name, (old_cert, new_cert) in startcom_ca_certificates
        )
    else:
        ca_certificates = startcom_ca_certificates

    for filename in get_filenames(args.files, args.recursive):
        try:
            new_contents = find_updated_cert(filename, ca_certificates)
        except EnvironmentError as e:
            _logger.warning('%s: read error: %s', filename, e)
            continue

        # Do not write unmodified files, or when in read-only mode.
        if not new_contents or not args.write:
            continue

        try:
            open(filename, 'wb').write(new_contents)
            _logger.warning('%s: wrote new certificate', filename)
        except EnvironmentError as e:
            _logger.warning('%s: write error: %s', filename, e)

def print_certificate(pem):
    sys.stdout.flush()  # Flush buffered messages
    p = subprocess.Popen(['openssl', 'x509', '-text'], stdin=subprocess.PIPE)
    p.communicate(pem)

def print_certificates():
    for name, (old_cert, new_cert) in startcom_ca_certificates:
        print('# Certificate %s:' % name)
        print('')

        print('## Problematic certificate:')
        print_certificate(old_cert)
        print('')

        print('## Fixed certificate:')
        print_certificate(new_cert)
        print('')

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=__doc__.split('\n\n')[0])
    parser.add_argument('-w', '--write', action='store_true',
                        help='Write new certificates besides printing changes.')
    parser.add_argument('-r', '--recursive', action='store_true',
                        help='Recurse into directories.')
    parser.add_argument('--reverse', action='store_true',
                        help='Replaces with the problematic certificate')
    parser.add_argument('-v', '--verbose', action='store_true',
                        help='Be verbose, print skipped files')
    parser.add_argument('files', metavar='file', nargs='*',
                        help='PEM-encoded certificate files')
    parser.add_argument('--certificates', action='store_true',
                        help='Print certificates and exit')
    args = parser.parse_args()

    if args.certificates:
        print_certificates()
    else:
        if not args.files:
            parser.error('At least one PEM file is required')
        main(args)