BK encoding and decoding complete, but untested.

This commit is contained in:
gardners 2012-05-15 20:04:41 +09:30
parent 8020401cf0
commit 0eafc34970
7 changed files with 89 additions and 15 deletions

View File

@ -1137,7 +1137,8 @@ int app_rhizome_extract_manifest(int argc, const char *const *argv, struct comma
case 0: ret = 1; break;
case 1: ret = 0;
if (manifestpath[0]) {
if (rhizome_manifest_finalise(m, 1) == -1)
#warning why do we ask for the manifest to be signed here, when we are just extracting it? Anyway, it wont work while the author field is null.
if (rhizome_manifest_finalise(m, 1,NULL) == -1)
ret = WHY("Could not overwrite manifest file.");
else if (rhizome_write_manifest_file(m, manifestpath) == -1)
ret = WHY("Could not overwrite manifest file.");

View File

@ -136,6 +136,22 @@ int stowSid(unsigned char *packet, int ofs, const char *sid)
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;
}
int hexvalue(unsigned char c)
{
if (c>='0'&&c<='9') return c-'0';

View File

@ -220,7 +220,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
fprintf(stderr, "Found duplicate payload: name=\"%s\" version=%llu hexhash=%s -- not adding\n", name, dupm->version, dupm->fileHexHash);
/* If the caller wants the duplicate manifest, it must be finalised, otherwise discarded. */
if (m_out) {
if (rhizome_manifest_finalise(dupm, 0))
if (rhizome_manifest_finalise(dupm, 0,NULL))
return WHY("Failed to finalise manifest.\n");
*m_out = dupm;
}
@ -250,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_privatekey(m_in))
if (!rhizome_extract_privatekey(m_in,author))
m_in->haveSecret=1;
} else {
/* The manifest had no ID (256 bit random string being a public key in the NaCl CryptoSign
@ -270,7 +270,13 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
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. */
int len=crypto_sign_edwards25519sha512batch_SECRETKEYBYTES;
unsigned char bkbytes[len];
if (!rhizome_bk_xor(author,m_in->cryptoSignPublic,
m_in->cryptoSignPublic,
bkbytes)) {
rhizome_manifest_set(m_in,"BK",rhizome_bytes_to_hex(bkbytes,len));
}
}
}
@ -282,7 +288,7 @@ int rhizome_add_manifest(rhizome_manifest *m_in,
}
/* Finish completing the manifest */
if (rhizome_manifest_finalise(m_in, signP))
if (rhizome_manifest_finalise(m_in, signP,author))
return WHY("Failed to finalise manifest.\n");
/* Okay, it is written, and can be put directly into the rhizome database now */

View File

@ -173,7 +173,7 @@ int rhizome_str_is_manifest_id(const char *text);
int rhizome_strn_is_file_hash(const char *text);
int rhizome_str_is_file_hash(const char *text);
int rhizome_write_manifest_file(rhizome_manifest *m, const char *filename);
int rhizome_manifest_sign(rhizome_manifest *m);
int rhizome_manifest_sign(rhizome_manifest *m,const char *authoring_sid);
int rhizome_drop_stored_file(char *id,int maximum_priority);
int rhizome_manifest_priority(char *id);
rhizome_manifest *rhizome_read_manifest_file(const char *filename, int bufferPAndSize, int flags);
@ -201,11 +201,11 @@ int rhizome_add_manifest(rhizome_manifest *m_in, rhizome_manifest **m_out, const
char *groups[], int ttl,
int verifyP, int checkFileP, int signP,
const char *author);
int rhizome_manifest_finalise(rhizome_manifest *m,int signP);
int rhizome_manifest_finalise(rhizome_manifest *m,int signP,const char *author);
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_find_privatekey(rhizome_manifest *m);
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m);
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m,const char *author);
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);
@ -239,3 +239,4 @@ 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]);
int rhizome_extract_privatekey(rhizome_manifest *m,const char *authorHex);

View File

@ -413,10 +413,12 @@ int rhizome_manifest_pack_variables(rhizome_manifest *m)
return 0;
}
/* Sign this manifest using our own private CryptoSign key */
int rhizome_manifest_sign(rhizome_manifest *m)
/* Sign this manifest using our own private CryptoSign key.
We may have multiple identities at any given point, so tell
which one we should be using. */
int rhizome_manifest_sign(rhizome_manifest *m,const char *author)
{
rhizome_signature *sig=rhizome_sign_hash(m);
rhizome_signature *sig=rhizome_sign_hash(m,author);
if (!sig) return WHY("rhizome_sign_hash() failed.");
@ -466,7 +468,7 @@ int rhizome_manifest_dump(rhizome_manifest *m,char *msg)
return 0;
}
int rhizome_manifest_finalise(rhizome_manifest *m,int signP)
int rhizome_manifest_finalise(rhizome_manifest *m,int signP,const char *author)
{
/* set fileHexHash */
if (!m->fileHashedP) {
@ -503,7 +505,7 @@ int rhizome_manifest_finalise(rhizome_manifest *m,int signP)
rhizome_manifest_pack_variables(m);
/* Sign it */
if (signP) rhizome_manifest_sign(m);
if (signP) rhizome_manifest_sign(m,author);
/* mark manifest as finalised */
m->finalised=1;

View File

@ -123,13 +123,60 @@ int rhizome_bk_xor(const char *author,
return 0;
}
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m)
/* See if the manifest has a BK entry, and if so, use it to obtain the
private key for the BID. Decoding BK's relies on the provision of
the appropriate SID.
XXX Note that this function is not able to verify that the private key
is correct, as there is no exposed API in NaCl for calculating the
public key from a cryptosign private key. We thus have to trust that
the supplied SID is correct.
*/
int rhizome_extract_privatekey(rhizome_manifest *m,const char *authorHex)
{
char *bk = rhizome_manifest_get(m, "bk", NULL, 0);
if (!bk) return WHY("Cannot obtain private key as manifest lacks BK field");
unsigned char bkBytes[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES];
if (stowBytes(bkBytes,bk,crypto_sign_edwards25519sha512batch_SECRETKEYBYTES))
return WHY("Failed to make packed version of BK. Is it a valid hex string of the correct length?");
if (rhizome_bk_xor(authorHex,
m->cryptoSignPublic,
bkBytes,
m->cryptoSignSecret))
return WHY("rhizome_bk_xor() failed");
/* Verify validity of key.
XXX This is a pretty ugly way to do it, but NaCl offers no API to
do this cleanly. */
{
#include "nacl-source/nacl-20110221/nacl-source/crypto_sign_edwards25519sha512batch_ref/ge25519.h"
unsigned char *sk=m->cryptoSignSecret;
unsigned char pk[crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES];
sc25519 scsk;
ge25519 gepk;
sc25519_from32bytes(&scsk,sk);
ge25519_scalarmult_base(&gepk, &scsk);
ge25519_pack(pk, &gepk);
bzero(&scsk,sizeof(scsk));
if (bcmp(pk,m->cryptoSignPublic,
crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES))
return WHY("BID secret key decoded from BK was not valid");
else return 0;
}
}
rhizome_signature *rhizome_sign_hash(rhizome_manifest *m,const char *author)
{
unsigned char *hash=m->manifesthash;
unsigned char *publicKeyBytes=m->cryptoSignPublic;
unsigned char secretKeyBytes[crypto_sign_edwards25519sha512batch_SECRETKEYBYTES];
if (rhizome_find_privatekey(m))
if (rhizome_extract_privatekey(m,author))
{
WHY("Cannot find secret key to sign manifest data.");
return NULL;

View File

@ -397,6 +397,7 @@ int recvwithttl(int sock,unsigned char *buffer,int bufferlen,int *ttl,
struct sockaddr *recvaddr,unsigned int *recvaddrlen);
int validateSid(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 isFieldZeroP(unsigned char *packet,int start,int count);
void srandomdev();