Add MBEDTLS_ASN1_CHK_CLEANUP_ADD macro to be able to release memory on failure

Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h
index acfc073..da73759 100644
--- a/include/mbedtls/asn1write.h
+++ b/include/mbedtls/asn1write.h
@@ -35,6 +35,15 @@
         (g) += ret;                                 \
     } while (0)
 
+#define MBEDTLS_ASN1_CHK_CLEANUP_ADD(g, f)                      \
+    do                                                  \
+    {                                                   \
+        if ((ret = (f)) < 0)                         \
+        goto cleanup;                              \
+        else                                            \
+        (g) += ret;                                 \
+    } while (0)
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index a1a1206..45e9187 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -99,7 +99,7 @@
     /* Determine the maximum size of the SubjectAltName list */
     while (cur != NULL) {
         /* Calculate size of the required buffer */
-        switch(cur->node.type) {
+        switch (cur->node.type) {
             case MBEDTLS_X509_SAN_DNS_NAME:
             case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
             case MBEDTLS_X509_SAN_IP_ADDRESS:
@@ -139,15 +139,20 @@
             case MBEDTLS_X509_SAN_DNS_NAME:
             case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
             case MBEDTLS_X509_SAN_IP_ADDRESS:
-                MBEDTLS_ASN1_CHK_ADD(len,
-                                     mbedtls_asn1_write_raw_buffer(&p, buf,
-                                                                   (const unsigned char *) cur->node.san.unstructured_name.p,
-                                                                   cur->node.san.unstructured_name.len));
-                MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, cur->node.san.unstructured_name.len));
-                MBEDTLS_ASN1_CHK_ADD(len,
-                                     mbedtls_asn1_write_tag(&p, buf,
-                                                            MBEDTLS_ASN1_CONTEXT_SPECIFIC |
-                                                            cur->node.type));
+                MBEDTLS_ASN1_CHK_CLEANUP_ADD(len,
+                                             mbedtls_asn1_write_raw_buffer(&p, buf,
+                                                                           (const unsigned char *)
+                                                                           cur->node.san.
+                                                                           unstructured_name.p,
+                                                                           cur->node.san.
+                                                                           unstructured_name.len));
+                MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&p, buf,
+                                                                         cur->node.san.
+                                                                         unstructured_name.len));
+                MBEDTLS_ASN1_CHK_CLEANUP_ADD(len,
+                                             mbedtls_asn1_write_tag(&p, buf,
+                                                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+                                                                    cur->node.type));
                 break;
             default:
                 /* Skip unsupported names. */
@@ -156,10 +161,11 @@
         cur = cur->next;
     }
 
-    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
-    MBEDTLS_ASN1_CHK_ADD(len,
-                         mbedtls_asn1_write_tag(&p, buf,
-                                                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
+    MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
+    MBEDTLS_ASN1_CHK_CLEANUP_ADD(len,
+                                 mbedtls_asn1_write_tag(&p, buf,
+                                                        MBEDTLS_ASN1_CONSTRUCTED |
+                                                        MBEDTLS_ASN1_SEQUENCE));
 
     ret = mbedtls_x509write_csr_set_extension(
         ctx,
@@ -169,6 +175,7 @@
         buf + buflen - len,
         len);
 
+cleanup:
     mbedtls_free(buf);
     return ret;
 }