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

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: }