Skip to content

Commit b82c9ca

Browse files
projectgusdpgeorge
authored andcommitted
extmod/modtls_mbedtls: Optimise the DER certificate parsing fix.
Small code size and binary size optimisation for the fix merged in 4d6d849. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
1 parent 706e09d commit b82c9ca

File tree

1 file changed

+18
-31
lines changed

1 file changed

+18
-31
lines changed

extmod/modtls_mbedtls.c

+18-31
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,22 @@ static void mbedtls_debug(void *ctx, int level, const char *file, int line, cons
100100
}
101101
#endif
102102

103-
#if defined(MBEDTLS_PEM_PARSE_C)
104-
static int mbedtls_is_pem(const byte *data, size_t len) {
105-
return (len >= 10) && (strstr((const char *)data, "-----BEGIN") != NULL);
103+
// Given a string-like object holding PEM or DER formatted ASN.1 data, return a
104+
// pointer to its buffer and the correct length for mbedTLS APIs.
105+
//
106+
// (mbedTLS >= 3.5 rejects DER formatted data with trailing bytes within keylen,
107+
// but PEM must include a terminating NUL byte in the keylen...)
108+
static const unsigned char *asn1_get_data(mp_obj_t obj, size_t *out_len) {
109+
size_t len;
110+
const char *str = mp_obj_str_get_data(obj, &len);
111+
#if defined(MBEDTLS_PEM_PARSE_C)
112+
if (strstr(str, "-----BEGIN ") != NULL) {
113+
++len;
114+
}
115+
#endif
116+
*out_len = len;
117+
return (const unsigned char *)str;
106118
}
107-
#endif
108119

109120
static NORETURN void mbedtls_raise_error(int err) {
110121
// Handle special cases.
@@ -352,15 +363,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(ssl_context_set_ciphers_obj, ssl_context_set_ci
352363

353364
static void ssl_context_load_key(mp_obj_ssl_context_t *self, mp_obj_t key_obj, mp_obj_t cert_obj) {
354365
size_t key_len;
355-
const byte *key = (const byte *)mp_obj_str_get_data(key_obj, &key_len);
356-
357-
#if defined(MBEDTLS_PEM_PARSE_C)
358-
// len should include terminating null if the data is PEM encoded
359-
if (mbedtls_is_pem(key, key_len)) {
360-
key_len += 1;
361-
}
362-
#endif
363-
366+
const unsigned char *key = asn1_get_data(key_obj, &key_len);
364367
int ret;
365368
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
366369
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len, NULL, 0, mbedtls_ctr_drbg_random, &self->ctr_drbg);
@@ -372,15 +375,7 @@ static void ssl_context_load_key(mp_obj_ssl_context_t *self, mp_obj_t key_obj, m
372375
}
373376

374377
size_t cert_len;
375-
const byte *cert = (const byte *)mp_obj_str_get_data(cert_obj, &cert_len);
376-
377-
#if defined(MBEDTLS_PEM_PARSE_C)
378-
// len should include terminating null if the data is PEM encoded
379-
if (mbedtls_is_pem(cert, cert_len)) {
380-
cert_len += 1;
381-
}
382-
#endif
383-
378+
const unsigned char *cert = asn1_get_data(cert_obj, &cert_len);
384379
ret = mbedtls_x509_crt_parse(&self->cert, cert, cert_len);
385380
if (ret != 0) {
386381
mbedtls_raise_error(MBEDTLS_ERR_X509_BAD_INPUT_DATA); // use general error for all cert errors
@@ -402,15 +397,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(ssl_context_load_cert_chain_obj, ssl_context_lo
402397

403398
static void ssl_context_load_cadata(mp_obj_ssl_context_t *self, mp_obj_t cadata_obj) {
404399
size_t cacert_len;
405-
const byte *cacert = (const byte *)mp_obj_str_get_data(cadata_obj, &cacert_len);
406-
407-
#if defined(MBEDTLS_PEM_PARSE_C)
408-
// len should include terminating null if the data is PEM encoded
409-
if (mbedtls_is_pem(cacert, cacert_len)) {
410-
cacert_len += 1;
411-
}
412-
#endif
413-
400+
const unsigned char *cacert = asn1_get_data(cadata_obj, &cacert_len);
414401
int ret = mbedtls_x509_crt_parse(&self->cacert, cacert, cacert_len);
415402
if (ret != 0) {
416403
mbedtls_raise_error(MBEDTLS_ERR_X509_BAD_INPUT_DATA); // use general error for all cert errors

0 commit comments

Comments
 (0)