Pass author SID parameters in binary, not hex

This commit is contained in:
Andrew Bettison 2012-06-08 15:27:15 +09:30
parent f5998b3862
commit 7a71a521f8
10 changed files with 126 additions and 137 deletions

View File

@ -1140,17 +1140,20 @@ int cli_optional_bundle_key(const char *arg)
int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_option *o) int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_option *o)
{ {
const char *filepath, *manifestpath, *authorSid, *pin, *bskhex; const char *filepath, *manifestpath, *authorSidHex, *pin, *bskhex;
cli_arg(argc, argv, o, "filepath", &filepath, NULL, ""); cli_arg(argc, argv, o, "filepath", &filepath, NULL, "");
if (cli_arg(argc, argv, o, "author_sid", &authorSid, cli_optional_sid, "") == -1) if (cli_arg(argc, argv, o, "author_sid", &authorSidHex, cli_optional_sid, "") == -1)
return -1; return -1;
cli_arg(argc, argv, o, "pin", &pin, NULL, ""); cli_arg(argc, argv, o, "pin", &pin, NULL, "");
cli_arg(argc, argv, o, "manifestpath", &manifestpath, NULL, ""); cli_arg(argc, argv, o, "manifestpath", &manifestpath, NULL, "");
if (cli_arg(argc, argv, o, "bsk", &bskhex, cli_optional_bundle_key, "") == -1) if (cli_arg(argc, argv, o, "bsk", &bskhex, cli_optional_bundle_key, "") == -1)
return -1; return -1;
unsigned char bsk[RHIZOME_BUNDLE_KEY_STRLEN + 1]; unsigned char authorSid[SID_SIZE];
if (bskhex[0] && stowBytes(bsk, bskhex, RHIZOME_BUNDLE_KEY_BYTES) == -1) if (authorSidHex[0] && fromhexstr(authorSid, authorSidHex, SID_SIZE) == -1)
return -1; return WHYF("invalid author_sid: %s", authorSidHex);
unsigned char bsk[RHIZOME_BUNDLE_KEY_BYTES];
if (bskhex[0] && fromhexstr(bsk, bskhex, RHIZOME_BUNDLE_KEY_BYTES) == -1)
return WHYF("invalid bsk: %s", bskhex);
if (create_serval_instance_dir() == -1) if (create_serval_instance_dir() == -1)
return -1; return -1;
if (!(keyring = keyring_open_with_pins((char *)pin))) if (!(keyring = keyring_open_with_pins((char *)pin)))
@ -1206,8 +1209,8 @@ int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_
/* Bind an ID to the manifest, and also bind the file. Then finalise the manifest. /* Bind an ID to the manifest, and also bind the file. Then finalise the manifest.
But if the manifest already contains an ID, don't override it. */ But if the manifest already contains an ID, don't override it. */
if (rhizome_manifest_get(m, "id", NULL, 0)==NULL) { if (rhizome_manifest_get(m, "id", NULL, 0) == NULL) {
if (rhizome_manifest_bind_id(m, authorSid)) { if (rhizome_manifest_bind_id(m, authorSidHex[0] ? authorSid : NULL)) {
rhizome_manifest_free(m); rhizome_manifest_free(m);
m = NULL; m = NULL;
return WHY("Could not bind manifest to an ID"); return WHY("Could not bind manifest to an ID");
@ -1219,14 +1222,18 @@ int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_
m = NULL; m = NULL;
return WHY("Incorrect BID secret key."); return WHY("Incorrect BID secret key.");
} }
} else { } else if (authorSidHex[0]) {
/* User supplied manifest has a BID, so see if we can extract the /* User supplied manifest has a BID, so see if we can extract the
private key from a BK entry */ private key from a BK entry */
if (rhizome_extract_privatekey(m,authorSid) == -1) { if (rhizome_extract_privatekey(m, authorSid) == -1) {
rhizome_manifest_free(m); rhizome_manifest_free(m);
m = NULL; m = NULL;
return WHY("Could not extract BID secret key. Does the manifest have a BK, did you supply the correct author SID?"); return WHY("Could not extract BID secret key. Does the manifest have a BK?");
} }
} else {
rhizome_manifest_free(m);
m = NULL;
return WHY("Author SID not specified");
} }
#warning need to sanely determine whether to encrypt a file #warning need to sanely determine whether to encrypt a file
#warning payload encryption disabled for now #warning payload encryption disabled for now
@ -1239,7 +1246,7 @@ int app_rhizome_add_file(int argc, const char *const *argv, struct command_line_
/* Add the manifest and its associated file to the Rhizome database, generating an "id" in the /* Add the manifest and its associated file to the Rhizome database, generating an "id" in the
* process */ * process */
rhizome_manifest *mout = NULL; rhizome_manifest *mout = NULL;
if (debug & DEBUG_RHIZOME) DEBUGF("rhizome_add_manifest(author='%s')", authorSid); if (debug & DEBUG_RHIZOME) DEBUGF("rhizome_add_manifest(author='%s')", authorSidHex);
int ret=0; int ret=0;
if (rhizome_manifest_check_duplicate(m,&mout)==2) if (rhizome_manifest_check_duplicate(m,&mout)==2)
@ -1349,7 +1356,7 @@ int app_rhizome_extract_file(int argc, const char *const *argv, struct command_l
return -1; return -1;
cli_arg(argc, argv, o, "key", &keyhex, cli_optional_bundle_crypt_key, ""); cli_arg(argc, argv, o, "key", &keyhex, cli_optional_bundle_crypt_key, "");
unsigned char key[RHIZOME_CRYPT_KEY_STRLEN + 1]; unsigned char key[RHIZOME_CRYPT_KEY_STRLEN + 1];
if (keyhex[0] && stowBytes(key, keyhex, RHIZOME_CRYPT_KEY_BYTES) == -1) if (keyhex[0] && fromhexstr(key, keyhex, RHIZOME_CRYPT_KEY_BYTES) == -1)
return -1; return -1;
/* Ensure the Rhizome database exists and is open */ /* Ensure the Rhizome database exists and is open */
if (create_serval_instance_dir() == -1) if (create_serval_instance_dir() == -1)

View File

@ -18,8 +18,38 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include "serval.h" #include "serval.h"
#include <ctype.h>
int hexdigit[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char hexdigit[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char *tohex(char *dstHex, const unsigned char *srcBinary, size_t bytes)
{
char *p;
for (p = dstHex; bytes--; ++srcBinary) {
*p++ = hexdigit[*srcBinary >> 4];
*p++ = hexdigit[*srcBinary & 0xf];
}
*p = '\0';
return dstHex;
}
size_t fromhex(unsigned char *dstBinary, const char *srcHex, size_t bytes)
{
size_t count = 0;
while (count != bytes) {
unsigned char high = hexvalue(*srcHex++);
if (high & 0xf0) return -1;
unsigned char low = hexvalue(*srcHex++);
if (low & 0xf0) return -1;
dstBinary[count++] = (high << 4) + low;
}
return count;
}
int fromhexstr(unsigned char *dstBinary, const char *srcHex, size_t bytes)
{
return (fromhex(dstBinary, srcHex, bytes) == bytes && srcHex[bytes * 2] == '\0') ? 0 : -1;
}
int extractDid(unsigned char *packet,int *ofs,char *did) int extractDid(unsigned char *packet,int *ofs,char *did)
{ {
@ -91,67 +121,47 @@ int stowDid(unsigned char *packet,int *ofs,char *did)
return 0; return 0;
} }
int extractSid(unsigned char *packet,int *ofs,char *sid) int extractSid(unsigned char *packet, int *ofs,char *sid)
{ {
int i=0; (void) tohex(sid, packet + *ofs, SID_SIZE);
int d=0; *ofs += SID_SIZE;
for(i=0;i<SID_SIZE;i++)
{
sid[d++]=hexdigit[packet[*ofs]>>4];
sid[d++]=hexdigit[packet[*ofs]&0xf];
(*ofs)++;
}
sid[d]=0;
return 0; return 0;
} }
int validateSid(const char *sid) int validateSid(const char *sid)
{ {
if (!sid) { if (!sid) {
WHY("SID == NULL"); WHY("invalid SID == NULL");
return 0;
}
if (strcasecmp(sid, "broadcast") == 0)
return 1;
const char *s = sid;
const char *e = sid + SID_STRLEN;
while (s != e && isxdigit(*s))
++s;
if (s != e) {
if (*s)
WHYF("invalid SID, contains non-hex character 0x%02x at offset %d", *s, s - sid);
else
WHYF("invalid SID, too short (strlen %d)", s - sid);
return 0;
}
if (*s) {
WHYF("invalid SID, too long");
return 0; return 0;
} }
if (!strcasecmp(sid,"broadcast")) return 1;
size_t n = strlen(sid);
if (n != SID_STRLEN)
{ WHYF("Invalid SID (strlen is %u, should be %u)", n, SID_STRLEN); return 0; }
const char *s;
for (s = sid; *s; ++s)
if (hexvalue(*s) == -1)
{ WHY("SID contains non-hex character"); return 0; }
return 1; return 1;
} }
int stowSid(unsigned char *packet, int ofs, const char *sid) int stowSid(unsigned char *packet, int ofs, const char *sid)
{ {
if (debug & DEBUG_PACKETFORMATS)
int i; printf("stowing SID \"%s\"\n", sid);
if (debug&DEBUG_PACKETFORMATS) if (strcasecmp(sid,"broadcast") == 0)
printf("Stowing SID \"%s\"\n", sid); memset(packet + ofs, 0xff, SID_SIZE);
if (!validateSid(sid)) else if (fromhex(packet + ofs, sid, SID_SIZE) != SID_SIZE || sid[SID_STRLEN] != '\0')
return WHY("Invalid SID passed in"); return WHY("invalid SID");
if (!strcasecmp(sid,"broadcast"))
for(i=0;i<32;i++) packet[ofs++]=0xff;
else
for(i = 0; i != SID_SIZE; ++i) {
packet[ofs] = hexvalue(sid[i<<1]) << 4;
packet[ofs++] |= hexvalue(sid[(i<<1)+1]);
}
return 0;
}
int stowBytes(unsigned char *packet, const char *in,int count)
{
int ofs=0;
if (strlen(in)!=(count*2))
return WHY("Input string is wrong length");
int i;
for(i = 0; i != count; ++i) {
if(hexvalue(in[i<<1])<0) return WHYF("Non-hex char at position %d",i<<1);
if(hexvalue(in[(i<<1)+1])<0) return WHYF("Non-hex char at position %d",(i<<1)+1);
packet[ofs] = hexvalue(in[i<<1]) << 4;
packet[ofs++] |= hexvalue(in[(i<<1)+1]);
}
return 0; return 0;
} }
@ -165,10 +175,10 @@ char *str_toupper_inplace(char *str)
int hexvalue(unsigned char c) int hexvalue(unsigned char c)
{ {
if (c>='0'&&c<='9') return c-'0'; if (c >= '0' && c <= '9') return c - '0';
if (c>='A'&&c<='F') return c-'A'+10; if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c>='a'&&c<='f') return c-'a'+10; if (c >= 'a' && c <= 'f') return c - 'a' + 10;
return WHY("Invalid hex digit in SID"); return -1;
} }
int packetGetID(unsigned char *packet,int len,char *did,char *sid) int packetGetID(unsigned char *packet,int len,char *did,char *sid)

View File

@ -1314,7 +1314,7 @@ unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid)
return NULL; return NULL;
} }
int keyring_find_sid(keyring_file *k,int *cn,int *in,int *kp,unsigned char *sid) int keyring_find_sid(keyring_file *k,int *cn,int *in,int *kp, const unsigned char *sid)
{ {
if (keyring_sanitise_position(k,cn,in,kp)) return 0; if (keyring_sanitise_position(k,cn,in,kp)) return 0;

View File

@ -136,18 +136,17 @@ int rhizome_manifest_check_sanity(rhizome_manifest *m_in)
by joining the parent group. by joining the parent group.
*/ */
int rhizome_manifest_bind_id(rhizome_manifest *m_in,const char *author) int rhizome_manifest_bind_id(rhizome_manifest *m_in, const unsigned char *authorSid)
{ {
rhizome_manifest_createid(m_in); rhizome_manifest_createid(m_in);
/* The ID is implicit in transit, but we need to store it in the file, so that reimporting /* 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 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 variable out of the manifest when sending it, or some other scheme to avoid sending all the
extra bytes. */ extra bytes. */
char id[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES*2+1]; char id[RHIZOME_MANIFEST_ID_STRLEN + 1];
rhizome_bytes_to_hex_upper(m_in->cryptoSignPublic, id, crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES); rhizome_bytes_to_hex_upper(m_in->cryptoSignPublic, id, RHIZOME_MANIFEST_ID_BYTES);
rhizome_manifest_set(m_in, "id", id); rhizome_manifest_set(m_in, "id", id);
if (author&&author[0]) { if (authorSid) {
/* Set the BK using the provided authorship information. /* Set the BK using the provided authorship information.
Serval Security Framework defines BK as being: Serval Security Framework defines BK as being:
BK = privateKey XOR sha512(RS##BID), where BID = cryptoSignPublic, BK = privateKey XOR sha512(RS##BID), where BID = cryptoSignPublic,
@ -156,9 +155,9 @@ int rhizome_manifest_bind_id(rhizome_manifest *m_in,const char *author)
privateKey = BK XOR sha512(RS##BID), so the same function can be used privateKey = BK XOR sha512(RS##BID), so the same function can be used
to encrypt and decrypt the BK field. */ to encrypt and decrypt the BK field. */
unsigned char bkbytes[RHIZOME_BUNDLE_KEY_BYTES]; unsigned char bkbytes[RHIZOME_BUNDLE_KEY_BYTES];
if (rhizome_bk_xor(author, m_in->cryptoSignPublic, m_in->cryptoSignSecret, bkbytes) == 0) { if (rhizome_bk_xor(authorSid, m_in->cryptoSignPublic, m_in->cryptoSignSecret, bkbytes) == 0) {
char bkhex[RHIZOME_BUNDLE_KEY_STRLEN + 1]; char bkhex[RHIZOME_BUNDLE_KEY_STRLEN + 1];
rhizome_bytes_to_hex_upper(bkbytes, bkhex, RHIZOME_BUNDLE_KEY_BYTES); (void) tohex(bkhex, bkbytes, RHIZOME_BUNDLE_KEY_BYTES);
if (debug&DEBUG_RHIZOME) DEBUGF("set BK=%s", bkhex); if (debug&DEBUG_RHIZOME) DEBUGF("set BK=%s", bkhex);
rhizome_manifest_set(m_in, "BK", bkhex); rhizome_manifest_set(m_in, "BK", bkhex);
} else { } else {
@ -353,16 +352,6 @@ int rhizome_bundle_push_update(char *id,long long version,unsigned char *data,in
return WHY("Not implemented"); return WHY("Not implemented");
} }
/** Return the uppercase hex digit for a given nybble value 0..15.
*/
char nybltochar_upper(int nybl)
{
if (nybl<0) return '?';
if (nybl>15) return '?';
if (nybl<10) return '0'+nybl;
return 'A'+nybl-10;
}
int chartonybl(int c) int chartonybl(int c)
{ {
if (c>='A'&&c<='F') return 0x0a+(c-'A'); if (c>='A'&&c<='F') return 0x0a+(c-'A');

View File

@ -234,7 +234,7 @@ int rhizome_manifest_check_sanity(rhizome_manifest *m_in);
int rhizome_manifest_check_file(rhizome_manifest *m_in); int rhizome_manifest_check_file(rhizome_manifest *m_in);
int rhizome_manifest_check_duplicate(rhizome_manifest *m_in,rhizome_manifest **m_out); int rhizome_manifest_check_duplicate(rhizome_manifest *m_in,rhizome_manifest **m_out);
int rhizome_manifest_bind_id(rhizome_manifest *m_in,const char *author); int rhizome_manifest_bind_id(rhizome_manifest *m_in, const unsigned char *authorSid);
int rhizome_manifest_bind_file(rhizome_manifest *m_in,const char *filename,int encryptP); int rhizome_manifest_bind_file(rhizome_manifest *m_in,const char *filename,int encryptP);
int rhizome_manifest_finalise(rhizome_manifest *m); int rhizome_manifest_finalise(rhizome_manifest *m);
int rhizome_add_manifest(rhizome_manifest *m_in,int ttl); int rhizome_add_manifest(rhizome_manifest *m_in,int ttl);
@ -242,7 +242,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in,int ttl);
void rhizome_bytes_to_hex_upper(unsigned const char *in, char *out, int byteCount); void rhizome_bytes_to_hex_upper(unsigned const char *in, char *out, int byteCount);
int rhizome_hex_to_bytes(const char *in,unsigned char *out,int hexChars); int rhizome_hex_to_bytes(const char *in,unsigned char *out,int hexChars);
int rhizome_find_privatekey(rhizome_manifest *m); int rhizome_find_privatekey(rhizome_manifest *m);
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m,const char *author); rhizome_signature *rhizome_sign_hash(rhizome_manifest *m, const unsigned char *authorSid);
int rhizome_server_free_http_request(rhizome_http_request *r); int rhizome_server_free_http_request(rhizome_http_request *r);
int rhizome_server_close_http_request(int i); int rhizome_server_close_http_request(int i);
int rhizome_server_http_send_bytes(int rn,rhizome_http_request *r); int rhizome_server_http_send_bytes(int rn,rhizome_http_request *r);
@ -261,7 +261,6 @@ int rhizome_update_file_priority(const char *fileid);
int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found, int rhizome_find_duplicate(const rhizome_manifest *m, rhizome_manifest **found,
int checkVersionP); int checkVersionP);
int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar); int rhizome_manifest_to_bar(rhizome_manifest *m,unsigned char *bar);
char nybltochar_upper(int n);
int rhizome_queue_manifest_import(rhizome_manifest *m, struct sockaddr_in *peerip, int *manifest_kept); int rhizome_queue_manifest_import(rhizome_manifest *m, struct sockaddr_in *peerip, int *manifest_kept);
int rhizome_list_manifests(const char *service, const char *sender_sid, const char *recipient_sid, int limit, int offset); int rhizome_list_manifests(const char *service, const char *sender_sid, const char *recipient_sid, int limit, int offset);
int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest **mp); int rhizome_retrieve_manifest(const char *manifestid, rhizome_manifest **mp);
@ -275,12 +274,12 @@ 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_lookup(rhizome_manifest *m);
int rhizome_manifest_version_cache_store(rhizome_manifest *m); int rhizome_manifest_version_cache_store(rhizome_manifest *m);
int monitor_announce_bundle(rhizome_manifest *m); int monitor_announce_bundle(rhizome_manifest *m);
int rhizome_bk_xor(const char *author, int rhizome_bk_xor(const unsigned char *authorSid, // binary
unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES], unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
unsigned char bkin[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES], unsigned char bkin[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES],
unsigned char bkout[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES]); unsigned char bkout[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES]);
unsigned char *rhizome_bundle_shared_secret(rhizome_manifest *m); unsigned char *rhizome_bundle_shared_secret(rhizome_manifest *m);
int rhizome_extract_privatekey(rhizome_manifest *m,const char *authorHex); int rhizome_extract_privatekey(rhizome_manifest *m, const unsigned char *authorSid);
int rhizome_verify_bundle_privatekey(rhizome_manifest *m); int rhizome_verify_bundle_privatekey(rhizome_manifest *m);
int rhizome_queue_ignore_manifest(rhizome_manifest *m, int rhizome_queue_ignore_manifest(rhizome_manifest *m,
struct sockaddr_in *peerip,int timeout); struct sockaddr_in *peerip,int timeout);

View File

@ -471,15 +471,7 @@ int rhizome_manifest_pack_variables(rhizome_manifest *m)
int rhizome_manifest_selfsign(rhizome_manifest *m) int rhizome_manifest_selfsign(rhizome_manifest *m)
{ {
if (!m->haveSecret) return WHY("Need private key to sign manifest"); if (!m->haveSecret) return WHY("Need private key to sign manifest");
rhizome_signature *sig = rhizome_sign_hash(m, m->cryptoSignSecret);
/* XXX we have to pass it in as hex, but then we just turn it into bytes
anyway. */
char secret[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES*2+1];
rhizome_bytes_to_hex_upper(m->cryptoSignSecret,secret,
crypto_sign_edwards25519sha512batch_SECRETKEYBYTES);
rhizome_signature *sig=rhizome_sign_hash(m,secret);
if (!sig) return WHY("rhizome_sign_hash() failed."); if (!sig) return WHY("rhizome_sign_hash() failed.");
/* Append signature to end of manifest data */ /* Append signature to end of manifest data */

View File

@ -121,7 +121,7 @@ int rhizome_find_keypair_bytes(unsigned char *p,unsigned char *s) {
} }
#endif #endif
int rhizome_bk_xor(const char *author, int rhizome_bk_xor(const unsigned char *authorSid, // binary
unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES], unsigned char bid[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES],
unsigned char bkin[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES], unsigned char bkin[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES],
unsigned char bkout[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES]) unsigned char bkout[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES])
@ -130,11 +130,9 @@ int rhizome_bk_xor(const char *author,
crypto_hash_sha512_BYTES) crypto_hash_sha512_BYTES)
return WHY("BK needs to be longer than it can be"); return WHY("BK needs to be longer than it can be");
unsigned char authorSid[SID_SIZE];
if (stowSid(authorSid,0,author)) return WHYF("stowSid(%s) failed", author);
int cn=0,in=0,kp=0; int cn=0,in=0,kp=0;
if (!keyring_find_sid(keyring,&cn,&in,&kp,authorSid)) if (!keyring_find_sid(keyring,&cn,&in,&kp,authorSid))
return WHYF("keyring_find_sid() couldn't find %s. Have you unlocked that identity?", author); return WHYF("keyring_find_sid() couldn't find %s. Have you unlocked that identity?", alloca_tohex_sid(authorSid));
for(kp=0;kp<keyring->contexts[cn]->identities[in]->keypair_count;kp++) for(kp=0;kp<keyring->contexts[cn]->identities[in]->keypair_count;kp++)
if (keyring->contexts[cn]->identities[in]->keypairs[kp]->type==KEYTYPE_RHIZOME) if (keyring->contexts[cn]->identities[in]->keypairs[kp]->type==KEYTYPE_RHIZOME)
break; break;
@ -172,23 +170,19 @@ int rhizome_bk_xor(const char *author,
the supplied SID is correct. the supplied SID is correct.
*/ */
int rhizome_extract_privatekey(rhizome_manifest *m, const char *authorHex) int rhizome_extract_privatekey(rhizome_manifest *m, const unsigned char *authorSid)
{ {
if (!authorHex) return -1; // WHY("No author SID supplied");
char *bk = rhizome_manifest_get(m, "BK", NULL, 0); char *bk = rhizome_manifest_get(m, "BK", NULL, 0);
if (!bk) return WHY("Cannot obtain private key as manifest lacks BK field"); if (!bk) return WHY("missing BK field");
unsigned char bkBytes[RHIZOME_BUNDLE_KEY_BYTES];
unsigned char bkBytes[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES]; if (fromhexstr(bkBytes, bk, RHIZOME_BUNDLE_KEY_BYTES) == -1)
if (stowBytes(bkBytes,bk,crypto_sign_edwards25519sha512batch_SECRETKEYBYTES)) return WHYF("invalid BK field: %s", bk);
return WHY("Failed to make packed version of BK. Is it a valid hex string of the correct length?"); if (rhizome_bk_xor(authorSid,
if (rhizome_bk_xor(authorHex,
m->cryptoSignPublic, m->cryptoSignPublic,
bkBytes, bkBytes,
m->cryptoSignSecret)) m->cryptoSignSecret))
return WHY("rhizome_bk_xor() failed"); return WHY("rhizome_bk_xor() failed");
return rhizome_verify_bundle_privatekey(m); return rhizome_verify_bundle_privatekey(m);
} }
/* Verify the validity of the manifest's sccret key. /* Verify the validity of the manifest's sccret key.
@ -236,17 +230,15 @@ int rhizome_verify_bundle_privatekey(rhizome_manifest *m)
#endif //!ge25519 #endif //!ge25519
} }
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m,const char *author) rhizome_signature *rhizome_sign_hash(rhizome_manifest *m, const unsigned char *authorSid)
{ {
unsigned char *hash=m->manifesthash; unsigned char *hash=m->manifesthash;
unsigned char *publicKeyBytes=m->cryptoSignPublic; unsigned char *publicKeyBytes=m->cryptoSignPublic;
if (!m->haveSecret) if (!m->haveSecret && rhizome_extract_privatekey(m, authorSid) == -1) {
if (rhizome_extract_privatekey(m,author)) WHY("Cannot find secret key to sign manifest data.");
{ return NULL;
WHY("Cannot find secret key to sign manifest data."); }
return NULL;
}
/* Signature is formed by running crypto_sign_edwards25519sha512batch() on the /* Signature is formed by running crypto_sign_edwards25519sha512batch() on the
hash of the manifest. The signature actually contains the hash, so to save hash of the manifest. The signature actually contains the hash, so to save

View File

@ -699,10 +699,8 @@ int rhizome_list_manifests(const char *service, const char *sender_sid, const ch
const char *blob_service = rhizome_manifest_get(m, "service", NULL, 0); const char *blob_service = rhizome_manifest_get(m, "service", NULL, 0);
if (service[0] && !(blob_service && strcasecmp(service, blob_service) == 0)) if (service[0] && !(blob_service && strcasecmp(service, blob_service) == 0))
match = 0; match = 0;
const char *blob_sender = rhizome_manifest_get(m, "sender", NULL, 0); const char *blob_sender = rhizome_manifest_get(m, "sender", NULL, 0);
const char *blob_recipient = rhizome_manifest_get(m, "recipient", NULL, 0); const char *blob_recipient = rhizome_manifest_get(m, "recipient", NULL, 0);
if (match && sender_sid[0]) { if (match && sender_sid[0]) {
if (!(blob_sender && strcasecmp(sender_sid, blob_sender) == 0)) if (!(blob_sender && strcasecmp(sender_sid, blob_sender) == 0))
match = 0; match = 0;
@ -711,7 +709,6 @@ int rhizome_list_manifests(const char *service, const char *sender_sid, const ch
if (!(blob_recipient && strcasecmp(recipient_sid, blob_recipient) == 0)) if (!(blob_recipient && strcasecmp(recipient_sid, blob_recipient) == 0))
match = 0; match = 0;
} }
if (match) { if (match) {
const char *blob_name = rhizome_manifest_get(m, "name", NULL, 0); const char *blob_name = rhizome_manifest_get(m, "name", NULL, 0);
long long blob_date = rhizome_manifest_get_ll(m, "date"); long long blob_date = rhizome_manifest_get_ll(m, "date");
@ -938,10 +935,7 @@ int rhizome_store_file(rhizome_manifest *m,const unsigned char *key)
void rhizome_bytes_to_hex_upper(unsigned const char *in, char *out, int byteCount) void rhizome_bytes_to_hex_upper(unsigned const char *in, char *out, int byteCount)
{ {
int i=0; (void) tohex(out, in, byteCount);
for(i = 0; i != byteCount * 2 ; ++i)
out[i] = nybltochar_upper((in[i >> 1] >> (4 - 4 * (i & 1))) & 0xf);
out[i] = '\0';
} }
int rhizome_update_file_priority(const char *fileid) int rhizome_update_file_priority(const char *fileid)

View File

@ -256,7 +256,7 @@ int keyring_set_did(keyring_identity *id,char *did,char *name);
int keyring_sanitise_position(keyring_file *k,int *cn,int *in,int *kp); int keyring_sanitise_position(keyring_file *k,int *cn,int *in,int *kp);
int keyring_next_identity(keyring_file *k,int *cn,int *in,int *kp); int keyring_next_identity(keyring_file *k,int *cn,int *in,int *kp);
int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did); int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did);
int keyring_find_sid(keyring_file *k,int *cn,int *in,int *kp,unsigned char *sid); int keyring_find_sid(keyring_file *k,int *cn,int *in,int *kp, const unsigned char *sid);
unsigned char *keyring_find_sas_private(keyring_file *k,unsigned char *sid, unsigned char *keyring_find_sas_private(keyring_file *k,unsigned char *sid,
unsigned char **sas_public); unsigned char **sas_public);
unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid); unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid);
@ -385,8 +385,6 @@ extern struct mphlr_variable vars[];
#define ACTION_PAD 0xfe #define ACTION_PAD 0xfe
#define ACTION_EOT 0xff #define ACTION_EOT 0xff
extern int hexdigit[16];
/* Make sure we have space to put bytes of the packet as we go along */ /* Make sure we have space to put bytes of the packet as we go along */
#define CHECK_PACKET_LEN(B) {if (((*packet_len)+(B))>=packet_maxlen) { return WHY("Packet composition ran out of space."); } } #define CHECK_PACKET_LEN(B) {if (((*packet_len)+(B))>=packet_maxlen) { return WHY("Packet composition ran out of space."); } }
@ -399,9 +397,12 @@ int confParseBoolean(const char *text, const char *option_name);
int recvwithttl(int sock,unsigned char *buffer,int bufferlen,int *ttl, int recvwithttl(int sock,unsigned char *buffer,int bufferlen,int *ttl,
struct sockaddr *recvaddr,unsigned int *recvaddrlen); struct sockaddr *recvaddr,unsigned int *recvaddrlen);
char *tohex(char *dstHex, const unsigned char *srcBinary, size_t bytes);
size_t fromhex(unsigned char *dstBinary, const char *srcHex, size_t bytes);
int fromhexstr(unsigned char *dstBinary, const char *srcHex, size_t bytes);
int validateSid(const char *sid); int validateSid(const char *sid);
int stowSid(unsigned char *packet, int ofs, const char *sid); int stowSid(unsigned char *packet, int ofs, const char *sid);
int stowBytes(unsigned char *packet, const char *in,int count);
int stowDid(unsigned char *packet,int *ofs,char *did); int stowDid(unsigned char *packet,int *ofs,char *did);
int isFieldZeroP(unsigned char *packet,int start,int count); int isFieldZeroP(unsigned char *packet,int start,int count);
void srandomdev(); void srandomdev();
@ -764,6 +765,9 @@ long long debugFlagMask(const char *flagname);
char *catv(const char *data, char *buf, size_t len); char *catv(const char *data, char *buf, size_t len);
int dump(char *name,unsigned char *addr,int len); int dump(char *name,unsigned char *addr,int len);
#define alloca_tohex(buf,len) tohex((char *)alloca((len)*2+1), (buf), (len))
#define alloca_tohex_sid(sid) alloca_tohex((sid), SID_SIZE)
const char *trimbuildpath(const char *s); const char *trimbuildpath(const char *s);
#define LOGF(L,F,...) logMessage(L, __FILE__, __LINE__, __FUNCTION__, F, ##__VA_ARGS__) #define LOGF(L,F,...) logMessage(L, __FILE__, __LINE__, __FUNCTION__, F, ##__VA_ARGS__)

View File

@ -64,7 +64,7 @@ assert_rhizome_list() {
local filename local filename
for filename; do for filename; do
unpack_manifest_for_grep "$filename" unpack_manifest_for_grep "$filename"
assertStdoutGrep --matches=1 "^$re_service:$re_manifestid:.*:$re_filehash:$re_sender:$re_recipient:$re_name\$" assertStdoutGrep --matches=1 "^$re_service:$re_manifestid:.*:$re_filesize:$re_filehash:$re_sender:$re_recipient:$re_name\$"
done done
} }
@ -78,19 +78,20 @@ assert_stdout_add_file() {
assertStdoutGrep --matches=1 "^manifestid:$re_manifestid\$" assertStdoutGrep --matches=1 "^manifestid:$re_manifestid\$"
assertStdoutGrep --matches=1 "^secret:$re_secret\$" assertStdoutGrep --matches=1 "^secret:$re_secret\$"
assertStdoutGrep --matches=1 "^filehash:$re_filehash\$" assertStdoutGrep --matches=1 "^filehash:$re_filehash\$"
assertStdoutGrep --matches=1 "^filesize:$re_size\$" assertStdoutGrep --matches=1 "^filesize:$re_filesize\$"
} }
unpack_manifest_for_grep() { unpack_manifest_for_grep() {
local filename="$1" local filename="$1"
re_service="$rexp_service" re_service="$rexp_service"
if [ -n "$filename" ]; then if [ -n "$filename" ]; then
re_size=$(( $(cat "$filename" | wc -c) + 0 )) re_filesize=$(( $(cat "$filename" | wc -c) + 0 ))
else else
re_size=0 re_filesize=0
fi fi
compute_filehash re_filehash "$filename" compute_filehash re_filehash "$filename"
re_manifestid="$rexp_manifestid" re_manifestid="$rexp_manifestid"
re_version="$rexp_version"
re_secret="$rexp_bundlesecret" re_secret="$rexp_bundlesecret"
re_name=$(escape_grep_basic "${filename##*/}") re_name=$(escape_grep_basic "${filename##*/}")
# If there is a manifest file that looks like it matches this payload # If there is a manifest file that looks like it matches this payload
@ -98,6 +99,7 @@ unpack_manifest_for_grep() {
local filehash=$(sed -n -e '/^filehash=/s///p' "$filename.manifest" 2>/dev/null) local filehash=$(sed -n -e '/^filehash=/s///p' "$filename.manifest" 2>/dev/null)
if [ "$filehash" = "$re_filehash" ]; then if [ "$filehash" = "$re_filehash" ]; then
re_manifestid=$(sed -n -e '/^id=/s///p' "$filename.manifest") re_manifestid=$(sed -n -e '/^id=/s///p' "$filename.manifest")
re_version=$(sed -n -e '/^version=/s///p' "$filename.manifest")
re_service=$(sed -n -e '/^service=/s///p' "$filename.manifest") re_service=$(sed -n -e '/^service=/s///p' "$filename.manifest")
re_service=$(escape_grep_basic "$re_service") re_service=$(escape_grep_basic "$re_service")
re_sender=$(sed -n -e '/^sender=/s///p' "$filename.manifest") re_sender=$(sed -n -e '/^sender=/s///p' "$filename.manifest")
@ -255,10 +257,10 @@ test_AddNonExistManifest() {
assertGrep file1.manifest "^BK=$rexp_bundlekey\$" assertGrep file1.manifest "^BK=$rexp_bundlekey\$"
assertGrep file1.manifest '^name=file1$' assertGrep file1.manifest '^name=file1$'
assertGrep file1.manifest "^date=$rexp_date\$" assertGrep file1.manifest "^date=$rexp_date\$"
assertGrep file1.manifest "^version=$rexp_version\$" assertGrep file1.manifest "^version=$re_version\$"
assertGrep file1.manifest "^id=$re_manifestid\$" assertGrep file1.manifest "^id=$re_manifestid\$"
assertGrep file1.manifest "^filehash=$re_filehash\$" assertGrep file1.manifest "^filehash=$re_filehash\$"
assertGrep file1.manifest "^filesize=$re_size\$" assertGrep file1.manifest "^filesize=$re_filesize\$"
} }
doc_AddManifest="Add with minimal manifest file" doc_AddManifest="Add with minimal manifest file"
@ -277,11 +279,11 @@ test_AddManifest() {
assertGrep file1.manifest '^service=file$' assertGrep file1.manifest '^service=file$'
assertGrep file1.manifest "^BK=$rexp_bundlekey\$" assertGrep file1.manifest "^BK=$rexp_bundlekey\$"
assertGrep file1.manifest '^name=wah$' assertGrep file1.manifest '^name=wah$'
assertGrep file1.manifest "^version=$rexp_version\$" assertGrep file1.manifest "^version=$re_version\$"
assertGrep file1.manifest '^date=12345$' assertGrep file1.manifest '^date=12345$'
assertGrep file1.manifest "^id=$re_manifestid\$" assertGrep file1.manifest "^id=$re_manifestid\$"
assertGrep file1.manifest "^filehash=$re_filehash\$" assertGrep file1.manifest "^filehash=$re_filehash\$"
assertGrep file1.manifest "^filesize=$re_size\$" assertGrep file1.manifest "^filesize=$re_filesize\$"
} }
doc_AddEmpty="Add with empty payload" doc_AddEmpty="Add with empty payload"
@ -297,7 +299,7 @@ test_AddEmpty() {
assertGrep .manifest '^service=file$' assertGrep .manifest '^service=file$'
assertGrep .manifest "^BK=$rexp_bundlekey\$" assertGrep .manifest "^BK=$rexp_bundlekey\$"
assertGrep .manifest '^name=$' assertGrep .manifest '^name=$'
assertGrep .manifest "^version=$rexp_version\$" assertGrep .manifest "^version=$re_version\$"
assertGrep .manifest "^date=$rexp_date\$" assertGrep .manifest "^date=$rexp_date\$"
assertGrep .manifest "^id=$re_manifestid\$" assertGrep .manifest "^id=$re_manifestid\$"
assertGrep .manifest "^filehash=$re_filehash\$" assertGrep .manifest "^filehash=$re_filehash\$"