mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-25 07:41:10 +00:00
substantial work towards implementing BK field in rhizome manifests.
This commit is contained in:
parent
17370b3464
commit
525d3c4154
@ -1044,9 +1044,11 @@ int app_config_get(int argc, const char *const *argv, struct command_line_option
|
||||
|
||||
int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_option *o)
|
||||
{
|
||||
const char *filepath, *manifestpath;
|
||||
const char *filepath, *manifestpath,*authorisingSid;
|
||||
cli_arg(argc, argv, o, "filepath", &filepath, NULL, "");
|
||||
cli_arg(argc, argv, o, "manifestpath", &manifestpath, NULL, "");
|
||||
cli_arg(argc, argv, o, "sid", &authorisingSid,NULL,"");
|
||||
|
||||
/* Ensure the Rhizome database exists and is open */
|
||||
if (create_serval_instance_dir() == -1)
|
||||
return -1;
|
||||
@ -1085,7 +1087,8 @@ int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_
|
||||
255, // ttl - XXX should read from somewhere
|
||||
manifest_file_supplied, // int verifyP
|
||||
1, // int checkFileP
|
||||
1 // int signP
|
||||
1, // int signP
|
||||
authorisingSid // SID of claiming author as hex, so that they can modify the bundle later
|
||||
);
|
||||
if (ret == -1)
|
||||
return WHY("Manifest not added to Rhizome database");
|
||||
|
22
rhizome.c
22
rhizome.c
@ -53,7 +53,10 @@ int rhizome_bundle_import(rhizome_manifest *m_in, rhizome_manifest **m_out, cons
|
||||
|
||||
/* Add the manifest and its associated file to the Rhizome database. */
|
||||
rhizome_manifest *dupm;
|
||||
int ret = rhizome_add_manifest(m, &dupm, filename, groups, ttl, verifyP, checkFileP, signP);
|
||||
int ret = rhizome_add_manifest(m, &dupm, filename, groups, ttl,
|
||||
verifyP, checkFileP, signP,
|
||||
NULL /* don't specify author for manifests
|
||||
received via mesh */);
|
||||
unlink(filename);
|
||||
if (ret == -1) {
|
||||
unlink(manifestname);
|
||||
@ -137,7 +140,8 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
int ttl,
|
||||
int verifyP, // verify that file's hash is consistent with manifest
|
||||
int checkFileP,
|
||||
int signP
|
||||
int signP,
|
||||
const char *author
|
||||
)
|
||||
{
|
||||
if (m_out) *m_out = NULL;
|
||||
@ -246,7 +250,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
}
|
||||
/* Check if we know its private key */
|
||||
rhizome_hex_to_bytes(id, m_in->cryptoSignPublic, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES*2);
|
||||
if (!rhizome_find_keypair_bytes(m_in->cryptoSignPublic, m_in->cryptoSignSecret))
|
||||
if (!rhizome_find_privatekey(m_in))
|
||||
m_in->haveSecret=1;
|
||||
} else {
|
||||
/* The manifest had no ID (256 bit random string being a public key in the NaCl CryptoSign
|
||||
@ -255,9 +259,19 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
|
||||
/* The ID is implicit in transit, but we need to store it in the file, so that reimporting
|
||||
manifests on receiver nodes works easily. We might implement something that strips the id
|
||||
variable out of the manifest when sending it, or some other scheme to avoid sending all the
|
||||
extra bytes. */
|
||||
extra bytes. */
|
||||
id = rhizome_bytes_to_hex(m_in->cryptoSignPublic, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES);
|
||||
rhizome_manifest_set(m_in, "id", id);
|
||||
if (author) {
|
||||
/* Set the BK using the provided authorship information.
|
||||
Serval Security Framework defines BK as being:
|
||||
BK = privateKey XOR sha512(RS##BID), where BID = cryptoSignPublic,
|
||||
and RS is the rhizome secret for the specified author.
|
||||
The nice thing about this specification is that:
|
||||
privateKey = BK XOR sha512(RS##BID), so the same function can be used
|
||||
to encrypt and decrypt the BK field. */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Add group memberships */
|
||||
|
13
rhizome.h
13
rhizome.h
@ -199,14 +199,13 @@ int rhizome_bundle_import(rhizome_manifest *m_in, rhizome_manifest **m_out, cons
|
||||
int verifyP, int checkFileP, int signP);
|
||||
int rhizome_add_manifest(rhizome_manifest *m_in, rhizome_manifest **m_out, const char *filename,
|
||||
char *groups[], int ttl,
|
||||
int verifyP, int checkFileP, int signP);
|
||||
int verifyP, int checkFileP, int signP,
|
||||
const char *author);
|
||||
int rhizome_manifest_finalise(rhizome_manifest *m,int signP);
|
||||
char *rhizome_bytes_to_hex(unsigned char *in,int byteCount);
|
||||
int rhizome_hex_to_bytes(const char *in,unsigned char *out,int hexChars);
|
||||
int rhizome_store_keypair_bytes(unsigned char *p,unsigned char *s);
|
||||
int rhizome_find_keypair_bytes(unsigned char *p,unsigned char *s);
|
||||
rhizome_signature *rhizome_sign_hash(unsigned char *hash,unsigned char *publicKeyBytes);
|
||||
|
||||
int rhizome_find_privatekey(rhizome_manifest *m);
|
||||
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m);
|
||||
int rhizome_server_free_http_request(rhizome_http_request *r);
|
||||
int rhizome_server_close_http_request(int i);
|
||||
int rhizome_server_http_send_bytes(int rn,rhizome_http_request *r);
|
||||
@ -236,3 +235,7 @@ int rhizome_fetching_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
||||
int rhizome_manifest_version_cache_lookup(rhizome_manifest *m);
|
||||
int rhizome_manifest_version_cache_store(rhizome_manifest *m);
|
||||
int monitor_announce_bundle(rhizome_manifest *m);
|
||||
int rhizome_bk_xor(const char *author,
|
||||
unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
|
||||
unsigned char bkin[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES],
|
||||
unsigned char bkout[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES]);
|
||||
|
@ -145,14 +145,7 @@ rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferP,
|
||||
} else m->selfSigned=1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for a BK entry that allows us to recover the private key for this bundle's ID.
|
||||
The challenge is that BK's are designed to offer plausible deniability, in that the
|
||||
manifest provides nothing that would allow an adversary, without posession of the creator's
|
||||
keyring, to be able to prove that any given identity is the creator of the file.
|
||||
*/
|
||||
|
||||
|
||||
if (debug&DEBUG_RHIZOME)
|
||||
fprintf(stderr, "Group membership determination not implemented (see which signatories are groups? what about manifests signed by groups we don't yet know about?)\n");
|
||||
}
|
||||
@ -423,7 +416,7 @@ int rhizome_manifest_pack_variables(rhizome_manifest *m)
|
||||
/* Sign this manifest using our own private CryptoSign key */
|
||||
int rhizome_manifest_sign(rhizome_manifest *m)
|
||||
{
|
||||
rhizome_signature *sig=rhizome_sign_hash(m->manifesthash,m->cryptoSignPublic);
|
||||
rhizome_signature *sig=rhizome_sign_hash(m);
|
||||
|
||||
if (!sig) return WHY("rhizome_sign_hash() failed.");
|
||||
|
||||
|
@ -41,10 +41,11 @@ int rhizome_manifest_createid(rhizome_manifest *m)
|
||||
{
|
||||
m->haveSecret=1;
|
||||
int r=crypto_sign_edwards25519sha512batch_keypair(m->cryptoSignPublic,m->cryptoSignSecret);
|
||||
if (!r) return rhizome_store_keypair_bytes(m->cryptoSignPublic,m->cryptoSignSecret);
|
||||
if (!r) return 0;
|
||||
return WHY("Failed to create keypair for manifest ID.");
|
||||
}
|
||||
|
||||
#ifdef DEPRECATED
|
||||
int rhizome_store_keypair_bytes(unsigned char *p,unsigned char *s) {
|
||||
/* XXX TODO Secrets should be encrypted using a keyring password. */
|
||||
if (sqlite_exec_int64("INSERT INTO KEYPAIRS(public,private) VALUES('%s','%s');",
|
||||
@ -79,12 +80,56 @@ int rhizome_find_keypair_bytes(unsigned char *p,unsigned char *s) {
|
||||
sqlite3_finalize(statement);
|
||||
return WHY("Could not find matching secret key.");
|
||||
}
|
||||
#endif
|
||||
|
||||
rhizome_signature *rhizome_sign_hash(unsigned char *hash,unsigned char *publicKeyBytes)
|
||||
int rhizome_bk_xor(const char *author,
|
||||
unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
|
||||
unsigned char bkin[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES],
|
||||
unsigned char bkout[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES])
|
||||
{
|
||||
if (crypto_sign_edwards25519sha512batch_SECRETKEYBYTES>
|
||||
crypto_hash_sha512_BYTES)
|
||||
return WHY("BK needs to be longer than it can be");
|
||||
|
||||
unsigned char authorSid[SID_SIZE];
|
||||
if (stowSid(authorSid,0,author)) return WHY("stowSid() failed");
|
||||
int cn=0,in=0,kp=0;
|
||||
if (!keyring_find_sid(keyring,&cn,&in,&kp,authorSid))
|
||||
return WHY("keyring_find_sid() couldn't find that SID. Have you unlocked that identity?");
|
||||
for(kp=0;kp<keyring->contexts[cn]->identities[in]->keypair_count;kp++)
|
||||
if (keyring->contexts[cn]->identities[in]->keypairs[kp]->type==KEYTYPE_RHIZOME)
|
||||
break;
|
||||
if (kp>=keyring->contexts[cn]->identities[in]->keypair_count)
|
||||
return WHY("Identity has no Rhizome Secret");
|
||||
int rs_len=keyring->contexts[cn]->identities[in]->keypairs[kp]->private_key_len;
|
||||
unsigned char *rs=keyring->contexts[cn]->identities[in]->keypairs[kp]->private_key;
|
||||
if (rs_len<16||rs_len>1024)
|
||||
return WHYF("Rhizome Secret is too short or too long (length=%d)",rs_len);
|
||||
|
||||
int combined_len=rs_len+crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES;
|
||||
unsigned char buffer[combined_len];
|
||||
bcopy(&rs[0],&buffer[0],rs_len);
|
||||
bcopy(&bid[0],&buffer[rs_len],crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES);
|
||||
unsigned char hash[crypto_hash_sha512_BYTES];
|
||||
crypto_hash_sha512(hash,buffer,combined_len);
|
||||
|
||||
int i;
|
||||
for(i=0;i<crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES;i++)
|
||||
bkout[i]=bkin[i]^hash[i];
|
||||
|
||||
bzero(&buffer[0],combined_len);
|
||||
bzero(&hash[0],crypto_hash_sha512_BYTES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m)
|
||||
{
|
||||
unsigned char *hash=m->manifesthash;
|
||||
unsigned char *publicKeyBytes=m->cryptoSignPublic;
|
||||
unsigned char secretKeyBytes[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES];
|
||||
|
||||
if (rhizome_find_keypair_bytes(publicKeyBytes,secretKeyBytes))
|
||||
if (rhizome_find_privatekey(m))
|
||||
{
|
||||
WHY("Cannot find secret key to sign manifest data.");
|
||||
return NULL;
|
||||
|
@ -399,11 +399,8 @@ int rhizome_store_bundle(rhizome_manifest *m, const char *associated_filename)
|
||||
manifestid, m->version, gettime_ms());
|
||||
|
||||
if (m->haveSecret) {
|
||||
if (rhizome_store_keypair_bytes(m->cryptoSignPublic,m->cryptoSignSecret))
|
||||
{
|
||||
WHY("*** Insert into manifests failed (-1).");
|
||||
return WHY("Failed to store key pair.");
|
||||
}
|
||||
/* We used to store the secret in the database, but we don't anymore, as we use
|
||||
the BK field in the manifest. So nothing to do here. */
|
||||
} else {
|
||||
/* We don't have the secret for this manifest, so only allow updates if
|
||||
the self-signature is valid */
|
||||
|
Loading…
Reference in New Issue
Block a user