From 180915018dd04f6ad66faa3e9fc66813a221643d Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 28 Nov 2023 08:37:06 +0100 Subject: [PATCH] pem: auto add newlines to header/footer in mbedtls_pem_write_buffer() Signed-off-by: Valerio Setti --- include/mbedtls/pem.h | 3 +++ library/pem.c | 7 ++++++- library/x509write_crt.c | 4 ++-- library/x509write_csr.c | 4 ++-- tests/suites/test_suite_pem.data | 12 ++++++------ tests/suites/test_suite_pem.function | 6 +++--- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h index cc617a9bc..2fe19d026 100644 --- a/include/mbedtls/pem.h +++ b/include/mbedtls/pem.h @@ -135,6 +135,9 @@ void mbedtls_pem_free(mbedtls_pem_context *ctx); * \param olen The address at which to store the total length written * or required (if \p buf_len is not enough). * + * \note Newlines are automatically appended to both header and + * footer. + * * \note You may pass \c NULL for \p buf and \c 0 for \p buf_len * to request the length of the resulting PEM buffer in * `*olen`. diff --git a/library/pem.c b/library/pem.c index 9500ffcf7..7c0c447ee 100644 --- a/library/pem.c +++ b/library/pem.c @@ -473,7 +473,10 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, size_t len = 0, use_len, add_len = 0; mbedtls_base64_encode(NULL, 0, &use_len, der_data, der_len); - add_len = strlen(header) + strlen(footer) + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1; + /* Newlines are appended to the end of both header and footer, so we + * account for an extra +2. */ + add_len = strlen(header) + strlen(footer) + 2 + \ + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1; if (use_len + add_len > buf_len) { *olen = use_len + add_len; @@ -493,6 +496,7 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, memcpy(p, header, strlen(header)); p += strlen(header); + *p++ = '\n'; c = encode_buf; while (use_len) { @@ -506,6 +510,7 @@ int mbedtls_pem_write_buffer(const char *header, const char *footer, memcpy(p, footer, strlen(footer)); p += strlen(footer); + *p++ = '\n'; *p++ = '\0'; *olen = p - buf; diff --git a/library/x509write_crt.c b/library/x509write_crt.c index 4c019eee4..8d920f267 100644 --- a/library/x509write_crt.c +++ b/library/x509write_crt.c @@ -651,8 +651,8 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, return (int) len; } -#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" -#define PEM_END_CRT "-----END CERTIFICATE-----\n" +#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----" +#define PEM_END_CRT "-----END CERTIFICATE-----" #if defined(MBEDTLS_PEM_WRITE_C) int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *crt, diff --git a/library/x509write_csr.c b/library/x509write_csr.c index 4e397553a..5ee683ff1 100644 --- a/library/x509write_csr.c +++ b/library/x509write_csr.c @@ -302,8 +302,8 @@ int mbedtls_x509write_csr_der(mbedtls_x509write_csr *ctx, unsigned char *buf, return ret; } -#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" -#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" +#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----" +#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----" #if defined(MBEDTLS_PEM_WRITE_C) int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, diff --git a/tests/suites/test_suite_pem.data b/tests/suites/test_suite_pem.data index a4dff45f0..238a0bc04 100644 --- a/tests/suites/test_suite_pem.data +++ b/tests/suites/test_suite_pem.data @@ -1,20 +1,20 @@ Standard PEM write -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" PEM write (zero data) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"":"-----START TEST-----\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"":"-----START TEST-----\n-----END TEST-----\n" PEM write (one byte) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"00":"-----START TEST-----\nAA==\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"00":"-----START TEST-----\nAA==\n-----END TEST-----\n" PEM write (more than line size) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8=\n-----END TEST-----\n" PEM write (exactly two lines) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\n-----END TEST-----\n" PEM write (exactly two lines + 1) -mbedtls_pem_write_buffer:"-----START TEST-----\n":"-----END TEST-----\n":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAA==\n-----END TEST-----\n" +mbedtls_pem_write_buffer:"-----START TEST-----":"-----END TEST-----":"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F00":"-----START TEST-----\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAAECAwQFBgcICQoLDA0ODwABAgMEBQYHCAkKCwwNDg8AAQIDBAUGBwgJCgsMDQ4P\nAA==\n-----END TEST-----\n" PEM write length reporting mbedtls_pem_write_buffer_lengths diff --git a/tests/suites/test_suite_pem.function b/tests/suites/test_suite_pem.function index 413dc551c..cb652d458 100644 --- a/tests/suites/test_suite_pem.function +++ b/tests/suites/test_suite_pem.function @@ -40,17 +40,17 @@ void mbedtls_pem_write_buffer_lengths() size_t olen_needed, olen; int ret; for (size_t l = 0; l <= sizeof(data); l++) { - ret = mbedtls_pem_write_buffer("\n", "\n", data, l, NULL, 0, &olen_needed); + ret = mbedtls_pem_write_buffer("", "", data, l, NULL, 0, &olen_needed); TEST_EQUAL(ret, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL); /* Test that a bigger buffer still only requires `olen_needed` */ - ret = mbedtls_pem_write_buffer("\n", "\n", data, l, buf, sizeof(buf), &olen); + ret = mbedtls_pem_write_buffer("", "", data, l, buf, sizeof(buf), &olen); TEST_EQUAL(ret, 0); TEST_EQUAL(olen_needed, olen); /* Test that a buffer of exactly `olen_needed` works */ memset(buf, 1, sizeof(buf)); - ret = mbedtls_pem_write_buffer("\n", "\n", data, l, buf, olen_needed, &olen); + ret = mbedtls_pem_write_buffer("", "", data, l, buf, olen_needed, &olen); TEST_EQUAL(ret, 0); TEST_EQUAL(olen_needed, olen); /* Test the function didn't overflow the given buffer */