tor  0.4.2.1-alpha-dev
Macros | Functions | Variables
keypin.c File Reference
#include "orconfig.h"
#include "lib/cc/torint.h"
#include "lib/crypt_ops/crypto_digest.h"
#include "lib/crypt_ops/crypto_format.h"
#include "lib/ctime/di_ops.h"
#include "lib/encoding/binascii.h"
#include "lib/encoding/time_fmt.h"
#include "lib/fdio/fdio.h"
#include "lib/fs/files.h"
#include "lib/fs/mmap.h"
#include "lib/log/log.h"
#include "lib/log/util_bug.h"
#include "lib/string/compat_ctype.h"
#include "lib/string/printf.h"
#include "lib/wallclock/approx_time.h"
#include "ht.h"
#include "feature/dirauth/keypin.h"
#include "siphash.h"
#include <errno.h>
#include <string.h>
#include <stdlib.h>

Go to the source code of this file.

Macros

#define KEYPIN_PRIVATE
 
#define O_SYNC   0
 
#define JOURNAL_LINE_LEN   (BASE64_DIGEST_LEN + BASE64_DIGEST256_LEN + 2)
 

Functions

static int keypin_journal_append_entry (const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key)
 
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 int keypin_add_or_replace_entry_in_map (keypin_ent_t *ent)
 
static HT_HEAD (rsamap, keypin_ent_st)
 
static unsigned keypin_ent_hash_rsa (const keypin_ent_t *a)
 
static int keypin_ents_eq_ed (const keypin_ent_t *a, const keypin_ent_t *b)
 
static unsigned keypin_ent_hash_ed (const keypin_ent_t *a)
 
 HT_PROTOTYPE (HT_GENERATE2(rsamap, HT_GENERATE2(keypin_ent_st, HT_GENERATE2(rsamap_node, HT_GENERATE2(keypin_ent_hash_rsa, HT_GENERATE2(keypin_ents_eq_rsa)
 
int keypin_check (const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key)
 
 MOCK_IMPL (STATIC void, keypin_add_entry_to_map,(keypin_ent_t *ent))
 
int keypin_check_lone_rsa (const uint8_t *rsa_id_digest)
 
int keypin_open_journal (const char *fname)
 
int keypin_close_journal (void)
 
STATIC int keypin_load_journal_impl (const char *data, size_t size)
 
int keypin_load_journal (const char *fname)
 
STATIC keypin_ent_t * keypin_parse_journal_line (const char *cp)
 
void keypin_clear (void)
 

Variables

static int keypin_journal_fd = -1
 

Detailed Description

Functions and structures for associating routers' RSA key fingerprints with their ED25519 keys.

Key-pinning for RSA and Ed25519 identity keys at directory authorities.

Many older clients, and many internal interfaces, still refer to relays by their RSA1024 identity keys. We can make this more secure, however: authorities use this module to track which RSA keys have been used along with which Ed25519 keys, and force such associations to be permanent.

This module implements a key-pinning mechanism to ensure that it's safe to use RSA keys as identitifers even as we migrate to Ed25519 keys. It remembers, for every Ed25519 key we've seen, what the associated Ed25519 key is. This way, if we see a different Ed25519 key with that RSA key, we'll know that there's a mismatch.

(As of this writing, these key associations are advisory only, mostly because some relay operators kept mishandling their Ed25519 keys during the initial Ed25519 rollout. We should fix this problem, and then toggle the AuthDirPinKeys option.)

We persist these entries to disk using a simple format, where each line has a base64-encoded RSA SHA1 hash, then a base64-endoded Ed25519 key. Empty lines, misformed lines, and lines beginning with # are ignored. Lines beginning with @ are reserved for future extensions.

The dirserv.c module is the main user of these functions.

Definition in file keypin.c.

Macro Definition Documentation

◆ JOURNAL_LINE_LEN

#define JOURNAL_LINE_LEN   (BASE64_DIGEST_LEN + BASE64_DIGEST256_LEN + 2)

Length of a keypinning journal line, including terminating newline.

Definition at line 348 of file keypin.c.

Function Documentation

◆ keypin_add_or_replace_entry_in_map()

static int keypin_add_or_replace_entry_in_map ( keypin_ent_t *  ent)
static

Helper: add 'ent' to the maps, replacing any entries that contradict it. Take ownership of 'ent', freeing it if needed.

Return 0 if the entry was a duplicate, -1 if there was a conflict, and 1 if there was no conflict.

Definition at line 234 of file keypin.c.

Referenced by keypin_load_journal_impl().

◆ keypin_check()

int keypin_check ( const uint8_t *  rsa_id_digest,
const uint8_t *  ed25519_id_key 
)

As keypin_check_and_add, but do not add. Return KEYPIN_NOT_FOUND if we would add.

Definition at line 157 of file keypin.c.

References keypin_check_and_add_impl().

◆ keypin_check_and_add_impl()

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

Helper: implements keypin_check and keypin_check_and_add.

Definition at line 167 of file keypin.c.

References tor_assert().

Referenced by keypin_check().

◆ keypin_check_lone_rsa()

int keypin_check_lone_rsa ( const uint8_t *  rsa_id_digest)

Check whether we already have an entry in the key pinning table for a router with RSA ID digest rsa_id_digest. If we have no such entry, return KEYPIN_NOT_FOUND. If we find an entry that matches the RSA key but which has an ed25519 key, return KEYPIN_MISMATCH.

Definition at line 284 of file keypin.c.

◆ keypin_clear()

void keypin_clear ( void  )

Remove all entries from the keypinning table.

Definition at line 491 of file keypin.c.

References tor_free.

◆ keypin_close_journal()

int keypin_close_journal ( void  )

Close the keypinning journal file.

Definition at line 339 of file keypin.c.

References keypin_journal_fd.

◆ keypin_ent_hash_ed()

static unsigned keypin_ent_hash_ed ( const keypin_ent_t *  a)
inlinestatic

Hashtable helper: hash a keypin table entries based on its ed25519 key

Definition at line 117 of file keypin.c.

◆ keypin_ent_hash_rsa()

static unsigned keypin_ent_hash_rsa ( const keypin_ent_t *  a)
inlinestatic

Hashtable helper: hash a keypin table entries based on its RSA key ID

Definition at line 102 of file keypin.c.

◆ keypin_ents_eq_ed()

static int keypin_ents_eq_ed ( const keypin_ent_t *  a,
const keypin_ent_t *  b 
)
inlinestatic

Hashtable helper: compare two keypin table entries and return true iff they have the same ed25519 keys

Definition at line 110 of file keypin.c.

References tor_memeq().

◆ keypin_journal_append_entry()

static int keypin_journal_append_entry ( const uint8_t *  rsa_id_digest,
const uint8_t *  ed25519_id_key 
)
static

Add an entry to the keypinning journal to map rsa_id_digest and ed25519_id_key.

Definition at line 353 of file keypin.c.

References BASE64_DIGEST256_LEN, BASE64_DIGEST_LEN, digest256_to_base64(), digest_to_base64(), JOURNAL_LINE_LEN, keypin_journal_fd, and write_all_to_fd().

◆ keypin_load_journal()

int keypin_load_journal ( const char *  fname)

Load a journal from the file called fname. Return 0 on success, -1 on failure.

Definition at line 452 of file keypin.c.

◆ keypin_load_journal_impl()

STATIC int keypin_load_journal_impl ( const char *  data,
size_t  size 
)

Load a journal from the size-byte region at data. Return 0 on success, -1 on failure.

Definition at line 378 of file keypin.c.

References JOURNAL_LINE_LEN, keypin_add_or_replace_entry_in_map(), keypin_parse_journal_line(), LD_DIRSERV, LOG_INFO, LOG_NOTICE, and tor_log().

◆ keypin_open_journal()

int keypin_open_journal ( const char *  fname)

Open the key-pinning journal to append to fname. Return 0 on success, -1 on failure.

Definition at line 305 of file keypin.c.

References tor_open_cloexec().

◆ keypin_parse_journal_line()

STATIC keypin_ent_t* keypin_parse_journal_line ( const char *  cp)

Parse a single keypinning journal line entry from cp. The input does not need to be NUL-terminated, but it does need to have KEYPIN_JOURNAL_LINE_LEN -1 bytes available to read. Return a new entry on success, and NULL on failure.

Definition at line 472 of file keypin.c.

Referenced by keypin_load_journal_impl().

◆ MOCK_IMPL()

MOCK_IMPL ( STATIC  void,
keypin_add_entry_to_map  ,
(keypin_ent_t *ent)   
)

Helper: add ent to the hash tables.

Definition at line 219 of file keypin.c.

Variable Documentation

◆ keypin_journal_fd

int keypin_journal_fd = -1
static

Open fd to the keypinning journal file.

Definition at line 300 of file keypin.c.

Referenced by keypin_close_journal(), and keypin_journal_append_entry().