version 1.1, 2001/08/01 21:22:16 |
version 1.2, 2001/08/01 22:20:10 |
|
|
* This software is provided AS IS with no express or implied warranty |
* This software is provided AS IS with no express or implied warranty |
* October 1995, Paul Borman <prb@krystal.com> |
* October 1995, Paul Borman <prb@krystal.com> |
*/ |
*/ |
#if defined(KRBDES) && !defined(__unix__) |
#include <sys/param.h> |
#define __unix__ |
#include <sys/stat.h> |
#endif |
|
#ifdef __unix__ |
|
#ifdef LITTLE_ENDIAN |
|
#undef LITTLE_ENDIAN |
|
#endif |
|
#include <pwd.h> |
|
#else |
|
#include <dos.h> |
|
#endif |
|
#include <ctype.h> |
#include <ctype.h> |
|
#include <err.h> |
|
#include <pwd.h> |
|
#include <readpassphrase.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <sys/stat.h> |
#include <des.h> |
extern char *optarg; |
|
|
|
|
#define KEYFILE ".keyfile.des" |
#ifdef __unix__ |
|
#define KEYFILE ".keyfile.des" |
|
#define MPL 1024 |
|
#else |
|
#define KEYFILE "keyfile.des" |
|
#define MPL 256 |
|
#endif |
|
|
|
#define HEXDIGITS "0123456789abcdef" |
#define HEXDIGITS "0123456789abcdef" |
#define DECDIGITS "0123456789012345" |
#define DECDIGITS "0123456789012345" |
|
|
|
void predict(des_key_schedule, char *, int); |
|
|
char *digits = HEXDIGITS; |
char *digits = HEXDIGITS; |
|
extern char *__progname; |
|
|
#ifdef KRBDES |
|
#include <des.h> |
|
#define setkey dessetkey |
|
|
|
void desinit(int i) { ; } |
|
void dessetkey(char ks[16][8], char key[8]) |
|
{ |
|
des_key_schedule *k = (des_key_schedule *)ks; |
|
des_fixup_key_parity((des_cblock *)key); |
|
des_key_sched((des_cblock *)key, *k); |
|
} |
|
void endes(char ks[16][8], char key[8]) |
|
{ |
|
des_cblock cb; |
|
des_key_schedule *k = (des_key_schedule *)ks; |
|
|
|
des_ecb_encrypt((des_cblock *)key, &cb, *k, DES_ENCRYPT); |
|
memcpy(key, &cb, 8); |
|
} |
|
#endif |
|
|
|
void predict(char ks[16][8], char *chal, int cnt); |
|
|
|
int |
int |
main(int ac, char **av) |
main(int argc, char **argv) |
{ |
{ |
int i; |
int i; |
char ks[16][8]; |
|
char buf[256]; |
char buf[256]; |
char key[8]; |
des_key_schedule ks; |
char _keyfile[MPL]; |
des_cblock key; |
|
char _keyfile[MAXPATHLEN]; |
char *keyfile = 0; |
char *keyfile = 0; |
FILE *fp; |
FILE *fp; |
int init = 0; |
int init = 0; |
int hex = 1; |
int hex = 1; |
int cnt = 1; |
int cnt = 1; |
unsigned long pin; |
unsigned int pin; |
#ifdef __unix__ |
|
struct passwd *pwd; |
struct passwd *pwd; |
#endif |
|
|
|
while ((i = getopt(ac, av, "dk:in:")) != EOF) |
while ((i = getopt(argc, argv, "dk:in:")) != -1) { |
switch (i) { |
switch (i) { |
case 'k': |
case 'k': |
keyfile = optarg; |
keyfile = optarg; |
|
|
break; |
break; |
case 'n': |
case 'n': |
cnt = atoi(optarg); |
cnt = atoi(optarg); |
if (cnt <= 0) { |
if (cnt <= 0) |
fprintf(stderr, "%s: invalid count\n", optarg); |
err(1, "invalid count: %s", optarg); |
exit(1); |
|
} |
|
break; |
break; |
default: |
default: |
fprintf(stderr, "Usage: x99token [-n cnt] [-h] [-k keyfile]\n" |
fprintf(stderr, "usage: %s [-n cnt] [-h] [-k keyfile]\n" |
" x99token -i [-k keyfile]\n"); |
" %s -i [-k keyfile]\n", __progname, |
|
__progname); |
exit(1); |
exit(1); |
} |
} |
|
} |
|
|
desinit(0); |
|
|
|
if (!keyfile) { |
if (!keyfile) { |
#ifdef __unix__ |
if ((pwd = getpwuid(getuid())) == NULL) { |
if ((pwd = getpwuid(getuid())) == 0) { |
|
fprintf(stderr, "Say, just who are you, anyhow?\n"); |
fprintf(stderr, "Say, just who are you, anyhow?\n"); |
exit(1); |
exit(1); |
} |
} |
sprintf(_keyfile, "%s/%s", pwd->pw_dir, KEYFILE); |
snprintf(_keyfile, sizeof(_keyfile), "%s/%s", pwd->pw_dir, |
|
KEYFILE); |
keyfile = _keyfile; |
keyfile = _keyfile; |
#else |
|
keyfile = KEYFILE; |
|
#endif |
|
} |
} |
|
|
if (init) { |
if (init) |
#ifdef __unix__ |
readpassphrase("Enter Key: ", buf, sizeof(buf), 0); |
strcpy(buf, (char *)getpass("Enter Key: ")); |
else if ((fp = fopen(keyfile, "r")) == NULL) |
#else |
err(1, "unable to open %s", keyfile); |
printf("Enter key: "); |
else { |
if (fgets(buf, sizeof(buf), stdin) == NULL) |
|
exit(0); |
|
#endif |
|
} else if ((fp = fopen(keyfile, "r")) == NULL) { |
|
fprintf(stderr, "Failed to open %s\n", keyfile); |
|
exit(1); |
|
} else { |
|
if (fgets(buf, sizeof(buf), fp) == NULL) { |
if (fgets(buf, sizeof(buf), fp) == NULL) { |
fprintf(stderr, "No key in %s\n", keyfile); |
fprintf(stderr, "No key in %s\n", keyfile); |
exit(1); |
exit(1); |
|
|
while (*b && !isdigit(*b)) |
while (*b && !isdigit(*b)) |
++b; |
++b; |
} |
} |
} else |
} else { |
for (i = 0; i < 16; ++i) { |
for (i = 0; i < 16; ++i) { |
int d; |
int d; |
|
|
|
|
} |
} |
key[i>>1] |= d << ((i & 1) ? 0 : 4); |
key[i>>1] |= d << ((i & 1) ? 0 : 4); |
} |
} |
|
} |
|
|
#ifdef __unix__ |
/* XXX - should warn on non-space or non-digit */ |
strcpy(buf, (char *)getpass("Enter Pin: ")); |
readpassphrase("Enter Pin: ", buf, sizeof(buf), 0); |
#else |
for (i = 0, pin = 0; buf[i] && buf[i] != '\n'; ++i) |
printf("Enter Pin: "); |
|
if (fgets(buf, sizeof(buf), stdin) == NULL) |
|
exit(0); |
|
#endif |
|
|
|
for (i = 0; buf[i] && buf[i] != '\n'; ++i) |
|
if (isdigit(buf[i])) |
if (isdigit(buf[i])) |
pin = pin * 16 + buf[i] - '0' + 1; |
pin = pin * 16 + buf[i] - '0' + 1; |
|
|
if ((pin & 0xffff0000L) == 0) |
if ((pin & 0xffff0000) == 0) |
pin |= pin << 16; |
pin |= pin << 16; |
|
|
for (i = 0; i < 8; ++i) |
for (i = 0; i < 8; ++i) |
key[0] ^= (pin >> ((i * 7) % 26)) & 0x7f; |
key[0] ^= (pin >> ((i * 7) % 26)) & 0x7f; |
|
|
if (init) { |
if (init) { |
if ((fp = fopen(keyfile, "w")) == NULL) { |
if ((fp = fopen(keyfile, "w")) == NULL) |
fprintf(stderr, "could not open %s for writing\n", |
err(1, "could not open %s for writing", keyfile); |
keyfile); |
fchmod(fileno(fp), 0600); |
exit(1); |
|
} |
|
for (i = 0; i < 8; ++i) { |
for (i = 0; i < 8; ++i) { |
fprintf(fp, "%c", digits[(key[i]>>4)&0xf]); |
fprintf(fp, "%c", digits[(key[i]>>4)&0xf]); |
fprintf(fp, "%c", digits[(key[i]>>0)&0xf]); |
fprintf(fp, "%c", digits[(key[i]>>0)&0xf]); |
} |
} |
fprintf(fp, "\n"); |
fputc('\n', fp); |
fclose(fp); |
fclose(fp); |
#ifdef __unix__ |
|
chmod(keyfile, 0600); |
|
#else |
|
dos_setfileattr(keyfile, FA_HIDDEN | FA_SYSTEM); |
|
#endif |
|
exit(0); |
exit(0); |
} |
} |
|
|
setkey(ks, key); |
des_fixup_key_parity(&key); |
|
des_key_sched(&key, ks); |
|
|
printf("Enter challange: "); |
buf[0] = '\0'; |
memset(buf, 0, sizeof(buf)); |
readpassphrase("Enter challange: ", buf, sizeof(buf), RPP_ECHO_ON); |
if (fgets(buf, sizeof(buf), stdin) == NULL) |
if (buf[0] == '\0') |
exit(0); |
exit(0); |
|
|
for (i = 0; i < 8; ++i) |
for (i = 0; i < 8; ++i) |
|
|
|
|
predict(ks, buf, cnt); |
predict(ks, buf, cnt); |
|
|
|
memset(&ks, 0, sizeof(ks)); |
|
memset(buf, 0, sizeof(buf)); |
|
|
exit(0); |
exit(0); |
} |
} |
|
|
void |
void |
predict(char ks[16][8], char *chal, int cnt) |
predict(des_key_schedule ks, char *chal, int cnt) |
{ |
{ |
int i; |
int i; |
|
des_cblock cb; |
|
|
while (cnt-- > 0) { |
while (cnt-- > 0) { |
printf("%.8s: ", chal); |
printf("%.8s: ", chal); |
endes(ks, chal); |
des_ecb_encrypt((des_cblock *)chal, &cb, ks, DES_ENCRYPT); |
for (i = 0; i < 4; ++i) { |
for (i = 0; i < 4; ++i) { |
printf("%c", digits[(chal[i]>>4) & 0xf]); |
printf("%c", digits[(cb[i]>>4) & 0xf]); |
printf("%c", digits[(chal[i]>>0) & 0xf]); |
printf("%c", digits[(cb[i]>>0) & 0xf]); |
} |
} |
printf("\n"); |
putchar('\n'); |
for (i = 0; i < 8; ++i) { |
for (i = 0; i < 8; ++i) { |
if ((chal[i] &= 0xf) > 9) |
if ((cb[i] &= 0xf) > 9) |
chal[i] -= 10; |
cb[i] -= 10; |
chal[i] |= 0x30; |
cb[i] |= 0x30; |
} |
} |
} |
} |
|
memset(&cb, 0, sizeof(cb)); |
} |
} |