#!/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)