From 8fe45d81f049857c37305c3685a1c376bf8970e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=B6khan=20=C5=9Eeng=C3=BCn?= <gsengun@linux-5d7d.site>
Date: Fri, 30 Mar 2012 23:09:47 +0300
Subject: [PATCH] add support to curl to incrementally calculate md5 sum of
 buffers, currently it is only possible to calculate md5 sum
 of a pre-prepared buffer, it is now possible to calculate
 md5 sum as stream of buffers becomes known

---
 lib/curl_md5.h |   38 ++++++++++++++++++++++++++++++++++++--
 lib/md5.c      |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/lib/curl_md5.h b/lib/curl_md5.h
index ddc61e3..85f0c5f 100644
--- a/lib/curl_md5.h
+++ b/lib/curl_md5.h
@@ -25,10 +25,44 @@
 #ifndef CURL_DISABLE_CRYPTO_AUTH
 #include "curl_hmac.h"
 
+#define MD5_DIGEST_LEN  16
+
+typedef void    (* Curl_MD5_init_func)(void * context);
+typedef void    (* Curl_MD5_update_func)(void * context,
+                                      const unsigned char * data,
+                                      unsigned int len);
+typedef void    (* Curl_MD5_final_func)(unsigned char * result,
+                                      void * context);
+
+
+typedef struct {
+  Curl_MD5_init_func       md5_init;     /* Initialize context procedure. */
+  Curl_MD5_update_func     md5_update;   /* Update context with data. */
+  Curl_MD5_final_func      md5_final;    /* Get final result procedure. */
+  unsigned int             md5_ctxtsize;  /* Context structure size. */
+  unsigned int             md5_resultlen; /* Result length (bytes). */
+} MD5_params;
+
+typedef struct {
+  const MD5_params*  md5_hash;    /* Hash function definition. */
+  void*              md5_hashctx; /* Hash function context. */
+} MD5_context;
+
+/* Prototypes. */
+
+ void Curl_md5it(unsigned char *output,
+                 const unsigned char *input);
+
+MD5_context * Curl_MD5_init(const MD5_params * md5params);
+
+int Curl_MD5_update(MD5_context * context,
+                     const unsigned char * data,
+                     unsigned int len);
+int Curl_MD5_final(MD5_context * context, unsigned char * result);
+
+extern const MD5_params Curl_DIGEST_MD5[1];
 extern const HMAC_params Curl_HMAC_MD5[1];
 
-void Curl_md5it(unsigned char *output,
-                const unsigned char *input);
 #endif
 
 #endif /* HEADER_CURL_MD5_H */
diff --git a/lib/md5.c b/lib/md5.c
index 13cb9e2..85cb25c 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -407,6 +407,16 @@ const HMAC_params Curl_HMAC_MD5[] = {
   }
 };
 
+const MD5_params Curl_DIGEST_MD5[] = {
+  {
+    (Curl_MD5_init_func) MD5_Init,       /* digest initialization function. */
+    (Curl_MD5_update_func) MD5_Update,   /* digest update function. */
+    (Curl_MD5_final_func) MD5_Final,     /* digest computation end function. */
+    sizeof(MD5_CTX),                     /* Size of digest context struct. */
+    16                                   /* Result size. */
+  }
+};
+
 
 void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
                 const unsigned char *input)
@@ -417,4 +427,44 @@ void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
   MD5_Final(outbuffer, &ctx);
 }
 
+MD5_context * Curl_MD5_init(const MD5_params * md5params)
+{
+  MD5_context* ctxt;
+
+  /* Create MD5 context. */
+  ctxt = malloc(sizeof *ctxt);
+
+  if(!ctxt)
+    return ctxt;
+
+  ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
+
+  if(!ctxt->md5_hashctx)
+    return ctxt->md5_hashctx;
+
+  ctxt->md5_hash = md5params;
+
+  (*md5params->md5_init)(ctxt->md5_hashctx);
+
+  return ctxt;
+}
+
+int Curl_MD5_update(MD5_context * context,
+                     const unsigned char * data,
+                     unsigned int len)
+{
+  (*context->md5_hash->md5_update)(context->md5_hashctx, data, len);
+  return 0;
+}
+
+int Curl_MD5_final(MD5_context * context, unsigned char * result)
+{
+  (*context->md5_hash->md5_final)(result, context->md5_hashctx);
+
+  free(context->md5_hashctx);
+  free(context);
+
+  return 0;
+}
+
 #endif /* CURL_DISABLE_CRYPTO_AUTH */
-- 
1.7.7

