10000 extmod/mbedtls: Fix DER certificate parsing with mbedTLS >=3.5. · micropython/micropython@86692a5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 86692a5

Browse files
committed
extmod/mbedtls: Fix DER certificate parsing with mbedTLS >=3.5.
MbedTLS 3.5 requires the length argument for a DER formatted key/cert to be exact or it fails parsing.(*) However PEM formatted keys are required to include a trailing NUL. Some discussion about the inconsistent length requirements at Mbed-TLS/mbedtls#3896 Fix by copying the heuristic mbedTLS uses to determine if we're parsing PEM or DER, and adjust the length to suit. (*) The release note says "mbedtls_pk_parse_key() now rejects trailing garbage in encrypted keys." but it seems to be the case whether it's encrypted or not. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent 72eb5e1 commit 86692a5

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

extmod/modtls_mbedtls.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -344,24 +344,41 @@ static mp_obj_t ssl_context_set_ciphers(mp_obj_t self_in, mp_obj_t ciphersuite)
344344
}
345345
static MP_DEFINE_CONST_FUN_OBJ_2(ssl_context_set_ciphers_obj, ssl_context_set_ciphers);
346346< 10BC0 div class="diff-text-inner">
347+
// Given a string-like object, return a ASN.1 container buffer (PEM or DER) and its
348+
// correct length. Result is not necessarily a C string.
349+
//
350+
// Starting with mbedTLS 3.5, DER formatted keys must consume the entire keylen
351+
// argument (no trailing bytes) or parsing fails. However, PEM formatted keys
352+
// must be submitted with a terminating NUL byte included in the keylen...
353+
static const byte *asn1_get_data(mp_obj_t obj, size_t *out_len) {
354+
size_t len;
355+
const char *str = mp_obj_str_get_data(obj, &len);
356+
#if defined(MBEDTLS_PEM_PARSE_C)
357+
// This is the heuristic for PEM format used by mbedtls_pk_load_file()...
358+
if (strstr(str, "-----BEGIN ") != NULL) {
359+
len++;
360+
}
361+
#endif
362+
*out_len = len;
363+
return (const byte *)str;
364+
}
365+
347366
static void ssl_context_load_key(mp_obj_ssl_context_t *self, mp_obj_t key_obj, mp_obj_t cert_obj) {
348367
size_t key_len;
349-
const byte *key = (const byte *)mp_obj_str_get_data(key_obj, &key_len);
350-
// len should include terminating null
351368
int ret;
369+
const byte *key = asn1_get_data(key_obj, &key_len);
352370
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
353-
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len + 1, NULL, 0, mbedtls_ctr_drbg_random, &self->ctr_drbg);
371+
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len, NULL, 0, mbedtls_ctr_drbg_random, &self->ctr_drbg);
354372
#else
355-
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len + 1, NULL, 0);
373+
ret = mbedtls_pk_parse_key(&self->pkey, key, key_len, NULL, 0);
356374
#endif
357375
if (ret != 0) {
358376
mbedtls_raise_error(MBEDTLS_ERR_PK_BAD_INPUT_DATA); // use general error for all key errors
359377
}
360378

361379
size_t cert_len;
362-
const byte *cert = (const byte *)mp_obj_str_get_data(cert_obj, &cert_len);
363-
// len should include terminating null
364-
ret = mbedtls_x509_crt_parse(&self->cert, cert, cert_len + 1);
380+
const byte *cert = asn1_get_data(cert_obj, &cert_len);
381+
ret = mbedtls_x509_crt_parse(&self->cert, cert, cert_len);
365382
if (ret != 0) {
366383
mbedtls_raise_error(MBEDTLS_ERR_X509_BAD_INPUT_DATA); // use general error for all cert errors
367384
}
@@ -382,9 +399,8 @@ static MP_DEFINE_CONST_FUN_OBJ_3(ssl_context_load_cert_chain_obj, ssl_context_lo
382399

383400
static void ssl_context_load_cadata(mp_obj_ssl_context_t *self, mp_obj_t cadata_obj) {
384401
size_t cacert_len;
385-
const byte *cacert = (const byte *)mp_obj_str_get_data(cadata_obj, &cacert_len);
386-
// len should include terminating null
387-
int ret = mbedtls_x509_crt_parse(&self->cacert, cacert, cacert_len + 1);
402+
const byte *cacert = asn1_get_data(cadata_obj, &cacert_len);
403+
int ret = mbedtls_x509_crt_parse(&self->cacert, cacert, cacert_len);
388404
if (ret != 0) {
389405
mbedtls_raise_error(MBEDTLS_ERR_X509_BAD_INPUT_DATA); // use general error for all cert errors
390406
}

0 commit comments

Comments
 (0)
0