-
-
Notifications
You must be signed in to change notification settings - Fork 183
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
365 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Script to download/update certificates and public keys | ||
# and generate compilable source files for c++/Arduino. | ||
# released to public domain | ||
# Retrieved from https://github.com/esp8266/Arduino/blob/master/tools/cert.py | ||
|
||
import urllib.request | ||
import re | ||
import ssl | ||
import sys | ||
import socket | ||
import argparse | ||
import datetime | ||
|
||
from cryptography import x509 | ||
from cryptography.hazmat.primitives import hashes | ||
from cryptography.hazmat.primitives.serialization import pkcs7 | ||
from cryptography.hazmat.primitives.serialization import Encoding | ||
from cryptography.hazmat.primitives.serialization import PublicFormat | ||
|
||
def printData(data, showPub = True): | ||
try: | ||
xcert = x509.load_der_x509_certificate(data) | ||
except: | ||
try: | ||
xcert = x509.load_pem_x509_certificate(data) | ||
except: | ||
try: | ||
xcert = pkcs7.load_der_pkcs7_certificates(data) | ||
except: | ||
xcert = pkcs7.load_pem_pkcs7_certificates(data) | ||
if len(xcert) > 1: | ||
print('// Warning: TODO: pkcs7 has {} entries'.format(len(xcert))) | ||
xcert = xcert[0] | ||
|
||
cn = '' | ||
for dn in xcert.subject.rfc4514_string().split(','): | ||
keyval = dn.split('=') | ||
if keyval[0] == 'CN': | ||
cn += keyval[1] | ||
name = re.sub('[^a-zA-Z0-9_]', '_', cn) | ||
print('// CN: {} => name: {}'.format(cn, name)) | ||
|
||
print('// not valid before:', xcert.not_valid_before) | ||
print('// not valid after: ', xcert.not_valid_after) | ||
|
||
if showPub: | ||
|
||
fingerprint = xcert.fingerprint(hashes.SHA1()).hex(':') | ||
print('const char fingerprint_{}[] PROGMEM = "{}";'.format(name, fingerprint)) | ||
|
||
pem = xcert.public_key().public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo).decode('utf-8') | ||
print('const char pubkey_{}[] PROGMEM = R"PUBKEY('.format(name)) | ||
print(pem + ')PUBKEY";') | ||
|
||
else: | ||
|
||
cert = xcert.public_bytes(Encoding.PEM).decode('utf-8') | ||
print('const char cert_{}[] PROGMEM = R"CERT('.format(name)) | ||
print(cert + ')CERT";') | ||
|
||
cas = [] | ||
for ext in xcert.extensions: | ||
if ext.oid == x509.ObjectIdentifier("1.3.6.1.5.5.7.1.1"): | ||
for desc in ext.value: | ||
if desc.access_method == x509.oid.AuthorityInformationAccessOID.CA_ISSUERS: | ||
cas.append(desc.access_location.value) | ||
for ca in cas: | ||
with urllib.request.urlopen(ca) as crt: | ||
print() | ||
print('// ' + ca) | ||
printData(crt.read(), False) | ||
|
||
def get_certificate(hostname, port, name): | ||
context = ssl.create_default_context() | ||
context.check_hostname = False | ||
context.verify_mode = ssl.CERT_NONE | ||
with socket.create_connection((hostname, port)) as sock: | ||
with context.wrap_socket(sock, server_hostname=hostname) as ssock: | ||
print('////////////////////////////////////////////////////////////') | ||
print('// certificate chain for {}:{}'.format(hostname, port)) | ||
print() | ||
# if name: | ||
# print('const char* {}_host = "{}";'.format(name, hostname)); | ||
# print('const uint16_t {}_port = {};'.format(name, port)); | ||
# print() | ||
printData(ssock.getpeercert(binary_form=True)) | ||
print() | ||
print('// end of certificate chain for {}:{}'.format(hostname, port)) | ||
print('////////////////////////////////////////////////////////////') | ||
print() | ||
return 0 | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description='download certificate chain and public keys under a C++/Arduino compilable form') | ||
parser.add_argument('-s', '--server', action='store', required=True, help='TLS server dns name') | ||
parser.add_argument('-p', '--port', action='store', required=False, help='TLS server port') | ||
parser.add_argument('-n', '--name', action='store', required=False, help='variable name') | ||
port = 443 | ||
args = parser.parse_args() | ||
server = args.server | ||
try: | ||
split = server.split(':') | ||
server = split[0] | ||
port = int(split[1]) | ||
except: | ||
pass | ||
try: | ||
port = int(args.port) | ||
except: | ||
pass | ||
|
||
print('// this file is autogenerated - any modification will be overwritten') | ||
print('// unused symbols will not be linked in the final binary') | ||
print('// generated on {}'.format(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) | ||
print('// by \'' + ' '.join(sys.argv) + '\'') | ||
print() | ||
print('// alternatively, the certificate chain can be extracted using openssl') | ||
print('// \'openssl s_client -verify 5 -showcerts -connect api.openweathermap.org:443 < /dev/null\'') | ||
|
||
print() | ||
print('#ifndef __CERT_H__') | ||
print('#define __CERT_H__') | ||
print() | ||
get_certificate(server, port, args.name) | ||
print('#endif') | ||
print() | ||
return | ||
|
||
if __name__ == '__main__': | ||
sys.exit(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// this file is autogenerated - any modification will be overwritten | ||
// unused symbols will not be linked in the final binary | ||
// generated on 2023-06-10 03:24:21 | ||
// by 'cert.py -s api.openweathermap.org -p 443 -n openweathermap' | ||
|
||
// alternatively, the certificate chain can be extracted using openssl | ||
// 'openssl s_client -verify 5 -showcerts -connect api.openweathermap.org:443 < /dev/null' | ||
|
||
#ifndef __CERT_H__ | ||
#define __CERT_H__ | ||
|
||
//////////////////////////////////////////////////////////// | ||
// certificate chain for api.openweathermap.org:443 | ||
|
||
// CN: *.openweathermap.org => name: __openweathermap_org | ||
// not valid before: 2022-06-06 00:00:00 | ||
// not valid after: 2023-07-07 23:59:59 | ||
const char fingerprint___openweathermap_org[] PROGMEM = "42:94:24:9c:7b:e9:07:bf:b8:fc:ac:61:cb:c7:3d:12:1c:e5:16:e6"; | ||
const char pubkey___openweathermap_org[] PROGMEM = R"PUBKEY( | ||
-----BEGIN PUBLIC KEY----- | ||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2DMTq6QbiQ6N/PK6u6dv | ||
8J1w5/w/GLm1d7J3daL80/15qRlsxUEpM78/OWmEs60kKSfyOVyxOHrVoXMfEhIx | ||
ATdYQtRtN2JQEFYDkRauvVgr5eXQO2EJZXBZUb2C0dLFMD2WtrQGl7059kCOBlA/ | ||
vX2+uTIQwFx/qZyVKkhzgdthtoDQ5jDzx7scDM0U9c/be/aWNPzoJV1HK37luC0n | ||
HUyT0zDpXMt82DgoCRix9z9RzDNkyjsPW2qP/pOERpXk0z49jOFqtUxTtR9HfbKo | ||
eQ/RobxD2fG5P1cfunZ2lU3lyl5PeKbmMlSdSlci4OuileGdauTqgU254X7bB/9i | ||
TQIDAQAB | ||
-----END PUBLIC KEY----- | ||
)PUBKEY"; | ||
|
||
// http://crt.sectigo.com/SectigoRSADomainValidationSecureServerCA.crt | ||
// CN: Sectigo RSA Domain Validation Secure Server CA => name: Sectigo_RSA_Domain_Validation_Secure_Server_CA | ||
// not valid before: 2018-11-02 00:00:00 | ||
// not valid after: 2030-12-31 23:59:59 | ||
const char cert_Sectigo_RSA_Domain_Validation_Secure_Server_CA[] PROGMEM = R"CERT( | ||
-----BEGIN CERTIFICATE----- | ||
MIIGEzCCA/ugAwIBAgIQfVtRJrR2uhHbdBYLvFMNpzANBgkqhkiG9w0BAQwFADCB | ||
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl | ||
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV | ||
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx | ||
MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBjzELMAkGA1UEBhMCR0IxGzAZBgNV | ||
BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE | ||
ChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQDEy5TZWN0aWdvIFJTQSBEb21haW4g | ||
VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC | ||
AQ8AMIIBCgKCAQEA1nMz1tc8INAA0hdFuNY+B6I/x0HuMjDJsGz99J/LEpgPLT+N | ||
TQEMgg8Xf2Iu6bhIefsWg06t1zIlk7cHv7lQP6lMw0Aq6Tn/2YHKHxYyQdqAJrkj | ||
eocgHuP/IJo8lURvh3UGkEC0MpMWCRAIIz7S3YcPb11RFGoKacVPAXJpz9OTTG0E | ||
oKMbgn6xmrntxZ7FN3ifmgg0+1YuWMQJDgZkW7w33PGfKGioVrCSo1yfu4iYCBsk | ||
Haswha6vsC6eep3BwEIc4gLw6uBK0u+QDrTBQBbwb4VCSmT3pDCg/r8uoydajotY | ||
uK3DGReEY+1vVv2Dy2A0xHS+5p3b4eTlygxfFQIDAQABo4IBbjCCAWowHwYDVR0j | ||
BBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFI2MXsRUrYrhd+mb | ||
+ZsF4bgBjWHhMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G | ||
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAbBgNVHSAEFDASMAYGBFUdIAAw | ||
CAYGZ4EMAQIBMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0 | ||
LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2Bggr | ||
BgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNv | ||
bS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDov | ||
L29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAMr9hvQ5Iw0/H | ||
ukdN+Jx4GQHcEx2Ab/zDcLRSmjEzmldS+zGea6TvVKqJjUAXaPgREHzSyrHxVYbH | ||
7rM2kYb2OVG/Rr8PoLq0935JxCo2F57kaDl6r5ROVm+yezu/Coa9zcV3HAO4OLGi | ||
H19+24rcRki2aArPsrW04jTkZ6k4Zgle0rj8nSg6F0AnwnJOKf0hPHzPE/uWLMUx | ||
RP0T7dWbqWlod3zu4f+k+TY4CFM5ooQ0nBnzvg6s1SQ36yOoeNDT5++SR2RiOSLv | ||
xvcRviKFxmZEJCaOEDKNyJOuB56DPi/Z+fVGjmO+wea03KbNIaiGCpXZLoUmGv38 | ||
sbZXQm2V0TP2ORQGgkE49Y9Y3IBbpNV9lXj9p5v//cWoaasm56ekBYdbqbe4oyAL | ||
l6lFhd2zi+WJN44pDfwGF/Y4QA5C5BIG+3vzxhFoYt/jmPQT2BVPi7Fp2RBgvGQq | ||
6jG35LWjOhSbJuMLe/0CjraZwTiXWTb2qHSihrZe68Zk6s+go/lunrotEbaGmAhY | ||
LcmsJWTyXnW0OMGuf1pGg+pRyrbxmRE1a6Vqe8YAsOf4vmSyrcjC8azjUeqkk+B5 | ||
yOGBQMkKW+ESPMFgKuOXwIlCypTPRpgSabuY0MLTDXJLR27lk8QyKGOHQ+SwMj4K | ||
00u/I5sUKUErmgQfky3xxzlIPK1aEn8= | ||
-----END CERTIFICATE----- | ||
)CERT"; | ||
|
||
// http://crt.usertrust.com/USERTrustRSAAddTrustCA.crt | ||
// CN: USERTrust RSA Certification Authority => name: USERTrust_RSA_Certification_Authority | ||
// not valid before: 2019-03-12 00:00:00 | ||
// not valid after: 2028-12-31 23:59:59 | ||
const char cert_USERTrust_RSA_Certification_Authority[] PROGMEM = R"CERT( | ||
-----BEGIN CERTIFICATE----- | ||
MIIFgTCCBGmgAwIBAgIQOXJEOvkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7 | ||
MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD | ||
VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE | ||
AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4 | ||
MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5 | ||
MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO | ||
ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0 | ||
aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sI | ||
s9CsVw127c0n00ytUINh4qogTQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnG | ||
vDoZtF+mvX2do2NCtnbyqTsrkfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQ | ||
Ijy8/hPwhxR79uQfjtTkUcYRZ0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfb | ||
IWax1Jt4A8BQOujM8Ny8nkz+rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0 | ||
tyA9yn8iNK5+O2hmAUTnAU5GU5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97E | ||
xwzf4TKuzJM7UXiVZ4vuPVb+DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNV | ||
icQNwZNUMBkTrNN9N6frXTpsNVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5 | ||
D9kCnusSTJV882sFqV4Wg8y4Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJ | ||
WBp/kjbmUZIO8yZ9HE0XvMnsQybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ | ||
5lhCLkMaTLTwJUdZ+gQek9QmRkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzG | ||
KAgEJTm4Diup8kyXHAc/DVL17e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSg | ||
EQojPpbxB+zirynvgqV/0DCktDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rID | ||
ZsswDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAG | ||
BgRVHSAAMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29t | ||
L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggr | ||
BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUA | ||
A4IBAQAYh1HcdCE9nIrgJ7cz0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+ | ||
rvSNb3I8QzvAP+u431yqqcau8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+ | ||
/czSAaF9ffgZGclCKxO/WIu6pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gA | ||
CiIDEOUMsfnNkjcZ7Tvx5Dq2+UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1F | ||
zZOFli9d31kWTz9RvdVFGD/tSo7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyA | ||
vGp4z7h/jnZymQyd/teRCBaho1+V | ||
-----END CERTIFICATE----- | ||
)CERT"; | ||
|
||
// end of certificate chain for api.openweathermap.org:443 | ||
//////////////////////////////////////////////////////////// | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.