crypto_format.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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-2018, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file crypto_format.c
  8. *
  9. * \brief Formatting and parsing code for crypto-related data structures.
  10. */
  11. #include "orconfig.h"
  12. #ifdef HAVE_SYS_STAT_H
  13. #include <sys/stat.h>
  14. #endif
  15. #include "lib/container/smartlist.h"
  16. #include "lib/crypt_ops/crypto_curve25519.h"
  17. #include "lib/crypt_ops/crypto_digest.h"
  18. #include "lib/crypt_ops/crypto_ed25519.h"
  19. #include "lib/crypt_ops/crypto_format.h"
  20. #include "lib/crypt_ops/crypto_util.h"
  21. #include "lib/string/util_string.h"
  22. #include "common/util.h"
  23. #include "lib/encoding/binascii.h"
  24. #include "lib/log/torlog.h"
  25. /** Write the <b>datalen</b> bytes from <b>data</b> to the file named
  26. * <b>fname</b> in the tagged-data format. This format contains a
  27. * 32-byte header, followed by the data itself. The header is the
  28. * NUL-padded string "== <b>typestring</b>: <b>tag</b> ==". The length
  29. * of <b>typestring</b> and <b>tag</b> must therefore be no more than
  30. * 24.
  31. **/
  32. int
  33. crypto_write_tagged_contents_to_file(const char *fname,
  34. const char *typestring,
  35. const char *tag,
  36. const uint8_t *data,
  37. size_t datalen)
  38. {
  39. char header[32];
  40. smartlist_t *chunks = smartlist_new();
  41. sized_chunk_t ch0, ch1;
  42. int r = -1;
  43. memset(header, 0, sizeof(header));
  44. if (tor_snprintf(header, sizeof(header),
  45. "== %s: %s ==", typestring, tag) < 0)
  46. goto end;
  47. ch0.bytes = header;
  48. ch0.len = 32;
  49. ch1.bytes = (const char*) data;
  50. ch1.len = datalen;
  51. smartlist_add(chunks, &ch0);
  52. smartlist_add(chunks, &ch1);
  53. r = write_chunks_to_file(fname, chunks, 1, 0);
  54. end:
  55. smartlist_free(chunks);
  56. return r;
  57. }
  58. /** Read a tagged-data file from <b>fname</b> into the
  59. * <b>data_out_len</b>-byte buffer in <b>data_out</b>. Check that the
  60. * typestring matches <b>typestring</b>; store the tag into a newly allocated
  61. * string in <b>tag_out</b>. Return -1 on failure, and the number of bytes of
  62. * data on success. Preserves the errno from reading the file. */
  63. ssize_t
  64. crypto_read_tagged_contents_from_file(const char *fname,
  65. const char *typestring,
  66. char **tag_out,
  67. uint8_t *data_out,
  68. ssize_t data_out_len)
  69. {
  70. char prefix[33];
  71. char *content = NULL;
  72. struct stat st;
  73. ssize_t r = -1;
  74. size_t st_size = 0;
  75. int saved_errno = 0;
  76. *tag_out = NULL;
  77. st.st_size = 0;
  78. content = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
  79. if (! content) {
  80. saved_errno = errno;
  81. goto end;
  82. }
  83. if (st.st_size < 32 || st.st_size > 32 + data_out_len) {
  84. saved_errno = EINVAL;
  85. goto end;
  86. }
  87. st_size = (size_t)st.st_size;
  88. memcpy(prefix, content, 32);
  89. prefix[32] = 0;
  90. /* Check type, extract tag. */
  91. if (strcmpstart(prefix, "== ") || strcmpend(prefix, " ==") ||
  92. ! tor_mem_is_zero(prefix+strlen(prefix), 32-strlen(prefix))) {
  93. saved_errno = EINVAL;
  94. goto end;
  95. }
  96. if (strcmpstart(prefix+3, typestring) ||
  97. 3+strlen(typestring) >= 32 ||
  98. strcmpstart(prefix+3+strlen(typestring), ": ")) {
  99. saved_errno = EINVAL;
  100. goto end;
  101. }
  102. *tag_out = tor_strndup(prefix+5+strlen(typestring),
  103. strlen(prefix)-8-strlen(typestring));
  104. memcpy(data_out, content+32, st_size-32);
  105. r = st_size - 32;
  106. end:
  107. if (content)
  108. memwipe(content, 0, st_size);
  109. tor_free(content);
  110. if (saved_errno)
  111. errno = saved_errno;
  112. return r;
  113. }
  114. /** Encode <b>pkey</b> as a base64-encoded string, without trailing "="
  115. * characters, in the buffer <b>output</b>, which must have at least
  116. * CURVE25519_BASE64_PADDED_LEN+1 bytes available. Return 0 on success, -1 on
  117. * failure. */
  118. int
  119. curve25519_public_to_base64(char *output,
  120. const curve25519_public_key_t *pkey)
  121. {
  122. char buf[128];
  123. base64_encode(buf, sizeof(buf),
  124. (const char*)pkey->public_key, CURVE25519_PUBKEY_LEN, 0);
  125. buf[CURVE25519_BASE64_PADDED_LEN] = '\0';
  126. memcpy(output, buf, CURVE25519_BASE64_PADDED_LEN+1);
  127. return 0;
  128. }
  129. /** Try to decode a base64-encoded curve25519 public key from <b>input</b>
  130. * into the object at <b>pkey</b>. Return 0 on success, -1 on failure.
  131. * Accepts keys with or without a trailing "=". */
  132. int
  133. curve25519_public_from_base64(curve25519_public_key_t *pkey,
  134. const char *input)
  135. {
  136. size_t len = strlen(input);
  137. if (len == CURVE25519_BASE64_PADDED_LEN - 1) {
  138. /* not padded */
  139. return digest256_from_base64((char*)pkey->public_key, input);
  140. } else if (len == CURVE25519_BASE64_PADDED_LEN) {
  141. char buf[128];
  142. if (base64_decode(buf, sizeof(buf), input, len) != CURVE25519_PUBKEY_LEN)
  143. return -1;
  144. memcpy(pkey->public_key, buf, CURVE25519_PUBKEY_LEN);
  145. return 0;
  146. } else {
  147. return -1;
  148. }
  149. }
  150. /** For logging convenience: Convert <b>pkey</b> to a statically allocated
  151. * base64 string and return it. Not threadsafe. Format not meant to be
  152. * computer-readable; it may change in the future. Subsequent calls invalidate
  153. * previous returns. */
  154. const char *
  155. ed25519_fmt(const ed25519_public_key_t *pkey)
  156. {
  157. static char formatted[ED25519_BASE64_LEN+1];
  158. if (pkey) {
  159. if (ed25519_public_key_is_zero(pkey)) {
  160. strlcpy(formatted, "<unset>", sizeof(formatted));
  161. } else {
  162. int r = ed25519_public_to_base64(formatted, pkey);
  163. tor_assert(!r);
  164. }
  165. } else {
  166. strlcpy(formatted, "<null>", sizeof(formatted));
  167. }
  168. return formatted;
  169. }
  170. /** Try to decode the string <b>input</b> into an ed25519 public key. On
  171. * success, store the value in <b>pkey</b> and return 0. Otherwise return
  172. * -1. */
  173. int
  174. ed25519_public_from_base64(ed25519_public_key_t *pkey,
  175. const char *input)
  176. {
  177. return digest256_from_base64((char*)pkey->pubkey, input);
  178. }
  179. /** Encode the public key <b>pkey</b> into the buffer at <b>output</b>,
  180. * which must have space for ED25519_BASE64_LEN bytes of encoded key,
  181. * plus one byte for a terminating NUL. Return 0 on success, -1 on failure.
  182. */
  183. int
  184. ed25519_public_to_base64(char *output,
  185. const ed25519_public_key_t *pkey)
  186. {
  187. return digest256_to_base64(output, (const char *)pkey->pubkey);
  188. }
  189. /** Encode the signature <b>sig</b> into the buffer at <b>output</b>,
  190. * which must have space for ED25519_SIG_BASE64_LEN bytes of encoded signature,
  191. * plus one byte for a terminating NUL. Return 0 on success, -1 on failure.
  192. */
  193. int
  194. ed25519_signature_to_base64(char *output,
  195. const ed25519_signature_t *sig)
  196. {
  197. char buf[256];
  198. int n = base64_encode_nopad(buf, sizeof(buf), sig->sig, ED25519_SIG_LEN);
  199. tor_assert(n == ED25519_SIG_BASE64_LEN);
  200. memcpy(output, buf, ED25519_SIG_BASE64_LEN+1);
  201. return 0;
  202. }
  203. /** Try to decode the string <b>input</b> into an ed25519 signature. On
  204. * success, store the value in <b>sig</b> and return 0. Otherwise return
  205. * -1. */
  206. int
  207. ed25519_signature_from_base64(ed25519_signature_t *sig,
  208. const char *input)
  209. {
  210. if (strlen(input) != ED25519_SIG_BASE64_LEN)
  211. return -1;
  212. char buf[ED25519_SIG_BASE64_LEN+3];
  213. memcpy(buf, input, ED25519_SIG_BASE64_LEN);
  214. buf[ED25519_SIG_BASE64_LEN+0] = '=';
  215. buf[ED25519_SIG_BASE64_LEN+1] = '=';
  216. buf[ED25519_SIG_BASE64_LEN+2] = 0;
  217. char decoded[128];
  218. int n = base64_decode(decoded, sizeof(decoded), buf, strlen(buf));
  219. if (n < 0 || n != ED25519_SIG_LEN)
  220. return -1;
  221. memcpy(sig->sig, decoded, ED25519_SIG_LEN);
  222. return 0;
  223. }
  224. /** Base64 encode DIGEST_LINE bytes from <b>digest</b>, remove the trailing =
  225. * characters, and store the nul-terminated result in the first
  226. * BASE64_DIGEST_LEN+1 bytes of <b>d64</b>. */
  227. /* XXXX unify with crypto_format.c code */
  228. int
  229. digest_to_base64(char *d64, const char *digest)
  230. {
  231. char buf[256];
  232. base64_encode(buf, sizeof(buf), digest, DIGEST_LEN, 0);
  233. buf[BASE64_DIGEST_LEN] = '\0';
  234. memcpy(d64, buf, BASE64_DIGEST_LEN+1);
  235. return 0;
  236. }
  237. /** Given a base64 encoded, nul-terminated digest in <b>d64</b> (without
  238. * trailing newline or = characters), decode it and store the result in the
  239. * first DIGEST_LEN bytes at <b>digest</b>. */
  240. /* XXXX unify with crypto_format.c code */
  241. int
  242. digest_from_base64(char *digest, const char *d64)
  243. {
  244. if (base64_decode(digest, DIGEST_LEN, d64, strlen(d64)) == DIGEST_LEN)
  245. return 0;
  246. else
  247. return -1;
  248. }
  249. /** Base64 encode DIGEST256_LINE bytes from <b>digest</b>, remove the
  250. * trailing = characters, and store the nul-terminated result in the first
  251. * BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */
  252. /* XXXX unify with crypto_format.c code */
  253. int
  254. digest256_to_base64(char *d64, const char *digest)
  255. {
  256. char buf[256];
  257. base64_encode(buf, sizeof(buf), digest, DIGEST256_LEN, 0);
  258. buf[BASE64_DIGEST256_LEN] = '\0';
  259. memcpy(d64, buf, BASE64_DIGEST256_LEN+1);
  260. return 0;
  261. }
  262. /** Given a base64 encoded, nul-terminated digest in <b>d64</b> (without
  263. * trailing newline or = characters), decode it and store the result in the
  264. * first DIGEST256_LEN bytes at <b>digest</b>. */
  265. /* XXXX unify with crypto_format.c code */
  266. int
  267. digest256_from_base64(char *digest, const char *d64)
  268. {
  269. if (base64_decode(digest, DIGEST256_LEN, d64, strlen(d64)) == DIGEST256_LEN)
  270. return 0;
  271. else
  272. return -1;
  273. }