mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 20:41:14 +00:00
feat(mbedtls/esp_crt_bundle): Reduced RAM & stack use of cert bundle
Closes https://github.com/espressif/esp-idf/pull/13204 Signed-off-by: harshal.patil <harshal.patil@espressif.com>
This commit is contained in:
@@ -8,18 +8,16 @@
|
||||
# The bundle will have the format: number of certificates; crt 1 subject name length; crt 1 public key length;
|
||||
# crt 1 subject name; crt 1 public key; crt 2...
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
from io import open
|
||||
|
||||
DEFAULT_CERT_BUNDLE_MAX_CERTS = 200
|
||||
|
||||
try:
|
||||
from cryptography import x509
|
||||
@@ -54,9 +52,6 @@ class CertificateBundle:
|
||||
self.certificates = []
|
||||
self.compressed_crts = []
|
||||
|
||||
if os.path.isfile(ca_bundle_bin_file):
|
||||
os.remove(ca_bundle_bin_file)
|
||||
|
||||
def add_from_path(self, crts_path):
|
||||
|
||||
found = False
|
||||
@@ -116,11 +111,21 @@ class CertificateBundle:
|
||||
self.certificates.append(x509.load_der_x509_certificate(crt_str, default_backend()))
|
||||
status('Successfully added 1 certificate')
|
||||
|
||||
def create_bundle(self):
|
||||
def create_bundle(self, max_certs=DEFAULT_CERT_BUNDLE_MAX_CERTS):
|
||||
if max_certs < len(self.certificates):
|
||||
critical(f'No. of certs in the certificate bundle = {len(self.certificates)} exceeds\n \
|
||||
Max allowed certificates in the certificate bundle = {max_certs} \
|
||||
Please update the menuconfig option with appropriate value')
|
||||
raise ValueError
|
||||
|
||||
# Sort certificates in order to do binary search when looking up certificates
|
||||
self.certificates = sorted(self.certificates, key=lambda cert: cert.subject.public_bytes(default_backend()))
|
||||
|
||||
bundle = struct.pack('>H', len(self.certificates))
|
||||
# List of offsets in bytes from the start of the bundle to each certificate inside
|
||||
offsets = []
|
||||
len_offsets = 4 * len(self.certificates) # final size of the offsets list
|
||||
|
||||
bundle = b''
|
||||
|
||||
for crt in self.certificates:
|
||||
""" Read the public key as DER format """
|
||||
@@ -132,12 +137,18 @@ class CertificateBundle:
|
||||
|
||||
name_len = len(sub_name_der)
|
||||
key_len = len(pub_key_der)
|
||||
len_data = struct.pack('>HH', name_len, key_len)
|
||||
len_data = struct.pack('<HH', name_len, key_len)
|
||||
|
||||
# Certificate starts at this position in the bundle
|
||||
offsets.append(len_offsets + len(bundle))
|
||||
|
||||
bundle += len_data
|
||||
bundle += sub_name_der
|
||||
bundle += pub_key_der
|
||||
|
||||
# Output all offsets before the first certificate
|
||||
bundle = struct.pack('<{0:d}L'.format(len(offsets)), *offsets) + bundle
|
||||
|
||||
return bundle
|
||||
|
||||
def add_with_filter(self, crts_path, filter_path):
|
||||
@@ -182,6 +193,8 @@ def main():
|
||||
help='Paths to the custom certificate folders or files to parse, parses all .pem or .der files')
|
||||
parser.add_argument('--filter', '-f', help='Path to CSV-file where the second columns contains the name of the certificates \
|
||||
that should be included from cacrt_all.pem')
|
||||
parser.add_argument('--max-certs', '-m', help='Maximum number of certificates allowed in the certificate bundle',
|
||||
type=int, default=DEFAULT_CERT_BUNDLE_MAX_CERTS)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -202,7 +215,7 @@ def main():
|
||||
|
||||
status('Successfully added %d certificates in total' % len(bundle.certificates))
|
||||
|
||||
crt_bundle = bundle.create_bundle()
|
||||
crt_bundle = bundle.create_bundle(args.max_certs)
|
||||
|
||||
with open(ca_bundle_bin_file, 'wb') as f:
|
||||
f.write(crt_bundle)
|
||||
|
Reference in New Issue
Block a user