summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-09-16 17:01:01 -0400
committerNick Mathewson <nickm@torproject.org>2009-10-15 15:17:13 -0400
commit3b2fc659a8ef83feedadcda32de49db06b80af10 (patch)
tree9df2972d2278f44f8e4fcfa6396aa45cc0d2e6db /src/common
parente1ddee8bbe724e934fe9a4cb2d290719a7d6105c (diff)
downloadtor-3b2fc659a8ef83feedadcda32de49db06b80af10.tar.gz
tor-3b2fc659a8ef83feedadcda32de49db06b80af10.zip
Refactor consensus signature storage for multiple digests and flavors.
This patch introduces a new type called document_signature_t to represent the signature of a consensus document. Now, each consensus document can have up to one document signature per voter per digest algorithm. Also, each detached-signatures document can have up to one signature per <voter, algorithm, flavor>.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/crypto.c33
-rw-r--r--src/common/crypto.h21
2 files changed, 51 insertions, 3 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 21c8aed2d4..ac0e628c48 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1448,6 +1448,39 @@ crypto_digest256(char *digest, const char *m, size_t len,
return (SHA256((const unsigned char*)m,len,(unsigned char*)digest) == NULL);
}
+/** Set the digests_t in <b>ds_out</b> to contain every digest on the
+ * <b>len</b> bytes in <b>m</b> that we know how to compute. Return 0 on
+ * success, -1 on failure. */
+int
+crypto_digest_all(digests_t *ds_out, const char *m, size_t len)
+{
+ digest_algorithm_t i;
+ tor_assert(ds_out);
+ memset(ds_out, 0, sizeof(*ds_out));
+ if (crypto_digest(ds_out->d[DIGEST_SHA1], m, len) < 0)
+ return -1;
+ for (i = DIGEST_SHA256; i < N_DIGEST_ALGORITHMS; ++i) {
+ if (crypto_digest256(ds_out->d[i], m, len, i) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+/** Return the name of an algorithm, as used in directory documents. */
+const char *
+crypto_digest_algorithm_get_name(digest_algorithm_t alg)
+{
+ switch (alg) {
+ case DIGEST_SHA1:
+ return "sha1";
+ case DIGEST_SHA256:
+ return "sha256";
+ default:
+ tor_fragile_assert();
+ return "??unknown_digest??";
+ }
+}
+
/** Intermediate information about the digest of a stream of data. */
struct crypto_digest_env_t {
union {
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 63ea96d056..ed8468046f 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -58,9 +58,22 @@
#define HEX_DIGEST256_LEN 64
typedef enum {
- DIGEST_SHA1,
- DIGEST_SHA256,
+ DIGEST_SHA1 = 0,
+ DIGEST_SHA256 = 1,
} digest_algorithm_t;
+#define N_DIGEST_ALGORITHMS (DIGEST_SHA256+1)
+
+/** A set of all the digests we know how to compute, taken on a single
+ * string. Any digests that are shorter than 256 bits are right-padded
+ * with 0 bits.
+ *
+ * Note that this representation wastes 12 bytes for the SHA1 case, so
+ * don't use it for anything where we need to allocate a whole bunch at
+ * once.
+ **/
+typedef struct {
+ char d[N_DIGEST_ALGORITHMS][DIGEST256_LEN];
+} digests_t;
typedef struct crypto_pk_env_t crypto_pk_env_t;
typedef struct crypto_cipher_env_t crypto_cipher_env_t;
@@ -158,10 +171,12 @@ int crypto_cipher_decrypt_with_iv(crypto_cipher_env_t *env,
char *to, size_t tolen,
const char *from, size_t fromlen);
-/* SHA-1 */
+/* SHA-1 and other digests. */
int crypto_digest(char *digest, const char *m, size_t len);
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);
+const char *crypto_digest_algorithm_get_name(digest_algorithm_t alg);
crypto_digest_env_t *crypto_new_digest_env(void);
crypto_digest_env_t *crypto_new_digest256_env(digest_algorithm_t algorithm);
void crypto_free_digest_env(crypto_digest_env_t *digest);