From f1b2a7d1b46664310da5b271b6c20eaa3b5394e0 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 15 Sep 2020 18:47:51 +0200 Subject: [PATCH] Fix certificate generation with mbedtls 2.16.8 . When generating certificates with `Crypto.generate_self_signed_certificate` we generate the PEM in a buffer via `mbedtls_x509write_crt_pem`. Since version 2.16.8, mbedtls adds spurious data at the end of the buffer due to internal optimizations, this breaks our logic when we try to immediately parse it and return a proper `X509Certificate` object. This commit updates the code to find the actual PEM length to parse using `strlen`, takes extra caution always adding the terminator to the buffer, and slightly improve error messages. (cherry picked from commit 60687ce778edcda007039541dd06034bc671b6e4) --- modules/mbedtls/crypto_mbedtls.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index 9b072785af..91544378ed 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -43,8 +43,8 @@ #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" #define PEM_END_CRT "-----END CERTIFICATE-----\n" -#include "mbedtls/pem.h" #include +#include CryptoKey *CryptoKeyMbedTLS::create() { return memnew(CryptoKeyMbedTLS); @@ -259,20 +259,15 @@ Ref CryptoMbedTLS::generate_self_signed_certificate(Ref out; - out.instance(); - mbedtls_x509write_crt_pem(&crt, buf, 4096, mbedtls_ctr_drbg_random, &ctr_drbg); - - int err = mbedtls_x509_crt_parse(&(out->cert), buf, 4096); - if (err != 0) { - mbedtls_mpi_free(&serial); - mbedtls_x509write_crt_free(&crt); - ERR_PRINTS("Generated invalid certificate: " + itos(err)); - return NULL; - } - + int ret = mbedtls_x509write_crt_pem(&crt, buf, 4096, mbedtls_ctr_drbg_random, &ctr_drbg); mbedtls_mpi_free(&serial); mbedtls_x509write_crt_free(&crt); + ERR_FAIL_COND_V_MSG(ret != 0, nullptr, "Failed to generate certificate: " + itos(ret)); + buf[4095] = '\0'; // Make sure strlen can't fail. + + Ref out; + out.instance(); + out->load_from_memory(buf, strlen((char *)buf) + 1); // Use strlen to find correct output size. return out; }