Bläddra i källkod

preliminary implementation for RFC 7616 support

Christian Grothoff 7 år sedan
förälder
incheckning
bcba3f58c5
8 ändrade filer med 773 tillägg och 401 borttagningar
  1. 4 0
      ChangeLog
  2. 111 3
      src/include/microhttpd.h
  3. 5 4
      src/microhttpd/Makefile.am
  4. 482 265
      src/microhttpd/digestauth.c
  5. 76 54
      src/microhttpd/md5.c
  6. 20 17
      src/microhttpd/md5.h
  7. 47 41
      src/microhttpd/sha256.c
  8. 28 17
      src/microhttpd/sha256.h

+ 4 - 0
ChangeLog

@@ -1,3 +1,7 @@
+Sat Dec  8 17:34:58 CET 2018
+	Adding support for RFC 7616, experimental, needs
+	testing and documentation still! -CG
+
 Fri Dec  7 12:37:17 CET 2018
 	Add option to build MHD without any threads
 	and MHD_FEATURE_THREADS to test for it.  -CG

+ 111 - 3
src/include/microhttpd.h

@@ -3192,7 +3192,30 @@ MHD_free (void *ptr);
 
 
 /**
- * Authenticates the authorization header sent by the client
+ * Which digest algorithm should MHD use for HTTP digest authentication?
+ */
+enum MHD_DigestAuthAlgorithm {
+
+  /**
+   * MHD should pick (currently defaults to SHA-256).
+   */
+  MHD_DIGEST_ALG_AUTO = 0,
+
+  /**
+   * Force use of MD5.
+   */
+  MHD_DIGEST_ALG_MD5,
+
+  /**
+   * Force use of SHA-256.
+   */
+  MHD_DIGEST_ALG_SHA256
+
+};
+
+
+/**
+ * Authenticates the authorization header sent by the client.
  *
  * @param connection The MHD connection structure
  * @param realm The realm presented to the client
@@ -3200,11 +3223,39 @@ MHD_free (void *ptr);
  * @param password The password used in the authentication
  * @param nonce_timeout The amount of time for a nonce to be
  * 			invalid in seconds
+ * @param algo digest algorithms allowed for verification
  * @return #MHD_YES if authenticated, #MHD_NO if not,
  * 			#MHD_INVALID_NONCE if nonce is invalid
  * @ingroup authentication
  */
 _MHD_EXTERN int
+MHD_digest_auth_check2 (struct MHD_Connection *connection,
+			const char *realm,
+			const char *username,
+			const char *password,
+			unsigned int nonce_timeout,
+			enum MHD_DigestAuthAlgorithm algo);
+
+
+/**
+ * Authenticates the authorization header sent by the client.
+ * Uses #MHD_DIGEST_ALG_MD5 (for now, for backwards-compatibility).
+ * Note that this MAY change to #MHD_DIGEST_ALG_AUTO in the future.
+ * If you want to be sure you get MD5, use #MHD_digest_auth_check2()
+ * and specifiy MD5 explicitly.
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param password The password used in the authentication
+ * @param nonce_timeout The amount of time for a nonce to be
+ * 			invalid in seconds
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * 			#MHD_INVALID_NONCE if nonce is invalid
+ * @ingroup authentication
+ * @deprecated use MHD_digest_auth_check2()
+ */
+_MHD_EXTERN int
 MHD_digest_auth_check (struct MHD_Connection *connection,
 		       const char *realm,
 		       const char *username,
@@ -3213,21 +3264,51 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
 
 
 /**
- * Authenticates the authorization header sent by the client
+ * Authenticates the authorization header sent by the client.
  *
  * @param connection The MHD connection structure
  * @param realm The realm presented to the client
  * @param username The username needs to be authenticated
  * @param digest An `unsigned char *' pointer to the binary MD5 sum
  * 			for the precalculated hash value "username:realm:password"
- * 			of #MHD_MD5_DIGEST_SIZE bytes
+ * 			of @a digest_size bytes
+ * @param digest_size number of bytes in @a digest (size must match @a algo!)
  * @param nonce_timeout The amount of time for a nonce to be
  * 			invalid in seconds
+ * @param algo digest algorithms allowed for verification
  * @return #MHD_YES if authenticated, #MHD_NO if not,
  * 			#MHD_INVALID_NONCE if nonce is invalid
  * @ingroup authentication
  */
 _MHD_EXTERN int
+MHD_digest_auth_check_digest2 (struct MHD_Connection *connection,
+			       const char *realm,
+			       const char *username,
+			       const uint8_t *digest,
+                               size_t digest_size,
+			       unsigned int nonce_timeout,
+			       enum MHD_DigestAuthAlgorithm algo);
+
+
+/**
+ * Authenticates the authorization header sent by the client
+ * Uses #MHD_DIGEST_ALG_MD5 (required, as @a digest is of fixed
+ * size).
+ *
+ * @param connection The MHD connection structure
+ * @param realm The realm presented to the client
+ * @param username The username needs to be authenticated
+ * @param digest An `unsigned char *' pointer to the binary hash
+ * 		for the precalculated hash value "username:realm:password";
+ * 		length must be #MHD_MD5_DIGEST_SIZE bytes
+ * @param nonce_timeout The amount of time for a nonce to be
+ * 			invalid in seconds
+ * @return #MHD_YES if authenticated, #MHD_NO if not,
+ * 			#MHD_INVALID_NONCE if nonce is invalid
+ * @ingroup authentication
+ * @deprecated use #MHD_digest_auth_check_digest2()
+ */
+_MHD_EXTERN int
 MHD_digest_auth_check_digest (struct MHD_Connection *connection,
 			      const char *realm,
 			      const char *username,
@@ -3239,6 +3320,32 @@ MHD_digest_auth_check_digest (struct MHD_Connection *connection,
  * Queues a response to request authentication from the client
  *
  * @param connection The MHD connection structure
+ * @param realm the realm presented to the client
+ * @param opaque string to user for opaque value
+ * @param response reply to send; should contain the "access denied"
+ *        body; note that this function will set the "WWW Authenticate"
+ *        header and that the caller should not do this
+ * @param signal_stale #MHD_YES if the nonce is invalid to add
+ * 			'stale=true' to the authentication header
+ * @param algo digest algorithm to use
+ * @return #MHD_YES on success, #MHD_NO otherwise
+ * @ingroup authentication
+ */
+int
+MHD_queue_auth_fail_response2 (struct MHD_Connection *connection,
+			       const char *realm,
+			       const char *opaque,
+			       struct MHD_Response *response,
+			       int signal_stale,
+			       enum MHD_DigestAuthAlgorithm algo);
+
+
+/**
+ * Queues a response to request authentication from the client
+ * For now uses MD5 (for backwards-compatibility). Still, if you
+ * need to be sure, use #MHD_queue_fail_auth_response2().
+ *
+ * @param connection The MHD connection structure
  * @param realm The realm presented to the client
  * @param opaque string to user for opaque value
  * @param response reply to send; should contain the "access denied"
@@ -3248,6 +3355,7 @@ MHD_digest_auth_check_digest (struct MHD_Connection *connection,
  * 			'stale=true' to the authentication header
  * @return #MHD_YES on success, #MHD_NO otherwise
  * @ingroup authentication
+ * @deprecated use MHD_queue_auth_fail_response2()
  */
 _MHD_EXTERN int
 MHD_queue_auth_fail_response (struct MHD_Connection *connection,

+ 5 - 4
src/microhttpd/Makefile.am

@@ -133,7 +133,8 @@ endif
 if ENABLE_DAUTH
 libmicrohttpd_la_SOURCES += \
   digestauth.c \
-  md5.c md5.h
+  md5.c md5.h \
+  sha256.c sha256.h
 endif
 
 if ENABLE_BAUTH
@@ -160,18 +161,18 @@ check_PROGRAMS = \
 
 if HAVE_POSIX_THREADS
 if ENABLE_UPGRADE
-if USE_POSIX_THREADS 
+if USE_POSIX_THREADS
   check_PROGRAMS += test_upgrade
 endif
 if USE_W32_THREADS
   check_PROGRAMS += test_upgrade
 endif
 if ENABLE_HTTPS
-if USE_POSIX_THREADS 
+if USE_POSIX_THREADS
 check_PROGRAMS += test_upgrade_tls
 endif
 if USE_W32_THREADS
-check_PROGRAMS += test_upgrade_tls	
+check_PROGRAMS += test_upgrade_tls
 endif
 endif
 endif

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 482 - 265
src/microhttpd/digestauth.c


+ 76 - 54
src/microhttpd/md5.c

@@ -42,16 +42,20 @@ static uint8_t PADDING[MD5_BLOCK_SIZE] = {
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
-/*
+
+/**
  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
  * initialization constants.
+ *
+ * @param ctx must be a `struct MD5Context *`
  */
 void
-MD5Init(struct MD5Context *ctx)
+MD5Init (void *ctx_)
 {
+  struct MD5Context *ctx = ctx_;
+
   if (!ctx)
     return;
-
   ctx->count = 0;
   ctx->state[0] = 0x67452301;
   ctx->state[1] = 0xefcdab89;
@@ -59,56 +63,13 @@ MD5Init(struct MD5Context *ctx)
   ctx->state[3] = 0x10325476;
 }
 
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len)
-{
-  size_t have, need;
-
-  if (!ctx || !input)
-    return;
-
-  /* Check how many bytes we already have and how many more we need. */
-  have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
-  need = MD5_BLOCK_SIZE - have;
-
-  /* Update bitcount */
-  ctx->count += (uint64_t)len << 3;
-
-  if (len >= need)
-  {
-    if (have != 0)
-    {
-      memcpy(ctx->buffer + have, input, need);
-      MD5Transform(ctx->state, ctx->buffer);
-      input += need;
-      len -= need;
-      have = 0;
-    }
 
-    /* Process data in MD5_BLOCK_SIZE-byte chunks. */
-    while (len >= MD5_BLOCK_SIZE)
-    {
-      MD5Transform(ctx->state, input);
-      input += MD5_BLOCK_SIZE;
-      len -= MD5_BLOCK_SIZE;
-    }
-  }
-
-  /* Handle any remaining bytes of data. */
-  if (len != 0)
-    memcpy(ctx->buffer + have, input, len);
-}
-
-/*
+/**
  * Pad pad to 64-byte boundary with the bit pattern
  * 1 0* (64-bit count of bits processed, MSB-first)
  */
-void
-MD5Pad(struct MD5Context *ctx)
+static void
+MD5Pad (struct MD5Context *ctx)
 {
   uint8_t count[8];
   size_t padlen;
@@ -128,12 +89,17 @@ MD5Pad(struct MD5Context *ctx)
   MD5Update(ctx, count, 8);
 }
 
-/*
+
+/**
  * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
+ *
+ * @param ctx must be a `struct MD5Context *`
  */
 void
-MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
+MD5Final (void *ctx_,
+          unsigned char digest[MD5_DIGEST_SIZE])
 {
+  struct MD5Context *ctx = ctx_;
   int i;
 
   if (!ctx || !digest)
@@ -159,13 +125,14 @@ MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx)
 #define MD5STEP(f, w, x, y, z, data, s) \
 	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
 
-/*
+/**
  * The core of the MD5 algorithm, this alters an existing MD5 hash to
  * reflect the addition of 16 longwords of new data.  MD5Update blocks
  * the data and converts bytes into longwords for this routine.
  */
-void
-MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE])
+static void
+MD5Transform (uint32_t state[4],
+              const uint8_t block[MD5_BLOCK_SIZE])
 {
   uint32_t a, b, c, d, in[MD5_BLOCK_SIZE / 4];
 
@@ -261,4 +228,59 @@ MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE])
   state[3] += d;
 }
 
+
+/**
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update (void *ctx_,
+           const uint8_t *input,
+           size_t len)
+{
+  struct MD5Context *ctx = ctx_;
+  size_t have, need;
+
+  if (!ctx || !input)
+    return;
+
+  /* Check how many bytes we already have and how many more we need. */
+  have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_SIZE - 1));
+  need = MD5_BLOCK_SIZE - have;
+
+  /* Update bitcount */
+  ctx->count += (uint64_t)len << 3;
+
+  if (len >= need)
+  {
+    if (have != 0)
+    {
+      memcpy (ctx->buffer + have,
+              input,
+              need);
+      MD5Transform(ctx->state, ctx->buffer);
+      input += need;
+      len -= need;
+      have = 0;
+    }
+
+    /* Process data in MD5_BLOCK_SIZE-byte chunks. */
+    while (len >= MD5_BLOCK_SIZE)
+    {
+      MD5Transform (ctx->state,
+                    (const unsigned char *) input);
+      input += MD5_BLOCK_SIZE;
+      len -= MD5_BLOCK_SIZE;
+    }
+  }
+
+  /* Handle any remaining bytes of data. */
+  if (0 != len)
+    memcpy (ctx->buffer + have,
+            input,
+            len);
+}
+
+
+
 /* end of md5.c */

+ 20 - 17
src/microhttpd/md5.h

@@ -31,34 +31,37 @@ struct MD5Context
   uint8_t buffer[MD5_BLOCK_SIZE];	/* input buffer */
 };
 
-/*
+
+/**
  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
  * initialization constants.
+ *
+ * @param ctx_ must be a `struct MD5Context *`
  */
-void MD5Init(struct MD5Context *ctx);
+void
+MD5Init (void *ctx_);
 
-/*
+
+/**
  * Update context to reflect the concatenation of another buffer full
  * of bytes.
+ *
+ * @param ctx_ must be a `struct MD5Context *`
  */
-void MD5Update(struct MD5Context *ctx, const unsigned char *input, size_t len);
+void
+MD5Update (void *ctx_,
+           const uint8_t *input,
+           size_t len);
 
-/*
- * Pad pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void MD5Pad(struct MD5Context *ctx);
 
-/*
+/**
  * Final wrapup--call MD5Pad, fill in digest and zero out ctx.
+ *
+ * @param ctx_ must be a `struct MD5Context *`
  */
-void MD5Final(unsigned char digest[MD5_DIGEST_SIZE], struct MD5Context *ctx);
+void
+MD5Final (void *ctx_,
+          unsigned char digest[MD5_DIGEST_SIZE]);
 
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data.  MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_SIZE]);
 
 #endif /* !MHD_MD5_H */

+ 47 - 41
src/microhttpd/sha256.c

@@ -48,22 +48,22 @@
 static const uint32_t
 K[64] =
 {
-  0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 
-  0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 
-  0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 
-  0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 
-  0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 
-  0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 
-  0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 
-  0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 
-  0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 
-  0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 
-  0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 
-  0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 
-  0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 
-  0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 
-  0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 
-  0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, 
+  0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+  0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+  0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+  0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+  0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+  0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+  0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+  0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+  0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+  0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+  0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+  0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+  0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+  0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+  0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+  0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL,
 };
 
 
@@ -77,11 +77,11 @@ K[64] =
    this */
 
 /* #define Choice(x,y,z) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) */
-#define Choice(x,y,z)   ( (z) ^ ( (x) & ( (y) ^ (z) ) ) ) 
+#define Choice(x,y,z)   ( (z) ^ ( (x) & ( (y) ^ (z) ) ) )
 /* #define Majority(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */
 #define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )
 
-#define S0(x) (ROTL32(30,(x)) ^ ROTL32(19,(x)) ^ ROTL32(10,(x))) 
+#define S0(x) (ROTL32(30,(x)) ^ ROTL32(19,(x)) ^ ROTL32(10,(x)))
 #define S1(x) (ROTL32(26,(x)) ^ ROTL32(21,(x)) ^ ROTL32(7,(x)))
 
 #define s0(x) (ROTL32(25,(x)) ^ ROTL32(14,(x)) ^ ((x) >> 3))
@@ -182,22 +182,22 @@ _nettle_sha256_compress(uint32_t *state, const uint8_t *input, const uint32_t *k
   F = state[5];
   G = state[6];
   H = state[7];
-  
+
   /* Heavy mangling */
   /* First 16 subrounds that act on the original data */
 
   for (i = 0, d = data; i<16; i+=8, k += 8, d+= 8)
     {
-      ROUND(A, B, C, D, E, F, G, H, k[0], d[0]); 
-      ROUND(H, A, B, C, D, E, F, G, k[1], d[1]); 
+      ROUND(A, B, C, D, E, F, G, H, k[0], d[0]);
+      ROUND(H, A, B, C, D, E, F, G, k[1], d[1]);
       ROUND(G, H, A, B, C, D, E, F, k[2], d[2]);
       ROUND(F, G, H, A, B, C, D, E, k[3], d[3]);
       ROUND(E, F, G, H, A, B, C, D, k[4], d[4]);
       ROUND(D, E, F, G, H, A, B, C, k[5], d[5]);
-      ROUND(C, D, E, F, G, H, A, B, k[6], d[6]); 
-      ROUND(B, C, D, E, F, G, H, A, k[7], d[7]); 
+      ROUND(C, D, E, F, G, H, A, B, k[6], d[6]);
+      ROUND(B, C, D, E, F, G, H, A, k[7], d[7]);
     }
-  
+
   for (; i<64; i += 16, k+= 16)
     {
       ROUND(A, B, C, D, E, F, G, H, k[ 0], EXPAND(data,  0));
@@ -235,20 +235,21 @@ _nettle_sha256_compress(uint32_t *state, const uint8_t *input, const uint32_t *k
 /* Initialize the SHA values */
 
 void
-sha256_init(struct sha256_ctx *ctx)
+sha256_init (void *ctx_)
 {
   /* Initial values, also generated by the shadata program. */
   static const uint32_t H0[_SHA256_DIGEST_LENGTH] =
   {
-    0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 
-    0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL, 
+    0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
+    0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL,
   };
+  struct sha256_ctx *ctx = ctx_;
 
   memcpy(ctx->state, H0, sizeof(H0));
 
   /* Initialize bit count */
   ctx->count = 0;
-  
+
   /* Initialize buffer */
   ctx->index = 0;
 }
@@ -322,9 +323,11 @@ sha256_init(struct sha256_ctx *ctx)
 
 
 void
-sha256_update(struct sha256_ctx *ctx,
-	      size_t length, const uint8_t *data)
+sha256_update (void *ctx_,
+               const uint8_t *data,
+               size_t length)
 {
+  struct sha256_ctx *ctx = ctx_;
   MD_UPDATE (ctx, length, data, COMPRESS, ctx->count++);
 }
 
@@ -337,7 +340,7 @@ _nettle_write_be32(size_t length, uint8_t *dst,
   size_t i;
   size_t words;
   unsigned leftover;
-  
+
   words = length / 4;
   leftover = length % 4;
 
@@ -348,9 +351,9 @@ _nettle_write_be32(size_t length, uint8_t *dst,
     {
       uint32_t word;
       unsigned j = leftover;
-      
+
       word = src[i];
-      
+
       switch (leftover)
 	{
 	default:
@@ -369,9 +372,9 @@ _nettle_write_be32(size_t length, uint8_t *dst,
 
 
 static void
-sha256_write_digest(struct sha256_ctx *ctx,
-		    size_t length,
-		    uint8_t *digest)
+sha256_write_digest (struct sha256_ctx *ctx,
+                     size_t length,
+                     uint8_t *digest)
 {
   uint64_t bit_count;
 
@@ -379,7 +382,7 @@ sha256_write_digest(struct sha256_ctx *ctx,
 
   MD_PAD(ctx, 8, COMPRESS);
 
-  /* There are 512 = 2^9 bits in one block */  
+  /* There are 512 = 2^9 bits in one block */
   bit_count = (ctx->count << 9) | (ctx->index << 3);
 
   /* This is slightly inefficient, as the numbers are converted to
@@ -392,10 +395,13 @@ sha256_write_digest(struct sha256_ctx *ctx,
 }
 
 void
-sha256_digest(struct sha256_ctx *ctx,
-	      size_t length,
+sha256_digest (void *ctx_,
 	      uint8_t *digest)
 {
-  sha256_write_digest(ctx, length, digest);
-  sha256_init(ctx);
+  struct sha256_ctx *ctx = ctx_;
+
+  sha256_write_digest (ctx,
+                       SHA256_DIGEST_SIZE,
+                       digest);
+  sha256_init (ctx);
 }

+ 28 - 17
src/microhttpd/sha256.h

@@ -32,14 +32,10 @@
    the GNU Lesser General Public License along with this program.  If
    not, see http://www.gnu.org/licenses/.
 */
- 
+
 #ifndef NETTLE_SHA2_H_INCLUDED
 #define NETTLE_SHA2_H_INCLUDED
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #define SHA256_DIGEST_SIZE 32
 #define SHA256_BLOCK_SIZE 64
 
@@ -54,21 +50,36 @@ struct sha256_ctx
   unsigned int index;                       /* index into buffer */
 };
 
-void
-sha256_init(struct sha256_ctx *ctx);
 
+/**
+ * Start SHA256 calculation.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ */
 void
-sha256_update(struct sha256_ctx *ctx,
-	      size_t length,
-	      const uint8_t *data);
+sha256_init (void *ctx_);
 
-void
-sha256_digest(struct sha256_ctx *ctx,
-	      size_t length,
-	      uint8_t *digest);
 
-#ifdef __cplusplus
-}
-#endif
+/**
+ * Update hash calculation.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ * @param length number of bytes in @a data
+ * @param data bytes to add to hash
+ */
+void
+sha256_update (void *ctx_,
+               const uint8_t *data,
+               size_t length);
+
+/**
+ * Complete SHA256 calculation.
+ *
+ * @param ctx_ must be a `struct sha256_ctx *`
+ * @param digest[out] set to the hash, must be #SHA256_DIGEST_SIZE bytes
+ */
+void
+sha256_digest (void *ctx_,
+               uint8_t digest[SHA256_DIGEST_SIZE]);
 
 #endif /* NETTLE_SHA2_H_INCLUDED */

Vissa filer visades inte eftersom för många filer har ändrats