pem: auto add newlines to header/footer in mbedtls_pem_write_buffer()

Signed-off-by: Valerio Setti <valerio.setti@nordicsemi.no>
diff --git a/include/mbedtls/pem.h b/include/mbedtls/pem.h
index cc617a9..2fe19d0 100644
--- a/include/mbedtls/pem.h
+++ b/include/mbedtls/pem.h
@@ -135,6 +135,9 @@
  * \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 9500ffc..7c0c447 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -473,7 +473,10 @@
     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 @@
 
     memcpy(p, header, strlen(header));
     p += strlen(header);
+    *p++ = '\n';
     c = encode_buf;
 
     while (use_len) {
@@ -506,6 +510,7 @@
 
     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 4c019ee..8d920f2 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -651,8 +651,8 @@
     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 4e39755..5ee683f 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -302,8 +302,8 @@
     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 a4dff45..238a0bc 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 413dc55..cb652d4 100644
--- a/tests/suites/test_suite_pem.function
+++ b/tests/suites/test_suite_pem.function
@@ -40,17 +40,17 @@
     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 */