Loading src/common/crypto.c +81 −1 Original line number Diff line number Diff line Loading @@ -1724,7 +1724,24 @@ crypto_digest_assign(crypto_digest_t *into, * <b>out_len</b> must be \<= DIGEST256_LEN. */ void crypto_digest_smartlist(char *digest_out, size_t len_out, const smartlist_t *lst, const char *append, const smartlist_t *lst, const char *append, digest_algorithm_t alg) { crypto_digest_smartlist_prefix(digest_out, len_out, NULL, lst, append, alg); } /** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest * at <b>digest_out</b> to the hash of the concatenation of: the * optional string <b>prepend</b>, those strings, * and the optional string <b>append</b>, computed with the algorithm * <b>alg</b>. * <b>out_len</b> must be \<= DIGEST256_LEN. */ void crypto_digest_smartlist_prefix(char *digest_out, size_t len_out, const char *prepend, const smartlist_t *lst, const char *append, digest_algorithm_t alg) { crypto_digest_t *d; Loading @@ -1732,6 +1749,8 @@ crypto_digest_smartlist(char *digest_out, size_t len_out, d = crypto_digest_new(); else d = crypto_digest256_new(alg); if (prepend) crypto_digest_add_bytes(d, prepend, strlen(prepend)); SMARTLIST_FOREACH(lst, const char *, cp, crypto_digest_add_bytes(d, cp, strlen(cp))); if (append) Loading Loading @@ -2692,6 +2711,8 @@ base64_encode(char *dest, size_t destlen, const char *src, size_t srclen) return -1; if (destlen > SIZE_T_CEILING) return -1; if (destlen) *dest = 0; /* Ensure we always initialize the buffer */ EVP_EncodeInit(&ctx); EVP_EncodeUpdate(&ctx, (unsigned char*)dest, &len, Loading @@ -2701,6 +2722,65 @@ base64_encode(char *dest, size_t destlen, const char *src, size_t srclen) return ret; } /** As base64_encode, but do not add any internal spaces or external padding * to the output stream. */ int base64_encode_nopad(char *dest, size_t destlen, const uint8_t *src, size_t srclen) { int n = base64_encode(dest, destlen, (const char*) src, srclen); if (n <= 0) return n; tor_assert((size_t)n < destlen && dest[n] == 0); char *in, *out; in = out = dest; while (*in) { if (*in == '=' || *in == '\n') { ++in; } else { *out++ = *in++; } } *out = 0; tor_assert(out - dest <= INT_MAX); return (int)(out - dest); } /** As base64_decode, but do not require any padding on the input */ int base64_decode_nopad(uint8_t *dest, size_t destlen, const char *src, size_t srclen) { if (srclen > SIZE_T_CEILING - 4) return -1; char *buf = tor_malloc(srclen + 4); memcpy(buf, src, srclen+1); size_t buflen; switch (srclen % 4) { case 0: default: buflen = srclen; break; case 1: tor_free(buf); return -1; case 2: memcpy(buf+srclen, "==", 3); buflen = srclen + 2; break; case 3: memcpy(buf+srclen, "=", 2); buflen = srclen + 1; break; } int n = base64_decode((char*)dest, destlen, buf, buflen); tor_free(buf); return n; } /** @{ */ /** Special values used for the base64_decode_table */ #define X 255 Loading src/common/crypto.h +10 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,11 @@ int crypto_digest256(char *digest, const char *m, size_t len, digest_algorithm_t algorithm); int crypto_digest_all(digests_t *ds_out, const char *m, size_t len); struct smartlist_t; void crypto_digest_smartlist_prefix(char *digest_out, size_t len_out, const char *prepend, const struct smartlist_t *lst, const char *append, digest_algorithm_t alg); void crypto_digest_smartlist(char *digest_out, size_t len_out, const struct smartlist_t *lst, const char *append, digest_algorithm_t alg); Loading Loading @@ -270,6 +275,11 @@ void smartlist_shuffle(struct smartlist_t *sl); int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen); int base64_encode_nopad(char *dest, size_t destlen, const uint8_t *src, size_t srclen); int base64_decode_nopad(uint8_t *dest, size_t destlen, const char *src, size_t srclen); /** Characters that can appear (case-insensitively) in a base32 encoding. */ #define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen); Loading src/common/crypto_ed25519.c +11 −0 Original line number Diff line number Diff line Loading @@ -351,6 +351,7 @@ ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, return 0; } /** Release all storage held for <b>kp</b>. */ void ed25519_keypair_free(ed25519_keypair_t *kp) { Loading @@ -361,3 +362,13 @@ ed25519_keypair_free(ed25519_keypair_t *kp) tor_free(kp); } /** Return true iff <b>key1</b> and <b>key2</b> are the same public key. */ int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2) { tor_assert(key1); tor_assert(key2); return tor_memeq(key1->pubkey, key2->pubkey, ED25519_PUBKEY_LEN); } src/common/crypto_ed25519.h +10 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,13 @@ int ed25519_public_from_base64(ed25519_public_key_t *pkey, int ed25519_public_to_base64(char *output, const ed25519_public_key_t *pkey); #define ED25519_SIG_BASE64_LEN 86 int ed25519_signature_from_base64(ed25519_signature_t *sig, const char *input); int ed25519_signature_to_base64(char *output, const ed25519_signature_t *sig); /* XXXX read encrypted, write encrypted. */ int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, Loading @@ -112,5 +119,8 @@ int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, void ed25519_keypair_free(ed25519_keypair_t *kp); int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2); #endif src/common/crypto_format.c +39 −0 Original line number Diff line number Diff line Loading @@ -65,3 +65,42 @@ ed25519_public_to_base64(char *output, return digest256_to_base64(output, (const char *)pkey->pubkey); } /** Encode the signature <b>sig</b> into the buffer at <b>output</b>, * which must have space for ED25519_SIG_BASE64_LEN bytes of encoded signature, * plus one byte for a terminating NUL. Return 0 on success, -1 on failure. */ int ed25519_signature_to_base64(char *output, const ed25519_signature_t *sig) { char buf[256]; int n = base64_encode_nopad(buf, sizeof(buf), sig->sig, ED25519_SIG_LEN); tor_assert(n == ED25519_SIG_BASE64_LEN); memcpy(output, buf, ED25519_SIG_BASE64_LEN+1); return 0; } /** Try to decode the string <b>input</b> into an ed25519 signature. On * success, store the value in <b>sig</b> and return 0. Otherwise return * -1. */ int ed25519_signature_from_base64(ed25519_signature_t *sig, const char *input) { if (strlen(input) != ED25519_SIG_BASE64_LEN) return -1; char buf[ED25519_SIG_BASE64_LEN+3]; memcpy(buf, input, ED25519_SIG_BASE64_LEN); buf[ED25519_SIG_BASE64_LEN+0] = '='; buf[ED25519_SIG_BASE64_LEN+1] = '='; buf[ED25519_SIG_BASE64_LEN+2] = 0; char decoded[128]; int n = base64_decode(decoded, sizeof(decoded), buf, strlen(buf)); if (n < 0 || n != ED25519_SIG_LEN) return -1; memcpy(sig->sig, decoded, ED25519_SIG_LEN); return 0; } Loading
src/common/crypto.c +81 −1 Original line number Diff line number Diff line Loading @@ -1724,7 +1724,24 @@ crypto_digest_assign(crypto_digest_t *into, * <b>out_len</b> must be \<= DIGEST256_LEN. */ void crypto_digest_smartlist(char *digest_out, size_t len_out, const smartlist_t *lst, const char *append, const smartlist_t *lst, const char *append, digest_algorithm_t alg) { crypto_digest_smartlist_prefix(digest_out, len_out, NULL, lst, append, alg); } /** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest * at <b>digest_out</b> to the hash of the concatenation of: the * optional string <b>prepend</b>, those strings, * and the optional string <b>append</b>, computed with the algorithm * <b>alg</b>. * <b>out_len</b> must be \<= DIGEST256_LEN. */ void crypto_digest_smartlist_prefix(char *digest_out, size_t len_out, const char *prepend, const smartlist_t *lst, const char *append, digest_algorithm_t alg) { crypto_digest_t *d; Loading @@ -1732,6 +1749,8 @@ crypto_digest_smartlist(char *digest_out, size_t len_out, d = crypto_digest_new(); else d = crypto_digest256_new(alg); if (prepend) crypto_digest_add_bytes(d, prepend, strlen(prepend)); SMARTLIST_FOREACH(lst, const char *, cp, crypto_digest_add_bytes(d, cp, strlen(cp))); if (append) Loading Loading @@ -2692,6 +2711,8 @@ base64_encode(char *dest, size_t destlen, const char *src, size_t srclen) return -1; if (destlen > SIZE_T_CEILING) return -1; if (destlen) *dest = 0; /* Ensure we always initialize the buffer */ EVP_EncodeInit(&ctx); EVP_EncodeUpdate(&ctx, (unsigned char*)dest, &len, Loading @@ -2701,6 +2722,65 @@ base64_encode(char *dest, size_t destlen, const char *src, size_t srclen) return ret; } /** As base64_encode, but do not add any internal spaces or external padding * to the output stream. */ int base64_encode_nopad(char *dest, size_t destlen, const uint8_t *src, size_t srclen) { int n = base64_encode(dest, destlen, (const char*) src, srclen); if (n <= 0) return n; tor_assert((size_t)n < destlen && dest[n] == 0); char *in, *out; in = out = dest; while (*in) { if (*in == '=' || *in == '\n') { ++in; } else { *out++ = *in++; } } *out = 0; tor_assert(out - dest <= INT_MAX); return (int)(out - dest); } /** As base64_decode, but do not require any padding on the input */ int base64_decode_nopad(uint8_t *dest, size_t destlen, const char *src, size_t srclen) { if (srclen > SIZE_T_CEILING - 4) return -1; char *buf = tor_malloc(srclen + 4); memcpy(buf, src, srclen+1); size_t buflen; switch (srclen % 4) { case 0: default: buflen = srclen; break; case 1: tor_free(buf); return -1; case 2: memcpy(buf+srclen, "==", 3); buflen = srclen + 2; break; case 3: memcpy(buf+srclen, "=", 2); buflen = srclen + 1; break; } int n = base64_decode((char*)dest, destlen, buf, buflen); tor_free(buf); return n; } /** @{ */ /** Special values used for the base64_decode_table */ #define X 255 Loading
src/common/crypto.h +10 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,11 @@ int crypto_digest256(char *digest, const char *m, size_t len, digest_algorithm_t algorithm); int crypto_digest_all(digests_t *ds_out, const char *m, size_t len); struct smartlist_t; void crypto_digest_smartlist_prefix(char *digest_out, size_t len_out, const char *prepend, const struct smartlist_t *lst, const char *append, digest_algorithm_t alg); void crypto_digest_smartlist(char *digest_out, size_t len_out, const struct smartlist_t *lst, const char *append, digest_algorithm_t alg); Loading Loading @@ -270,6 +275,11 @@ void smartlist_shuffle(struct smartlist_t *sl); int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen); int base64_encode_nopad(char *dest, size_t destlen, const uint8_t *src, size_t srclen); int base64_decode_nopad(uint8_t *dest, size_t destlen, const char *src, size_t srclen); /** Characters that can appear (case-insensitively) in a base32 encoding. */ #define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen); Loading
src/common/crypto_ed25519.c +11 −0 Original line number Diff line number Diff line Loading @@ -351,6 +351,7 @@ ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, return 0; } /** Release all storage held for <b>kp</b>. */ void ed25519_keypair_free(ed25519_keypair_t *kp) { Loading @@ -361,3 +362,13 @@ ed25519_keypair_free(ed25519_keypair_t *kp) tor_free(kp); } /** Return true iff <b>key1</b> and <b>key2</b> are the same public key. */ int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2) { tor_assert(key1); tor_assert(key2); return tor_memeq(key1->pubkey, key2->pubkey, ED25519_PUBKEY_LEN); }
src/common/crypto_ed25519.h +10 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,13 @@ int ed25519_public_from_base64(ed25519_public_key_t *pkey, int ed25519_public_to_base64(char *output, const ed25519_public_key_t *pkey); #define ED25519_SIG_BASE64_LEN 86 int ed25519_signature_from_base64(ed25519_signature_t *sig, const char *input); int ed25519_signature_to_base64(char *output, const ed25519_signature_t *sig); /* XXXX read encrypted, write encrypted. */ int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, Loading @@ -112,5 +119,8 @@ int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, void ed25519_keypair_free(ed25519_keypair_t *kp); int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2); #endif
src/common/crypto_format.c +39 −0 Original line number Diff line number Diff line Loading @@ -65,3 +65,42 @@ ed25519_public_to_base64(char *output, return digest256_to_base64(output, (const char *)pkey->pubkey); } /** Encode the signature <b>sig</b> into the buffer at <b>output</b>, * which must have space for ED25519_SIG_BASE64_LEN bytes of encoded signature, * plus one byte for a terminating NUL. Return 0 on success, -1 on failure. */ int ed25519_signature_to_base64(char *output, const ed25519_signature_t *sig) { char buf[256]; int n = base64_encode_nopad(buf, sizeof(buf), sig->sig, ED25519_SIG_LEN); tor_assert(n == ED25519_SIG_BASE64_LEN); memcpy(output, buf, ED25519_SIG_BASE64_LEN+1); return 0; } /** Try to decode the string <b>input</b> into an ed25519 signature. On * success, store the value in <b>sig</b> and return 0. Otherwise return * -1. */ int ed25519_signature_from_base64(ed25519_signature_t *sig, const char *input) { if (strlen(input) != ED25519_SIG_BASE64_LEN) return -1; char buf[ED25519_SIG_BASE64_LEN+3]; memcpy(buf, input, ED25519_SIG_BASE64_LEN); buf[ED25519_SIG_BASE64_LEN+0] = '='; buf[ED25519_SIG_BASE64_LEN+1] = '='; buf[ED25519_SIG_BASE64_LEN+2] = 0; char decoded[128]; int n = base64_decode(decoded, sizeof(decoded), buf, strlen(buf)); if (n < 0 || n != ED25519_SIG_LEN) return -1; memcpy(sig->sig, decoded, ED25519_SIG_LEN); return 0; }