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

Annotation of src/usr.bin/gzsig/ssh2.c, Revision 1.3

1.3     ! jsg         1: /* $OpenBSD: ssh2.c,v 1.2 2005/05/29 09:10:23 djm Exp $ */
1.1       marius      2: /*
                      3:  * ssh2.c
                      4:  *
                      5:  * Copyright (c) 2005 Marius Eriksen <marius@openbsd.org>
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: #include <sys/types.h>
                     21: #include <sys/uio.h>
                     22:
1.2       djm        23: #include <netinet/in.h>
1.1       marius     24: #include <arpa/nameser.h>
                     25: #include <openssl/ssl.h>
                     26: #include <openssl/des.h>
                     27: #include <openssl/md5.h>
                     28:
                     29: #include <errno.h>
                     30: #include <stdio.h>
                     31: #include <stdlib.h>
                     32: #include <string.h>
                     33: #include <unistd.h>
1.2       djm        34: #include <resolv.h>
1.1       marius     35: #include <err.h>
                     36:
                     37: #include "key.h"
                     38: #include "ssh2.h"
                     39:
                     40: #define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \
                     41:                       ((u_long)(u_char)(cp)[1] << 16) | \
                     42:                       ((u_long)(u_char)(cp)[2] << 8) | \
                     43:                       ((u_long)(u_char)(cp)[3]))
                     44:
                     45: /* From OpenSSH */
                     46: static int
                     47: _uudecode(const char *src, u_char *target, size_t targsize)
                     48: {
                     49:        int len;
                     50:        char *encoded, *p;
                     51:
                     52:        /* copy the 'readonly' source */
                     53:        if ((encoded = strdup(src)) == NULL)
1.2       djm        54:                err(1, "strdup");
1.1       marius     55:        /* skip whitespace and data */
                     56:        for (p = encoded; *p == ' ' || *p == '\t'; p++)
                     57:                ;
                     58:        for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
                     59:                ;
                     60:        /* and remove trailing whitespace because __b64_pton needs this */
                     61:        *p = '\0';
                     62:        len = __b64_pton(encoded, target, targsize);
                     63:
                     64:        free(encoded);
                     65:
                     66:        return len;
                     67: }
                     68:
                     69: /*
                     70:  * Small compatibility layer for the OpenSSH buffers.  Only what we
                     71:  * need here.
                     72:  */
                     73:
                     74: static int
                     75: _keyfromstr(char *str, int len)
                     76: {
                     77:        if (strncmp(str, "rsa", len) == 0 ||
                     78:            strncmp(str, "ssh-rsa", len) == 0)
                     79:                return KEY_RSA;
                     80:        else if (strncmp(str, "dsa", len) == 0 ||
                     81:            strncmp(str, "ssh-dss", len) == 0)
                     82:                return KEY_DSA;
                     83:
                     84:        return (-1);
                     85: }
                     86:
                     87: static int
                     88: _read_int(struct iovec *iov, int *ival)
                     89: {
                     90:        iov->iov_len -= 4;
                     91:        if (iov->iov_len < 0)
                     92:                return (-1);
                     93:        *ival = GET_32BIT((u_char *)iov->iov_base);
1.3     ! jsg        94:        iov->iov_base = (u_char*)iov->iov_base + 4;
1.1       marius     95:
                     96:        return (0);
                     97: }
                     98:
                     99: static int
                    100: _read_opaque(struct iovec *iov, u_char **buf, int *len)
                    101: {
                    102:        if (_read_int(iov, len) < 0 || *len < 0)
                    103:                return (-1);
                    104:
                    105:        iov->iov_len -= *len;
                    106:        if (iov->iov_len < 0)
                    107:                return (-1);
                    108:
                    109:        *buf = iov->iov_base;
1.3     ! jsg       110:        iov->iov_base = (u_char*)iov->iov_base + *len;
1.1       marius    111:
                    112:        return (0);
                    113: }
                    114:
                    115: static int
                    116: _read_bignum(struct iovec *iov, BIGNUM *bn)
                    117: {
                    118:        u_char *bp;
                    119:        int blen;
                    120:
                    121:        if (_read_opaque(iov, &bp, &blen) < 0)
                    122:                return (-1);
                    123:
                    124:        if ((blen > 0 && bp[0] & 0x80) ||  /* No negative values */
                    125:            (blen > 8*1024))               /* Too large */
                    126:                return (-1);
                    127:
                    128:        BN_bin2bn(bp, blen, bn);
                    129:
                    130:        return (0);
                    131: }
                    132:
                    133: int
                    134: ssh2_load_public(struct key *k, struct iovec *iovp)
                    135: {
1.2       djm       136:        int len, keytype, error = 0;
1.1       marius    137:        u_char *bp;
                    138:        struct iovec iov;
                    139:        /* iov->iov_base is NULL terminated */
                    140:        char *cp0, *savep = NULL, *cp = iovp->iov_base;
                    141:
                    142:        if ((cp0 = strchr(cp, ' ')) == NULL)
                    143:                return (-1);
                    144:
                    145:        len = cp0 - cp;
                    146:
                    147:        if ((keytype = _keyfromstr(cp, len)) < 0)
                    148:                return (-1);
                    149:
                    150:        /* cp0 is a space (' '), so we have at least one more */
                    151:        cp = cp0 + 1;
                    152:
                    153:        len = 2*strlen(cp);
                    154:        if ((savep = iov.iov_base = malloc(len)) == NULL)
1.2       djm       155:                err(1, "malloc(%d)", len);
1.1       marius    156:        iov.iov_len = _uudecode(cp, iov.iov_base, len);
                    157:
                    158:        if (_read_opaque(&iov, &bp, &len) < 0 ||
                    159:            keytype != _keyfromstr(bp, len)) {
                    160:                error = -1;
                    161:                goto out;
                    162:        }
                    163:
                    164:        k->type = keytype;
                    165:        switch (keytype) {
                    166:        case KEY_RSA: {
                    167:                RSA *rsa;
                    168:
                    169:                if ((rsa = RSA_new()) == NULL ||
                    170:                    (rsa->e = BN_new()) == NULL ||
                    171:                    (rsa->n = BN_new()) == NULL)
1.2       djm       172:                        errx(1, "BN_new");
1.1       marius    173:
                    174:                if (_read_bignum(&iov, rsa->e) < 0 ||
                    175:                    _read_bignum(&iov, rsa->n) < 0) {
                    176:                        error = -1;
                    177:                        RSA_free(rsa);
                    178:                        goto out;
                    179:                }
                    180:
                    181:                k->data = (void *)rsa;
                    182:
                    183:                break;
                    184:        }
                    185:        case KEY_DSA: {
                    186:                DSA *dsa;
                    187:
                    188:                if ((dsa = DSA_new()) == NULL ||
                    189:                    (dsa->p = BN_new()) == NULL ||
                    190:                    (dsa->q = BN_new()) == NULL ||
                    191:                    (dsa->g = BN_new()) == NULL ||
                    192:                    (dsa->pub_key = BN_new()) == NULL)
1.2       djm       193:                        errx(1, "BN_new");
1.1       marius    194:
                    195:                if (_read_bignum(&iov, dsa->p) < 0 ||
                    196:                    _read_bignum(&iov, dsa->q) < 0 ||
                    197:                    _read_bignum(&iov, dsa->g) < 0 ||
                    198:                    _read_bignum(&iov, dsa->pub_key) < 0) {
                    199:                        error = -1;
                    200:                        DSA_free(dsa);
                    201:                        goto out;
                    202:                }
                    203:
                    204:                k->data = (void *)dsa;
                    205:
                    206:                break;
                    207:        }
                    208:        default:
                    209:                error = -1;
                    210:        }
                    211:
                    212: #if 0
                    213:        if (iov->iov_len != 0)
                    214:                /* Sanity check. */
                    215:                return (-1);
                    216: #endif
                    217:
                    218:
                    219: out:
                    220:        if (savep != NULL)
                    221:                free(savep);
                    222:        return (error);
                    223: }