Set authorship to remote if the sender sid can be generated from the id

This commit is contained in:
Jeremy Lakeman 2016-10-16 10:44:36 +10:30
parent 65831e31d4
commit 30aa1c16b8
10 changed files with 94 additions and 18 deletions

View File

@ -30,6 +30,22 @@ int crypto_isvalid_keypair(const sign_private_t *private_key, const sign_public_
return bcmp(test_key.public_key.binary, public_key->binary, sizeof (sign_public_t)) == 0 ? 1 : 0;
}
int crypto_sign_to_sid(const sign_public_t *public_key, sid_t *sid)
{
if (crypto_sign_ed25519_pk_to_curve25519(sid->binary, public_key->binary))
return WHY("Failed to convert sign key to sid");
return 0;
}
int crypto_ismatching_sign_sid(const sign_public_t *public_key, const sid_t *sid)
{
sid_t test_sid;
if (crypto_sign_to_sid(public_key, &test_sid)==0
&& cmp_sid_t(&test_sid, sid)==0)
return 1;
return 0;
}
// verify the signature at the end of a message, on return message_len will be reduced by the length of the signature.
int crypto_verify_message(struct subscriber *subscriber, unsigned char *message, size_t *message_len)
{

View File

@ -25,5 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
int crypto_isvalid_keypair(const sign_private_t *private_key, const sign_public_t *public_key);
int crypto_verify_message(struct subscriber *subscriber, unsigned char *message, size_t *message_len);
int crypto_sign_to_sid(const sign_public_t *public_key, sid_t *sid);
int crypto_ismatching_sign_sid(const sign_public_t *public_key, const sid_t *sid);
#endif

View File

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <arpa/inet.h>
#include "serval.h"
#include "conf.h"
#include "crypto.h"
#include "str.h"
#include "overlay_address.h"
#include "overlay_buffer.h"
@ -317,12 +318,12 @@ int overlay_broadcast_parse(struct overlay_buffer *b, struct broadcast *broadcas
static int decode_sid_from_signkey(struct overlay_buffer *b, struct subscriber **subscriber)
{
const uint8_t *id = ob_get_bytes_ptr(b, crypto_sign_PUBLICKEYBYTES);
const sign_public_t *id = (const sign_public_t *)ob_get_bytes_ptr(b, crypto_sign_PUBLICKEYBYTES);
if (!id)
return WHY("Not enough space in buffer to parse address");
sid_t sid;
if (crypto_sign_ed25519_pk_to_curve25519(sid.binary, id))
return WHY("Failed to convert sign key to sid");
if (crypto_sign_to_sid(id, &sid))
return -1;
struct subscriber *s = find_subscriber(sid.binary, SID_SIZE, 1);
if (s && !s->id_combined){
bcopy(id, s->id_public.binary, crypto_sign_PUBLICKEYBYTES);

View File

@ -71,17 +71,15 @@ static int keyring_store_id(struct internal_mdp_header *header, struct overlay_b
if (ob_remaining(payload) < IDENTITY_SIZE + crypto_sign_BYTES)
return WHY("Truncated key mapping announcement?");
const uint8_t *id_public = ob_get_bytes_ptr(payload, IDENTITY_SIZE);
const sign_public_t *id_public = (const sign_public_t *)ob_get_bytes_ptr(payload, IDENTITY_SIZE);
const uint8_t *compactsignature = ob_get_bytes_ptr(payload, crypto_sign_BYTES);
if (crypto_sign_verify_detached(compactsignature, header->source->sid.binary, SID_SIZE, id_public))
if (crypto_sign_verify_detached(compactsignature, header->source->sid.binary, SID_SIZE, id_public->binary))
return WHY("SID:SAS mapping verification signature does not verify");
// test if the signing key can be used to derive the sid
sid_t sid;
if (crypto_sign_ed25519_pk_to_curve25519(sid.binary, id_public)==0
&& memcmp(&sid, &header->source->sid, sizeof sid) == 0)
if (crypto_ismatching_sign_sid(id_public, &header->source->sid))
header->source->id_combined=1;
/* now store it */

View File

@ -159,7 +159,8 @@ typedef struct rhizome_manifest
AUTHOR_UNKNOWN, // author is not a local identity
AUTHOR_LOCAL, // author is in keyring (unlocked) but not verified
AUTHOR_IMPOSTOR, // author is a local identity but fails verification
AUTHOR_AUTHENTIC // a local identity is the verified author
AUTHOR_AUTHENTIC, // a local identity is the verified author
AUTHOR_REMOTE // the author of this bundle has signed it, but isn't in our keyring
} authorship;
/* Whether the paylaod is encrypted or not */

View File

@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <sys/uio.h>
#include "serval.h"
#include "conf.h"
#include "crypto.h"
#include "rhizome.h"
#include "str.h"
#include "numeric_str.h"
@ -1473,7 +1474,7 @@ struct rhizome_bundle_result rhizome_fill_manifest(rhizome_manifest *m, const ch
return rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_NEW);
}
/* Work out the authorship status of the bundle without performing any cryptographic checks.
/* Work out the authorship status of the bundle without performing expensive cryptographic checks.
* Sets the 'authorship' element and returns 1 if an author was found, 0 if not.
*
* @author Andrew Bettison <andrew@servalproject.com>
@ -1484,6 +1485,7 @@ int rhizome_lookup_author(rhizome_manifest *m)
switch (m->authorship) {
case AUTHOR_LOCAL:
case AUTHOR_AUTHENTIC:
case AUTHOR_REMOTE:
RETURN(1);
case AUTHOR_NOT_CHECKED:
DEBUGF(rhizome, "manifest %p lookup author=%s", m, alloca_tohex_sid_t(m->author));
@ -1501,6 +1503,12 @@ int rhizome_lookup_author(rhizome_manifest *m)
rhizome_manifest_set_author(m, &m->sender);
m->authorship = AUTHOR_LOCAL;
RETURN(1);
} else if(crypto_ismatching_sign_sid(&m->keypair.public_key, &m->sender)) {
// if the author matches the bundle id...
DEBUGF(rhizome, "sender matches manifest signature");
m->author = m->sender;
m->authorship = AUTHOR_REMOTE;
RETURN(1);
}
}
// fall through

View File

@ -780,6 +780,9 @@ static int app_rhizome_list(const struct cli_parsed *parsed, struct cli_context
fromhere = 1;
cli_put_hexvalue(context, m->author.binary, sizeof m->author.binary, ":");
break;
case AUTHOR_REMOTE:
cli_put_hexvalue(context, m->author.binary, sizeof m->author.binary, ":");
break;
default:
cli_put_string(context, NULL, ":");
break;

View File

@ -162,6 +162,16 @@ static keypair *get_secret(const keyring_identity *id)
return kp;
}
static enum rhizome_bundle_authorship set_authentic(rhizome_manifest *m, const keyring_identity *id, const sid_t *sid)
{
m->authorship = AUTHOR_AUTHENTIC;
m->author = *sid;
m->author_identity = id;
if (!m->haveSecret)
m->haveSecret = EXISTING_BUNDLE_ID;
return m->authorship;
}
/*
* If this identity has permission to alter the bundle, then set;
* - the manifest 'authorship' field to AUTHOR_AUTHENTIC
@ -223,13 +233,7 @@ static enum rhizome_bundle_authorship try_author(rhizome_manifest *m, const keyr
INT64, m->rowid,
END);
}
m->authorship = AUTHOR_AUTHENTIC;
m->author = *sid;
m->author_identity = id;
if (!m->haveSecret)
m->haveSecret = EXISTING_BUNDLE_ID;
return m->authorship;
return set_authentic(m, id, sid);
}
/* Attempt to authenticate the authorship of the given bundle, and set the 'authorship' element
@ -256,6 +260,24 @@ void rhizome_authenticate_author(rhizome_manifest *m)
assert(is_sid_t_any(m->author));
if (m->has_sender){
sid_t test_sid;
if (crypto_sign_to_sid(&m->keypair.public_key, &test_sid)==0){
if (cmp_sid_t(&test_sid, &m->sender)==0){
// self signed bundle, is it ours?
keyring_identity *id = keyring_find_identity(keyring, &m->keypair.public_key);
if (id){
set_authentic(m, id, &m->sender);
RETURNVOID;
}else{
m->authorship = AUTHOR_REMOTE;
m->author = m->sender;
RETURNVOID;
}
}
}
}
// Optimisation: try 'sender' SID first, if present.
if (m->has_sender && try_author(m, NULL, &m->sender) == AUTHOR_AUTHENTIC)
RETURNVOID;
@ -277,11 +299,13 @@ void rhizome_authenticate_author(rhizome_manifest *m)
case AUTHOR_LOCAL:
m->authorship = try_author(m, m->author_identity, &m->author);
RETURNVOID;
case AUTHOR_REMOTE:
case AUTHENTICATION_ERROR:
case AUTHOR_UNKNOWN:
case AUTHOR_IMPOSTOR:
case AUTHOR_AUTHENTIC:
// work has already been done, don't repeat it
// TODO rescan keyring if more identities are unlocked??
RETURNVOID;
}
FATALF("m->authorship = %d", (int)m->authorship);

View File

@ -328,6 +328,9 @@ static int restful_rhizome_bundlelist_json_content_chunk(struct http_request *hr
fromhere = 1;
strbuf_json_hex(b, m->author.binary, sizeof m->author.binary);
break;
case AUTHOR_REMOTE:
strbuf_json_hex(b, m->author.binary, sizeof m->author.binary);
break;
default:
strbuf_json_null(b);
break;

View File

@ -1446,6 +1446,26 @@ test_ImportOwnBundle() {
assert_rhizome_list --fromhere=1 --author=$SIDB2 fileB
}
doc_ImportSelfSigned="Import a bundle with id matching identity"
setup_ImportSelfSigned(){
B_IDENTITY_COUNT=1
setup_servald
setup_rhizome
echo "Self signed" > file
}
test_ImportSelfSigned(){
set_instance +A
executeOk_servald rhizome add file $SIDA file file.manifest '' id=$IDA sender=$SIDA
extract_stdout_manifestid BID
assert [ "$BID" = "$IDA" ]
executeOk_servald rhizome list
set_instance +B
executeOk_servald rhizome import bundle file file.manifest
executeOk_servald rhizome list
tfw_cat --stdout --stderr
#TODO assert that .author == $SIDA
}
doc_ImportCombinedBundle="Create and import combined bundle"
setup_ImportCombinedBundle() {
# A "combined bundle" is a single file consisting of a payload with its