From e4e06ca028a8aa4d33db30946a8909a86c141f99 Mon Sep 17 00:00:00 2001 From: divverent Date: Thu, 25 Nov 2010 20:30:42 +0000 Subject: [PATCH] initial work for DETACHED signatures git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10633 d7cf8633-e32d-0410-b094-e92efae38249 --- crypto-keygen-standalone.c | 72 +++++++++++++++++++++++++++++++------- crypto.c | 14 ++++++++ crypto.h | 1 + 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/crypto-keygen-standalone.c b/crypto-keygen-standalone.c index 95268400..17b825d2 100644 --- a/crypto-keygen-standalone.c +++ b/crypto-keygen-standalone.c @@ -188,10 +188,11 @@ void USAGE(const char *me) "%s -p public.d0pk -I idkey.d0si\n" "%s -0 -p public.d0pk -I idkey.d0si\n" "%s -0 -p public.d0pk\n" - "%s -p public.d0pk -I idkey.d0si -f file-to-sign.dat -o file-signed.dat\n" - "%s -p public.d0pk -f file-signed.dat -o file-content.dat\n" - "%s -p public.d0pk -f file-signed.dat -o file-content.dat -O idkey.d0pi\n", - me, me, me, me, me, me, me, me, me, me, me, me, me, me, me, me, me + "%s -p public.d0pk -I idkey.d0si -d file-to-sign.dat -o file-signed.dat\n" + "%s -p public.d0pk -s file-signed.dat -o file-content.dat [-O id.d0pi]\n" + "%s -p public.d0pk -I idkey.d0si -d file-to-sign.dat -O signature.dat\n" + "%s -p public.d0pk -d file-to-sign.dat -s signature.dat [-O id.d0pi]\n", + me, me, me, me, me, me, me, me, me, me, me, me, me, me, me, me, me, me ); } @@ -271,9 +272,10 @@ int main(int argc, char **argv) const char *lumps[2]; char *databuf_in; size_t databufsize_in; char *databuf_out; size_t databufsize_out; + char *databuf_sig; size_t databufsize_sig; char lumps_w0[65536]; char lumps_w1[65536]; - const char *pubkeyfile = NULL, *privkeyfile = NULL, *pubidfile = NULL, *prividfile = NULL, *idreqfile = NULL, *idresfile = NULL, *outfile = NULL, *outfile2 = NULL, *camouflagefile = NULL, *datafile = NULL; + const char *pubkeyfile = NULL, *privkeyfile = NULL, *pubidfile = NULL, *prividfile = NULL, *idreqfile = NULL, *idresfile = NULL, *outfile = NULL, *outfile2 = NULL, *camouflagefile = NULL, *datafile = NULL, *sigfile = NULL; char fp64[513]; size_t fp64size = 512; int mask = 0; int bits = 1024; @@ -289,7 +291,7 @@ int main(int argc, char **argv) umask_save = umask(0022); ctx = d0_blind_id_new(); - while((opt = getopt(argc, argv, "f:p:P:i:I:j:J:o:O:c:b:x:X:y:Fn:C0")) != -1) + while((opt = getopt(argc, argv, "d:s:p:P:i:I:j:J:o:O:c:b:x:X:y:Fn:C0")) != -1) { switch(opt) { @@ -346,10 +348,14 @@ int main(int argc, char **argv) // test mode mask |= 0x200; break; - case 'f': + case 'd': datafile = optarg; mask |= 0x400; break; + case 's': + sigfile = optarg; + mask |= 0x800; + break; case 'X': infix = optarg; break; @@ -470,7 +476,17 @@ int main(int argc, char **argv) file2buf(datafile, &databuf_in, &databufsize_in); if(!databuf_in) { - fprintf(stderr, "could not decode private ID\n"); + fprintf(stderr, "could not decode data\n"); + exit(1); + } + } + + if(mask & 0x800) + { + file2buf(sigfile, &databuf_sig, &databufsize_sig); + if(!databuf_sig) + { + fprintf(stderr, "could not decode signature\n"); exit(1); } } @@ -610,14 +626,44 @@ int main(int argc, char **argv) CHECK(d0_blind_id_sign_with_private_id_sign(ctx, 1, 0, databuf_in, databufsize_in, databuf_out, &databufsize_out)); buf2file(outfile, databuf_out, databufsize_out); break; - case 0x441: - case 0x4C1: - // public key, data -> signed data, optional public ID + case 0x489: + // public key, private ID, data -> signature + databufsize_out = databufsize_in + 8192; + databuf_out = malloc(databufsize_out); + CHECK(d0_blind_id_sign_with_private_id_sign_detached(ctx, 1, 0, databuf_in, databufsize_in, databuf_out, &databufsize_out)); + buf2file(outfile2, databuf_out, databufsize_out); + break; + case 0x841: + case 0x8C1: + // public key, signed data -> data, optional public ID { D0_BOOL status; - databufsize_out = databufsize_in; + databufsize_out = databufsize_sig; databuf_out = malloc(databufsize_out); - CHECK(d0_blind_id_sign_with_private_id_verify(ctx, 1, 0, databuf_in, databufsize_in, databuf_out, &databufsize_out, &status)); + CHECK(d0_blind_id_sign_with_private_id_verify(ctx, 1, 0, databuf_sig, databufsize_sig, databuf_out, &databufsize_out, &status)); + CHECK(d0_blind_id_fingerprint64_public_id(ctx, fp64, &fp64size)); + printf("%d\n", (int)status); + printf("%.*s\n", (int)fp64size, fp64); + buf2file(outfile, databuf_out, databufsize_out); + + if(outfile2) + { + lumps[0] = lumps_w0; + lumpsize[0] = sizeof(lumps_w0); + lumps[1] = lumps_w1; + lumpsize[1] = sizeof(lumps_w1); + CHECK(d0_blind_id_write_public_key(ctx, lumps_w0, &lumpsize[0])); + CHECK(d0_blind_id_write_private_id_modulus(ctx, lumps_w1, &lumpsize[1])); + lumps2file(outfile2, FOURCC_D0PK, lumps, lumpsize, 2, 0); + } + } + break; + case 0xC01: + case 0xC81: + // public key, signature, signed data -> optional public ID + { + D0_BOOL status; + CHECK(d0_blind_id_sign_with_private_id_verify_detached(ctx, 1, 0, databuf_sig, databufsize_sig, databuf_in, databufsize_in, &status)); CHECK(d0_blind_id_fingerprint64_public_id(ctx, fp64, &fp64size)); printf("%d\n", (int)status); printf("%.*s\n", (int)fp64size, fp64); diff --git a/crypto.c b/crypto.c index cf83ed1b..f3259a6f 100644 --- a/crypto.c +++ b/crypto.c @@ -143,6 +143,7 @@ static size_t Crypto_UnParsePack(char *buf, size_t len, unsigned long header, co #define qd0_blind_id_SHUTDOWN d0_blind_id_SHUTDOWN #define qd0_blind_id_util_sha256 d0_blind_id_util_sha256 #define qd0_blind_id_sign_with_private_id_sign d0_blind_id_sign_with_private_id_sign +#define qd0_blind_id_sign_with_private_id_sign_detached d0_blind_id_sign_with_private_id_sign_detached #else @@ -191,6 +192,7 @@ static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL (*qd0_blind_id_INITIALIZE) (void) static D0_EXPORT void (*qd0_blind_id_SHUTDOWN) (void); static D0_EXPORT void (*qd0_blind_id_util_sha256) (char *out, const char *in, size_t n); static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL (*qd0_blind_id_sign_with_private_id_sign) (d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen); +static D0_EXPORT D0_WARN_UNUSED_RESULT D0_BOOL (*qd0_blind_id_sign_with_private_id_sign_detached) (d0_blind_id_t *ctx, D0_BOOL is_first, D0_BOOL send_modulus, const char *message, size_t msglen, char *outbuf, size_t *outbuflen); static dllfunction_t d0_blind_id_funcs[] = { {"d0_blind_id_new", (void **) &qd0_blind_id_new}, @@ -227,6 +229,7 @@ static dllfunction_t d0_blind_id_funcs[] = {"d0_blind_id_SHUTDOWN", (void **) &qd0_blind_id_SHUTDOWN}, {"d0_blind_id_util_sha256", (void **) &qd0_blind_id_util_sha256}, {"d0_blind_id_sign_with_private_id_sign", (void **) &qd0_blind_id_sign_with_private_id_sign}, + {"d0_blind_id_sign_with_private_id_sign_detached", (void **) &qd0_blind_id_sign_with_private_id_sign_detached}, {NULL, NULL} }; // end of d0_blind_id interface @@ -2340,3 +2343,14 @@ size_t Crypto_SignData(const void *data, size_t datasize, int keyid, void *signe return signed_size; return 0; } + +size_t Crypto_SignDataDetached(const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size) +{ + if(keyid < 0 || keyid >= MAX_PUBKEYS) + return 0; + if(!pubkeys_havepriv[keyid]) + return 0; + if(qd0_blind_id_sign_with_private_id_sign_detached(pubkeys[keyid], true, false, (const char *)data, datasize, (char *)signed_data, &signed_size)) + return signed_size; + return 0; +} diff --git a/crypto.h b/crypto.h index e7e77c60..507c0a06 100644 --- a/crypto.h +++ b/crypto.h @@ -54,6 +54,7 @@ qboolean Crypto_RetrieveHostKey(lhnetaddress_t *peeraddress, int *keyid, char *k int Crypto_RetrieveLocalKey(int keyid, char *keyfp, size_t keyfplen, char *idfp, size_t idfplen); // return value: -1 if more to come, +1 if valid, 0 if end of list size_t Crypto_SignData(const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size); +size_t Crypto_SignDataDetached(const void *data, size_t datasize, int keyid, void *signed_data, size_t signed_size); // netconn protocol: // non-crypto: -- 2.39.2