Generate encryption key from signing key for new identities

This commit is contained in:
Jeremy Lakeman 2016-04-19 15:15:53 +09:30
parent 37bdd0b5f9
commit 5feb67512c
7 changed files with 243 additions and 153 deletions

View File

@ -45,23 +45,4 @@ int crypto_verify_message(struct subscriber *subscriber, unsigned char *message,
return 0;
}
// sign the hash of a message, adding the signature to the end of the message buffer.
int crypto_sign_message(struct keyring_identity *identity, unsigned char *content, size_t buffer_len, size_t *content_len)
{
if (*content_len + SIGNATURE_BYTES > buffer_len)
return WHYF("Insufficient space in message buffer to add signature. %zu, need %zu",buffer_len, *content_len + SIGNATURE_BYTES);
struct keypair *key = keyring_find_sas_private(keyring, identity);
if (!key)
return WHY("Could not find signing key");
unsigned char hash[crypto_hash_sha512_BYTES];
crypto_hash_sha512(hash, content, *content_len);
if (crypto_sign_detached(&content[*content_len], NULL, hash, crypto_hash_sha512_BYTES, key->private_key))
return WHY("Signing failed");
*content_len += SIGNATURE_BYTES;
return 0;
}

View File

@ -22,9 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sodium.h"
#define SIGNATURE_BYTES crypto_sign_BYTES
struct keyring_identity;
int crypto_verify_message(struct subscriber *subscriber, unsigned char *message, size_t *message_len);
int crypto_sign_message(struct keyring_identity *identity, unsigned char *content, size_t buffer_len, size_t *content_len);
#endif

346
keyring.c
View File

@ -45,6 +45,16 @@ static void keyring_free_keypair(keypair *kp);
static void keyring_free_identity(keyring_identity *id);
static int keyring_identity_mac(const keyring_identity *id, unsigned char *pkrsalt, unsigned char *mac);
struct combined_pk{
uint8_t sign_key[crypto_sign_PUBLICKEYBYTES];
sid_t box_key;
};
struct combined_sk{
uint8_t sign_key[crypto_sign_SECRETKEYBYTES];
uint8_t box_key[crypto_box_SECRETKEYBYTES];
};
static int _keyring_open(keyring_file *k, const char *path, const char *mode)
{
DEBUGF(keyring, "opening %s in \"%s\" mode", alloca_str_toprint(path), mode);
@ -206,7 +216,6 @@ keypair *keyring_identity_keytype(keyring_identity *id, unsigned keytype)
kp=kp->next;
return kp;
}
#define find_keypair_sid(X) keyring_identity_keytype((X),KEYTYPE_CRYPTOBOX)
keypair *keyring_find_did(keyring_iterator *it, const char *did)
{
@ -222,20 +231,53 @@ keypair *keyring_find_did(keyring_iterator *it, const char *did)
return NULL;
}
keypair *keyring_find_sid(keyring_iterator *it, const sid_t *sidp)
static int keyring_find_box(keyring_iterator *it, const sid_t *sidp, const uint8_t **sk)
{
keypair *kp;
while((kp=keyring_next_keytype(it, KEYTYPE_CRYPTOBOX))){
if (memcmp(sidp->binary, kp->public_key, SID_SIZE) == 0)
return kp;
while((kp=keyring_next_key(it))){
if (kp->type == KEYTYPE_CRYPTOBOX){
if (memcmp(sidp->binary, kp->public_key, SID_SIZE) == 0){
if (sk)
*sk = kp->private_key;
return 1;
}
}else if(kp->type == KEYTYPE_CRYPTOCOMBINED){
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
if (memcmp(sidp->binary, pk->box_key.binary, SID_SIZE) == 0){
if (sk){
struct combined_sk *secret = (struct combined_sk *)kp->private_key;
*sk = secret->box_key;
}
return 1;
}
}
}
return 0;
}
int keyring_find_sid(keyring_iterator *it, const sid_t *sidp)
{
return keyring_find_box(it, sidp, NULL);
}
const sid_t *keyring_identity_sid(const keyring_identity *id)
{
keypair *kp=id->keypairs;
while(kp){
if (kp->type == KEYTYPE_CRYPTOBOX)
return (const sid_t *)kp->public_key;
if (kp->type == KEYTYPE_CRYPTOCOMBINED){
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
return &pk->box_key;
}
kp=kp->next;
}
return NULL;
}
static void add_subscriber(keyring_identity *id, keypair *kp)
static void add_subscriber(keyring_identity *id, const sid_t *sid)
{
assert(kp->type == KEYTYPE_CRYPTOBOX);
id->subscriber = find_subscriber(kp->public_key, SID_SIZE, 1);
id->subscriber = find_subscriber(sid->binary, SID_SIZE, 1);
if (id->subscriber) {
if (id->subscriber->reachable == REACHABLE_NONE){
id->subscriber->reachable = REACHABLE_SELF;
@ -438,6 +480,7 @@ static const char *keytype_str(unsigned ktype, const char *unknown)
case KEYTYPE_RHIZOME: return "RHIZOME";
case KEYTYPE_DID: return "DID";
case KEYTYPE_PUBLIC_TAG: return "PUBLIC_TAG";
case KEYTYPE_CRYPTOCOMBINED: return "CRYPTOCOMBINED";
default: return unknown;
}
}
@ -453,41 +496,42 @@ struct keytype {
int (*loader)(keypair *, const char *);
};
static void create_cryptobox(keypair *kp)
{
/* Filter out public keys that start with 0x0, as they are reserved for address
abbreviation. */
do {
crypto_box_keypair(kp->public_key, kp->private_key);
} while (kp->public_key[0] < 0x10);
}
/* Compute public key from private key.
*
* Public key calculation as below is taken from section 3 of:
* http://cr.yp.to/highspeed/naclcrypto-20090310.pdf
*
* This can take a while on a mobile phone since it involves a scalarmult operation, so searching
* through all slots for a pin could take a while (perhaps 1 second per pin:slot cominbation). This
* is both good and bad. The other option is to store the public key as well, which would make
* entering a pin faster, but would also make trying an incorrect pin faster, thus simplifying some
* brute-force attacks. We need to make a decision between speed/convenience and security here.
*/
static void _derive_scalarmult_public(unsigned char *public, const unsigned char *private)
{
crypto_scalarmult_base(public, private);
}
static void create_cryptosign(keypair *kp)
{
crypto_sign_keypair(kp->public_key, kp->private_key);
}
static void create_rhizome(keypair *kp)
{
randombytes_buf(kp->private_key, kp->private_key_len);
}
static void create_cryptocombined(keypair *kp)
{
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
struct combined_sk *sk = (struct combined_sk *)kp->private_key;
crypto_sign_ed25519_keypair(pk->sign_key, sk->sign_key);
crypto_sign_ed25519_sk_to_curve25519(sk->box_key, sk->sign_key);
crypto_scalarmult_base(pk->box_key.binary, sk->box_key);
}
static int pack_cryptocombined(const keypair *kp, struct rotbuf *rb)
{
uint8_t seed[crypto_sign_SEEDBYTES];
struct combined_sk *sk = (struct combined_sk *)kp->private_key;
crypto_sign_ed25519_sk_to_seed(seed, sk->sign_key);
rotbuf_putbuf(rb, seed, sizeof seed);
return 0;
}
static int unpack_cryptocombined(keypair *kp, struct rotbuf *rb, size_t key_length)
{
uint8_t seed[crypto_sign_SEEDBYTES];
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
struct combined_sk *sk = (struct combined_sk *)kp->private_key;
assert(key_length == sizeof seed);
rotbuf_getbuf(rb, seed, sizeof seed);
crypto_sign_ed25519_seed_keypair(pk->sign_key, sk->sign_key, seed);
crypto_sign_ed25519_sk_to_curve25519(sk->box_key, sk->sign_key);
crypto_scalarmult_base(pk->box_key.binary, sk->box_key);
return 0;
}
static int pack_private_only(const keypair *kp, struct rotbuf *rb)
{
rotbuf_putbuf(rb, kp->private_key, kp->private_key_len);
@ -599,7 +643,7 @@ static int load_cryptobox(keypair *kp, const char *text)
{
if (load_private(kp, text) == -1)
return -1;
_derive_scalarmult_public(kp->public_key, kp->private_key);
crypto_scalarmult_base(kp->public_key, kp->private_key);
return 0;
}
@ -648,6 +692,8 @@ static int unpack_private_only(keypair *kp, struct rotbuf *rb, size_t key_length
kp->private_key_len = key_length;
if ((kp->private_key = emalloc(kp->private_key_len))==NULL)
return -1;
}else{
assert(kp->private_key_len == key_length);
}
rotbuf_getbuf(rb, kp->private_key, kp->private_key_len);
return 0;
@ -659,6 +705,8 @@ static int unpack_public_only(keypair *kp, struct rotbuf *rb, size_t key_length)
kp->public_key_len = key_length;
if ((kp->public_key = emalloc(kp->public_key_len))==NULL)
return -1;
}else{
assert(kp->public_key_len == key_length);
}
rotbuf_getbuf(rb, kp->public_key, kp->public_key_len);
return 0;
@ -669,7 +717,7 @@ static int unpack_cryptobox(keypair *kp, struct rotbuf *rb, size_t key_length)
assert(key_length == kp->private_key_len);
rotbuf_getbuf(rb, kp->private_key, kp->private_key_len);
if (!rb->wrap)
_derive_scalarmult_public(kp->public_key, kp->private_key);
crypto_scalarmult_base(kp->public_key, kp->private_key);
return 0;
}
@ -750,7 +798,7 @@ const struct keytype keytypes[] = {
.private_key_size = crypto_box_SECRETKEYBYTES,
.public_key_size = crypto_box_PUBLICKEYBYTES,
.packed_size = crypto_box_SECRETKEYBYTES,
.creator = create_cryptobox,
.creator = NULL, // deprecated
.packer = pack_private_only,
.unpacker = unpack_cryptobox,
.dumper = dump_private_public,
@ -765,7 +813,7 @@ const struct keytype keytypes[] = {
.private_key_size = crypto_sign_SECRETKEYBYTES,
.public_key_size = crypto_sign_PUBLICKEYBYTES,
.packed_size = crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES,
.creator = create_cryptosign,
.creator = NULL, // deprecated
.packer = pack_private_public,
.unpacker = unpack_private_public,
.dumper = dump_private_public,
@ -806,7 +854,17 @@ const struct keytype keytypes[] = {
.unpacker = unpack_public_only,
.dumper = dump_private_public,
.loader = load_unknown
}
},
[KEYTYPE_CRYPTOCOMBINED] = {
.private_key_size = sizeof (struct combined_sk),
.public_key_size = sizeof (struct combined_pk),
.packed_size = crypto_sign_SEEDBYTES,
.creator = create_cryptocombined,
.packer = pack_cryptocombined,
.unpacker = unpack_cryptocombined,
.dumper = dump_private_public,
.loader = load_private_public
}
// ADD MORE KEY TYPES HERE
};
@ -1061,30 +1119,29 @@ static keyring_identity *keyring_unpack_identity(unsigned char *slot, const char
return NULL;
}
struct rotbuf rbstart = rbuf;
if (ktype < NELS(keytypes) && keytypes[ktype].unpacker) {
DEBUGF(keyring, "unpack key type = 0x%02x(%s) at offset %u", ktype, keytype_str(ktype, "unknown"), (int)rotbuf_position(&rbo));
if (keytypes[ktype].unpacker(kp, &rbuf, keypair_len) != 0) {
// If there is an error, it is probably an empty slot.
DEBUGF(keyring, "key type 0x%02x does not unpack", ktype);
keyring_free_keypair(kp);
keyring_free_identity(id);
return NULL;
}
// Ensure that the correct number of bytes was consumed.
size_t unpacked = rotbuf_delta(&rbstart, &rbuf);
if (unpacked != keypair_len) {
// If the number of bytes unpacked does not match the keypair length, it is probably an
// empty slot.
DEBUGF(keyring, "key type 0x%02x unpacked wrong length (unpacked %u, expecting %u)", ktype, (int)unpacked, (int)keypair_len);
keyring_free_keypair(kp);
keyring_free_identity(id);
return NULL;
}
} else {
DEBUGF(keyring, "unsupported key type 0x%02x at offset %u, reading %u bytes as private key", ktype, (unsigned)rotbuf_position(&rbo), (unsigned)kp->private_key_len);
assert(kp->public_key_len == 0);
assert(kp->public_key == NULL);
rotbuf_getbuf(&rbuf, kp->private_key, kp->private_key_len);
int (*unpacker)(keypair *, struct rotbuf *, size_t) = NULL;
if (ktype < NELS(keytypes))
unpacker = keytypes[ktype].unpacker;
else
unpacker = unpack_private_only;
DEBUGF(keyring, "unpack key type = 0x%02x(%s) at offset %u", ktype, keytype_str(ktype, "unknown"), (int)rotbuf_position(&rbo));
if (unpacker(kp, &rbuf, keypair_len) != 0) {
// If there is an error, it is probably an empty slot.
DEBUGF(keyring, "key type 0x%02x does not unpack", ktype);
keyring_free_keypair(kp);
keyring_free_identity(id);
return NULL;
}
// Ensure that the correct number of bytes was consumed.
size_t unpacked = rotbuf_delta(&rbstart, &rbuf);
if (unpacked != keypair_len) {
// If the number of bytes unpacked does not match the keypair length, it is probably an
// empty slot.
DEBUGF(keyring, "key type 0x%02x unpacked wrong length (unpacked %u, expecting %u)", ktype, (int)unpacked, (int)keypair_len);
keyring_free_keypair(kp);
keyring_free_identity(id);
return NULL;
}
// Got a valid key pair! Sort the key pairs by (key type, public key, private key) and weed
// out duplicates.
@ -1097,8 +1154,8 @@ static keyring_identity *keyring_unpack_identity(unsigned char *slot, const char
keyring_free_identity(id);
return NULL;
}
if (!id->keypairs || id->keypairs->type != KEYTYPE_CRYPTOBOX) {
DEBUGF(keyring, "first keypair is not type CRYPTOBOX");
if (!keyring_identity_sid(id)) {
DEBUGF(keyring, "identity does not have a SID");
keyring_free_identity(id);
return NULL;
}
@ -1122,10 +1179,17 @@ static int keyring_identity_mac(const keyring_identity *id, unsigned char *pkrsa
}
APPEND(&pkrsalt[0], 32);
keypair *kp=id->keypairs;
if (!kp || kp->type != KEYTYPE_CRYPTOBOX)
return WHY("first keypair is not type CRYPTOBOX");
APPEND(kp->private_key, kp->private_key_len);
APPEND(kp->public_key, kp->public_key_len);
uint8_t found = 0;
while(kp){
if (kp->type == KEYTYPE_CRYPTOBOX || kp->type == KEYTYPE_CRYPTOCOMBINED){
APPEND(kp->private_key, kp->private_key_len);
APPEND(kp->public_key, kp->public_key_len);
found = 1;
}
kp = kp->next;
}
if (!found)
return WHY("Identity does not have a primary key");
APPEND(id->PKRPin, strlen(id->PKRPin));
#undef APPEND
crypto_hash_sha512(mac, work, ofs);
@ -1174,9 +1238,11 @@ static int keyring_decrypt_pkr(keyring_file *k, const char *pin, int slot_number
}
// Add any unlocked subscribers to our memory table, flagged as local SIDs.
keypair *kp=keyring_identity_keytype(id, KEYTYPE_CRYPTOBOX);
if (kp)
add_subscriber(id, kp);
{
const sid_t *sid = keyring_identity_sid(id);
if (sid)
add_subscriber(id, sid);
}
/* All fine, so add the id into the context and return. */
keyring_identity **i=&k->identities;
@ -1280,16 +1346,20 @@ static unsigned find_free_slot(const keyring_file *k)
static int keyring_commit_identity(keyring_file *k, keyring_identity *id)
{
keypair *kp=find_keypair_sid(id);
keyring_identity **i=&k->identities;
while(*i){
if (cmp_keypair(kp, find_keypair_sid(*i))==0)
return 0;
i=&(*i)->next;
}
const sid_t *sid=keyring_identity_sid(id);
// Do nothing if an identity with this sid already exists
keyring_iterator it;
keyring_iterator_start(k, &it);
if (keyring_find_sid(&it, sid))
return 0;
set_slot(k, id->slot, 1);
keyring_identity **i=&k->identities;
while(*i)
i=&(*i)->next;
*i=id;
add_subscriber(id, kp);
add_subscriber(id, sid);
return 1;
}
@ -1541,34 +1611,68 @@ keypair * keyring_find_public_tag_value(keyring_iterator *it, const char *name,
return NULL;
}
struct keypair *keyring_find_sas_private(keyring_file *k, keyring_identity *identity)
static int keyring_find_sign_key(keyring_file *k, keyring_identity *identity, const uint8_t **sk, const uint8_t **pk)
{
IN();
assert(identity);
keypair *kp = keyring_identity_keytype(identity, KEYTYPE_CRYPTOSIGN);
if (kp==NULL) {
WHY("Identity lacks SAS");
RETURN(NULL);
}
if (!kp->verified){
if (!rhizome_verify_bundle_privatekey(kp->private_key,kp->public_key)){
/* SAS key is invalid (perhaps because it was a pre 0.90 format one),
so replace it */
WARN("SAS key is invalid -- regenerating.");
crypto_sign_keypair(kp->public_key, kp->private_key);
keyring_commit(k);
keypair *kp=identity->keypairs;
while(kp){
if (kp->type == KEYTYPE_CRYPTOSIGN){
if (!kp->verified){
if (!rhizome_verify_bundle_privatekey(kp->private_key,kp->public_key)){
/* SAS key is invalid (perhaps because it was a pre 0.90 format one),
so replace it */
WARN("SAS key is invalid -- regenerating.");
crypto_sign_keypair(kp->public_key, kp->private_key);
keyring_commit(k);
}
kp->verified=1;
}
DEBUGF(keyring, "Found SAS entry");
if (sk)
*sk = kp->private_key;
if (pk)
*pk = kp->public_key;
RETURN(0);
}else if (kp->type == KEYTYPE_CRYPTOCOMBINED){
DEBUGF(keyring, "Found combined key");
if (sk){
struct combined_sk *secret = (struct combined_sk *)kp->private_key;
*sk = secret->sign_key;
}
if (pk){
struct combined_pk *secret = (struct combined_pk *)kp->public_key;
*pk = secret->sign_key;
}
RETURN(0);
}
kp->verified=1;
kp=kp->next;
}
DEBUGF(keyring, "Found SAS entry");
RETURN(kp);
RETURN(WHY("Identity lacks SAS"));
OUT();
}
// sign the hash of a message, adding the signature to the end of the message buffer.
int keyring_sign_message(struct keyring_identity *identity, unsigned char *content, size_t buffer_len, size_t *content_len)
{
if (*content_len + SIGNATURE_BYTES > buffer_len)
return WHYF("Insufficient space in message buffer to add signature. %zu, need %zu",buffer_len, *content_len + SIGNATURE_BYTES);
const uint8_t *sk = NULL;
if (keyring_find_sign_key(keyring, identity, &sk, NULL)==-1)
return -1;
unsigned char hash[crypto_hash_sha512_BYTES];
crypto_hash_sha512(hash, content, *content_len);
if (crypto_sign_detached(&content[*content_len], NULL, hash, crypto_hash_sha512_BYTES, sk))
return WHY("Signing failed");
*content_len += SIGNATURE_BYTES;
return 0;
}
static int keyring_store_sas(struct internal_mdp_header *header, struct overlay_buffer *payload)
{
if (header->source->sas_valid){
@ -1602,13 +1706,13 @@ static int keyring_store_sas(struct internal_mdp_header *header, struct overlay_
static int keyring_respond_sas(keyring_file *k, struct internal_mdp_header *header)
{
const uint8_t *sk = NULL;
const uint8_t *pk = NULL;
if (keyring_find_sign_key(k, header->destination->identity, &sk, &pk)==-1)
return -1;
/* It's a request, so find the SAS for the SID the request was addressed to,
use that to sign that SID, and then return it in an authcrypted frame. */
struct keypair *kp = keyring_find_sas_private(k, header->destination->identity);
if (!kp)
return WHY("I don't have that SAS key");
struct internal_mdp_header response;
bzero(&response, sizeof response);
mdp_init_response(header, &response);
@ -1617,11 +1721,11 @@ static int keyring_respond_sas(keyring_file *k, struct internal_mdp_header *head
struct overlay_buffer *response_payload = ob_static(buff, sizeof buff);
ob_limitsize(response_payload, sizeof buff);
ob_append_byte(response_payload, kp->type);
ob_append_bytes(response_payload, kp->public_key, kp->public_key_len);
ob_append_byte(response_payload, KEYTYPE_CRYPTOSIGN);
ob_append_bytes(response_payload, pk, crypto_sign_PUBLICKEYBYTES);
uint8_t *sig = ob_append_space(response_payload, crypto_sign_BYTES);
if (crypto_sign_detached(sig, NULL, header->destination->sid.binary, SID_SIZE, kp->private_key))
if (crypto_sign_detached(sig, NULL, header->destination->sid.binary, SID_SIZE, sk))
return WHY("crypto_sign() failed");
DEBUGF(keyring, "Sending SID:SAS mapping, %zd bytes, %s:%"PRImdp_port_t" -> %s:%"PRImdp_port_t,
@ -1660,7 +1764,7 @@ int keyring_send_unlock(struct subscriber *subscriber)
ob_append_byte(response, UNLOCK_REQUEST);
size_t len = ob_position(response);
if (crypto_sign_message(subscriber->identity, ob_ptr(response), sizeof(buff), &len))
if (keyring_sign_message(subscriber->identity, ob_ptr(response), sizeof(buff), &len))
return -1;
ob_append_space(response, len - ob_position(response));
@ -1723,7 +1827,7 @@ static int keyring_respond_challenge(struct subscriber *subscriber, struct overl
ob_append_bytes(response, ob_current_ptr(payload), ob_remaining(payload));
size_t len = ob_position(response);
if (crypto_sign_message(subscriber->identity, ob_ptr(response), sizeof(buff), &len))
if (keyring_sign_message(subscriber->identity, ob_ptr(response), sizeof(buff), &len))
return -1;
ob_append_space(response, len - ob_position(response));
@ -1822,21 +1926,24 @@ int keyring_send_sas_request(struct subscriber *subscriber){
void keyring_identity_extract(const keyring_identity *id, const sid_t **sidp, const char **didp, const char **namep)
{
int todo = (sidp ? 1 : 0) | (didp ? 2 : 0) | (namep ? 4 : 0);
keypair *kp=id->keypairs;
while(kp){
switch (kp->type) {
case KEYTYPE_CRYPTOBOX:
if (sidp)
*sidp = (const sid_t *)kp->public_key;
todo &= ~1;
break;
case KEYTYPE_DID:
if (didp)
*didp = (const char *) kp->private_key;
if (namep)
*namep = (const char *) kp->public_key;
todo &= ~6;
break;
case KEYTYPE_CRYPTOCOMBINED:
if (sidp){
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
*sidp = &pk->box_key;
}
break;
}
kp=kp->next;
@ -1959,7 +2066,8 @@ unsigned char *keyring_get_nm_bytes(const sid_t *known_sidp, const sid_t *unknow
in fact a known key */
keyring_iterator it;
keyring_iterator_start(keyring, &it);
if (!keyring_find_sid(&it, known_sidp)) {
const uint8_t *sk;
if (!keyring_find_box(&it, known_sidp, &sk)) {
WHY("known key is not in fact known.");
RETURN(NULL);
}
@ -1974,7 +2082,7 @@ unsigned char *keyring_get_nm_bytes(const sid_t *known_sidp, const sid_t *unknow
/* calculate and store */
nm_cache[i].known_key = *known_sidp;
nm_cache[i].unknown_key = *unknown_sidp;
if (crypto_box_beforenm(nm_cache[i].nm_bytes, unknown_sidp->binary, it.keypair->private_key)){
if (crypto_box_beforenm(nm_cache[i].nm_bytes, unknown_sidp->binary, sk)){
WHY("crypto_box_beforenm failed");
RETURN(NULL);
}

View File

@ -81,7 +81,8 @@ keypair * keyring_next_key(keyring_iterator *it);
keypair * keyring_next_keytype(keyring_iterator *it, unsigned keytype);
keypair *keyring_identity_keytype(keyring_identity *id, unsigned keytype);
keypair *keyring_find_did(keyring_iterator *it, const char *did);
keypair *keyring_find_sid(keyring_iterator *it, const sid_t *sidp);
int keyring_find_sid(keyring_iterator *it, const sid_t *sidp);
const sid_t *keyring_identity_sid(const keyring_identity *id);
void keyring_free(keyring_file *k);
int keyring_release_identity(keyring_iterator *it);
@ -96,6 +97,9 @@ int keyring_release_identity(keyring_iterator *it);
/* Arbitrary name / value pairs */
#define KEYTYPE_PUBLIC_TAG 0x05
// Combined signing / encryption key data
#define KEYTYPE_CRYPTOCOMBINED 0x06
/* handle to keyring file for use in running instance */
extern __thread keyring_file *keyring;
@ -105,7 +109,7 @@ keyring_file *keyring_open_instance(const char *pin);
keyring_file *keyring_open_instance_cli(const struct cli_parsed *parsed);
int keyring_enter_pin(keyring_file *k, const char *pin);
int keyring_set_did(keyring_identity *id, const char *did, const char *name);
struct keypair *keyring_find_sas_private(keyring_file *k, keyring_identity *identity);
int keyring_sign_message(struct keyring_identity *identity, unsigned char *content, size_t buffer_len, size_t *content_len);
int keyring_send_sas_request(struct subscriber *subscriber);
int keyring_commit(keyring_file *k);

View File

@ -151,13 +151,14 @@ static int app_keyring_list(const struct cli_parsed *parsed, struct cli_context
static void cli_output_identity(struct cli_context *context, const keyring_identity *id)
{
const sid_t *sid = keyring_identity_sid(id);
if (sid){
cli_field_name(context, "sid", ":");
cli_put_string(context, alloca_tohex_sid_t(*sid), "\n");
}
keypair *kp=id->keypairs;
while(kp){
switch(kp->type){
case KEYTYPE_CRYPTOBOX:
cli_field_name(context, "sid", ":");
cli_put_string(context, alloca_tohex(kp->public_key, kp->public_key_len), "\n");
break;
case KEYTYPE_DID:
{
char *str = (char*)kp->private_key;

View File

@ -859,7 +859,7 @@ int _overlay_send_frame(struct __sourceloc whence, struct internal_mdp_header *h
// Lets just append some space into the existing payload buffer for the signature, without copying it.
frame->payload = plaintext;
if ( !ob_makespace(frame->payload, SIGNATURE_BYTES)
|| crypto_sign_message(frame->source->identity, ob_ptr(frame->payload), frame->payload->allocSize, &frame->payload->position) == -1
|| keyring_sign_message(frame->source->identity, ob_ptr(frame->payload), frame->payload->allocSize, &frame->payload->position) == -1
) {
op_free(frame);
return -1;

View File

@ -395,12 +395,10 @@ void rhizome_find_bundle_author_and_secret(rhizome_manifest *m)
continue; // don't try the same identity again
if (rhizome_secret_yields_bundle_secret(m, kp->private_key, kp->private_key_len)) {
DEBUGF(rhizome, " found matching Rhizome secret!");
keypair *kp_sid = keyring_identity_keytype(it.identity, KEYTYPE_CRYPTOBOX);
if (kp_sid)
author_sidp = (const sid_t *) kp_sid->public_key;
else
DEBUGF(rhizome, " ... but its identity has no SID");
break;
author_sidp = keyring_identity_sid(it.identity);
if (author_sidp)
break;
DEBUGF(rhizome, " ... but its identity has no SID");
}
}
}