diff -urN nsd-3.2.4/compat/b64_pton.c nsd-3.2.4-new/compat/b64_pton.c
--- nsd-3.2.4/compat/b64_pton.c	2004-02-04 13:17:32.000000000 +0100
+++ nsd-3.2.4-new/compat/b64_pton.c	2010-02-21 19:43:33.000000000 +0100
@@ -128,65 +128,98 @@
    it returns the number of data bytes stored at the target, or -1 on error.
  */
 
-int
-b64_pton(char const *src, uint8_t *target, size_t targsize)
+
+static int b64rmap_initialized = 0;
+static uint8_t b64rmap[256];
+
+static const uint8_t b64rmap_special = 0xf0;
+static const uint8_t b64rmap_end = 0xfd;
+static const uint8_t b64rmap_space = 0xfe;
+static const uint8_t b64rmap_invalid = 0xff;
+
+static void 
+b64_initialize_rmap ()
+{
+	int i;
+	char ch;
+
+	/* Null: end of string, stop parsing */
+	b64rmap[0] = b64rmap_end;
+
+	for (i = 1; i < 256; ++i) {
+		ch = (char)i;
+		/* Whitespaces */
+		if (isspace(ch))
+			b64rmap[i] = b64rmap_space;
+		/* Padding: stop parsing */
+		else if (ch == Pad64)
+			b64rmap[i] = b64rmap_end;
+		/* Non-base64 char */
+		else 
+			b64rmap[i] = b64rmap_invalid;
+	}
+
+	/* Fill reverse mapping for base64 chars */
+	for (i = 0; Base64[i] != '\0'; ++i)
+		b64rmap[(uint8_t)Base64[i]] = i;
+
+	b64rmap_initialized = 1;
+}
+
+static int
+b64_pton_do(char const *src, uint8_t *target, size_t targsize)
 {
 	int tarindex, state, ch;
-	char *pos;
+	uint8_t ofs;
 
 	state = 0;
 	tarindex = 0;
 
-	while ((ch = *src++) != '\0') {
-		if (isspace((unsigned char)ch))        /* Skip whitespace anywhere. */
-			continue;
-
-		if (ch == Pad64)
-			break;
-
-		pos = strchr(Base64, ch);
-		if (pos == 0) {
+	while (1)
+	{
+		ch = *src++;
+		ofs = b64rmap[ch];
+
+		if (ofs >= b64rmap_special) {
+			/* Ignore whitespaces */
+			if (ofs == b64rmap_space)
+				continue;
+			/* End of base64 characters */
+			if (ofs == b64rmap_end)
+				break;
 			/* A non-base64 character. */
 			return (-1);
 		}
 
 		switch (state) {
 		case 0:
-			if (target) {
-				if ((size_t)tarindex >= targsize)
-					return (-1);
-				target[tarindex] = (pos - Base64) << 2;
-			}
+			if ((size_t)tarindex >= targsize)
+				return (-1);
+			target[tarindex] = ofs << 2;
 			state = 1;
 			break;
 		case 1:
-			if (target) {
-				if ((size_t)tarindex + 1 >= targsize)
-					return (-1);
-				target[tarindex]   |=  (pos - Base64) >> 4;
-				target[tarindex+1]  = ((pos - Base64) & 0x0f)
-							<< 4 ;
-			}
+			if ((size_t)tarindex + 1 >= targsize)
+				return (-1);
+			target[tarindex]   |=  ofs >> 4;
+			target[tarindex+1]  = (ofs & 0x0f)
+						<< 4 ;
 			tarindex++;
 			state = 2;
 			break;
 		case 2:
-			if (target) {
-				if ((size_t)tarindex + 1 >= targsize)
-					return (-1);
-				target[tarindex]   |=  (pos - Base64) >> 2;
-				target[tarindex+1]  = ((pos - Base64) & 0x03)
-							<< 6;
-			}
+			if ((size_t)tarindex + 1 >= targsize)
+				return (-1);
+			target[tarindex]   |=  ofs >> 2;
+			target[tarindex+1]  = (ofs & 0x03)
+						<< 6;
 			tarindex++;
 			state = 3;
 			break;
 		case 3:
-			if (target) {
-				if ((size_t)tarindex >= targsize)
-					return (-1);
-				target[tarindex] |= (pos - Base64);
-			}
+			if ((size_t)tarindex >= targsize)
+				return (-1);
+			target[tarindex] |= ofs;
 			tarindex++;
 			state = 0;
 			break;
@@ -210,7 +243,7 @@
 		case 2:		/* Valid, means one byte of info */
 			/* Skip any number of spaces. */
 			for ((void)NULL; ch != '\0'; ch = *src++)
-				if (!isspace((unsigned char)ch))
+				if (b64rmap[ch] != b64rmap_space)
 					break;
 			/* Make sure there is another trailing = sign. */
 			if (ch != Pad64)
@@ -225,7 +258,7 @@
 			 * whitespace after it?
 			 */
 			for ((void)NULL; ch != '\0'; ch = *src++)
-				if (!isspace((unsigned char)ch))
+				if (b64rmap[ch] != b64rmap_space)
 					return (-1);
 
 			/*
@@ -234,7 +267,7 @@
 			 * zeros.  If we don't check them, they become a
 			 * subliminal channel.
 			 */
-			if (target && target[tarindex] != 0)
+			if (target[tarindex] != 0)
 				return (-1);
 		}
 	} else {
@@ -248,3 +281,109 @@
 
 	return (tarindex);
 }
+
+
+static int
+b64_pton_len(char const *src)
+{
+	int tarindex, state, ch;
+	uint8_t ofs;
+
+	state = 0;
+	tarindex = 0;
+
+	while (1)
+	{
+		ch = *src++;
+		ofs = b64rmap[ch];
+
+		if (ofs >= b64rmap_special) {
+			/* Ignore whitespaces */
+			if (ofs == b64rmap_space)
+				continue;
+			/* End of base64 characters */
+			if (ofs == b64rmap_end)
+				break;
+			/* A non-base64 character. */
+			return (-1);
+		}
+
+		switch (state) {
+		case 0:
+			state = 1;
+			break;
+		case 1:
+			tarindex++;
+			state = 2;
+			break;
+		case 2:
+			tarindex++;
+			state = 3;
+			break;
+		case 3:
+			tarindex++;
+			state = 0;
+			break;
+		default:
+			abort();
+		}
+	}
+
+	/*
+	 * We are done decoding Base-64 chars.  Let's see if we ended
+	 * on a byte boundary, and/or with erroneous trailing characters.
+	 */
+
+	if (ch == Pad64) {		/* We got a pad char. */
+		ch = *src++;		/* Skip it, get next. */
+		switch (state) {
+		case 0:		/* Invalid = in first position */
+		case 1:		/* Invalid = in second position */
+			return (-1);
+
+		case 2:		/* Valid, means one byte of info */
+			/* Skip any number of spaces. */
+			for ((void)NULL; ch != '\0'; ch = *src++)
+				if (b64rmap[ch] != b64rmap_space)
+					break;
+			/* Make sure there is another trailing = sign. */
+			if (ch != Pad64)
+				return (-1);
+			ch = *src++;		/* Skip the = */
+			/* Fall through to "single trailing =" case. */
+			/* FALLTHROUGH */
+
+		case 3:		/* Valid, means two bytes of info */
+			/*
+			 * We know this char is an =.  Is there anything but
+			 * whitespace after it?
+			 */
+			for ((void)NULL; ch != '\0'; ch = *src++)
+				if (b64rmap[ch] != b64rmap_space)
+					return (-1);
+
+		}
+	} else {
+		/*
+		 * We ended by seeing the end of the string.  Make sure we
+		 * have no partial bytes lying around.
+		 */
+		if (state != 0)
+			return (-1);
+	}
+
+	return (tarindex);
+}
+
+
+int
+b64_pton(char const *src, uint8_t *target, size_t targsize)
+{
+	if (!b64rmap_initialized)
+		b64_initialize_rmap ();
+
+	if (target)
+		return b64_pton_do (src, target, targsize);
+	else
+		return b64_pton_len (src);
+}
