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

1.1     ! marius      1: /* $OpenBSD$ */
        !             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:
        !            23: #include <arpa/nameser.h>
        !            24: #include <openssl/ssl.h>
        !            25: #include <openssl/des.h>
        !            26: #include <openssl/md5.h>
        !            27:
        !            28: #include <errno.h>
        !            29: #include <stdio.h>
        !            30: #include <stdlib.h>
        !            31: #include <string.h>
        !            32: #include <unistd.h>
        !            33: #include <err.h>
        !            34:
        !            35: #include "key.h"
        !            36: #include "ssh2.h"
        !            37:
        !            38: #define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \
        !            39:                       ((u_long)(u_char)(cp)[1] << 16) | \
        !            40:                       ((u_long)(u_char)(cp)[2] << 8) | \
        !            41:                       ((u_long)(u_char)(cp)[3]))
        !            42:
        !            43: /* From OpenSSH */
        !            44: static int
        !            45: _uudecode(const char *src, u_char *target, size_t targsize)
        !            46: {
        !            47:        int len;
        !            48:        char *encoded, *p;
        !            49:
        !            50:        /* copy the 'readonly' source */
        !            51:        if ((encoded = strdup(src)) == NULL)
        !            52:                err(1, "");
        !            53:        /* skip whitespace and data */
        !            54:        for (p = encoded; *p == ' ' || *p == '\t'; p++)
        !            55:                ;
        !            56:        for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
        !            57:                ;
        !            58:        /* and remove trailing whitespace because __b64_pton needs this */
        !            59:        *p = '\0';
        !            60:        len = __b64_pton(encoded, target, targsize);
        !            61:
        !            62:        free(encoded);
        !            63:
        !            64:        return len;
        !            65: }
        !            66:
        !            67: /*
        !            68:  * Small compatibility layer for the OpenSSH buffers.  Only what we
        !            69:  * need here.
        !            70:  */
        !            71:
        !            72: static int
        !            73: _keyfromstr(char *str, int len)
        !            74: {
        !            75:        if (strncmp(str, "rsa", len) == 0 ||
        !            76:            strncmp(str, "ssh-rsa", len) == 0)
        !            77:                return KEY_RSA;
        !            78:        else if (strncmp(str, "dsa", len) == 0 ||
        !            79:            strncmp(str, "ssh-dss", len) == 0)
        !            80:                return KEY_DSA;
        !            81:
        !            82:        return (-1);
        !            83: }
        !            84:
        !            85: static int
        !            86: _read_int(struct iovec *iov, int *ival)
        !            87: {
        !            88:        iov->iov_len -= 4;
        !            89:        if (iov->iov_len < 0)
        !            90:                return (-1);
        !            91:        *ival = GET_32BIT((u_char *)iov->iov_base);
        !            92:        (u_char*)iov->iov_base += 4;
        !            93:
        !            94:        return (0);
        !            95: }
        !            96:
        !            97: static int
        !            98: _read_opaque(struct iovec *iov, u_char **buf, int *len)
        !            99: {
        !           100:        if (_read_int(iov, len) < 0 || *len < 0)
        !           101:                return (-1);
        !           102:
        !           103:        iov->iov_len -= *len;
        !           104:        if (iov->iov_len < 0)
        !           105:                return (-1);
        !           106:
        !           107:        *buf = iov->iov_base;
        !           108:        (u_char*)iov->iov_base += *len;
        !           109:
        !           110:        return (0);
        !           111: }
        !           112:
        !           113: static int
        !           114: _read_bignum(struct iovec *iov, BIGNUM *bn)
        !           115: {
        !           116:        u_char *bp;
        !           117:        int blen;
        !           118:
        !           119:        if (_read_opaque(iov, &bp, &blen) < 0)
        !           120:                return (-1);
        !           121:
        !           122:        if ((blen > 0 && bp[0] & 0x80) ||  /* No negative values */
        !           123:            (blen > 8*1024))               /* Too large */
        !           124:                return (-1);
        !           125:
        !           126:        BN_bin2bn(bp, blen, bn);
        !           127:
        !           128:        return (0);
        !           129: }
        !           130:
        !           131: int
        !           132: ssh2_load_public(struct key *k, struct iovec *iovp)
        !           133: {
        !           134:        int len, keytype, error = 0, blen;
        !           135:        u_char *bp;
        !           136:        struct iovec iov;
        !           137:        /* iov->iov_base is NULL terminated */
        !           138:        char *cp0, *savep = NULL, *cp = iovp->iov_base;
        !           139:
        !           140:        if ((cp0 = strchr(cp, ' ')) == NULL)
        !           141:                return (-1);
        !           142:
        !           143:        len = cp0 - cp;
        !           144:
        !           145:        if ((keytype = _keyfromstr(cp, len)) < 0)
        !           146:                return (-1);
        !           147:
        !           148:        /* cp0 is a space (' '), so we have at least one more */
        !           149:        cp = cp0 + 1;
        !           150:
        !           151:        len = 2*strlen(cp);
        !           152:        if ((savep = iov.iov_base = malloc(len)) == NULL)
        !           153:                err(1, "");
        !           154:        iov.iov_len = _uudecode(cp, iov.iov_base, len);
        !           155:
        !           156:        if (_read_opaque(&iov, &bp, &len) < 0 ||
        !           157:            keytype != _keyfromstr(bp, len)) {
        !           158:                error = -1;
        !           159:                goto out;
        !           160:        }
        !           161:
        !           162:        k->type = keytype;
        !           163:        switch (keytype) {
        !           164:        case KEY_RSA: {
        !           165:                RSA *rsa;
        !           166:
        !           167:                if ((rsa = RSA_new()) == NULL ||
        !           168:                    (rsa->e = BN_new()) == NULL ||
        !           169:                    (rsa->n = BN_new()) == NULL)
        !           170:                        errx(1, "");
        !           171:
        !           172:                if (_read_bignum(&iov, rsa->e) < 0 ||
        !           173:                    _read_bignum(&iov, rsa->n) < 0) {
        !           174:                        error = -1;
        !           175:                        RSA_free(rsa);
        !           176:                        goto out;
        !           177:                }
        !           178:
        !           179:                k->data = (void *)rsa;
        !           180:
        !           181:                break;
        !           182:        }
        !           183:        case KEY_DSA: {
        !           184:                DSA *dsa;
        !           185:
        !           186:                if ((dsa = DSA_new()) == NULL ||
        !           187:                    (dsa->p = BN_new()) == NULL ||
        !           188:                    (dsa->q = BN_new()) == NULL ||
        !           189:                    (dsa->g = BN_new()) == NULL ||
        !           190:                    (dsa->pub_key = BN_new()) == NULL)
        !           191:                        errx(1, "");
        !           192:
        !           193:                if (_read_bignum(&iov, dsa->p) < 0 ||
        !           194:                    _read_bignum(&iov, dsa->q) < 0 ||
        !           195:                    _read_bignum(&iov, dsa->g) < 0 ||
        !           196:                    _read_bignum(&iov, dsa->pub_key) < 0) {
        !           197:                        error = -1;
        !           198:                        DSA_free(dsa);
        !           199:                        goto out;
        !           200:                }
        !           201:
        !           202:                k->data = (void *)dsa;
        !           203:
        !           204:                break;
        !           205:        }
        !           206:        default:
        !           207:                error = -1;
        !           208:        }
        !           209:
        !           210: #if 0
        !           211:        if (iov->iov_len != 0)
        !           212:                /* Sanity check. */
        !           213:                return (-1);
        !           214: #endif
        !           215:
        !           216:
        !           217: out:
        !           218:        if (savep != NULL)
        !           219:                free(savep);
        !           220:        return (error);
        !           221: }