diff options
author | Nick Mathewson <nickm@torproject.org> | 2009-08-19 20:03:40 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2009-10-15 15:17:12 -0400 |
commit | 8d41e6c47126fb467858f98b06ab7460dcc6647b (patch) | |
tree | 3ffc6a5c8561892069abbb3a54fa4cbc4e043947 /src | |
parent | 5ef97ddd42dfd51fc296bb51b612780aec09c5c7 (diff) | |
download | tor-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.c | 38 | ||||
-rw-r--r-- | src/common/crypto.h | 2 | ||||
-rw-r--r-- | 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 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] -> |