certs-from-mozilla.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env python3
  2. # This script pulls the list of Mozilla trusted certificate authorities
  3. # from the web at the "mozurl" below, parses the file to grab the PEM
  4. # for each cert, and then generates DER files in a new ./data directory
  5. # Upload these to an on-chip filesystem and use the CertManager to parse
  6. # and use them for your outgoing SSL connections.
  7. #
  8. # Script by Earle F. Philhower, III. Released to the public domain.
  9. from __future__ import print_function
  10. import csv
  11. import os
  12. import sys
  13. from shutil import which
  14. from subprocess import Popen, PIPE, call
  15. try:
  16. from urllib.request import urlopen
  17. except Exception:
  18. from urllib2 import urlopen
  19. try:
  20. from StringIO import StringIO
  21. except Exception:
  22. from io import StringIO
  23. # check if ar and openssl are available
  24. if which('ar') is None and not os.path.isfile('./ar') and not os.path.isfile('./ar.exe'):
  25. raise Exception("You need the program 'ar' from xtensa-lx106-elf found here: (esp8266-arduino-core)/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/xtensa-lx106-elf/bin/ar")
  26. if which('openssl') is None and not os.path.isfile('./openssl') and not os.path.isfile('./openssl.exe'):
  27. raise Exception("You need to have openssl in PATH, installable e.g. from https://download.firedaemon.com/FireDaemon-OpenSSL/FireDaemon-OpenSSL-x64-3.0.7.exe")
  28. # Mozilla's URL for the CSV file with included PEM certs
  29. mozurl = "https://ccadb-public.secure.force.com/mozilla/IncludedCACertificateReportPEMCSV"
  30. # Load the names[] and pems[] array from the URL
  31. names = []
  32. pems = []
  33. response = urlopen(mozurl)
  34. csvData = response.read()
  35. if sys.version_info[0] > 2:
  36. csvData = csvData.decode('utf-8')
  37. csvFile = StringIO(csvData)
  38. csvReader = csv.reader(csvFile)
  39. for row in csvReader:
  40. names.append(row[0]+":"+row[1]+":"+row[2])
  41. for item in row:
  42. if item.startswith("'-----BEGIN CERTIFICATE-----"):
  43. pems.append(item)
  44. del names[0] # Remove headers
  45. del pems[0] # Remove headers
  46. # Try and make ./data, skip if present
  47. try:
  48. os.mkdir("data")
  49. except Exception:
  50. pass
  51. derFiles = []
  52. idx = 0
  53. # Process the text PEM using openssl into DER files
  54. for i in range(0, len(pems)):
  55. certName = "data/ca_%03d.der" % (idx);
  56. thisPem = pems[i].replace("'", "")
  57. print(names[i] + " -> " + certName)
  58. ssl = Popen(['openssl','x509','-inform','PEM','-outform','DER','-out', certName], shell = False, stdin = PIPE)
  59. pipe = ssl.stdin
  60. pipe.write(thisPem.encode('utf-8'))
  61. pipe.close()
  62. ssl.wait()
  63. if os.path.exists(certName):
  64. derFiles.append(certName)
  65. idx = idx + 1
  66. if os.path.exists("data/certs.ar"):
  67. os.unlink("data/certs.ar");
  68. arCmd = ['ar', 'q', 'data/certs.ar'] + derFiles;
  69. call( arCmd )
  70. for der in derFiles:
  71. os.unlink(der)