diff --git a/src/http-ntlm.c b/src/http-ntlm.c
index 87f5a37c..72f6fcd5 100644
--- a/src/http-ntlm.c
+++ b/src/http-ntlm.c
@@ -122,7 +122,7 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
 
       DEBUGP (("Received a type-2 NTLM message.\n"));
 
-      size = wget_base64_decode (header, buffer);
+      size = wget_base64_decode (header, buffer, strlen (header));
       if (size < 0)
         return false;           /* malformed base64 from server */
 
diff --git a/src/http.c b/src/http.c
index 323f5595..da6552e2 100644
--- a/src/http.c
+++ b/src/http.c
@@ -2998,7 +2998,7 @@ skip_content_type:
           char *bin_hash = alloca (dig_hash_str_len * 3 / 4 + 1);
           ssize_t hash_bin_len;
 
-          hash_bin_len = wget_base64_decode (dig_hash, bin_hash);
+          hash_bin_len = wget_base64_decode (dig_hash, bin_hash, dig_hash_str_len * 3 / 4 + 1);
 
           /* Detect malformed base64 input.  */
           if (hash_bin_len < 0)
diff --git a/src/utils.c b/src/utils.c
index 3a57e6c7..81f28010 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -2346,7 +2346,7 @@ wget_base64_encode (const void *data, size_t length, char *dest)
    This function originates from Free Recode.  */
 
 ssize_t
-wget_base64_decode (const char *base64, void *dest)
+wget_base64_decode (const char *base64, void *dest, size_t size)
 {
   /* Table of base64 values for first 128 characters.  Note that this
      assumes ASCII (but so does Wget in other places).  */
@@ -2370,7 +2370,8 @@ wget_base64_decode (const char *base64, void *dest)
 #define IS_BASE64(c) ((IS_ASCII (c) && BASE64_CHAR_TO_VALUE (c) >= 0) || c == '=')
 
   const char *p = base64;
-  char *q = dest;
+  unsigned char *q = dest;
+  ssize_t n = 0;
 
   while (1)
     {
@@ -2392,7 +2393,12 @@ wget_base64_decode (const char *base64, void *dest)
       if (c == '=' || !IS_BASE64 (c))
         return -1;              /* illegal char while decoding base64 */
       value |= BASE64_CHAR_TO_VALUE (c) << 12;
-      *q++ = value >> 16;
+      if (size)
+        {
+          *q++ = value >> 16;
+          size--;
+        }
+      n++;
 
       /* Process third byte of a quadruplet.  */
       NEXT_CHAR (c, p);
@@ -2412,7 +2418,12 @@ wget_base64_decode (const char *base64, void *dest)
         }
 
       value |= BASE64_CHAR_TO_VALUE (c) << 6;
-      *q++ = 0xff & value >> 8;
+      if (size)
+        {
+          *q++ = 0xff & value >> 8;
+          size--;
+        }
+      n++;
 
       /* Process fourth byte of a quadruplet.  */
       NEXT_CHAR (c, p);
@@ -2424,12 +2435,17 @@ wget_base64_decode (const char *base64, void *dest)
         return -1;              /* illegal char while decoding base64 */
 
       value |= BASE64_CHAR_TO_VALUE (c);
-      *q++ = 0xff & value;
+      if (size)
+        {
+          *q++ = 0xff & value;
+          size--;
+        }
+      n++;
     }
 #undef IS_BASE64
 #undef BASE64_CHAR_TO_VALUE
 
-  return q - (char *) dest;
+  return n;
 }
 
 #ifdef HAVE_LIBPCRE
@@ -2726,7 +2742,7 @@ wg_pubkey_pem_to_der (const char *pem, unsigned char **der, size_t *der_len)
 
   base64data = xmalloc (BASE64_LENGTH(stripped_pem_count));
 
-  size = wget_base64_decode (stripped_pem, base64data);
+  size = wget_base64_decode (stripped_pem, base64data, BASE64_LENGTH(stripped_pem_count));
 
   if (size < 0) {
     xfree (base64data);           /* malformed base64 from server */
@@ -2765,54 +2781,65 @@ wg_pin_peer_pubkey (const char *pinnedpubkey, const char *pubkey, size_t pubkeyl
     return result;
 
   /* only do this if pinnedpubkey starts with "sha256//", length 8 */
-  if (strncmp (pinnedpubkey, "sha256//", 8) == 0) {
-    /* compute sha256sum of public key */
-    sha256sumdigest = xmalloc (SHA256_DIGEST_SIZE);
-    sha256_buffer (pubkey, pubkeylen, sha256sumdigest);
-    expectedsha256sumdigest = xmalloc (SHA256_DIGEST_SIZE + 1);
+  if (strncmp (pinnedpubkey, "sha256//", 8) == 0)
+    {
+      /* compute sha256sum of public key */
+      sha256sumdigest = xmalloc (SHA256_DIGEST_SIZE);
+      sha256_buffer (pubkey, pubkeylen, sha256sumdigest);
+      expectedsha256sumdigest = xmalloc (SHA256_DIGEST_SIZE);
 
-    /* it starts with sha256//, copy so we can modify it */
-    pinkeylen = strlen (pinnedpubkey) + 1;
-    pinkeycopy = xmalloc (pinkeylen);
-    memcpy (pinkeycopy, pinnedpubkey, pinkeylen);
+      /* it starts with sha256//, copy so we can modify it */
+      pinkeylen = strlen (pinnedpubkey) + 1;
+      pinkeycopy = xmalloc (pinkeylen);
+      memcpy (pinkeycopy, pinnedpubkey, pinkeylen);
 
-    /* point begin_pos to the copy, and start extracting keys */
-    begin_pos = pinkeycopy;
-    do
-      {
-        end_pos = strstr (begin_pos, ";sha256//");
-        /*
-         * if there is an end_pos, null terminate,
-         * otherwise it'll go to the end of the original string
-         */
-        if (end_pos)
-          end_pos[0] = '\0';
+      /* point begin_pos to the copy, and start extracting keys */
+      begin_pos = pinkeycopy;
+      do
+        {
+          end_pos = strstr (begin_pos, ";sha256//");
+          /*
+           * if there is an end_pos, null terminate,
+           * otherwise it'll go to the end of the original string
+           */
+          if (end_pos)
+            end_pos[0] = '\0';
 
-        /* decode base64 pinnedpubkey, 8 is length of "sha256//" */
-        decoded_hash_length = wget_base64_decode (begin_pos + 8, expectedsha256sumdigest);
-        /* if valid base64, compare sha256 digests directly */
-        if (SHA256_DIGEST_SIZE == decoded_hash_length &&
-           !memcmp (sha256sumdigest, expectedsha256sumdigest, SHA256_DIGEST_SIZE)) {
-          result = true;
-          break;
+          /* decode base64 pinnedpubkey, 8 is length of "sha256//" */
+          decoded_hash_length = wget_base64_decode (begin_pos + 8, expectedsha256sumdigest, SHA256_DIGEST_SIZE);
+
+          /* if valid base64, compare sha256 digests directly */
+          if (SHA256_DIGEST_SIZE == decoded_hash_length)
+            {
+              if (!memcmp (sha256sumdigest, expectedsha256sumdigest, SHA256_DIGEST_SIZE))
+                {
+                  result = true;
+                  break;
+                }
+            }
+          else
+            logprintf (LOG_VERBOSE, _ ("Skipping key with wrong size (%d/%d): %s\n"),
+                       (strlen (begin_pos + 8) * 3) / 4, SHA256_DIGEST_SIZE,
+                       quote (begin_pos + 8));
+
+          /*
+           * change back the null-terminator we changed earlier,
+           * and look for next begin
+           */
+          if (end_pos)
+            {
+              end_pos[0] = ';';
+              begin_pos = strstr (end_pos, "sha256//");
+            }
         }
+      while (end_pos && begin_pos);
 
-        /*
-         * change back the null-terminator we changed earlier,
-         * and look for next begin
-         */
-        if (end_pos) {
-          end_pos[0] = ';';
-          begin_pos = strstr (end_pos, "sha256//");
-        }
-      } while (end_pos && begin_pos);
+      xfree (sha256sumdigest);
+      xfree (expectedsha256sumdigest);
+      xfree (pinkeycopy);
 
-    xfree (sha256sumdigest);
-    xfree (expectedsha256sumdigest);
-    xfree (pinkeycopy);
-
-    return result;
-  }
+      return result;
+    }
 
   /* fall back to assuming this is a file path */
   fm = wget_read_file (pinnedpubkey);
@@ -2832,11 +2859,12 @@ wg_pin_peer_pubkey (const char *pinnedpubkey, const char *pubkey, size_t pubkeyl
     goto cleanup;
 
   /* If the sizes are the same, it can't be base64 encoded, must be der */
-  if (pubkeylen == size) {
-    if (!memcmp (pubkey, fm->content, pubkeylen))
-      result = true;
-    goto cleanup;
-  }
+  if (pubkeylen == size)
+    {
+      if (!memcmp (pubkey, fm->content, pubkeylen))
+        result = true;
+      goto cleanup;
+    }
 
   /*
    * Otherwise we will assume it's PEM and try to decode it
@@ -2858,7 +2886,7 @@ wg_pin_peer_pubkey (const char *pinnedpubkey, const char *pubkey, size_t pubkeyl
   if (pubkeylen == pem_len && !memcmp (pubkey, pem_ptr, pubkeylen))
     result = true;
 
- cleanup:
+cleanup:
   xfree (buf);
   xfree (pem_ptr);
   wget_read_file_free (fm);
diff --git a/src/utils.h b/src/utils.h
index 8acb2589..9936d97c 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -149,7 +149,7 @@ void xsleep (double);
 #define BASE64_LENGTH(len) (4 * (((len) + 2) / 3))
 
 size_t wget_base64_encode (const void *, size_t, char *);
-ssize_t wget_base64_decode (const char *, void *);
+ssize_t wget_base64_decode (const char *, void *, size_t);
 
 #ifdef HAVE_LIBPCRE
 void *compile_pcre_regex (const char *);