mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-06 11:09:13 +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;
|
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.
|
// 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)
|
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_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_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
|
#endif
|
||||||
|
@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "serval.h"
|
#include "serval.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "crypto.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "overlay_address.h"
|
#include "overlay_address.h"
|
||||||
#include "overlay_buffer.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)
|
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)
|
if (!id)
|
||||||
return WHY("Not enough space in buffer to parse address");
|
return WHY("Not enough space in buffer to parse address");
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
if (crypto_sign_ed25519_pk_to_curve25519(sid.binary, id))
|
if (crypto_sign_to_sid(id, &sid))
|
||||||
return WHY("Failed to convert sign key to sid");
|
return -1;
|
||||||
struct subscriber *s = find_subscriber(sid.binary, SID_SIZE, 1);
|
struct subscriber *s = find_subscriber(sid.binary, SID_SIZE, 1);
|
||||||
if (s && !s->id_combined){
|
if (s && !s->id_combined){
|
||||||
bcopy(id, s->id_public.binary, crypto_sign_PUBLICKEYBYTES);
|
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)
|
if (ob_remaining(payload) < IDENTITY_SIZE + crypto_sign_BYTES)
|
||||||
return WHY("Truncated key mapping announcement?");
|
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);
|
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");
|
return WHY("SID:SAS mapping verification signature does not verify");
|
||||||
|
|
||||||
// test if the signing key can be used to derive the sid
|
// test if the signing key can be used to derive the sid
|
||||||
sid_t sid;
|
if (crypto_ismatching_sign_sid(id_public, &header->source->sid))
|
||||||
if (crypto_sign_ed25519_pk_to_curve25519(sid.binary, id_public)==0
|
|
||||||
&& memcmp(&sid, &header->source->sid, sizeof sid) == 0)
|
|
||||||
header->source->id_combined=1;
|
header->source->id_combined=1;
|
||||||
|
|
||||||
/* now store it */
|
/* now store it */
|
||||||
|
@ -159,7 +159,8 @@ typedef struct rhizome_manifest
|
|||||||
AUTHOR_UNKNOWN, // author is not a local identity
|
AUTHOR_UNKNOWN, // author is not a local identity
|
||||||
AUTHOR_LOCAL, // author is in keyring (unlocked) but not verified
|
AUTHOR_LOCAL, // author is in keyring (unlocked) but not verified
|
||||||
AUTHOR_IMPOSTOR, // author is a local identity but fails verification
|
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;
|
} authorship;
|
||||||
|
|
||||||
/* Whether the paylaod is encrypted or not */
|
/* 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 <sys/uio.h>
|
||||||
#include "serval.h"
|
#include "serval.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "crypto.h"
|
||||||
#include "rhizome.h"
|
#include "rhizome.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "numeric_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);
|
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.
|
* Sets the 'authorship' element and returns 1 if an author was found, 0 if not.
|
||||||
*
|
*
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @author Andrew Bettison <andrew@servalproject.com>
|
||||||
@ -1484,6 +1485,7 @@ int rhizome_lookup_author(rhizome_manifest *m)
|
|||||||
switch (m->authorship) {
|
switch (m->authorship) {
|
||||||
case AUTHOR_LOCAL:
|
case AUTHOR_LOCAL:
|
||||||
case AUTHOR_AUTHENTIC:
|
case AUTHOR_AUTHENTIC:
|
||||||
|
case AUTHOR_REMOTE:
|
||||||
RETURN(1);
|
RETURN(1);
|
||||||
case AUTHOR_NOT_CHECKED:
|
case AUTHOR_NOT_CHECKED:
|
||||||
DEBUGF(rhizome, "manifest %p lookup author=%s", m, alloca_tohex_sid_t(m->author));
|
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);
|
rhizome_manifest_set_author(m, &m->sender);
|
||||||
m->authorship = AUTHOR_LOCAL;
|
m->authorship = AUTHOR_LOCAL;
|
||||||
RETURN(1);
|
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
|
// fall through
|
||||||
|
@ -780,6 +780,9 @@ static int app_rhizome_list(const struct cli_parsed *parsed, struct cli_context
|
|||||||
fromhere = 1;
|
fromhere = 1;
|
||||||
cli_put_hexvalue(context, m->author.binary, sizeof m->author.binary, ":");
|
cli_put_hexvalue(context, m->author.binary, sizeof m->author.binary, ":");
|
||||||
break;
|
break;
|
||||||
|
case AUTHOR_REMOTE:
|
||||||
|
cli_put_hexvalue(context, m->author.binary, sizeof m->author.binary, ":");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cli_put_string(context, NULL, ":");
|
cli_put_string(context, NULL, ":");
|
||||||
break;
|
break;
|
||||||
|
@ -162,6 +162,16 @@ static keypair *get_secret(const keyring_identity *id)
|
|||||||
return kp;
|
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;
|
* If this identity has permission to alter the bundle, then set;
|
||||||
* - the manifest 'authorship' field to AUTHOR_AUTHENTIC
|
* - 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,
|
INT64, m->rowid,
|
||||||
END);
|
END);
|
||||||
}
|
}
|
||||||
|
return set_authentic(m, id, sid);
|
||||||
m->authorship = AUTHOR_AUTHENTIC;
|
|
||||||
m->author = *sid;
|
|
||||||
m->author_identity = id;
|
|
||||||
if (!m->haveSecret)
|
|
||||||
m->haveSecret = EXISTING_BUNDLE_ID;
|
|
||||||
return m->authorship;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to authenticate the authorship of the given bundle, and set the 'authorship' element
|
/* 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));
|
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.
|
// Optimisation: try 'sender' SID first, if present.
|
||||||
if (m->has_sender && try_author(m, NULL, &m->sender) == AUTHOR_AUTHENTIC)
|
if (m->has_sender && try_author(m, NULL, &m->sender) == AUTHOR_AUTHENTIC)
|
||||||
RETURNVOID;
|
RETURNVOID;
|
||||||
@ -277,11 +299,13 @@ void rhizome_authenticate_author(rhizome_manifest *m)
|
|||||||
case AUTHOR_LOCAL:
|
case AUTHOR_LOCAL:
|
||||||
m->authorship = try_author(m, m->author_identity, &m->author);
|
m->authorship = try_author(m, m->author_identity, &m->author);
|
||||||
RETURNVOID;
|
RETURNVOID;
|
||||||
|
case AUTHOR_REMOTE:
|
||||||
case AUTHENTICATION_ERROR:
|
case AUTHENTICATION_ERROR:
|
||||||
case AUTHOR_UNKNOWN:
|
case AUTHOR_UNKNOWN:
|
||||||
case AUTHOR_IMPOSTOR:
|
case AUTHOR_IMPOSTOR:
|
||||||
case AUTHOR_AUTHENTIC:
|
case AUTHOR_AUTHENTIC:
|
||||||
// work has already been done, don't repeat it
|
// work has already been done, don't repeat it
|
||||||
|
// TODO rescan keyring if more identities are unlocked??
|
||||||
RETURNVOID;
|
RETURNVOID;
|
||||||
}
|
}
|
||||||
FATALF("m->authorship = %d", (int)m->authorship);
|
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;
|
fromhere = 1;
|
||||||
strbuf_json_hex(b, m->author.binary, sizeof m->author.binary);
|
strbuf_json_hex(b, m->author.binary, sizeof m->author.binary);
|
||||||
break;
|
break;
|
||||||
|
case AUTHOR_REMOTE:
|
||||||
|
strbuf_json_hex(b, m->author.binary, sizeof m->author.binary);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
strbuf_json_null(b);
|
strbuf_json_null(b);
|
||||||
break;
|
break;
|
||||||
|
@ -1446,6 +1446,26 @@ test_ImportOwnBundle() {
|
|||||||
assert_rhizome_list --fromhere=1 --author=$SIDB2 fileB
|
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"
|
doc_ImportCombinedBundle="Create and import combined bundle"
|
||||||
setup_ImportCombinedBundle() {
|
setup_ImportCombinedBundle() {
|
||||||
# A "combined bundle" is a single file consisting of a payload with its
|
# A "combined bundle" is a single file consisting of a payload with its
|
||||||
|
Loading…
x
Reference in New Issue
Block a user