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

Annotation of src/usr.bin/ssh/key.c, Revision 1.11

1.1       markus      1: /*
1.11    ! deraadt     2:  * read_bignum():
        !             3:  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
        !             4:  *
        !             5:  * As far as I am concerned, the code I have written for this software
        !             6:  * can be used freely for any purpose.  Any derived versions of this
        !             7:  * software must be clearly marked as such, and if the derived work is
        !             8:  * incompatible with the protocol description in the RFC file, it must be
        !             9:  * called by a name other than "ssh" or "Secure Shell".
        !            10:  *
        !            11:  *
1.1       markus     12:  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
                     13:  *
                     14:  * Redistribution and use in source and binary forms, with or without
                     15:  * modification, are permitted provided that the following conditions
                     16:  * are met:
                     17:  * 1. Redistributions of source code must retain the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer.
                     19:  * 2. Redistributions in binary form must reproduce the above copyright
                     20:  *    notice, this list of conditions and the following disclaimer in the
                     21:  *    documentation and/or other materials provided with the distribution.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include "includes.h"
                     36: #include "ssh.h"
1.2       markus     37: #include <openssl/rsa.h>
                     38: #include <openssl/dsa.h>
                     39: #include <openssl/evp.h>
1.1       markus     40: #include "xmalloc.h"
                     41: #include "key.h"
1.3       markus     42: #include "dsa.h"
                     43: #include "uuencode.h"
                     44:
1.11    ! deraadt    45: RCSID("$OpenBSD: key.c,v 1.10 2000/08/19 21:34:43 markus Exp $");
1.9       djm        46:
1.3       markus     47: #define SSH_DSS "ssh-dss"
1.1       markus     48:
                     49: Key *
                     50: key_new(int type)
                     51: {
                     52:        Key *k;
                     53:        RSA *rsa;
                     54:        DSA *dsa;
                     55:        k = xmalloc(sizeof(*k));
                     56:        k->type = type;
1.3       markus     57:        k->dsa = NULL;
                     58:        k->rsa = NULL;
1.1       markus     59:        switch (k->type) {
                     60:        case KEY_RSA:
                     61:                rsa = RSA_new();
                     62:                rsa->n = BN_new();
                     63:                rsa->e = BN_new();
                     64:                k->rsa = rsa;
                     65:                break;
                     66:        case KEY_DSA:
                     67:                dsa = DSA_new();
                     68:                dsa->p = BN_new();
                     69:                dsa->q = BN_new();
                     70:                dsa->g = BN_new();
                     71:                dsa->pub_key = BN_new();
                     72:                k->dsa = dsa;
                     73:                break;
                     74:        case KEY_EMPTY:
                     75:                break;
                     76:        default:
                     77:                fatal("key_new: bad key type %d", k->type);
                     78:                break;
                     79:        }
                     80:        return k;
                     81: }
                     82: void
                     83: key_free(Key *k)
                     84: {
                     85:        switch (k->type) {
                     86:        case KEY_RSA:
                     87:                if (k->rsa != NULL)
                     88:                        RSA_free(k->rsa);
                     89:                k->rsa = NULL;
                     90:                break;
                     91:        case KEY_DSA:
                     92:                if (k->dsa != NULL)
                     93:                        DSA_free(k->dsa);
                     94:                k->dsa = NULL;
                     95:                break;
                     96:        default:
                     97:                fatal("key_free: bad key type %d", k->type);
                     98:                break;
                     99:        }
                    100:        xfree(k);
                    101: }
                    102: int
                    103: key_equal(Key *a, Key *b)
                    104: {
                    105:        if (a == NULL || b == NULL || a->type != b->type)
                    106:                return 0;
                    107:        switch (a->type) {
                    108:        case KEY_RSA:
                    109:                return a->rsa != NULL && b->rsa != NULL &&
                    110:                    BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
                    111:                    BN_cmp(a->rsa->n, b->rsa->n) == 0;
                    112:                break;
                    113:        case KEY_DSA:
                    114:                return a->dsa != NULL && b->dsa != NULL &&
                    115:                    BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
                    116:                    BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
                    117:                    BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
                    118:                    BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
                    119:                break;
                    120:        default:
1.3       markus    121:                fatal("key_equal: bad key type %d", a->type);
1.1       markus    122:                break;
                    123:        }
                    124:        return 0;
                    125: }
                    126:
                    127: /*
                    128:  * Generate key fingerprint in ascii format.
                    129:  * Based on ideas and code from Bjoern Groenvall <bg@sics.se>
                    130:  */
                    131: char *
                    132: key_fingerprint(Key *k)
                    133: {
1.8       markus    134:        static char retval[(EVP_MAX_MD_SIZE+1)*3];
1.3       markus    135:        unsigned char *blob = NULL;
1.1       markus    136:        int len = 0;
1.3       markus    137:        int nlen, elen;
1.1       markus    138:
                    139:        switch (k->type) {
                    140:        case KEY_RSA:
                    141:                nlen = BN_num_bytes(k->rsa->n);
                    142:                elen = BN_num_bytes(k->rsa->e);
                    143:                len = nlen + elen;
1.3       markus    144:                blob = xmalloc(len);
                    145:                BN_bn2bin(k->rsa->n, blob);
                    146:                BN_bn2bin(k->rsa->e, blob + nlen);
1.1       markus    147:                break;
                    148:        case KEY_DSA:
1.3       markus    149:                dsa_make_key_blob(k, &blob, &len);
1.1       markus    150:                break;
                    151:        default:
                    152:                fatal("key_fingerprint: bad key type %d", k->type);
                    153:                break;
                    154:        }
1.8       markus    155:        retval[0] = '\0';
                    156:
1.3       markus    157:        if (blob != NULL) {
1.8       markus    158:                int i;
                    159:                unsigned char digest[EVP_MAX_MD_SIZE];
                    160:                EVP_MD *md = EVP_md5();
                    161:                EVP_MD_CTX ctx;
                    162:                EVP_DigestInit(&ctx, md);
                    163:                EVP_DigestUpdate(&ctx, blob, len);
                    164:                EVP_DigestFinal(&ctx, digest, NULL);
                    165:                for(i = 0; i < md->md_size; i++) {
                    166:                        char hex[4];
                    167:                        snprintf(hex, sizeof(hex), "%02x:", digest[i]);
                    168:                        strlcat(retval, hex, sizeof(retval));
                    169:                }
                    170:                retval[strlen(retval) - 1] = '\0';
1.3       markus    171:                memset(blob, 0, len);
                    172:                xfree(blob);
1.1       markus    173:        }
                    174:        return retval;
                    175: }
                    176:
                    177: /*
                    178:  * Reads a multiple-precision integer in decimal from the buffer, and advances
                    179:  * the pointer.  The integer must already be initialized.  This function is
                    180:  * permitted to modify the buffer.  This leaves *cpp to point just beyond the
                    181:  * last processed (and maybe modified) character.  Note that this may modify
                    182:  * the buffer containing the number.
                    183:  */
                    184: int
                    185: read_bignum(char **cpp, BIGNUM * value)
                    186: {
                    187:        char *cp = *cpp;
                    188:        int old;
                    189:
                    190:        /* Skip any leading whitespace. */
                    191:        for (; *cp == ' ' || *cp == '\t'; cp++)
                    192:                ;
                    193:
                    194:        /* Check that it begins with a decimal digit. */
                    195:        if (*cp < '0' || *cp > '9')
                    196:                return 0;
                    197:
                    198:        /* Save starting position. */
                    199:        *cpp = cp;
                    200:
                    201:        /* Move forward until all decimal digits skipped. */
                    202:        for (; *cp >= '0' && *cp <= '9'; cp++)
                    203:                ;
                    204:
                    205:        /* Save the old terminating character, and replace it by \0. */
                    206:        old = *cp;
                    207:        *cp = 0;
                    208:
                    209:        /* Parse the number. */
                    210:        if (BN_dec2bn(&value, *cpp) == 0)
                    211:                return 0;
                    212:
                    213:        /* Restore old terminating character. */
                    214:        *cp = old;
                    215:
                    216:        /* Move beyond the number and return success. */
                    217:        *cpp = cp;
                    218:        return 1;
                    219: }
                    220: int
                    221: write_bignum(FILE *f, BIGNUM *num)
                    222: {
                    223:        char *buf = BN_bn2dec(num);
                    224:        if (buf == NULL) {
                    225:                error("write_bignum: BN_bn2dec() failed");
                    226:                return 0;
                    227:        }
                    228:        fprintf(f, " %s", buf);
                    229:        free(buf);
                    230:        return 1;
                    231: }
1.3       markus    232: unsigned int
                    233: key_read(Key *ret, char **cpp)
1.1       markus    234: {
1.3       markus    235:        Key *k;
                    236:        unsigned int bits = 0;
                    237:        char *cp;
                    238:        int len, n;
                    239:        unsigned char *blob;
                    240:
                    241:        cp = *cpp;
                    242:
1.1       markus    243:        switch(ret->type) {
                    244:        case KEY_RSA:
1.3       markus    245:                /* Get number of bits. */
                    246:                if (*cp < '0' || *cp > '9')
                    247:                        return 0;       /* Bad bit count... */
                    248:                for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
                    249:                        bits = 10 * bits + *cp - '0';
1.1       markus    250:                if (bits == 0)
                    251:                        return 0;
1.3       markus    252:                *cpp = cp;
1.1       markus    253:                /* Get public exponent, public modulus. */
                    254:                if (!read_bignum(cpp, ret->rsa->e))
                    255:                        return 0;
                    256:                if (!read_bignum(cpp, ret->rsa->n))
                    257:                        return 0;
                    258:                break;
                    259:        case KEY_DSA:
1.3       markus    260:                if (strncmp(cp, SSH_DSS " ", 7) != 0)
1.1       markus    261:                        return 0;
1.3       markus    262:                cp += 7;
                    263:                len = 2*strlen(cp);
                    264:                blob = xmalloc(len);
                    265:                n = uudecode(cp, blob, len);
1.6       markus    266:                if (n < 0) {
1.7       markus    267:                        error("key_read: uudecode %s failed", cp);
1.6       markus    268:                        return 0;
                    269:                }
1.3       markus    270:                k = dsa_key_from_blob(blob, n);
1.7       markus    271:                if (k == NULL) {
                    272:                        error("key_read: dsa_key_from_blob %s failed", cp);
                    273:                        return 0;
                    274:                }
1.3       markus    275:                xfree(blob);
                    276:                if (ret->dsa != NULL)
                    277:                        DSA_free(ret->dsa);
                    278:                ret->dsa = k->dsa;
                    279:                k->dsa = NULL;
                    280:                key_free(k);
                    281:                bits = BN_num_bits(ret->dsa->p);
1.7       markus    282:                /* advance cp: skip whitespace and data */
                    283:                while (*cp == ' ' || *cp == '\t')
                    284:                        cp++;
                    285:                while (*cp != '\0' && *cp != ' ' && *cp != '\t')
                    286:                        cp++;
                    287:                *cpp = cp;
1.1       markus    288:                break;
                    289:        default:
1.3       markus    290:                fatal("key_read: bad key type: %d", ret->type);
1.1       markus    291:                break;
                    292:        }
1.3       markus    293:        return bits;
1.1       markus    294: }
                    295: int
                    296: key_write(Key *key, FILE *f)
                    297: {
                    298:        int success = 0;
                    299:        unsigned int bits = 0;
                    300:
                    301:        if (key->type == KEY_RSA && key->rsa != NULL) {
                    302:                /* size of modulus 'n' */
                    303:                bits = BN_num_bits(key->rsa->n);
                    304:                fprintf(f, "%u", bits);
                    305:                if (write_bignum(f, key->rsa->e) &&
                    306:                    write_bignum(f, key->rsa->n)) {
                    307:                        success = 1;
                    308:                } else {
                    309:                        error("key_write: failed for RSA key");
                    310:                }
                    311:        } else if (key->type == KEY_DSA && key->dsa != NULL) {
1.3       markus    312:                int len, n;
                    313:                unsigned char *blob, *uu;
                    314:                dsa_make_key_blob(key, &blob, &len);
                    315:                uu = xmalloc(2*len);
1.5       markus    316:                n = uuencode(blob, len, uu, 2*len);
                    317:                if (n > 0) {
                    318:                        fprintf(f, "%s %s", SSH_DSS, uu);
                    319:                        success = 1;
                    320:                }
1.3       markus    321:                xfree(blob);
                    322:                xfree(uu);
1.1       markus    323:        }
                    324:        return success;
                    325: }
1.4       markus    326: char *
                    327: key_type(Key *k)
                    328: {
                    329:        switch (k->type) {
                    330:        case KEY_RSA:
                    331:                return "RSA";
                    332:                break;
                    333:        case KEY_DSA:
                    334:                return "DSA";
                    335:                break;
                    336:        }
                    337:        return "unknown";
1.10      markus    338: }
                    339: unsigned int
                    340: key_size(Key *k){
                    341:        switch (k->type) {
                    342:        case KEY_RSA:
                    343:                return BN_num_bits(k->rsa->n);
                    344:                break;
                    345:        case KEY_DSA:
                    346:                return BN_num_bits(k->dsa->p);
                    347:                break;
                    348:        }
                    349:        return 0;
1.4       markus    350: }