asn_encode_to_new_buffer()
diff --git a/skeletons/asn_application.c b/skeletons/asn_application.c
index ee74e32..b8852ea 100644
--- a/skeletons/asn_application.c
+++ b/skeletons/asn_application.c
@@ -42,6 +42,12 @@
     size_t computed_size;
 };
 
+struct dynamic_encoder_key {
+    void *buffer;
+    size_t buffer_size;
+    size_t computed_size;
+};
+
 struct callback_failure_catch_key {
     asn_app_consume_bytes_f *callback;
     void *callback_key;
@@ -71,6 +77,43 @@
 }
 
 /*
+ * Encoder which dynamically allocates output, and continues
+ * to count even if allocation failed.
+ */
+static int
+dynamic_encoder_cb(const void *data, size_t size, void *keyp) {
+    struct dynamic_encoder_key *key = keyp;
+
+    if(key->buffer) {
+        if(key->computed_size + size >= key->buffer_size) {
+            void *p;
+            size_t new_size = key->buffer_size;
+
+            do {
+                new_size *= 2;
+            } while(new_size <= key->computed_size + size);
+
+            p = REALLOC(key->buffer, new_size);
+            if(p) {
+                key->buffer = p;
+                key->buffer_size = new_size;
+            } else {
+                FREEMEM(key->buffer);
+                key->buffer = 0;
+                key->buffer_size = 0;
+                key->computed_size += size;
+                return 0;
+            }
+        }
+        memcpy((char *)key->buffer + key->computed_size, data, size);
+    }
+
+    key->computed_size += size;
+
+    return 0;
+}
+
+/*
  * Encoder which help convert the application level encoder failure into EIO.
  */
 static int
@@ -134,7 +177,8 @@
                              overrun_encoder_cb, &buf_key);
 
     if(er.encoded >= 0 && (size_t)er.encoded != buf_key.computed_size) {
-        ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE " yet produced %" ASN_PRI_SIZE " bytes",
+        ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE
+                  " yet produced %" ASN_PRI_SIZE " bytes",
                   er.encoded, buf_key.computed_size);
         assert(er.encoded < 0 || (size_t)er.encoded == buf_key.computed_size);
     }
@@ -142,6 +186,40 @@
     return er;
 }
 
+asn_encode_to_new_buffer_result_t
+asn_encode_to_new_buffer(const asn_codec_ctx_t *opt_codec_ctx,
+                         enum asn_transfer_syntax syntax,
+                         const asn_TYPE_descriptor_t *td, const void *sptr) {
+    struct dynamic_encoder_key buf_key;
+    asn_encode_to_new_buffer_result_t res;
+
+    buf_key.buffer_size = 16;
+    buf_key.buffer = MALLOC(buf_key.buffer_size);
+    buf_key.computed_size = 0;
+
+    res.result = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,
+                                     dynamic_encoder_cb, &buf_key);
+
+    if(res.result.encoded >= 0
+       && (size_t)res.result.encoded != buf_key.computed_size) {
+        ASN_DEBUG("asn_encode() returned %" ASN_PRI_SSIZE
+                  " yet produced %" ASN_PRI_SIZE " bytes",
+                  er.encoded, buf_key.computed_size);
+        assert(res.result.encoded < 0
+               || (size_t)res.result.encoded == buf_key.computed_size);
+    }
+
+    res.buffer = buf_key.buffer;
+
+    /* 0-terminate just in case. */
+    if(res.buffer) {
+        assert(buf_key.computed_size < buf_key.buffer_size);
+        ((char *)res.buffer)[buf_key.computed_size] = '\0';
+    }
+
+    return res;
+}
+
 static asn_enc_rval_t
 asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
                     enum asn_transfer_syntax syntax,
diff --git a/skeletons/asn_application.h b/skeletons/asn_application.h
index a125562..acc91ab 100644
--- a/skeletons/asn_application.h
+++ b/skeletons/asn_application.h
@@ -81,6 +81,28 @@
     const struct asn_TYPE_descriptor_s *type_to_encode,
     const void *structure_to_encode, void *buffer, size_t buffer_size);
 
+/*
+ * A variant of asn_encode_to_buffer() with automatically allocated buffer.
+ * RETURN VALUES:
+ * On success, returns a newly allocated (.buffer) containing the whole message.
+ * The message size is returned in (.result.encoded).
+ * On failure:
+ *  (.buffer) is NULL,
+ *  (.result.encoded) as in asn_encode_to_buffer(),
+ *  The errno codes as in asn_encode_to_buffer(), plus the following:
+ *      ENOMEM: Memory allocation failed due to system or internal limits.
+ * The user is responsible for freeing the (.buffer).
+ */
+typedef struct asn_encode_to_new_buffer_result_s {
+    void *buffer;   /* NULL if failed to encode. */
+    asn_enc_rval_t result;
+} asn_encode_to_new_buffer_result_t;
+asn_encode_to_new_buffer_result_t asn_encode_to_new_buffer(
+    const asn_codec_ctx_t *opt_codec_parameters, /* See asn_codecs.h */
+    enum asn_transfer_syntax,
+    const struct asn_TYPE_descriptor_s *type_to_encode,
+    const void *structure_to_encode);
+
 
 /*
  * Generic type of an application-defined callback to return various