/*
 * Copyright (c) 1997 Stanford University
 *
 * The use of this software for revenue-generating purposes may require a
 * license from the owners of the underlying intellectual property.
 *
 * Within that constraint, permission to use, copy, modify, and distribute
 * this software and its documentation for any purpose is hereby granted
 * without fee, provided that the above copyright notices and this permission
 * notice appear in all copies of the software and related documentation.
 *
 * 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.
 */

#include <errno.h>
#include <stdio.h>
#include "t_defines.h"
#include "t_pwd.h"
#include "t_sha.h"

main(argc, argv)
     int argc;
     char **argv;
{
  struct t_conf * tc;
  struct t_confent * tce;
  struct t_pw * tpw;
  struct t_pwent * ent;
  int i;
  unsigned char dout[SHA_DIGESTSIZE];
  SHA1_CTX ctxt;
  BigInteger N, g, xs, xp;
  char hexbuf[MAXHEXPARAMLEN];
  char username[16];
  char pass[128];

  t_random(hexbuf, 64);
  printf("Strong random numbers:\n");
  for(i = 0; i < 64; ++i)
    printf(" %02X", (unsigned char) hexbuf[i]);

  printf("\n");

  if(argc > 1) {
    tpw = t_openpw(NULL);
    if(tpw == NULL) {
      fprintf(stderr, "t_openpw failed, errno=%d\n", errno);
      exit(1);
    }

    printf("Getting password entry for %s...\n", argv[1]);
    ent = t_getpwbyname(tpw, argv[1]);
    if(ent == NULL)
      printf("%s not found\n", argv[1]);
    else {
      printf("%s's public password (length %d) = ", argv[1], ent->password.len);
      for(i = 0; i < ent->password.len; ++i) {
	printf("%.2X ", ent->password.data[i]);
      }
      printf("\nIndex = %d\n", ent->index);
      tc = t_openconf(NULL);
      if(tc == NULL) {
	fprintf(stderr, "t_openconf failed, errno=%d\n", errno);
	exit(1);
      }
      tce = t_getconfbyindex(tc, ent->index);
      if(tce == NULL)
	printf("Index %d not found!\n", ent->index);
      else {
	printf("Modulus length = %d, modulus = ", tce->modulus.len);
	for(i = 0; i < tce->modulus.len; ++i) {
	  printf("%.2X ", tce->modulus.data[i]);
	}
	printf("\nGenerator length = %d, generator = ", tce->generator.len);
	for(i = 0; i < tce->generator.len; ++i) {
	  printf("%.2X ", tce->generator.data[i]);
	}
	printf("\n");
      }
#ifndef WIN32
      t_getpass(pass, 128, "Enter a password:");
      SHA1Init(&ctxt);
      SHA1Update(&ctxt, ent->name, strlen(ent->name));
      SHA1Update(&ctxt, ":", 1);
      SHA1Update(&ctxt, pass, strlen(pass));
      SHA1Final(dout, &ctxt);
      printf("Password hash = ");
      for(i = 0; i < sizeof(dout); ++i)
	printf("%.2X ", dout[i]);
      printf("\n");

      N = BigIntegerFromBytes(tce->modulus.data, tce->modulus.len);
      g = BigIntegerFromBytes(tce->generator.data, tce->generator.len);
      xs = BigIntegerFromBytes(dout, sizeof(dout));
      xp = BigIntegerFromInt(0);
      BigIntegerModExp(xp, g, xs, N);
      BigIntegerToHex(xp, hexbuf);
#endif

      BigIntegerFree(xp);
      BigIntegerFree(xs);
      BigIntegerFree(g);
      BigIntegerFree(N);

      t_closeconf(tc);

      printf("Public password: %s\n", hexbuf);
    }
    t_closepw(tpw);
  }
  else
    while(printf("login: "), gets(username) != NULL)
    {
      t_getpass(pass, 128, "Enter a password:");
      if(t_verifypw(username, pass) > 0)
	printf("Login accepted\n");
      else
	printf("Login incorrect\n");
    }
  return 0;
}

