wrath-darkplaces/crypto-keygen-standalone.c

774 lines
22 KiB
C

#define _GNU_SOURCE
#include <d0_blind_id/d0_blind_id.h>
#include <ctype.h>
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
// BEGIN stuff shared with crypto.c
#define FOURCC_D0PK (('d' << 0) | ('0' << 8) | ('p' << 16) | ('k' << 24))
#define FOURCC_D0SK (('d' << 0) | ('0' << 8) | ('s' << 16) | ('k' << 24))
#define FOURCC_D0PI (('d' << 0) | ('0' << 8) | ('p' << 16) | ('i' << 24))
#define FOURCC_D0SI (('d' << 0) | ('0' << 8) | ('s' << 16) | ('i' << 24))
#define FOURCC_D0IQ (('d' << 0) | ('0' << 8) | ('i' << 16) | ('q' << 24))
#define FOURCC_D0IR (('d' << 0) | ('0' << 8) | ('i' << 16) | ('r' << 24))
#define FOURCC_D0ER (('d' << 0) | ('0' << 8) | ('e' << 16) | ('r' << 24))
#define FOURCC_D0IC (('d' << 0) | ('0' << 8) | ('i' << 16) | ('c' << 24))
static unsigned long Crypto_LittleLong(const char *data)
{
return
((unsigned char) data[0]) |
(((unsigned char) data[1]) << 8) |
(((unsigned char) data[2]) << 16) |
(((unsigned char) data[3]) << 24);
}
static void Crypto_UnLittleLong(char *data, unsigned long l)
{
data[0] = l & 0xFF;
data[1] = (l >> 8) & 0xFF;
data[2] = (l >> 16) & 0xFF;
data[3] = (l >> 24) & 0xFF;
}
static size_t Crypto_ParsePack(const char *buf, size_t len, unsigned long header, const char **lumps, size_t *lumpsize, size_t nlumps)
{
size_t i;
size_t pos;
pos = 0;
if(header)
{
if(len < 4)
return 0;
if(Crypto_LittleLong(buf) != header)
return 0;
pos += 4;
}
for(i = 0; i < nlumps; ++i)
{
if(pos + 4 > len)
return 0;
lumpsize[i] = Crypto_LittleLong(&buf[pos]);
pos += 4;
if(pos + lumpsize[i] > len)
return 0;
lumps[i] = &buf[pos];
pos += lumpsize[i];
}
return pos;
}
static size_t Crypto_UnParsePack(char *buf, size_t len, unsigned long header, const char *const *lumps, const size_t *lumpsize, size_t nlumps)
{
size_t i;
size_t pos;
pos = 0;
if(header)
{
if(len < 4)
return 0;
Crypto_UnLittleLong(buf, header);
pos += 4;
}
for(i = 0; i < nlumps; ++i)
{
if(pos + 4 + lumpsize[i] > len)
return 0;
Crypto_UnLittleLong(&buf[pos], lumpsize[i]);
pos += 4;
memcpy(&buf[pos], lumps[i], lumpsize[i]);
pos += lumpsize[i];
}
return pos;
}
void file2buf(const char *fn, char **data, size_t *datasize)
{
FILE *f;
*data = NULL;
*datasize = 0;
size_t n = 0, dn = 0;
if(!strncmp(fn, "/dev/fd/", 8))
f = fdopen(atoi(fn + 8), "rb");
else
f = fopen(fn, "rb");
if(!f)
{
return;
}
for(;;)
{
*data = realloc(*data, *datasize += 8192);
if(!*data)
{
*datasize = 0;
fclose(f);
return;
}
dn = fread(*data + n, 1, *datasize - n, f);
if(!dn)
break;
n += dn;
}
fclose(f);
*datasize = n;
}
int buf2file(const char *fn, const char *data, size_t n)
{
FILE *f;
if(!strncmp(fn, "/dev/fd/", 8))
f = fdopen(atoi(fn + 8), "wb");
else
f = fopen(fn, "wb");
if(!f)
return 0;
n = fwrite(data, n, 1, f);
if(fclose(f) || !n)
return 0;
return 1;
}
void file2lumps(const char *fn, unsigned long header, const char **lumps, size_t *lumpsize, size_t nlumps)
{
char *buf;
size_t n;
file2buf(fn, &buf, &n);
if(!buf)
{
fprintf(stderr, "could not open %s\n", fn);
exit(1);
}
if(!Crypto_ParsePack(buf, n, header, lumps, lumpsize, nlumps))
{
fprintf(stderr, "could not parse %s as %c%c%c%c (%d lumps expected)\n", fn, (int) header & 0xFF, (int) (header >> 8) & 0xFF, (int) (header >> 16) & 0xFF, (int) (header >> 24) & 0xFF, (int) nlumps);
free(buf);
exit(1);
}
free(buf);
}
mode_t umask_save;
void lumps2file(const char *fn, unsigned long header, const char *const *lumps, size_t *lumpsize, size_t nlumps, D0_BOOL private)
{
char buf[65536];
size_t n;
if(private)
umask(umask_save | 0077);
else
umask(umask_save);
if(!(n = Crypto_UnParsePack(buf, sizeof(buf), header, lumps, lumpsize, nlumps)))
{
fprintf(stderr, "could not unparse for %s\n", fn);
exit(1);
}
if(!buf2file(fn, buf, n))
{
fprintf(stderr, "could not write %s\n", fn);
exit(1);
}
}
void USAGE(const char *me)
{
printf("Usage:\n"
"%s [-F] [-b bits] [-n progress-denominator] [-x prefix] [-X infix] [-C] -o private.d0sk\n"
"%s -P private.d0sk -o public.d0pk\n"
"%s [-n progress-denominator] [-x prefix] [-X infix] [-C] -p public.d0pk -o idkey-unsigned.d0si\n"
"%s -p public.d0pk -I idkey-unsigned.d0si -o request.d0iq -O camouflage.d0ic\n"
"%s -P private.d0sk -j request.d0iq -o response.d0ir\n"
"%s -p public.d0pk -I idkey-unsigned.d0si -c camouflage.d0ic -J response.d0ir -o idkey.d0si\n"
"%s -P private.d0sk -I idkey-unsigned.d0si -o idkey.d0si\n"
"%s -I idkey.d0si -o id.d0pi\n"
"%s -p public.d0pk\n"
"%s -P private.d0sk\n"
"%s -p public.d0pk -i id.d0pi\n"
"%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 -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
);
}
unsigned int seconds;
unsigned int generated;
unsigned int ntasks = 1;
double generated_offset;
double guesscount;
double guessfactor;
void print_generated(int signo)
{
(void) signo;
++seconds;
if(generated >= 1000000000)
{
generated_offset += generated;
generated = 0;
}
fprintf(stderr, "Generated: %.0f (about %.0f, %.1f/s, about %.2f hours for %.0f)\n",
// nasty and dishonest hack:
// we are adjusting the values "back", so the total count is
// divided by guessfactor (as the check function is called
// guessfactor as often as it would be if no fastreject were
// done)
// so the values indicate the relative speed of fastreject vs
// normal!
(generated + generated_offset) / guessfactor,
(generated + generated_offset) * ntasks / guessfactor,
(generated + generated_offset) * ntasks / (guessfactor * seconds),
guesscount * ((guessfactor * seconds) / (generated + generated_offset) / ntasks) / 3600.0,
guesscount);
alarm(1);
}
#define CHECK(x) if(!(x)) { fprintf(stderr, "error exit: error returned by %s\n", #x); exit(2); }
const char *prefix = NULL, *infix = NULL;
size_t prefixlen = 0;
int ignorecase;
typedef D0_BOOL (*fingerprint_func) (const d0_blind_id_t *ctx, char *outbuf, size_t *outbuflen);
D0_BOOL fastreject(const d0_blind_id_t *ctx, void *pass)
{
static char fp64[513]; size_t fp64size = 512;
CHECK(((fingerprint_func) pass)(ctx, fp64, &fp64size));
++generated;
if(ignorecase)
{
if(prefixlen)
if(strncasecmp(fp64, prefix, prefixlen))
return 1;
if(infix)
{
fp64[fp64size] = 0;
if(!strcasestr(fp64, infix))
return 1;
}
}
else
{
if(prefixlen)
if(memcmp(fp64, prefix, prefixlen))
return 1;
if(infix)
{
fp64[fp64size] = 0;
if(!strstr(fp64, infix))
return 1;
}
}
return 0;
}
int main(int argc, char **argv)
{
int opt;
size_t lumpsize[2];
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, *sigfile = NULL;
char fp64[513]; size_t fp64size = 512;
int mask = 0;
int bits = 1024;
int i;
D0_BOOL do_fastreject = 1;
d0_blind_id_t *ctx;
if(!d0_blind_id_INITIALIZE())
{
fprintf(stderr, "could not initialize\n");
exit(1);
}
umask_save = umask(0022);
ctx = d0_blind_id_new();
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)
{
case 'C':
ignorecase = 1;
break;
case 'n':
ntasks = atoi(optarg);
break;
case 'b':
bits = atoi(optarg);
break;
case 'p': // d0pk = <pubkey> <modulus>
pubkeyfile = optarg;
mask |= 1;
break;
case 'P': // d0sk = <privkey> <modulus>
privkeyfile = optarg;
mask |= 2;
break;
case 'i': // d0pi = <pubid>
pubidfile = optarg;
mask |= 4;
break;
case 'I': // d0si = <privid>
prividfile = optarg;
mask |= 8;
break;
case 'j': // d0iq = <req>
idreqfile = optarg;
mask |= 0x10;
break;
case 'J': // d0ir = <resp>
idresfile = optarg;
mask |= 0x20;
break;
case 'o':
outfile = optarg;
mask |= 0x40;
break;
case 'O':
outfile2 = optarg;
mask |= 0x80;
break;
case 'c':
camouflagefile = optarg;
mask |= 0x100;
break;
case 'x':
prefix = optarg;
prefixlen = strlen(prefix);
break;
case '0':
// test mode
mask |= 0x200;
break;
case 'd':
datafile = optarg;
mask |= 0x400;
break;
case 's':
sigfile = optarg;
mask |= 0x800;
break;
case 'X':
infix = optarg;
break;
case 'F':
do_fastreject = 0;
break;
default:
USAGE(*argv);
return 1;
}
}
// fastreject is a slight slowdown when rejecting nothing at all
if(!infix && !prefixlen)
do_fastreject = 0;
guesscount = pow(64.0, prefixlen);
if(infix)
guesscount /= (1 - pow(1 - pow(1/64.0, strlen(infix)), 44 - prefixlen - strlen(infix)));
// 44 chars; prefix is assumed to not match the infix (although it theoretically could)
// 43'th char however is always '=' and does not count
if(ignorecase)
{
if(infix)
for(i = 0; infix[i]; ++i)
if(toupper(infix[i]) != tolower(infix[i]))
guesscount /= 2;
for(i = 0; i < (int)prefixlen; ++i)
if(toupper(prefix[i]) != tolower(prefix[i]))
guesscount /= 2;
}
if(do_fastreject)
{
// fastreject: reject function gets called about log(2^bits) times more often
guessfactor = bits * log(2) / 2;
// so guess function gets called guesscount * guessfactor times, and it tests as many valid keys as guesscount
}
if(mask & 1)
{
file2lumps(pubkeyfile, FOURCC_D0PK, lumps, lumpsize, 2);
if(!d0_blind_id_read_public_key(ctx, lumps[0], lumpsize[0]))
{
fprintf(stderr, "could not decode public key\n");
exit(1);
}
if(!d0_blind_id_read_private_id_modulus(ctx, lumps[1], lumpsize[1]))
{
fprintf(stderr, "could not decode modulus\n");
exit(1);
}
}
else if(mask & 2)
{
file2lumps(privkeyfile, FOURCC_D0SK, lumps, lumpsize, 2);
if(!d0_blind_id_read_private_key(ctx, lumps[0], lumpsize[0]))
{
fprintf(stderr, "could not decode private key\n");
exit(1);
}
if(!d0_blind_id_read_private_id_modulus(ctx, lumps[1], lumpsize[1]))
{
fprintf(stderr, "could not decode modulus\n");
exit(1);
}
}
if(mask & 4)
{
file2lumps(pubidfile, FOURCC_D0PI, lumps, lumpsize, 1);
if(!d0_blind_id_read_public_id(ctx, lumps[0], lumpsize[0]))
{
fprintf(stderr, "could not decode public ID\n");
exit(1);
}
}
if(mask & 8)
{
file2lumps(prividfile, FOURCC_D0SI, lumps, lumpsize, 1);
if(!d0_blind_id_read_private_id(ctx, lumps[0], lumpsize[0]))
{
fprintf(stderr, "could not decode private ID\n");
exit(1);
}
}
if(mask & 0x10)
{
file2lumps(idreqfile, FOURCC_D0IQ, lumps, lumpsize, 1);
lumpsize[1] = sizeof(lumps_w1);
lumps[1] = lumps_w1;
if(!d0_blind_id_answer_private_id_request(ctx, lumps[0], lumpsize[0], lumps_w1, &lumpsize[1]))
{
fprintf(stderr, "could not answer private ID request\n");
exit(1);
}
}
else if((mask & 0x120) == 0x120)
{
file2lumps(camouflagefile, FOURCC_D0IC, lumps, lumpsize, 1);
if(!d0_blind_id_read_private_id_request_camouflage(ctx, lumps[0], lumpsize[0]))
{
fprintf(stderr, "could not decode camouflage\n");
exit(1);
}
file2lumps(idresfile, FOURCC_D0IR, lumps, lumpsize, 1);
if(!d0_blind_id_finish_private_id_request(ctx, lumps[0], lumpsize[0]))
{
fprintf(stderr, "could not finish private ID request\n");
exit(1);
}
}
if(mask & 0x400)
{
file2buf(datafile, &databuf_in, &databufsize_in);
if(!databuf_in)
{
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);
}
}
switch(mask)
{
// modes of operation:
case 0x40:
// nothing -> private key file (incl modulus), print fingerprint
generated = 0;
generated_offset = 0;
seconds = 0;
signal(SIGALRM, print_generated);
alarm(1);
if(do_fastreject)
{
CHECK(d0_blind_id_generate_private_key_fastreject(ctx, bits, fastreject, d0_blind_id_fingerprint64_public_key));
}
else
{
guessfactor = 1; // no fastreject here
do
{
CHECK(d0_blind_id_generate_private_key(ctx, bits));
}
while(fastreject(ctx, d0_blind_id_fingerprint64_public_key));
}
alarm(0);
signal(SIGALRM, NULL);
CHECK(d0_blind_id_generate_private_id_modulus(ctx));
lumps[0] = lumps_w0;
lumpsize[0] = sizeof(lumps_w0);
lumps[1] = lumps_w1;
lumpsize[1] = sizeof(lumps_w1);
CHECK(d0_blind_id_write_private_key(ctx, lumps_w0, &lumpsize[0]));
CHECK(d0_blind_id_write_private_id_modulus(ctx, lumps_w1, &lumpsize[1]));
lumps2file(outfile, FOURCC_D0SK, lumps, lumpsize, 2, 1);
break;
case 0x42:
// private key file -> public key file (incl modulus)
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(outfile, FOURCC_D0PK, lumps, lumpsize, 2, 0);
break;
case 0x41:
// public key file -> unsigned private ID file
generated = 0;
generated_offset = 0;
seconds = 0;
signal(SIGALRM, print_generated);
alarm(1);
guessfactor = 1; // no fastreject here
do
{
CHECK(d0_blind_id_generate_private_id_start(ctx));
}
while(fastreject(ctx, d0_blind_id_fingerprint64_public_id));
alarm(0);
signal(SIGALRM, 0);
lumps[0] = lumps_w0;
lumpsize[0] = sizeof(lumps_w0);
CHECK(d0_blind_id_write_private_id(ctx, lumps_w0, &lumpsize[0]));
lumps2file(outfile, FOURCC_D0SI, lumps, lumpsize, 1, 1);
break;
case 0xC9:
// public key file, unsigned private ID file -> ID request file and camouflage file
lumps[0] = lumps_w0;
lumpsize[0] = sizeof(lumps_w0);
CHECK(d0_blind_id_generate_private_id_request(ctx, lumps_w0, &lumpsize[0]));
lumps2file(outfile, FOURCC_D0IQ, lumps, lumpsize, 1, 0);
lumpsize[0] = sizeof(lumps_w0);
CHECK(d0_blind_id_write_private_id_request_camouflage(ctx, lumps_w0, &lumpsize[0]));
lumps2file(outfile2, FOURCC_D0IC, lumps, lumpsize, 1, 1);
break;
case 0x52:
// private key file, ID request file -> ID response file
lumps2file(outfile, FOURCC_D0IR, lumps+1, lumpsize+1, 1, 0);
break;
case 0x169:
// public key file, ID response file, private ID file -> signed private ID file
lumps[0] = lumps_w0;
lumpsize[0] = sizeof(lumps_w0);
CHECK(d0_blind_id_write_private_id(ctx, lumps_w0, &lumpsize[0]));
lumps2file(outfile, FOURCC_D0SI, lumps, lumpsize, 1, 1);
break;
case 0x4A:
// private key file, private ID file -> signed private ID file
{
char buf[65536]; size_t bufsize;
char buf2[65536]; size_t buf2size;
D0_BOOL status;
d0_blind_id_t *ctx2 = d0_blind_id_new();
CHECK(d0_blind_id_copy(ctx2, ctx));
bufsize = sizeof(buf);
CHECK(d0_blind_id_authenticate_with_private_id_start(ctx, 1, 1, "hello world", 11, buf, &bufsize));
buf2size = sizeof(buf2);
CHECK(d0_blind_id_authenticate_with_private_id_challenge(ctx2, 1, 1, buf, bufsize, buf2, &buf2size, &status));
bufsize = sizeof(buf);
CHECK(d0_blind_id_authenticate_with_private_id_response(ctx, buf2, buf2size, buf, &bufsize));
buf2size = sizeof(buf2);
CHECK(d0_blind_id_authenticate_with_private_id_verify(ctx2, buf, bufsize, buf2, &buf2size, &status));
CHECK(status == 0);
CHECK(d0_blind_id_authenticate_with_private_id_generate_missing_signature(ctx2));
lumps[0] = lumps_w0;
lumpsize[0] = sizeof(lumps_w0);
CHECK(d0_blind_id_write_private_id(ctx2, lumps_w0, &lumpsize[0]));
lumps2file(outfile, FOURCC_D0SI, lumps, lumpsize, 1, 1);
}
break;
case 0x48:
// private ID file -> public ID file
lumps[0] = lumps_w0;
lumpsize[0] = sizeof(lumps_w0);
CHECK(d0_blind_id_write_public_id(ctx, lumps_w0, &lumpsize[0]));
lumps2file(outfile, FOURCC_D0PI, lumps, lumpsize, 1, 0);
break;
case 0x01:
case 0x02:
// public/private key file -> fingerprint
CHECK(d0_blind_id_fingerprint64_public_key(ctx, fp64, &fp64size));
printf("%.*s\n", (int)fp64size, fp64);
break;
case 0x05:
case 0x09:
// public/private ID file -> fingerprint
CHECK(d0_blind_id_fingerprint64_public_id(ctx, fp64, &fp64size));
printf("%.*s\n", (int)fp64size, fp64);
break;
case 0x449:
// public key, private ID, data -> signed data
databufsize_out = databufsize_in + 8192;
databuf_out = malloc(databufsize_out);
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 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_sig;
databuf_out = malloc(databufsize_out);
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);
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 0x09:
// public key, private ID file -> test whether key is properly signed
{
char buf[65536]; size_t bufsize;
char buf2[65536]; size_t buf2size;
D0_BOOL status;
d0_blind_id_t *ctx2 = d0_blind_id_new();
CHECK(d0_blind_id_copy(ctx2, ctx));
bufsize = sizeof(buf);
CHECK(d0_blind_id_authenticate_with_private_id_start(ctx, 1, 1, "hello world", 11, buf, &bufsize));
buf2size = sizeof(buf2);
CHECK(d0_blind_id_authenticate_with_private_id_challenge(ctx2, 1, 1, buf, bufsize, buf2, &buf2size, &status));
bufsize = sizeof(buf);
CHECK(d0_blind_id_authenticate_with_private_id_response(ctx, buf2, buf2size, buf, &bufsize));
buf2size = sizeof(buf2);
CHECK(d0_blind_id_authenticate_with_private_id_verify(ctx2, buf, bufsize, buf2, &buf2size, &status));
if(status)
printf("OK\n");
else
printf("EPIC FAIL\n");
}
break;
*/
case 0x209:
// protocol client
{
char hexbuf[131073];
const char hex[] = "0123456789abcdef";
char buf[65536]; size_t bufsize;
char buf2[65536]; size_t buf2size;
bufsize = sizeof(buf);
CHECK(d0_blind_id_authenticate_with_private_id_start(ctx, 1, 1, "hello world", 11, buf, &bufsize));
for(i = 0; i < (int)bufsize; ++i)
sprintf(&hexbuf[2*i], "%02x", (unsigned char)buf[i]);
printf("%s\n", hexbuf);
fgets(hexbuf, sizeof(hexbuf), stdin);
buf2size = strlen(hexbuf) / 2;
for(i = 0; i < (int)buf2size; ++i)
buf2[i] = ((strchr(hex, hexbuf[2*i]) - hex) << 4) | (strchr(hex, hexbuf[2*i+1]) - hex);
bufsize = sizeof(buf);
CHECK(d0_blind_id_authenticate_with_private_id_response(ctx, buf2, buf2size, buf, &bufsize));
for(i = 0; i < (int)bufsize; ++i)
sprintf(&hexbuf[2*i], "%02x", (unsigned char)buf[i]);
printf("%s\n", hexbuf);
}
break;
case 0x201:
// protocol server
{
char hexbuf[131073];
const char hex[] = "0123456789abcdef";
char buf[65536]; size_t bufsize;
char buf2[65536]; size_t buf2size;
D0_BOOL status;
fgets(hexbuf, sizeof(hexbuf), stdin);
buf2size = strlen(hexbuf) / 2;
for(i = 0; i < (int)buf2size; ++i)
buf2[i] = ((strchr(hex, hexbuf[2*i]) - hex) << 4) | (strchr(hex, hexbuf[2*i+1]) - hex);
bufsize = sizeof(buf);
CHECK(d0_blind_id_authenticate_with_private_id_challenge(ctx, 1, 1, buf2, buf2size, buf, &bufsize, &status));
for(i = 0; i < (int)bufsize; ++i)
sprintf(&hexbuf[2*i], "%02x", (unsigned char)buf[i]);
printf("%s\n", hexbuf);
fgets(hexbuf, sizeof(hexbuf), stdin);
buf2size = strlen(hexbuf) / 2;
for(i = 0; i < (int)buf2size; ++i)
buf2[i] = ((strchr(hex, hexbuf[2*i]) - hex) << 4) | (strchr(hex, hexbuf[2*i+1]) - hex);
bufsize = sizeof(buf);
CHECK(d0_blind_id_authenticate_with_private_id_verify(ctx, buf2, buf2size, buf, &bufsize, &status));
printf("verify status: %d\n", status);
CHECK(d0_blind_id_fingerprint64_public_id(ctx, fp64, &fp64size));
printf("%.*s\n", (int)fp64size, fp64);
}
break;
default:
USAGE(*argv);
exit(1);
break;
}
d0_blind_id_SHUTDOWN();
return 0;
}