mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 14:51:11 +01:00
Support for writing ed25519 public/private components to disk.
This refactors the "== type:tag ==" code from crypto_curve25519.c
This commit is contained in:
parent
c75e275574
commit
ed48b0fe56
4 changed files with 183 additions and 34 deletions
|
@ -8,6 +8,7 @@
|
||||||
#ifdef HAVE_SYS_STAT_H
|
#ifdef HAVE_SYS_STAT_H
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "container.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
#include "crypto_curve25519.h"
|
#include "crypto_curve25519.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -127,69 +128,132 @@ curve25519_keypair_generate(curve25519_keypair_t *keypair_out,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
crypto_write_tagged_contents_to_file(const char *fname,
|
||||||
|
const char *typestring,
|
||||||
|
const char *tag,
|
||||||
|
const uint8_t *data,
|
||||||
|
size_t datalen)
|
||||||
|
{
|
||||||
|
char header[32];
|
||||||
|
smartlist_t *chunks = smartlist_new();
|
||||||
|
sized_chunk_t ch0, ch1;
|
||||||
|
int r = -1;
|
||||||
|
|
||||||
|
memset(header, 0, sizeof(header));
|
||||||
|
if (tor_snprintf(header, sizeof(header),
|
||||||
|
"== %s: %s ==", typestring, tag) < 0)
|
||||||
|
goto end;
|
||||||
|
ch0.bytes = header;
|
||||||
|
ch0.len = 32;
|
||||||
|
ch1.bytes = (const char*) data;
|
||||||
|
ch1.len = datalen;
|
||||||
|
smartlist_add(chunks, &ch0);
|
||||||
|
smartlist_add(chunks, &ch1);
|
||||||
|
|
||||||
|
r = write_chunks_to_file(fname, chunks, 1, 0);
|
||||||
|
|
||||||
|
end:
|
||||||
|
smartlist_free(chunks);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
ssize_t
|
||||||
|
crypto_read_tagged_contents_from_file(const char *fname,
|
||||||
|
const char *typestring,
|
||||||
|
char **tag_out,
|
||||||
|
uint8_t *data_out,
|
||||||
|
ssize_t data_out_len)
|
||||||
|
{
|
||||||
|
char prefix[33];
|
||||||
|
char *content = NULL;
|
||||||
|
struct stat st;
|
||||||
|
ssize_t r = -1;
|
||||||
|
|
||||||
|
*tag_out = NULL;
|
||||||
|
st.st_size = 0;
|
||||||
|
content = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
|
||||||
|
if (! content)
|
||||||
|
goto end;
|
||||||
|
if (st.st_size < 32 || st.st_size > 32 + data_out_len)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
memcpy(prefix, content, 32);
|
||||||
|
prefix[32] = 0;
|
||||||
|
/* Check type, extract tag. */
|
||||||
|
if (strcmpstart(prefix, "== ") || strcmpend(prefix, " ==") ||
|
||||||
|
! tor_mem_is_zero(prefix+strlen(prefix), 32-strlen(prefix)))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
if (strcmpstart(prefix+3, typestring) ||
|
||||||
|
3+strlen(typestring) >= 32 ||
|
||||||
|
strcmpstart(prefix+3+strlen(typestring), ": "))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
*tag_out = tor_strndup(prefix+5+strlen(typestring),
|
||||||
|
strlen(prefix)-8-strlen(typestring));
|
||||||
|
|
||||||
|
memcpy(data_out, content+32, st.st_size-32);
|
||||||
|
r = st.st_size - 32;
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (content)
|
||||||
|
memwipe(content, 0, st.st_size);
|
||||||
|
tor_free(content);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
int
|
int
|
||||||
curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair,
|
curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
const char *tag)
|
const char *tag)
|
||||||
{
|
{
|
||||||
char contents[32 + CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN];
|
uint8_t contents[CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN];
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
memset(contents, 0, sizeof(contents));
|
memcpy(contents, keypair->seckey.secret_key, CURVE25519_SECKEY_LEN);
|
||||||
tor_snprintf(contents, sizeof(contents), "== c25519v1: %s ==", tag);
|
memcpy(contents+CURVE25519_SECKEY_LEN,
|
||||||
tor_assert(strlen(contents) <= 32);
|
|
||||||
memcpy(contents+32, keypair->seckey.secret_key, CURVE25519_SECKEY_LEN);
|
|
||||||
memcpy(contents+32+CURVE25519_SECKEY_LEN,
|
|
||||||
keypair->pubkey.public_key, CURVE25519_PUBKEY_LEN);
|
keypair->pubkey.public_key, CURVE25519_PUBKEY_LEN);
|
||||||
|
|
||||||
r = write_bytes_to_file(fname, contents, sizeof(contents), 1);
|
r = crypto_write_tagged_contents_to_file(fname,
|
||||||
|
"c25519v1",
|
||||||
|
tag,
|
||||||
|
contents,
|
||||||
|
sizeof(contents));
|
||||||
|
|
||||||
memwipe(contents, 0, sizeof(contents));
|
memwipe(contents, 0, sizeof(contents));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
int
|
int
|
||||||
curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
|
curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
|
||||||
char **tag_out,
|
char **tag_out,
|
||||||
const char *fname)
|
const char *fname)
|
||||||
{
|
{
|
||||||
char prefix[33];
|
uint8_t content[CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN];
|
||||||
char *content;
|
ssize_t len;
|
||||||
struct stat st;
|
|
||||||
int r = -1;
|
int r = -1;
|
||||||
|
|
||||||
*tag_out = NULL;
|
len = crypto_read_tagged_contents_from_file(fname, "c25519v1", tag_out,
|
||||||
|
content, sizeof(content));
|
||||||
st.st_size = 0;
|
if (len != sizeof(content))
|
||||||
content = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
|
|
||||||
if (! content)
|
|
||||||
goto end;
|
|
||||||
if (st.st_size != 32 + CURVE25519_SECKEY_LEN + CURVE25519_PUBKEY_LEN)
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
memcpy(prefix, content, 32);
|
memcpy(keypair_out->seckey.secret_key, content, CURVE25519_SECKEY_LEN);
|
||||||
prefix[32] = '\0';
|
|
||||||
if (strcmpstart(prefix, "== c25519v1: ") ||
|
|
||||||
strcmpend(prefix, " =="))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
*tag_out = tor_strndup(prefix+strlen("== c25519v1: "),
|
|
||||||
strlen(prefix) - strlen("== c25519v1: =="));
|
|
||||||
|
|
||||||
memcpy(keypair_out->seckey.secret_key, content+32, CURVE25519_SECKEY_LEN);
|
|
||||||
curve25519_public_key_generate(&keypair_out->pubkey, &keypair_out->seckey);
|
curve25519_public_key_generate(&keypair_out->pubkey, &keypair_out->seckey);
|
||||||
if (tor_memneq(keypair_out->pubkey.public_key,
|
if (tor_memneq(keypair_out->pubkey.public_key,
|
||||||
content + 32 + CURVE25519_SECKEY_LEN,
|
content + CURVE25519_SECKEY_LEN,
|
||||||
CURVE25519_PUBKEY_LEN))
|
CURVE25519_PUBKEY_LEN))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (content) {
|
memwipe(content, 0, sizeof(content));
|
||||||
memwipe(content, 0, (size_t) st.st_size);
|
|
||||||
tor_free(content);
|
|
||||||
}
|
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
memset(keypair_out, 0, sizeof(*keypair_out));
|
memset(keypair_out, 0, sizeof(*keypair_out));
|
||||||
tor_free(*tag_out);
|
tor_free(*tag_out);
|
||||||
|
|
|
@ -72,5 +72,17 @@ int curve25519_public_from_base64(curve25519_public_key_t *pkey,
|
||||||
int curve25519_public_to_base64(char *output,
|
int curve25519_public_to_base64(char *output,
|
||||||
const curve25519_public_key_t *pkey);
|
const curve25519_public_key_t *pkey);
|
||||||
|
|
||||||
|
int crypto_write_tagged_contents_to_file(const char *fname,
|
||||||
|
const char *typestring,
|
||||||
|
const char *tag,
|
||||||
|
const uint8_t *data,
|
||||||
|
size_t datalen);
|
||||||
|
|
||||||
|
ssize_t crypto_read_tagged_contents_from_file(const char *fname,
|
||||||
|
const char *typestring,
|
||||||
|
char **tag_out,
|
||||||
|
uint8_t *data_out,
|
||||||
|
ssize_t data_out_len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -161,3 +161,63 @@ ed25519_checksig_batch(int *okay_out,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey,
|
||||||
|
const char *filename,
|
||||||
|
const char *tag)
|
||||||
|
{
|
||||||
|
return crypto_write_tagged_contents_to_file(filename,
|
||||||
|
"ed25519v1-secret",
|
||||||
|
tag,
|
||||||
|
seckey->seckey,
|
||||||
|
sizeof(seckey->seckey));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out,
|
||||||
|
char **tag_out,
|
||||||
|
const char *filename)
|
||||||
|
{
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-secret",
|
||||||
|
tag_out, seckey_out->seckey,
|
||||||
|
sizeof(seckey_out->seckey));
|
||||||
|
if (len != sizeof(seckey_out->seckey))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey,
|
||||||
|
const char *filename,
|
||||||
|
const char *tag)
|
||||||
|
{
|
||||||
|
return crypto_write_tagged_contents_to_file(filename,
|
||||||
|
"ed25519v1-public",
|
||||||
|
tag,
|
||||||
|
pubkey->pubkey,
|
||||||
|
sizeof(pubkey->pubkey));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
|
||||||
|
char **tag_out,
|
||||||
|
const char *filename)
|
||||||
|
{
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-public",
|
||||||
|
tag_out, pubkey_out->pubkey,
|
||||||
|
sizeof(pubkey_out->pubkey));
|
||||||
|
if (len != sizeof(pubkey_out->pubkey))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,21 @@ int ed25519_public_from_base64(ed25519_public_key_t *pkey,
|
||||||
int ed25519_public_to_base64(char *output,
|
int ed25519_public_to_base64(char *output,
|
||||||
const ed25519_public_key_t *pkey);
|
const ed25519_public_key_t *pkey);
|
||||||
|
|
||||||
/* XXXX write secret keys to disk, load secret keys from disk, read encrypted,
|
/* XXXX read encrypted, write encrypted. */
|
||||||
* write encrypted. */
|
|
||||||
|
int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey,
|
||||||
|
const char *filename,
|
||||||
|
const char *tag);
|
||||||
|
int ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out,
|
||||||
|
char **tag_out,
|
||||||
|
const char *filename);
|
||||||
|
int ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey,
|
||||||
|
const char *filename,
|
||||||
|
const char *tag);
|
||||||
|
int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
|
||||||
|
char **tag_out,
|
||||||
|
const char *filename);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue