/*
 * Copyright (c) 1997-2000  The Stanford SRP Authentication Project
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * In addition, the following conditions apply:
 *
 * 1. Any software that incorporates the SRP authentication technology
 *    must display the following acknowlegment:
 *    "This product uses the 'Secure Remote Password' cryptographic
 *     authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
 *
 * 2. Any software that incorporates all or part of the SRP distribution
 *    itself must also display the following acknowledgment:
 *    "This product includes software developed by Tom Wu and Eugene
 *     Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
 *
 * 3. Redistributions in source or binary form must retain an intact copy
 *    of this copyright notice and list of conditions.
 */

#include <unistd.h>     /* close getlogin */
#include <stdlib.h>     /* atexit exit */
#include <stdio.h>
#include <string.h>

#include "t_pwd.h"

#define MIN_BASIS_BITS 512
#define BASIS_BITS 2048

extern int  optind;
extern char *optarg;

extern int errno;

char *progName;

int  debug   = 0;
int  verbose = 0;
int  composite = 0;

int main(argc, argv)
     int argc;
     char *argv[];
{
  char *chp;
  char *configFile = NULL;
  char cbuf[256];
  char b64buf[MAXB64PARAMLEN];
  int c, ch, i, lastidx, keylen, yesno, fsize, status, nparams;
  FILE *efp;

  struct t_preconf * tpc;
  struct t_conf tcs;
  struct t_conf * tc = &tcs;
  struct t_confent * tcent;

  progName = *argv;
  if ((chp = strrchr(progName, '/')) != (char *) 0) progName = chp + 1;

  while ((ch = getopt(argc, argv, "dv2c:")) != EOF)
    switch(ch) {
    case 'c':
      configFile = optarg;
      break;
    case 'v':
      verbose++;
      break;
    case 'd':
      debug++;
      break;
    case '2':
      composite++;
      break;
    default:
      fprintf(stderr, "usage: %s [-dv2] [-c configfile]\n", progName);
      exit(1);
    }

  argc -= optind;
  argv += optind;

  lastidx = 0;
  keylen = 0;

  tcent = t_newconfent(tc);

  printf("\nThis program will generate a set of parameters for the EPS\n");
  printf("password file.  The size of these parameters, measured in bits,\n");
  printf("determines the level of security offered by SRP, and is related\n");
  printf("to the security of similarly-sized RSA or Diffie-Hellman keys.\n");
  printf("Choosing a predefined field is generally preferable to generating\n");
  printf("a new field because clients can avoid costly parameter verification.\n");
  printf("Either way, the values generated by this program are public and\n");
  printf("can even shared between systems.\n");

  printf("\nEnter the new field size, in bits.  Suggested sizes:\n\n");
  printf(" 512 (fast, minimally secure)\n");
  printf(" 768 (moderate security)\n");
  printf("1024 (most popular default)\n");
  printf("1536 (additional security, possibly slow)\n");
  printf("2048 (maximum supported security level)\n");
  printf("\nField size (%d to %d): ", MIN_BASIS_BITS, BASIS_BITS);

  fgets(cbuf, sizeof(cbuf), stdin);
  fsize = atoi(cbuf);
  if(fsize < MIN_BASIS_BITS || fsize > BASIS_BITS) {
    fprintf(stderr, "%s: field size must be between %d and %d\n",
	    progName, MIN_BASIS_BITS, BASIS_BITS);
    exit(1);
  }

  if(fsize <= keylen)
    fprintf(stderr, "Warning: new field size is not larger than old field size\n");

  printf("\nInitializing random number generator...");
  fflush(stdout);
  t_initrand();

  if(composite)
    printf("done.\n\nGenerating a %d-bit composite with safe prime factors.  This may take a while.\n", fsize);
  else
    printf("done.\n\nGenerating a %d-bit safe prime.  This may take a while.\n", fsize);

  while((tcent = (composite ? t_makeconfent_c(tc, fsize) :
			      t_makeconfent(tc, fsize))) == NULL)
    printf("Parameter generation failed, retrying...\n");
  tcent->index = lastidx + 1;

  printf("\nParameters successfully generated.\n");
  printf("N = [%s]\n", t_tob64(b64buf,
			       tcent->modulus.data, tcent->modulus.len));
  printf("g = [%s]\n", t_tob64(b64buf,
			       tcent->generator.data, tcent->generator.len));
  printf("\nYou must update the pre_params array in t_getconf.c\n");
}
