aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-08-19 20:03:40 -0400
committerNick Mathewson <nickm@torproject.org>2009-10-15 15:17:12 -0400
commit8d41e6c47126fb467858f98b06ab7460dcc6647b (patch)
tree3ffc6a5c8561892069abbb3a54fa4cbc4e043947 /src
parent5ef97ddd42dfd51fc296bb51b612780aec09c5c7 (diff)
downloadtor-8d41e6c47126fb467858f98b06ab7460dcc6647b.tar
tor-8d41e6c47126fb467858f98b06ab7460dcc6647b.tar.gz
Support for encoding and decoding 256-bit digests in base64
Diffstat (limited to 'src')
-rw-r--r--src/common/crypto.c38
-rw-r--r--src/common/crypto.h2
-rw-r--r--src/test/test_crypto.c11
3 files changed, 51 insertions, 0 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 581d1ba5a..21c8aed2d 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 f0958a807..63ea96d05 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 d235520d0..2edb8035b 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] ->