summaryrefslogtreecommitdiff
path: root/src/common/crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/crypto.c')
-rw-r--r--src/common/crypto.c609
1 files changed, 274 insertions, 335 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index f980d7ecfc..28963f52cb 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -51,9 +51,9 @@
#define CRYPTO_PRIVATE
#include "crypto.h"
-#include "../common/torlog.h"
+#include "torlog.h"
#include "aes.h"
-#include "../common/util.h"
+#include "util.h"
#include "container.h"
#include "compat.h"
#include "sandbox.h"
@@ -1394,6 +1394,78 @@ crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out)
return 0;
}
+/** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the
+ * Base64 encoding of the DER representation of the private key as a NUL
+ * terminated string, and return it via <b>priv_out</b>. Return 0 on
+ * sucess, -1 on failure.
+ *
+ * It is the caller's responsibility to sanitize and free the resulting buffer.
+ */
+int
+crypto_pk_base64_encode(const crypto_pk_t *pk, char **priv_out)
+{
+ unsigned char *der = NULL;
+ int der_len;
+ int ret = -1;
+
+ *priv_out = NULL;
+
+ der_len = i2d_RSAPrivateKey(pk->key, &der);
+ if (der_len < 0 || der == NULL)
+ return ret;
+
+ size_t priv_len = base64_encode_size(der_len, 0) + 1;
+ char *priv = tor_malloc_zero(priv_len);
+ if (base64_encode(priv, priv_len, (char *)der, der_len, 0) >= 0) {
+ *priv_out = priv;
+ ret = 0;
+ } else {
+ tor_free(priv);
+ }
+
+ memwipe(der, 0, der_len);
+ OPENSSL_free(der);
+ return ret;
+}
+
+/** Given a string containing the Base64 encoded DER representation of the
+ * private key <b>str</b>, decode and return the result on success, or NULL
+ * on failure.
+ */
+crypto_pk_t *
+crypto_pk_base64_decode(const char *str, size_t len)
+{
+ crypto_pk_t *pk = NULL;
+
+ char *der = tor_malloc_zero(len + 1);
+ int der_len = base64_decode(der, len, str, len);
+ if (der_len <= 0) {
+ log_warn(LD_CRYPTO, "Stored RSA private key seems corrupted (base64).");
+ goto out;
+ }
+
+ const unsigned char *dp = (unsigned char*)der; /* Shut the compiler up. */
+ RSA *rsa = d2i_RSAPrivateKey(NULL, &dp, der_len);
+ if (!rsa) {
+ crypto_log_errors(LOG_WARN, "decoding private key");
+ goto out;
+ }
+
+ pk = crypto_new_pk_from_rsa_(rsa);
+
+ /* Make sure it's valid. */
+ if (crypto_pk_check_key(pk) <= 0) {
+ crypto_pk_free(pk);
+ pk = NULL;
+ goto out;
+ }
+
+ out:
+ memwipe(der, 0, len + 1);
+ tor_free(der);
+ return pk;
+}
+
/* symmetric crypto */
/** Return a pointer to the key set for the cipher in <b>env</b>.
@@ -1765,235 +1837,12 @@ static BIGNUM *dh_param_p_tls = NULL;
/** Shared G parameter for our DH key exchanges. */
static BIGNUM *dh_param_g = NULL;
-/** Generate and return a reasonable and safe DH parameter p. */
-static BIGNUM *
-crypto_generate_dynamic_dh_modulus(void)
-{
- BIGNUM *dynamic_dh_modulus;
- DH *dh_parameters;
- int r, dh_codes;
- char *s;
-
- dynamic_dh_modulus = BN_new();
- tor_assert(dynamic_dh_modulus);
-
- dh_parameters = DH_new();
- tor_assert(dh_parameters);
-
- r = DH_generate_parameters_ex(dh_parameters,
- DH_BYTES*8, DH_GENERATOR, NULL);
- tor_assert(r == 0);
-
- r = DH_check(dh_parameters, &dh_codes);
- tor_assert(r && !dh_codes);
-
- BN_copy(dynamic_dh_modulus, dh_parameters->p);
- tor_assert(dynamic_dh_modulus);
-
- DH_free(dh_parameters);
-
- { /* log the dynamic DH modulus: */
- s = BN_bn2hex(dynamic_dh_modulus);
- tor_assert(s);
- log_info(LD_OR, "Dynamic DH modulus generated: [%s]", s);
- OPENSSL_free(s);
- }
-
- return dynamic_dh_modulus;
-}
-
-/** Store our dynamic DH modulus (and its group parameters) to
- <b>fname</b> for future use. */
-static int
-crypto_store_dynamic_dh_modulus(const char *fname)
-{
- int len, new_len;
- DH *dh = NULL;
- unsigned char *dh_string_repr = NULL;
- char *base64_encoded_dh = NULL;
- char *file_string = NULL;
- int retval = -1;
- static const char file_header[] = "# This file contains stored Diffie-"
- "Hellman parameters for future use.\n# You *do not* need to edit this "
- "file.\n\n";
-
- tor_assert(fname);
-
- if (!dh_param_p_tls) {
- log_info(LD_CRYPTO, "Tried to store a DH modulus that does not exist.");
- goto done;
- }
-
- if (!(dh = DH_new()))
- goto done;
- if (!(dh->p = BN_dup(dh_param_p_tls)))
- goto done;
- if (!(dh->g = BN_new()))
- goto done;
- if (!BN_set_word(dh->g, DH_GENERATOR))
- goto done;
-
- len = i2d_DHparams(dh, &dh_string_repr);
- if ((len < 0) || (dh_string_repr == NULL)) {
- log_warn(LD_CRYPTO, "Error occured while DER encoding DH modulus (2).");
- goto done;
- }
-
- base64_encoded_dh = tor_calloc(len, 2); /* should be enough */
- new_len = base64_encode(base64_encoded_dh, len * 2,
- (char *)dh_string_repr, len);
- if (new_len < 0) {
- log_warn(LD_CRYPTO, "Error occured while base64-encoding DH modulus.");
- goto done;
- }
-
- /* concatenate file header and the dh parameters blob */
- new_len = tor_asprintf(&file_string, "%s%s", file_header, base64_encoded_dh);
-
- /* write to file */
- if (write_bytes_to_new_file(fname, file_string, new_len, 0) < 0) {
- log_info(LD_CRYPTO, "'%s' was already occupied.", fname);
- goto done;
- }
-
- retval = 0;
-
- done:
- if (dh)
- DH_free(dh);
- if (dh_string_repr)
- OPENSSL_free(dh_string_repr);
- tor_free(base64_encoded_dh);
- tor_free(file_string);
-
- return retval;
-}
-
-/** Return the dynamic DH modulus stored in <b>fname</b>. If there is no
- dynamic DH modulus stored in <b>fname</b>, return NULL. */
-static BIGNUM *
-crypto_get_stored_dynamic_dh_modulus(const char *fname)
-{
- int retval;
- char *contents = NULL;
- const char *contents_tmp = NULL;
- int dh_codes;
- DH *stored_dh = NULL;
- BIGNUM *dynamic_dh_modulus = NULL;
- int length = 0;
- unsigned char *base64_decoded_dh = NULL;
- const unsigned char *cp = NULL;
-
- tor_assert(fname);
-
- contents = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
- if (!contents) {
- log_info(LD_CRYPTO, "Could not open file '%s'", fname);
- goto done; /*usually means that ENOENT. don't try to move file to broken.*/
- }
-
- /* skip the file header */
- contents_tmp = eat_whitespace(contents);
- if (!*contents_tmp) {
- log_warn(LD_CRYPTO, "Stored dynamic DH modulus file "
- "seems corrupted (eat_whitespace).");
- goto err;
- }
-
- /* 'fname' contains the DH parameters stored in base64-ed DER
- * format. We are only interested in the DH modulus.
- * NOTE: We allocate more storage here than we need. Since we're already
- * doing that, we can also add 1 byte extra to appease Coverity's
- * scanner. */
-
- cp = base64_decoded_dh = tor_malloc_zero(strlen(contents_tmp) + 1);
- length = base64_decode((char *)base64_decoded_dh, strlen(contents_tmp),
- contents_tmp, strlen(contents_tmp));
- if (length < 0) {
- log_warn(LD_CRYPTO, "Stored dynamic DH modulus seems corrupted (base64).");
- goto err;
- }
-
- stored_dh = d2i_DHparams(NULL, &cp, length);
- if ((!stored_dh) || (cp - base64_decoded_dh != length)) {
- log_warn(LD_CRYPTO, "Stored dynamic DH modulus seems corrupted (d2i).");
- goto err;
- }
-
- { /* check the cryptographic qualities of the stored dynamic DH modulus: */
- retval = DH_check(stored_dh, &dh_codes);
- if (!retval || dh_codes) {
- log_warn(LD_CRYPTO, "Stored dynamic DH modulus is not a safe prime.");
- goto err;
- }
-
- retval = DH_size(stored_dh);
- if (retval < DH_BYTES) {
- log_warn(LD_CRYPTO, "Stored dynamic DH modulus is smaller "
- "than '%d' bits.", DH_BYTES*8);
- goto err;
- }
-
- if (!BN_is_word(stored_dh->g, 2)) {
- log_warn(LD_CRYPTO, "Stored dynamic DH parameters do not use '2' "
- "as the group generator.");
- goto err;
- }
- }
-
- { /* log the dynamic DH modulus: */
- char *s = BN_bn2hex(stored_dh->p);
- tor_assert(s);
- log_info(LD_OR, "Found stored dynamic DH modulus: [%s]", s);
- OPENSSL_free(s);
- }
-
- goto done;
-
- err:
-
- {
- /* move broken prime to $filename.broken */
- char *fname_new=NULL;
- tor_asprintf(&fname_new, "%s.broken", fname);
-
- log_warn(LD_CRYPTO, "Moving broken dynamic DH prime to '%s'.", fname_new);
-
- if (replace_file(fname, fname_new))
- log_notice(LD_CRYPTO, "Error while moving '%s' to '%s'.",
- fname, fname_new);
-
- tor_free(fname_new);
- }
-
- if (stored_dh) {
- DH_free(stored_dh);
- stored_dh = NULL;
- }
-
- done:
- tor_free(contents);
- tor_free(base64_decoded_dh);
-
- if (stored_dh) {
- dynamic_dh_modulus = BN_dup(stored_dh->p);
- DH_free(stored_dh);
- }
-
- return dynamic_dh_modulus;
-}
-
-/** Set the global TLS Diffie-Hellman modulus.
- * If <b>dynamic_dh_modulus_fname</b> is set, try to read a dynamic DH modulus
- * off it and use it as the DH modulus. If that's not possible,
- * generate a new dynamic DH modulus.
- * If <b>dynamic_dh_modulus_fname</b> is NULL, use the Apache mod_ssl DH
+/** Set the global TLS Diffie-Hellman modulus. Use the Apache mod_ssl DH
* modulus. */
void
-crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname)
+crypto_set_tls_dh_prime(void)
{
BIGNUM *tls_prime = NULL;
- int store_dh_prime_afterwards = 0;
int r;
/* If the space is occupied, free the previous TLS DH prime */
@@ -2002,44 +1851,24 @@ crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname)
dh_param_p_tls = NULL;
}
- if (dynamic_dh_modulus_fname) { /* use dynamic DH modulus: */
- log_info(LD_OR, "Using stored dynamic DH modulus.");
- tls_prime = crypto_get_stored_dynamic_dh_modulus(dynamic_dh_modulus_fname);
-
- if (!tls_prime) {
- log_notice(LD_OR, "Generating fresh dynamic DH modulus. "
- "This might take a while...");
- tls_prime = crypto_generate_dynamic_dh_modulus();
-
- store_dh_prime_afterwards++;
- }
- } else { /* use the static DH prime modulus used by Apache in mod_ssl: */
- tls_prime = BN_new();
- tor_assert(tls_prime);
+ tls_prime = BN_new();
+ tor_assert(tls_prime);
- /* This is the 1024-bit safe prime that Apache uses for its DH stuff; see
- * modules/ssl/ssl_engine_dh.c; Apache also uses a generator of 2 with this
- * prime.
- */
- r =BN_hex2bn(&tls_prime,
- "D67DE440CBBBDC1936D693D34AFD0AD50C84D239A45F520BB88174CB98"
- "BCE951849F912E639C72FB13B4B4D7177E16D55AC179BA420B2A29FE324A"
- "467A635E81FF5901377BEDDCFD33168A461AAD3B72DAE8860078045B07A7"
- "DBCA7874087D1510EA9FCC9DDD330507DD62DB88AEAA747DE0F4D6E2BD68"
- "B0E7393E0F24218EB3");
- tor_assert(r);
- }
+ /* This is the 1024-bit safe prime that Apache uses for its DH stuff; see
+ * modules/ssl/ssl_engine_dh.c; Apache also uses a generator of 2 with this
+ * prime.
+ */
+ r = BN_hex2bn(&tls_prime,
+ "D67DE440CBBBDC1936D693D34AFD0AD50C84D239A45F520BB88174CB98"
+ "BCE951849F912E639C72FB13B4B4D7177E16D55AC179BA420B2A29FE324A"
+ "467A635E81FF5901377BEDDCFD33168A461AAD3B72DAE8860078045B07A7"
+ "DBCA7874087D1510EA9FCC9DDD330507DD62DB88AEAA747DE0F4D6E2BD68"
+ "B0E7393E0F24218EB3");
+ tor_assert(r);
tor_assert(tls_prime);
dh_param_p_tls = tls_prime;
-
- if (store_dh_prime_afterwards)
- /* save the new dynamic DH modulus to disk. */
- if (crypto_store_dynamic_dh_modulus(dynamic_dh_modulus_fname)) {
- log_notice(LD_CRYPTO, "Failed while storing dynamic DH modulus. "
- "Make sure your data directory is sane.");
- }
}
/** Initialize dh_param_p and dh_param_g if they are not already
@@ -2076,10 +1905,8 @@ init_dh_param(void)
dh_param_p = circuit_dh_prime;
dh_param_g = generator;
- /* Ensure that we have TLS DH parameters set up, too, even if we're
- going to change them soon. */
if (!dh_param_p_tls) {
- crypto_set_tls_dh_prime(NULL);
+ crypto_set_tls_dh_prime();
}
}
@@ -2548,8 +2375,40 @@ crypto_rand_int(unsigned int max)
}
}
+/** Return a pseudorandom integer, chosen uniformly from the values <i>i</i>
+ * such that <b>min</b> &lt;= <i>i</i> &lt <b>max</b>.
+ *
+ * <b>min</b> MUST be in range [0, <b>max</b>).
+ * <b>max</b> MUST be in range (min, INT_MAX].
+ */
+int
+crypto_rand_int_range(unsigned int min, unsigned int max)
+{
+ tor_assert(min < max);
+ tor_assert(max <= INT_MAX);
+
+ /* The overflow is avoided here because crypto_rand_int() returns a value
+ * between 0 and (max - min) inclusive. */
+ return min + crypto_rand_int(max - min);
+}
+
+/** As crypto_rand_int_range, but supports uint64_t. */
+uint64_t
+crypto_rand_uint64_range(uint64_t min, uint64_t max)
+{
+ tor_assert(min < max);
+ return min + crypto_rand_uint64(max - min);
+}
+
+/** As crypto_rand_int_range, but supports time_t. */
+time_t
+crypto_rand_time_range(time_t min, time_t max)
+{
+ return (time_t) crypto_rand_uint64_range(min, max);
+}
+
/** Return a pseudorandom 64-bit integer, chosen uniformly from the values
- * between 0 and <b>max</b>-1. */
+ * between 0 and <b>max</b>-1 inclusive. */
uint64_t
crypto_rand_uint64(uint64_t max)
{
@@ -2610,7 +2469,7 @@ crypto_random_hostname(int min_rand_len, int max_rand_len, const char *prefix,
if (min_rand_len > max_rand_len)
min_rand_len = max_rand_len;
- randlen = min_rand_len + crypto_rand_int(max_rand_len - min_rand_len + 1);
+ randlen = crypto_rand_int_range(min_rand_len, max_rand_len+1);
prefixlen = strlen(prefix);
resultlen = prefixlen + strlen(suffix) + randlen + 16;
@@ -2657,36 +2516,163 @@ smartlist_shuffle(smartlist_t *sl)
}
}
+#define BASE64_OPENSSL_LINELEN 64
+
+/** Return the Base64 encoded size of <b>srclen</b> bytes of data in
+ * bytes.
+ *
+ * If <b>flags</b>&amp;BASE64_ENCODE_MULTILINE is true, return the size
+ * of the encoded output as multiline output (64 character, `\n' terminated
+ * lines).
+ */
+size_t
+base64_encode_size(size_t srclen, int flags)
+{
+ size_t enclen;
+ tor_assert(srclen < INT_MAX);
+
+ if (srclen == 0)
+ return 0;
+
+ enclen = ((srclen - 1) / 3) * 4 + 4;
+ if (flags & BASE64_ENCODE_MULTILINE) {
+ size_t remainder = enclen % BASE64_OPENSSL_LINELEN;
+ enclen += enclen / BASE64_OPENSSL_LINELEN;
+ if (remainder)
+ enclen++;
+ }
+ tor_assert(enclen < INT_MAX && enclen > srclen);
+ return enclen;
+}
+
+/** Internal table mapping 6 bit values to the Base64 alphabet. */
+static const char base64_encode_table[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/'
+};
+
/** Base64 encode <b>srclen</b> bytes of data from <b>src</b>. Write
* the result into <b>dest</b>, if it will fit within <b>destlen</b>
- * bytes. Return the number of bytes written on success; -1 if
+ * bytes. Return the number of bytes written on success; -1 if
* destlen is too short, or other failure.
+ *
+ * If <b>flags</b>&amp;BASE64_ENCODE_MULTILINE is true, return encoded
+ * output in multiline format (64 character, `\n' terminated lines).
*/
int
-base64_encode(char *dest, size_t destlen, const char *src, size_t srclen)
-{
- /* FFFF we might want to rewrite this along the lines of base64_decode, if
- * it ever shows up in the profile. */
- EVP_ENCODE_CTX ctx;
- int len, ret;
- tor_assert(srclen < INT_MAX);
+base64_encode(char *dest, size_t destlen, const char *src, size_t srclen,
+ int flags)
+{
+ const unsigned char *usrc = (unsigned char *)src;
+ const unsigned char *eous = usrc + srclen;
+ char *d = dest;
+ uint32_t n = 0;
+ size_t linelen = 0;
+ size_t enclen;
+ int n_idx = 0;
+
+ if (!src || !dest)
+ return -1;
- /* 48 bytes of input -> 64 bytes of output plus newline.
- Plus one more byte, in case I'm wrong.
- */
- if (destlen < ((srclen/48)+1)*66)
+ /* Ensure that there is sufficient space, including the NUL. */
+ enclen = base64_encode_size(srclen, flags);
+ if (destlen < enclen + 1)
return -1;
if (destlen > SIZE_T_CEILING)
return -1;
+ if (enclen > INT_MAX)
+ return -1;
- EVP_EncodeInit(&ctx);
- EVP_EncodeUpdate(&ctx, (unsigned char*)dest, &len,
- (unsigned char*)src, (int)srclen);
- EVP_EncodeFinal(&ctx, (unsigned char*)(dest+len), &ret);
- ret += len;
- return ret;
+ memset(dest, 0, enclen);
+
+ /* XXX/Yawning: If this ends up being too slow, this can be sped up
+ * by separating the multiline format case and the normal case, and
+ * processing 48 bytes of input at a time when newlines are desired.
+ */
+#define ENCODE_CHAR(ch) \
+ STMT_BEGIN \
+ *d++ = ch; \
+ if (flags & BASE64_ENCODE_MULTILINE) { \
+ if (++linelen % BASE64_OPENSSL_LINELEN == 0) { \
+ linelen = 0; \
+ *d++ = '\n'; \
+ } \
+ } \
+ STMT_END
+
+#define ENCODE_N(idx) \
+ ENCODE_CHAR(base64_encode_table[(n >> ((3 - idx) * 6)) & 0x3f])
+
+#define ENCODE_PAD() ENCODE_CHAR('=')
+
+ /* Iterate over all the bytes in src. Each one will add 8 bits to the
+ * value we're encoding. Accumulate bits in <b>n</b>, and whenever we
+ * have 24 bits, batch them into 4 bytes and flush those bytes to dest.
+ */
+ for ( ; usrc < eous; ++usrc) {
+ n = (n << 8) | *usrc;
+ if ((++n_idx) == 3) {
+ ENCODE_N(0);
+ ENCODE_N(1);
+ ENCODE_N(2);
+ ENCODE_N(3);
+ n_idx = 0;
+ n = 0;
+ }
+ }
+ switch (n_idx) {
+ case 0:
+ /* 0 leftover bits, no pading to add. */
+ break;
+ case 1:
+ /* 8 leftover bits, pad to 12 bits, write the 2 6-bit values followed
+ * by 2 padding characters.
+ */
+ n <<= 4;
+ ENCODE_N(2);
+ ENCODE_N(3);
+ ENCODE_PAD();
+ ENCODE_PAD();
+ break;
+ case 2:
+ /* 16 leftover bits, pad to 18 bits, write the 3 6-bit values followed
+ * by 1 padding character.
+ */
+ n <<= 2;
+ ENCODE_N(1);
+ ENCODE_N(2);
+ ENCODE_N(3);
+ ENCODE_PAD();
+ break;
+ default:
+ /* Something went catastrophically wrong. */
+ tor_fragile_assert();
+ return -1;
+ }
+
+#undef ENCODE_N
+#undef ENCODE_PAD
+#undef ENCODE_CHAR
+
+ /* Multiline output always includes at least one newline. */
+ if (flags & BASE64_ENCODE_MULTILINE && linelen != 0)
+ *d++ = '\n';
+
+ tor_assert(d - dest == (ptrdiff_t)enclen);
+
+ *d++ = '\0'; /* NUL terminate the output. */
+
+ return (int) enclen;
}
+#undef BASE64_OPENSSL_LINELEN
+
/** @{ */
/** Special values used for the base64_decode_table */
#define X 255
@@ -2731,26 +2717,6 @@ static const uint8_t base64_decode_table[256] = {
int
base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
{
-#ifdef USE_OPENSSL_BASE64
- EVP_ENCODE_CTX ctx;
- int len, ret;
- /* 64 bytes of input -> *up to* 48 bytes of output.
- Plus one more byte, in case I'm wrong.
- */
- if (destlen < ((srclen/64)+1)*49)
- return -1;
- if (destlen > SIZE_T_CEILING)
- return -1;
-
- memset(dest, 0, destlen);
-
- EVP_DecodeInit(&ctx);
- EVP_DecodeUpdate(&ctx, (unsigned char*)dest, &len,
- (unsigned char*)src, srclen);
- EVP_DecodeFinal(&ctx, (unsigned char*)dest, &ret);
- ret += len;
- return ret;
-#else
const char *eos = src+srclen;
uint32_t n=0;
int n_idx=0;
@@ -2821,20 +2787,19 @@ base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
tor_assert((dest-dest_orig) <= INT_MAX);
return (int)(dest-dest_orig);
-#endif
}
#undef X
#undef SP
#undef PAD
/** Base64 encode DIGEST_LINE bytes from <b>digest</b>, remove the trailing =
- * and newline characters, and store the nul-terminated result in the first
+ * characters, and store the nul-terminated result in the first
* BASE64_DIGEST_LEN+1 bytes of <b>d64</b>. */
int
digest_to_base64(char *d64, const char *digest)
{
char buf[256];
- base64_encode(buf, sizeof(buf), digest, DIGEST_LEN);
+ base64_encode(buf, sizeof(buf), digest, DIGEST_LEN, 0);
buf[BASE64_DIGEST_LEN] = '\0';
memcpy(d64, buf, BASE64_DIGEST_LEN+1);
return 0;
@@ -2846,33 +2811,20 @@ digest_to_base64(char *d64, const char *digest)
int
digest_from_base64(char *digest, const char *d64)
{
-#ifdef USE_OPENSSL_BASE64
- char buf_in[BASE64_DIGEST_LEN+3];
- char buf[256];
- if (strlen(d64) != BASE64_DIGEST_LEN)
- return -1;
- memcpy(buf_in, d64, BASE64_DIGEST_LEN);
- memcpy(buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
- if (base64_decode(buf, sizeof(buf), buf_in, strlen(buf_in)) != DIGEST_LEN)
- return -1;
- memcpy(digest, buf, DIGEST_LEN);
- return 0;
-#else
if (base64_decode(digest, DIGEST_LEN, d64, strlen(d64)) == DIGEST_LEN)
return 0;
else
return -1;
-#endif
}
/** Base64 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>. */
+ * trailing = 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);
+ base64_encode(buf, sizeof(buf), digest, DIGEST256_LEN, 0);
buf[BASE64_DIGEST256_LEN] = '\0';
memcpy(d64, buf, BASE64_DIGEST256_LEN+1);
return 0;
@@ -2884,23 +2836,10 @@ digest256_to_base64(char *d64, const char *digest)
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 RFC 4648. Limitation: Requires