[BACK]Return to skey.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / skey

File: [local] / src / usr.bin / skey / skey.c (download)

Revision 1.35, Fri Jan 25 00:19:26 2019 UTC (5 years, 3 months ago) by millert
Branch: MAIN
CVS Tags: OPENBSD_7_5_BASE, OPENBSD_7_5, OPENBSD_7_4_BASE, OPENBSD_7_4, OPENBSD_7_3_BASE, OPENBSD_7_3, OPENBSD_7_2_BASE, OPENBSD_7_2, OPENBSD_7_1_BASE, OPENBSD_7_1, OPENBSD_7_0_BASE, OPENBSD_7_0, OPENBSD_6_9_BASE, OPENBSD_6_9, OPENBSD_6_8_BASE, OPENBSD_6_8, OPENBSD_6_7_BASE, OPENBSD_6_7, OPENBSD_6_6_BASE, OPENBSD_6_6, OPENBSD_6_5_BASE, OPENBSD_6_5, HEAD
Changes since 1.34: +2 -2 lines

I am retiring my old email address;  replace it with my OpenBSD one.

/*	$OpenBSD: skey.c,v 1.35 2019/01/25 00:19:26 millert Exp $	*/
/*
 * OpenBSD S/Key (skey.c)
 *
 * Authors:
 *          Neil M. Haller <nmh@thumper.bellcore.com>
 *          Philip R. Karn <karn@chicago.qualcomm.com>
 *          John S. Walden <jsw@thumper.bellcore.com>
 *          Scott Chasin <chasin@crimelab.com>
 *          Todd C. Miller <millert@openbsd.org>
 *
 *
 * Stand-alone program for computing responses to S/Key challenges.
 * Takes the iteration count and seed as command line args, prompts
 * for the user's key, and produces both word and hex format responses.
 *
 * Usage example:
 *	>skey 88 ka9q2
 *	Enter password:
 *	OMEN US HORN OMIT BACK AHOY
 *	>
 *
 */

#include <err.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <readpassphrase.h>
#include <skey.h>

void usage();

extern char *__progname;

int
main(int argc, char *argv[])
{
	int     n, i, cnt = 1, pass = 0, hexmode = 0;
	char    passwd[SKEY_MAX_PW_LEN+1], key[SKEY_BINKEY_SIZE];
	char	buf[33], *seed, *slash, *algo;
	const char *errstr;

	if (pledge("stdio tty", NULL) == -1)
		err(1, "pledge");

	/* If we were called as otp-METHOD, set algorithm based on that */
	if (strncmp(__progname, "otp-", 4) == 0) {
		algo = __progname + 4;
		if (skey_set_algorithm(algo) == NULL)
			errx(1, "Unknown hash algorithm %s", algo);
	}

	for (i = 1; i < argc && argv[i][0] == '-' && strcmp(argv[i], "--");) {
		if (argv[i][2] == '\0') {
			/* Single character switch */
			switch (argv[i][1]) {
			case 'n':
				if (++i == argc)
					usage();
				cnt = strtonum(argv[i], 1, SKEY_MAX_SEQ -1, &errstr);
				if (errstr)
					usage();
				break;
			case 'p':
				if (++i == argc)
					usage();
				if (strlcpy(passwd, argv[i], sizeof(passwd)) >=
				    sizeof(passwd))
					errx(1, "Password too long");
				pass = 1;
				break;
			case 'x':
				hexmode = 1;
				break;
			default:
				usage();
			}
		} else {
			/* Multi character switches are hash types */
			if (skey_set_algorithm(&argv[i][1]) == NULL) {
				warnx("Unknown hash algorithm %s", &argv[i][1]);
				usage();
			}
		}
		i++;
	}

	if (argc > i + 2)
		usage();

	/* Could be in the form <number>/<seed> */
	if (argc <= i + 1) {
		/* look for / in it */
		if (argc <= i)
			usage();
		slash = strchr(argv[i], '/');
		if (slash == NULL)
			usage();
		*slash++ = '\0';
		seed = slash;

		n = strtonum(argv[i], 0, SKEY_MAX_SEQ, &errstr);
		if (errstr) {
			warnx("%s: %s", argv[i], errstr);
			usage();
		}
	} else {
		n = strtonum(argv[i], 0, SKEY_MAX_SEQ, &errstr);
		if (errstr) {
			warnx("%s: %s", argv[i], errstr);
			usage();
		}
		seed = argv[++i];
	}

	/* Get user's secret passphrase */
	if (!pass && (readpassphrase("Enter secret passphrase: ", passwd,
	    sizeof(passwd), 0) == NULL || passwd[0] == '\0'))
		exit(1);

	/* Crunch seed and passphrase into starting key */
	if (keycrunch(key, seed, passwd) != 0) {
		explicit_bzero(passwd, sizeof(passwd));
		errx(1, "key crunch failed");
	}

	explicit_bzero(passwd, sizeof(passwd));

	if (cnt == 1) {
		while (n-- != 0)
			f(key);
		(void)puts(hexmode ? put8(buf, key) : btoe(buf, key));
	} else {
		for (i = 0; i <= n - cnt; i++)
			f(key);
		for (; i <= n; i++) {
			if (hexmode)
				(void)printf("%d: %s\n", i, put8(buf, key));
			else
				(void)printf("%d: %-29s\n", i, btoe(buf, key));
			f(key);
		}
	}
	exit(0);
}

void
usage(void)
{
	fprintf(stderr,
	    "usage: %s [-x] [-md5 | -rmd160 | -sha1] [-n count]\n\t"
	    "[-p passphrase] <sequence#>[/] key\n", __progname);
	exit(1);
}