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