[or-cvs] [tor/master] Support for encoding and decoding 256-bit digests in base64
Nick Mathewson
nickm at seul.org
Mon Oct 19 04:48:27 UTC 2009
Author: Nick Mathewson <nickm at torproject.org>
Date: Wed, 19 Aug 2009 20:03:40 -0400
Subject: Support for encoding and decoding 256-bit digests in base64
Commit: 8d41e6c47126fb467858f98b06ab7460dcc6647b
---
src/common/crypto.c | 38 ++++++++++++++++++++++++++++++++++++++
src/common/crypto.h | 2 ++
src/test/test_crypto.c | 11 +++++++++++
3 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 581d1ba..21c8aed 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -2274,6 +2274,44 @@ digest_from_base64(char *digest, const char *d64)
#endif
}
+/** Base-64 encode DIGEST256_LINE bytes from <b>digest</b>, remove the
+ * trailing = and newline characters, and store the nul-terminated result in
+ * the first BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */
+int
+digest256_to_base64(char *d64, const char *digest)
+{
+ char buf[256];
+ base64_encode(buf, sizeof(buf), digest, DIGEST256_LEN);
+ buf[BASE64_DIGEST256_LEN] = '\0';
+ memcpy(d64, buf, BASE64_DIGEST256_LEN+1);
+ return 0;
+}
+
+/** Given a base-64 encoded, nul-terminated digest in <b>d64</b> (without
+ * trailing newline or = characters), decode it and store the result in the
+ * first DIGEST256_LEN bytes at <b>digest</b>. */
+int
+digest256_from_base64(char *digest, const char *d64)
+{
+#ifdef USE_OPENSSL_BASE64
+ char buf_in[BASE64_DIGEST256_LEN+3];
+ char buf[256];
+ if (strlen(d64) != BASE64_DIGEST256_LEN)
+ return -1;
+ memcpy(buf_in, d64, BASE64_DIGEST256_LEN);
+ memcpy(buf_in+BASE64_DIGEST256_LEN, "=\n\0", 3);
+ if (base64_decode(buf, sizeof(buf), buf_in, strlen(buf_in)) != DIGEST256_LEN)
+ return -1;
+ memcpy(digest, buf, DIGEST256_LEN);
+ return 0;
+#else
+ if (base64_decode(digest, DIGEST256_LEN, d64, strlen(d64)) == DIGEST256_LEN)
+ return 0;
+ else
+ return -1;
+#endif
+}
+
/** Implements base32 encoding as in rfc3548. Limitation: Requires
* that srclen*8 is a multiple of 5.
*/
diff --git a/src/common/crypto.h b/src/common/crypto.h
index f0958a8..63ea96d 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -211,6 +211,8 @@ int base32_decode(char *dest, size_t destlen, const char *src, size_t srclen);
int digest_to_base64(char *d64, const char *digest);
int digest_from_base64(char *digest, const char *d64);
+int digest256_to_base64(char *d64, const char *digest);
+int digest256_from_base64(char *digest, const char *d64);
/** Length of RFC2440-style S2K specifier: the first 8 bytes are a salt, the
* 9th describes how much iteration to do. */
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index d235520..2edb803 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -472,6 +472,17 @@ test_crypto_formats(void)
test_assert(digest_from_base64(data3, "###") < 0);
+ /* Encoding SHA256 */
+ crypto_rand(data2, DIGEST256_LEN);
+ memset(data2, 100, 1024);
+ digest256_to_base64(data2, data1);
+ test_eq(BASE64_DIGEST256_LEN, strlen(data2));
+ test_eq(100, data2[BASE64_DIGEST256_LEN+2]);
+ memset(data3, 99, 1024);
+ test_eq(digest256_from_base64(data3, data2), 0);
+ test_memeq(data1, data3, DIGEST256_LEN);
+ test_eq(99, data3[DIGEST256_LEN+1]);
+
/* Base32 tests */
strlcpy(data1, "5chrs", 1024);
/* bit pattern is: [35 63 68 72 73] ->
--
1.5.6.5
More information about the tor-commits
mailing list