shared_random.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* Copyright (c) 2016, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file shared_random.c
  5. *
  6. * \brief Functions and data structure needed to accomplish the shared
  7. * random protocol as defined in proposal #250.
  8. **/
  9. #define SHARED_RANDOM_PRIVATE
  10. #include "or.h"
  11. #include "shared_random.h"
  12. #include "config.h"
  13. #include "confparse.h"
  14. #include "networkstatus.h"
  15. #include "routerkeys.h"
  16. #include "router.h"
  17. #include "routerlist.h"
  18. #include "shared_random_state.h"
  19. /* Allocate a new commit object and initializing it with <b>identity</b>
  20. * that MUST be provided. The digest algorithm is set to the default one
  21. * that is supported. The rest is uninitialized. This never returns NULL. */
  22. static sr_commit_t *
  23. commit_new(const char *rsa_identity_fpr)
  24. {
  25. sr_commit_t *commit;
  26. tor_assert(rsa_identity_fpr);
  27. commit = tor_malloc_zero(sizeof(*commit));
  28. commit->alg = SR_DIGEST_ALG;
  29. strlcpy(commit->rsa_identity_fpr, rsa_identity_fpr,
  30. sizeof(commit->rsa_identity_fpr));
  31. return commit;
  32. }
  33. /* Parse the encoded commit. The format is:
  34. * base64-encode( TIMESTAMP || H(REVEAL) )
  35. *
  36. * If successfully decoded and parsed, commit is updated and 0 is returned.
  37. * On error, return -1. */
  38. STATIC int
  39. commit_decode(const char *encoded, sr_commit_t *commit)
  40. {
  41. int decoded_len = 0;
  42. size_t offset = 0;
  43. /* XXX: Needs two extra bytes for the base64 decode calculation matches
  44. * the binary length once decoded. #17868. */
  45. char b64_decoded[SR_COMMIT_LEN + 2];
  46. tor_assert(encoded);
  47. tor_assert(commit);
  48. if (strlen(encoded) > SR_COMMIT_BASE64_LEN) {
  49. /* This means that if we base64 decode successfully the reveiced commit,
  50. * we'll end up with a bigger decoded commit thus unusable. */
  51. goto error;
  52. }
  53. /* Decode our encoded commit. Let's be careful here since _encoded_ is
  54. * coming from the network in a dirauth vote so we expect nothing more
  55. * than the base64 encoded length of a commit. */
  56. decoded_len = base64_decode(b64_decoded, sizeof(b64_decoded),
  57. encoded, strlen(encoded));
  58. if (decoded_len < 0) {
  59. log_warn(LD_BUG, "SR: Commit from authority %s can't be decoded.",
  60. commit->rsa_identity_fpr);
  61. goto error;
  62. }
  63. if (decoded_len != SR_COMMIT_LEN) {
  64. log_warn(LD_BUG, "SR: Commit from authority %s decoded length doesn't "
  65. "match the expected length (%d vs %d).",
  66. commit->rsa_identity_fpr, decoded_len, SR_COMMIT_LEN);
  67. goto error;
  68. }
  69. /* First is the timestamp (8 bytes). */
  70. commit->commit_ts = (time_t) tor_ntohll(get_uint64(b64_decoded));
  71. offset += sizeof(uint64_t);
  72. /* Next is hashed reveal. */
  73. memcpy(commit->hashed_reveal, b64_decoded + offset,
  74. sizeof(commit->hashed_reveal));
  75. /* Copy the base64 blob to the commit. Useful for voting. */
  76. strlcpy(commit->encoded_commit, encoded, sizeof(commit->encoded_commit));
  77. return 0;
  78. error:
  79. return -1;
  80. }
  81. /* Parse the b64 blob at <b>encoded</b> containing reveal information and
  82. * store the information in-place in <b>commit</b>. Return 0 on success else
  83. * a negative value. */
  84. STATIC int
  85. reveal_decode(const char *encoded, sr_commit_t *commit)
  86. {
  87. int decoded_len = 0;
  88. /* XXX: Needs two extra bytes for the base64 decode calculation matches
  89. * the binary length once decoded. #17868. */
  90. char b64_decoded[SR_REVEAL_LEN + 2];
  91. tor_assert(encoded);
  92. tor_assert(commit);
  93. if (strlen(encoded) > SR_REVEAL_BASE64_LEN) {
  94. /* This means that if we base64 decode successfully the received reveal
  95. * value, we'll end up with a bigger decoded value thus unusable. */
  96. goto error;
  97. }
  98. /* Decode our encoded reveal. Let's be careful here since _encoded_ is
  99. * coming from the network in a dirauth vote so we expect nothing more
  100. * than the base64 encoded length of our reveal. */
  101. decoded_len = base64_decode(b64_decoded, sizeof(b64_decoded),
  102. encoded, strlen(encoded));
  103. if (decoded_len < 0) {
  104. log_warn(LD_BUG, "SR: Reveal from authority %s can't be decoded.",
  105. commit->rsa_identity_fpr);
  106. goto error;
  107. }
  108. if (decoded_len != SR_REVEAL_LEN) {
  109. log_warn(LD_BUG, "SR: Reveal from authority %s decoded length is "
  110. "doesn't match the expected length (%d vs %d)",
  111. commit->rsa_identity_fpr, decoded_len, SR_REVEAL_LEN);
  112. goto error;
  113. }
  114. commit->reveal_ts = (time_t) tor_ntohll(get_uint64(b64_decoded));
  115. /* Copy the last part, the random value. */
  116. memcpy(commit->random_number, b64_decoded + 8,
  117. sizeof(commit->random_number));
  118. /* Also copy the whole message to use during verification */
  119. strlcpy(commit->encoded_reveal, encoded, sizeof(commit->encoded_reveal));
  120. return 0;
  121. error:
  122. return -1;
  123. }
  124. /* Cleanup both our global state and disk state. */
  125. static void
  126. sr_cleanup(void)
  127. {
  128. sr_state_free();
  129. }
  130. /* Free a commit object. */
  131. void
  132. sr_commit_free(sr_commit_t *commit)
  133. {
  134. if (commit == NULL) {
  135. return;
  136. }
  137. /* Make sure we do not leave OUR random number in memory. */
  138. memwipe(commit->random_number, 0, sizeof(commit->random_number));
  139. tor_free(commit);
  140. }
  141. /* Parse a list of arguments from a SRV value either from a vote, consensus
  142. * or from our disk state and return a newly allocated srv object. NULL is
  143. * returned on error.
  144. *
  145. * The arguments' order:
  146. * num_reveals, value
  147. */
  148. sr_srv_t *
  149. sr_parse_srv(const smartlist_t *args)
  150. {
  151. char *value;
  152. int num_reveals, ok;
  153. sr_srv_t *srv = NULL;
  154. tor_assert(args);
  155. if (smartlist_len(args) < 2) {
  156. goto end;
  157. }
  158. /* First argument is the number of reveal values */
  159. num_reveals = (int)tor_parse_long(smartlist_get(args, 0),
  160. 10, 0, INT32_MAX, &ok, NULL);
  161. if (!ok) {
  162. goto end;
  163. }
  164. srv = tor_malloc_zero(sizeof(*srv));
  165. srv->num_reveals = num_reveals;
  166. /* Second and last argument is the shared random value it self. */
  167. value = smartlist_get(args, 1);
  168. base16_decode((char *) srv->value, sizeof(srv->value), value,
  169. HEX_DIGEST256_LEN);
  170. end:
  171. return srv;
  172. }
  173. /* Parse a commit from a vote or from our disk state and return a newly
  174. * allocated commit object. NULL is returned on error.
  175. *
  176. * The commit's data is in <b>args</b> and the order matters very much:
  177. * algname, RSA fingerprint, commit value[, reveal value]
  178. */
  179. sr_commit_t *
  180. sr_parse_commit(const smartlist_t *args)
  181. {
  182. char *value;
  183. digest_algorithm_t alg;
  184. const char *rsa_identity_fpr;
  185. sr_commit_t *commit = NULL;
  186. if (smartlist_len(args) < 3) {
  187. goto error;
  188. }
  189. /* First argument is the algorithm. */
  190. value = smartlist_get(args, 0);
  191. alg = crypto_digest_algorithm_parse_name(value);
  192. if (alg != SR_DIGEST_ALG) {
  193. log_warn(LD_BUG, "SR: Commit algorithm %s is not recognized.",
  194. escaped(value));
  195. goto error;
  196. }
  197. /* Second argument is the RSA fingerprint of the auth */
  198. rsa_identity_fpr = smartlist_get(args, 1);
  199. if (base16_decode(digest, DIGEST_LEN, rsa_identity_fpr,
  200. HEX_DIGEST_LEN) < 0) {
  201. log_warn(LD_DIR, "SR: RSA fingerprint '%s' not decodable",
  202. rsa_identity_fpr);
  203. goto error;
  204. }
  205. /* Let's make sure, for extra safety, that this fingerprint is known to
  206. * us. Even though this comes from a vote, doesn't hurt to be
  207. * extracareful. */
  208. if (trusteddirserver_get_by_v3_auth_digest(digest) == NULL) {
  209. log_warn(LD_DIR, "SR: Fingerprint %s is not from a recognized "
  210. "authority. Discarding commit.",
  211. rsa_identity_fpr);
  212. goto error;
  213. }
  214. /* Allocate commit since we have a valid identity now. */
  215. commit = commit_new(rsa_identity_fpr);
  216. /* Third argument is the commitment value base64-encoded. */
  217. value = smartlist_get(args, 2);
  218. if (commit_decode(value, commit) < 0) {
  219. goto error;
  220. }
  221. /* (Optional) Fourth argument is the revealed value. */
  222. if (smartlist_len(args) > 3) {
  223. value = smartlist_get(args, 3);
  224. if (reveal_decode(value, commit) < 0) {
  225. goto error;
  226. }
  227. }
  228. return commit;
  229. error:
  230. sr_commit_free(commit);
  231. return NULL;
  232. }
  233. /* Initialize shared random subsystem. This MUST be called early in the boot
  234. * process of tor. Return 0 on success else -1 on error. */
  235. int
  236. sr_init(int save_to_disk)
  237. {
  238. return sr_state_init(save_to_disk, 1);
  239. }
  240. /* Save our state to disk and cleanup everything. */
  241. void
  242. sr_save_and_cleanup(void)
  243. {
  244. sr_state_save();
  245. sr_cleanup();
  246. }