11 #define KEYPIN_PRIVATE
78 const uint8_t *ed25519_id_key);
80 const uint8_t *ed25519_id_key,
85 static HT_HEAD(rsamap, keypin_ent_st) the_rsa_map = HT_INITIALIZER();
86 static HT_HEAD(edmap, keypin_ent_st) the_ed_map = HT_INITIALIZER();
91 keypin_ents_eq_rsa(
const keypin_ent_t *a,
const keypin_ent_t *b)
93 return tor_memeq(a->rsa_id, b->rsa_id,
sizeof(a->rsa_id));
97 static inline unsigned
100 return (
unsigned) siphash24g(a->rsa_id,
sizeof(a->rsa_id));
108 return tor_memeq(a->ed25519_key, b->ed25519_key,
sizeof(a->ed25519_key));
112 static inline unsigned
115 return (
unsigned) siphash24g(a->ed25519_key,
sizeof(a->ed25519_key));
121 keypin_ents_eq_rsa, 0.6, tor_reallocarray,
tor_free_);
141 const uint8_t *ed25519_id_key,
142 const int replace_existing_entry)
145 replace_existing_entry);
154 const uint8_t *ed25519_id_key)
164 const uint8_t *ed25519_id_key,
165 const int do_not_add,
168 keypin_ent_t search, *ent;
169 memset(&search, 0,
sizeof(search));
170 memcpy(search.rsa_id, rsa_id_digest,
sizeof(search.rsa_id));
171 memcpy(search.ed25519_key, ed25519_id_key,
sizeof(search.ed25519_key));
174 ent = HT_FIND(rsamap, &the_rsa_map, &search);
177 if (
tor_memeq(ent->ed25519_key, ed25519_id_key,
sizeof(ent->ed25519_key))) {
181 return KEYPIN_MISMATCH;
187 ent = HT_FIND(edmap, &the_ed_map, &search);
191 sizeof(ent->ed25519_key)));
193 return KEYPIN_MISMATCH;
199 return KEYPIN_NOT_FOUND;
201 ent = tor_memdup(&search,
sizeof(search));
218 HT_INSERT(rsamap, &the_rsa_map, ent);
219 HT_INSERT(edmap, &the_ed_map, ent);
233 keypin_ent_t *ent2 = HT_FIND(rsamap, &the_rsa_map, ent);
234 keypin_ent_t *ent3 = HT_FIND(edmap, &the_ed_map, ent);
240 }
else if (ent2 || ent3) {
250 const keypin_ent_t *t;
252 t = HT_REMOVE(rsamap, &the_rsa_map, ent2);
254 t = HT_REMOVE(edmap, &the_ed_map, ent2);
257 if (ent3 && ent2 != ent3) {
258 t = HT_REMOVE(rsamap, &the_rsa_map, ent3);
260 t = HT_REMOVE(edmap, &the_ed_map, ent3);
282 keypin_ent_t search, *ent;
283 memset(&search, 0,
sizeof(search));
284 memcpy(search.rsa_id, rsa_id_digest,
sizeof(search.rsa_id));
287 ent = HT_FIND(rsamap, &the_rsa_map, &search);
289 return KEYPIN_MISMATCH;
291 return KEYPIN_NOT_FOUND;
314 if (write(fd,
"\n", 1) < 1)
319 char tbuf[ISO_TIME_LEN+1];
321 tor_snprintf(buf,
sizeof(buf),
"@opened-at %s\n", tbuf);
344 #define JOURNAL_LINE_LEN (BASE64_DIGEST_LEN + BASE64_DIGEST256_LEN + 2)
350 const uint8_t *ed25519_id_key)
358 (
const char*)ed25519_id_key);
362 log_warn(
LD_DIRSERV,
"Error while adding a line to the key-pinning "
363 "journal: %s", strerror(errno));
376 const char *start = data, *end = data + size, *next;
378 int n_corrupt_lines = 0;
380 int n_duplicates = 0;
383 for (
const char *cp = start; cp < end; cp = next) {
384 const char *eol = memchr(cp,
'\n', end-cp);
385 const char *eos = eol ? eol : end;
386 const size_t len = eos - cp;
388 next = eol ? eol + 1 : end;
407 for (
const char *s = cp; s < eos; ++s) {
408 if (! TOR_ISSPACE(*s)) {
426 }
else if (r == -1) {
435 "Loaded %d entries from keypin journal. "
436 "Found %d corrupt lines (ignored), %d duplicates (harmless), "
437 "and %d conflicts (resolved in favor of more recent entry).",
438 n_entries, n_corrupt_lines, n_duplicates, n_conflicts);
458 tor_munmap_file(map);
471 keypin_ent_t *ent = tor_malloc_zero(
sizeof(keypin_ent_t));
476 base64_decode((
char*)ent->ed25519_key,
sizeof(ent->ed25519_key),
491 keypin_ent_t **ent, **next, *
this;
492 for (ent = HT_START(rsamap, &the_rsa_map); ent != NULL; ent = next) {
494 next = HT_NEXT_RMV(rsamap, &the_rsa_map, ent);
496 keypin_ent_t *other_ent = HT_REMOVE(edmap, &the_ed_map,
this);
497 bad_entries += (other_ent !=
this);
502 bad_entries += HT_SIZE(&the_ed_map);
504 HT_CLEAR(edmap,&the_ed_map);
505 HT_CLEAR(rsamap,&the_rsa_map);
508 log_warn(
LD_BUG,
"Found %d discrepancies in the keypin database.",
Header for approx_time.c.
int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
Locale-independent character-type inspection (header)
Headers for crypto_digest.c.
#define BASE64_DIGEST256_LEN
#define BASE64_DIGEST_LEN
int tor_memeq(const void *a, const void *b, size_t sz)
#define fast_memeq(a, b, c)
#define fast_memneq(a, b, c)
int tor_fd_seekend(int fd)
Wrappers for reading and writing data to files on disk.
int tor_open_cloexec(const char *path, int flags, unsigned mode)
ssize_t write_all_to_fd(int fd, const char *buf, size_t count)
HT_PROTOTYPE(hs_circuitmap_ht, circuit_t, hs_circuitmap_node, hs_circuit_hash_token, hs_circuits_have_same_token)
typedef HT_HEAD(hs_service_ht, hs_service_t) hs_service_ht
static unsigned keypin_ent_hash_ed(const keypin_ent_t *a)
STATIC void keypin_add_entry_to_map(keypin_ent_t *ent)
static int keypin_ents_eq_ed(const keypin_ent_t *a, const keypin_ent_t *b)
int keypin_load_journal(const char *fname)
static int keypin_journal_fd
static int keypin_check_and_add_impl(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key, const int do_not_add, const int replace)
STATIC keypin_ent_t * keypin_parse_journal_line(const char *cp)
STATIC int keypin_load_journal_impl(const char *data, size_t size)
int keypin_check_lone_rsa(const uint8_t *rsa_id_digest)
int keypin_check(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key)
static int keypin_journal_append_entry(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key)
int keypin_open_journal(const char *fname)
static int keypin_add_or_replace_entry_in_map(keypin_ent_t *ent)
int keypin_check_and_add(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key, const int replace_existing_entry)
int keypin_close_journal(void)
static unsigned keypin_ent_hash_rsa(const keypin_ent_t *a)
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
void tor_free_(void *mem)
int tor_snprintf(char *str, size_t size, const char *format,...)
#define MOCK_IMPL(rv, funcname, arglist)
void format_iso_time(char *buf, time_t t)
Integer definitions used throughout Tor.
Macros to manage assertions, fatal and non-fatal.