mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-29 15:43:56 +00:00
Set authorship to remote if the sender sid can be generated from the id
This commit is contained in:
parent
65831e31d4
commit
30aa1c16b8
16
crypto.c
16
crypto.c
@ -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)
|
||||
{
|
||||
|
2
crypto.h
2
crypto.h
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user