Logo Search packages:      
Sourcecode: darkplaces version File versions  Download package

crypto-keygen-standalone.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;
}

Generated by  Doxygen 1.6.0   Back to index