tor  0.4.1.0-alpha-dev
sigcommon.c
Go to the documentation of this file.
1 /* Copyright (c) 2001 Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
13 #define SIGCOMMON_PRIVATE
14 
15 #include "core/or/or.h"
18 
26 int
27 router_get_hash_impl_helper(const char *s, size_t s_len,
28  const char *start_str,
29  const char *end_str, char end_c,
30  int log_severity,
31  const char **start_out, const char **end_out)
32 {
33  const char *start, *end;
34  start = tor_memstr(s, s_len, start_str);
35  if (!start) {
36  log_fn(log_severity,LD_DIR,
37  "couldn't find start of hashed material \"%s\"",start_str);
38  return -1;
39  }
40  if (start != s && *(start-1) != '\n') {
41  log_fn(log_severity,LD_DIR,
42  "first occurrence of \"%s\" is not at the start of a line",
43  start_str);
44  return -1;
45  }
46  end = tor_memstr(start+strlen(start_str),
47  s_len - (start-s) - strlen(start_str), end_str);
48  if (!end) {
49  log_fn(log_severity,LD_DIR,
50  "couldn't find end of hashed material \"%s\"",end_str);
51  return -1;
52  }
53  end = memchr(end+strlen(end_str), end_c, s_len - (end-s) - strlen(end_str));
54  if (!end) {
55  log_fn(log_severity,LD_DIR,
56  "couldn't find EOL");
57  return -1;
58  }
59  ++end;
60 
61  *start_out = start;
62  *end_out = end;
63  return 0;
64 }
65 
73 int
74 router_get_hash_impl(const char *s, size_t s_len, char *digest,
75  const char *start_str,
76  const char *end_str, char end_c,
77  digest_algorithm_t alg)
78 {
79  const char *start=NULL, *end=NULL;
80  if (router_get_hash_impl_helper(s,s_len,start_str,end_str,end_c,LOG_WARN,
81  &start,&end)<0)
82  return -1;
83 
84  return router_compute_hash_final(digest, start, end-start, alg);
85 }
86 
90 MOCK_IMPL(STATIC int,
91 router_compute_hash_final,(char *digest,
92  const char *start, size_t len,
93  digest_algorithm_t alg))
94 {
95  if (alg == DIGEST_SHA1) {
96  if (crypto_digest(digest, start, len) < 0) {
97  log_warn(LD_BUG,"couldn't compute digest");
98  return -1;
99  }
100  } else {
101  if (crypto_digest256(digest, start, len, alg) < 0) {
102  log_warn(LD_BUG,"couldn't compute digest");
103  return -1;
104  }
105  }
106 
107  return 0;
108 }
109 
111 int
112 router_get_hashes_impl(const char *s, size_t s_len, common_digests_t *digests,
113  const char *start_str,
114  const char *end_str, char end_c)
115 {
116  const char *start=NULL, *end=NULL;
117  if (router_get_hash_impl_helper(s,s_len,start_str,end_str,end_c,LOG_WARN,
118  &start,&end)<0)
119  return -1;
120 
121  if (crypto_common_digests(digests, start, end-start)) {
122  log_warn(LD_BUG,"couldn't compute digests");
123  return -1;
124  }
125 
126  return 0;
127 }
128 
129 MOCK_IMPL(STATIC int,
130 signed_digest_equals, (const uint8_t *d1, const uint8_t *d2, size_t len))
131 {
132  return tor_memeq(d1, d2, len);
133 }
134 
142 int
143 check_signature_token(const char *digest,
144  ssize_t digest_len,
145  directory_token_t *tok,
146  crypto_pk_t *pkey,
147  int flags,
148  const char *doctype)
149 {
150  char *signed_digest;
151  size_t keysize;
152  const int check_objtype = ! (flags & CST_NO_CHECK_OBJTYPE);
153 
154  tor_assert(pkey);
155  tor_assert(tok);
156  tor_assert(digest);
157  tor_assert(doctype);
158 
159  if (check_objtype) {
160  if (strcmp(tok->object_type, "SIGNATURE")) {
161  log_warn(LD_DIR, "Bad object type on %s signature", doctype);
162  return -1;
163  }
164  }
165 
166  keysize = crypto_pk_keysize(pkey);
167  signed_digest = tor_malloc(keysize);
168  if (crypto_pk_public_checksig(pkey, signed_digest, keysize,
169  tok->object_body, tok->object_size)
170  < digest_len) {
171  log_warn(LD_DIR, "Error reading %s: invalid signature.", doctype);
172  tor_free(signed_digest);
173  return -1;
174  }
175  // log_debug(LD_DIR,"Signed %s hash starts %s", doctype,
176  // hex_str(signed_digest,4));
177  if (! signed_digest_equals((const uint8_t *)digest,
178  (const uint8_t *)signed_digest, digest_len)) {
179  log_warn(LD_DIR, "Error reading %s: signature does not match.", doctype);
180  tor_free(signed_digest);
181  return -1;
182  }
183  tor_free(signed_digest);
184  return 0;
185 }
int router_get_hash_impl_helper(const char *s, size_t s_len, const char *start_str, const char *end_str, char end_c, int log_severity, const char **start_out, const char **end_out)
Definition: sigcommon.c:27
#define tor_free(p)
Definition: malloc.h:52
int crypto_digest256(char *digest, const char *m, size_t len, digest_algorithm_t algorithm)
MOCK_IMPL(STATIC int, router_compute_hash_final,(char *digest, const char *start, size_t len, digest_algorithm_t alg))
Definition: sigcommon.c:90
int crypto_common_digests(common_digests_t *ds_out, const char *m, size_t len)
tor_assert(buffer)
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
Master header file for Tor-specific functionality.
#define LOG_WARN
Definition: log.h:49
#define LD_DIR
Definition: log.h:84
Header file for parsecommon.c.
#define log_fn(severity, domain, args,...)
Definition: log.h:255
size_t crypto_pk_keysize(const crypto_pk_t *env)
int router_get_hashes_impl(const char *s, size_t s_len, common_digests_t *digests, const char *start_str, const char *end_str, char end_c)
Definition: sigcommon.c:112
int router_get_hash_impl(const char *s, size_t s_len, char *digest, const char *start_str, const char *end_str, char end_c, digest_algorithm_t alg)
Definition: sigcommon.c:74
int check_signature_token(const char *digest, ssize_t digest_len, directory_token_t *tok, crypto_pk_t *pkey, int flags, const char *doctype)
Definition: sigcommon.c:143
Header file for sigcommon.c.
#define LD_BUG
Definition: log.h:82