[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.11

1.11    ! bluhm       1: /*     $OpenBSD: x99token.c,v 1.10 2015/01/16 06:40:14 deraadt Exp $   */
1.6       millert     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.10      deraadt    10:
1.2       millert    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.10      deraadt    21: #include <limits.h>
1.8       jsg        22: #include <openssl/des.h>
1.1       millert    23:
1.2       millert    24: #define        KEYFILE         ".keyfile.des"
1.1       millert    25: #define        HEXDIGITS       "0123456789abcdef"
                     26: #define        DECDIGITS       "0123456789012345"
                     27:
1.8       jsg        28: void predict(DES_key_schedule, const char *, int);
1.2       millert    29:
1.1       millert    30: char *digits = HEXDIGITS;
1.2       millert    31: extern char *__progname;
1.1       millert    32:
                     33: int
1.2       millert    34: main(int argc, char **argv)
1.1       millert    35: {
                     36:        int i;
                     37:        char buf[256];
1.8       jsg        38:        DES_key_schedule ks;
                     39:        DES_cblock key;
1.10      deraadt    40:        char _keyfile[PATH_MAX];
1.1       millert    41:        char *keyfile = 0;
                     42:        FILE *fp;
                     43:        int init = 0;
                     44:        int hex = 1;
                     45:        int cnt = 1;
1.2       millert    46:        unsigned int pin;
1.1       millert    47:        struct passwd *pwd;
1.11    ! bluhm      48:
        !            49:        if (pledge("stdio rpath wpath cpath fattr getpw tty", NULL) == -1)
        !            50:                err(1, "pledge");
1.1       millert    51:
1.2       millert    52:        while ((i = getopt(argc, argv, "dk:in:")) != -1) {
1.1       millert    53:                switch (i) {
                     54:                case 'k':
                     55:                        keyfile = optarg;
                     56:                        break;
                     57:                case 'i':
                     58:                        init = 1;
                     59:                        break;
                     60:                case 'd':
                     61:                        hex = 0;
                     62:                        break;
                     63:                case 'n':
                     64:                        cnt = atoi(optarg);
1.2       millert    65:                        if (cnt <= 0)
                     66:                                err(1, "invalid count: %s", optarg);
1.1       millert    67:                        break;
                     68:                default:
1.7       jmc        69:                        fprintf(stderr,
                     70:                            "usage: %s [-d] [-k keyfile] [-n count]\n"
                     71:                            "       %s -i [-k keyfile]\n",
                     72:                            __progname, __progname);
1.1       millert    73:                        exit(1);
                     74:                }
1.2       millert    75:        }
1.1       millert    76:
                     77:        if (!keyfile) {
1.2       millert    78:                if ((pwd = getpwuid(getuid())) == NULL) {
1.1       millert    79:                        fprintf(stderr, "Say, just who are you, anyhow?\n");
                     80:                        exit(1);
                     81:                }
1.2       millert    82:                snprintf(_keyfile, sizeof(_keyfile), "%s/%s", pwd->pw_dir,
                     83:                    KEYFILE);
1.1       millert    84:                keyfile = _keyfile;
                     85:        }
                     86:
1.2       millert    87:        if (init)
                     88:                readpassphrase("Enter Key: ", buf, sizeof(buf), 0);
                     89:        else if ((fp = fopen(keyfile, "r")) == NULL)
                     90:                err(1, "unable to open %s", keyfile);
                     91:        else {
1.1       millert    92:                if (fgets(buf, sizeof(buf), fp) == NULL) {
                     93:                        fprintf(stderr, "No key in %s\n", keyfile);
                     94:                        exit(1);
                     95:                }
                     96:                fclose(fp);
                     97:        }
                     98:
                     99:        memset(key, 0, sizeof(key));
                    100:        if (init && buf[3] == ' ') {
                    101:                char *b = buf;
                    102:                /* Assume octal input */
                    103:                for (i = 0; i < 8; ++i) {
1.4       millert   104:                        if (!*b)
1.1       millert   105:                                fprintf(stderr, "%s: invalid key\n", buf);
1.9       deraadt   106:                        while (isdigit((unsigned char)*b))
1.4       millert   107:                                key[i] = key[i] << 3 | (*b++ - '0');
1.9       deraadt   108:                        while (*b && !isdigit((unsigned char)*b))
1.1       millert   109:                                ++b;
                    110:                }
1.2       millert   111:        } else {
1.1       millert   112:                for (i = 0; i < 16; ++i) {
                    113:                        int d;
                    114:
1.9       deraadt   115:                        if (islower((unsigned char)buf[i]))
                    116:                                buf[i] = toupper((unsigned char)buf[i]);
1.1       millert   117:                        if (buf[i] >= '0' && buf[i] <= '9')
                    118:                                d = buf[i] - '0';
                    119:                        else if (buf[i] >= 'A' && buf[i] <= 'F')
                    120:                                d = buf[i] - 'A' + 10;
                    121:                        else {
                    122:                                fprintf(stderr, "invalid key: %s\n", buf);
                    123:                                exit(1);
                    124:                        }
                    125:                        key[i>>1] |= d << ((i & 1) ? 0 : 4);
                    126:                }
1.2       millert   127:        }
1.1       millert   128:
1.2       millert   129:        /* XXX - should warn on non-space or non-digit */
                    130:        readpassphrase("Enter Pin: ", buf, sizeof(buf), 0);
                    131:        for (i = 0, pin = 0; buf[i] && buf[i] != '\n'; ++i)
1.9       deraadt   132:                if (isdigit((unsigned char)buf[i]))
1.1       millert   133:                        pin = pin * 16 + buf[i] - '0' + 1;
                    134:
1.2       millert   135:        if ((pin & 0xffff0000) == 0)
1.1       millert   136:                pin |= pin << 16;
                    137:
                    138:        for (i = 0; i < 8; ++i)
                    139:                key[0] ^= (pin >> ((i * 7) % 26)) & 0x7f;
                    140:
                    141:        if (init) {
1.2       millert   142:                if ((fp = fopen(keyfile, "w")) == NULL)
                    143:                        err(1, "could not open %s for writing", keyfile);
                    144:                fchmod(fileno(fp), 0600);
1.1       millert   145:                for (i = 0; i < 8; ++i) {
                    146:                        fprintf(fp, "%c", digits[(key[i]>>4)&0xf]);
                    147:                        fprintf(fp, "%c", digits[(key[i]>>0)&0xf]);
                    148:                }
1.2       millert   149:                fputc('\n', fp);
1.1       millert   150:                fclose(fp);
                    151:                exit(0);
                    152:        }
                    153:
1.8       jsg       154:        DES_fixup_key_parity(&key);
                    155:        DES_key_sched(&key, &ks);
1.1       millert   156:
1.2       millert   157:        buf[0] = '\0';
1.3       deraadt   158:        readpassphrase("Enter challenge: ", buf, sizeof(buf), RPP_ECHO_ON);
1.2       millert   159:        if (buf[0] == '\0')
1.1       millert   160:                exit(0);
                    161:
                    162:        for (i = 0; i < 8; ++i)
                    163:                if (buf[i] == '\n')
                    164:                        buf[i] = '\0';
                    165:
                    166:        if (!hex)
                    167:                digits = DECDIGITS;
                    168:
                    169:        predict(ks, buf, cnt);
                    170:
1.2       millert   171:        memset(&ks, 0, sizeof(ks));
                    172:        memset(buf, 0, sizeof(buf));
                    173:
1.1       millert   174:        exit(0);
                    175: }
                    176:
                    177: void
1.8       jsg       178: predict(DES_key_schedule ks, const char *chal, int cnt)
1.1       millert   179: {
                    180:        int i;
1.8       jsg       181:        DES_cblock cb;
1.1       millert   182:
1.4       millert   183:        memcpy(&cb, chal, sizeof(cb));
1.1       millert   184:        while (cnt-- > 0) {
1.4       millert   185:                printf("%.8s: ", (char *)cb);
1.8       jsg       186:                DES_ecb_encrypt(&cb, &cb, &ks, DES_ENCRYPT);
1.1       millert   187:                for (i = 0; i < 4; ++i) {
1.2       millert   188:                        printf("%c", digits[(cb[i]>>4) & 0xf]);
                    189:                        printf("%c", digits[(cb[i]>>0) & 0xf]);
1.1       millert   190:                }
1.2       millert   191:                putchar('\n');
1.1       millert   192:                for (i = 0; i < 8; ++i) {
1.2       millert   193:                        if ((cb[i] &= 0xf) > 9)
                    194:                                cb[i] -= 10;
                    195:                        cb[i] |= 0x30;
1.1       millert   196:                }
                    197:        }
1.2       millert   198:        memset(&cb, 0, sizeof(cb));
1.1       millert   199: }