Annotation of src/usr.bin/x99token/x99token.c, Revision 1.3
1.1 millert 1: /*
2: * X9.9 calculator
3: * This software is provided AS IS with no express or implied warranty
4: * October 1995, Paul Borman <prb@krystal.com>
5: */
1.2 millert 6: #include <sys/param.h>
7: #include <sys/stat.h>
8:
9: #include <ctype.h>
10: #include <err.h>
1.1 millert 11: #include <pwd.h>
1.2 millert 12: #include <readpassphrase.h>
1.1 millert 13: #include <stdio.h>
14: #include <stdlib.h>
15: #include <string.h>
16: #include <unistd.h>
1.2 millert 17: #include <des.h>
1.1 millert 18:
1.2 millert 19: #define KEYFILE ".keyfile.des"
1.1 millert 20: #define HEXDIGITS "0123456789abcdef"
21: #define DECDIGITS "0123456789012345"
22:
1.2 millert 23: void predict(des_key_schedule, char *, int);
24:
1.1 millert 25: char *digits = HEXDIGITS;
1.2 millert 26: extern char *__progname;
1.1 millert 27:
28: int
1.2 millert 29: main(int argc, char **argv)
1.1 millert 30: {
31: int i;
32: char buf[256];
1.2 millert 33: des_key_schedule ks;
34: des_cblock key;
35: char _keyfile[MAXPATHLEN];
1.1 millert 36: char *keyfile = 0;
37: FILE *fp;
38: int init = 0;
39: int hex = 1;
40: int cnt = 1;
1.2 millert 41: unsigned int pin;
1.1 millert 42: struct passwd *pwd;
43:
1.2 millert 44: while ((i = getopt(argc, argv, "dk:in:")) != -1) {
1.1 millert 45: switch (i) {
46: case 'k':
47: keyfile = optarg;
48: break;
49: case 'i':
50: init = 1;
51: break;
52: case 'd':
53: hex = 0;
54: break;
55: case 'n':
56: cnt = atoi(optarg);
1.2 millert 57: if (cnt <= 0)
58: err(1, "invalid count: %s", optarg);
1.1 millert 59: break;
60: default:
1.2 millert 61: fprintf(stderr, "usage: %s [-n cnt] [-h] [-k keyfile]\n"
62: " %s -i [-k keyfile]\n", __progname,
63: __progname);
1.1 millert 64: exit(1);
65: }
1.2 millert 66: }
1.1 millert 67:
68: if (!keyfile) {
1.2 millert 69: if ((pwd = getpwuid(getuid())) == NULL) {
1.1 millert 70: fprintf(stderr, "Say, just who are you, anyhow?\n");
71: exit(1);
72: }
1.2 millert 73: snprintf(_keyfile, sizeof(_keyfile), "%s/%s", pwd->pw_dir,
74: KEYFILE);
1.1 millert 75: keyfile = _keyfile;
76: }
77:
1.2 millert 78: if (init)
79: readpassphrase("Enter Key: ", buf, sizeof(buf), 0);
80: else if ((fp = fopen(keyfile, "r")) == NULL)
81: err(1, "unable to open %s", keyfile);
82: else {
1.1 millert 83: if (fgets(buf, sizeof(buf), fp) == NULL) {
84: fprintf(stderr, "No key in %s\n", keyfile);
85: exit(1);
86: }
87: fclose(fp);
88: }
89:
90: memset(key, 0, sizeof(key));
91: if (init && buf[3] == ' ') {
92: char *b = buf;
93: /* Assume octal input */
94: for (i = 0; i < 8; ++i) {
95: if (!*b) {
96: fprintf(stderr, "%s: invalid key\n", buf);
97: }
98: while (isdigit(*b))
99: key[i] = key[i] << 3 | *b++ - '0';
100: while (*b && !isdigit(*b))
101: ++b;
102: }
1.2 millert 103: } else {
1.1 millert 104: for (i = 0; i < 16; ++i) {
105: int d;
106:
107: if (islower(buf[i]))
108: buf[i] = toupper(buf[i]);
109: if (buf[i] >= '0' && buf[i] <= '9')
110: d = buf[i] - '0';
111: else if (buf[i] >= 'A' && buf[i] <= 'F')
112: d = buf[i] - 'A' + 10;
113: else {
114: fprintf(stderr, "invalid key: %s\n", buf);
115: exit(1);
116: }
117: key[i>>1] |= d << ((i & 1) ? 0 : 4);
118: }
1.2 millert 119: }
1.1 millert 120:
1.2 millert 121: /* XXX - should warn on non-space or non-digit */
122: readpassphrase("Enter Pin: ", buf, sizeof(buf), 0);
123: for (i = 0, pin = 0; buf[i] && buf[i] != '\n'; ++i)
1.1 millert 124: if (isdigit(buf[i]))
125: pin = pin * 16 + buf[i] - '0' + 1;
126:
1.2 millert 127: if ((pin & 0xffff0000) == 0)
1.1 millert 128: pin |= pin << 16;
129:
130: for (i = 0; i < 8; ++i)
131: key[0] ^= (pin >> ((i * 7) % 26)) & 0x7f;
132:
133: if (init) {
1.2 millert 134: if ((fp = fopen(keyfile, "w")) == NULL)
135: err(1, "could not open %s for writing", keyfile);
136: fchmod(fileno(fp), 0600);
1.1 millert 137: for (i = 0; i < 8; ++i) {
138: fprintf(fp, "%c", digits[(key[i]>>4)&0xf]);
139: fprintf(fp, "%c", digits[(key[i]>>0)&0xf]);
140: }
1.2 millert 141: fputc('\n', fp);
1.1 millert 142: fclose(fp);
143: exit(0);
144: }
145:
1.2 millert 146: des_fixup_key_parity(&key);
147: des_key_sched(&key, ks);
1.1 millert 148:
1.2 millert 149: buf[0] = '\0';
1.3 ! deraadt 150: readpassphrase("Enter challenge: ", buf, sizeof(buf), RPP_ECHO_ON);
1.2 millert 151: if (buf[0] == '\0')
1.1 millert 152: exit(0);
153:
154: for (i = 0; i < 8; ++i)
155: if (buf[i] == '\n')
156: buf[i] = '\0';
157:
158: if (!hex)
159: digits = DECDIGITS;
160:
161: predict(ks, buf, cnt);
162:
1.2 millert 163: memset(&ks, 0, sizeof(ks));
164: memset(buf, 0, sizeof(buf));
165:
1.1 millert 166: exit(0);
167: }
168:
169: void
1.2 millert 170: predict(des_key_schedule ks, char *chal, int cnt)
1.1 millert 171: {
172: int i;
1.2 millert 173: des_cblock cb;
1.1 millert 174:
175: while (cnt-- > 0) {
176: printf("%.8s: ", chal);
1.2 millert 177: des_ecb_encrypt((des_cblock *)chal, &cb, ks, DES_ENCRYPT);
1.1 millert 178: for (i = 0; i < 4; ++i) {
1.2 millert 179: printf("%c", digits[(cb[i]>>4) & 0xf]);
180: printf("%c", digits[(cb[i]>>0) & 0xf]);
1.1 millert 181: }
1.2 millert 182: putchar('\n');
1.1 millert 183: for (i = 0; i < 8; ++i) {
1.2 millert 184: if ((cb[i] &= 0xf) > 9)
185: cb[i] -= 10;
186: cb[i] |= 0x30;
1.1 millert 187: }
188: }
1.2 millert 189: memset(&cb, 0, sizeof(cb));
1.1 millert 190: }