key.c revision 126277
158582Skris/* 265674Skris * read_bignum(): 365674Skris * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 465674Skris * 565674Skris * As far as I am concerned, the code I have written for this software 665674Skris * can be used freely for any purpose. Any derived versions of this 765674Skris * software must be clearly marked as such, and if the derived work is 865674Skris * incompatible with the protocol description in the RFC file, it must be 965674Skris * called by a name other than "ssh" or "Secure Shell". 1065674Skris * 1165674Skris * 1292559Sdes * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 1358582Skris * 1458582Skris * Redistribution and use in source and binary forms, with or without 1558582Skris * modification, are permitted provided that the following conditions 1658582Skris * are met: 1758582Skris * 1. Redistributions of source code must retain the above copyright 1858582Skris * notice, this list of conditions and the following disclaimer. 1958582Skris * 2. Redistributions in binary form must reproduce the above copyright 2058582Skris * notice, this list of conditions and the following disclaimer in the 2158582Skris * documentation and/or other materials provided with the distribution. 2258582Skris * 2358582Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2458582Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2558582Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2658582Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2758582Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2858582Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2958582Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3058582Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3158582Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3258582Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3358582Skris */ 3476262Sgreen#include "includes.h" 35126277SdesRCSID("$OpenBSD: key.c,v 1.55 2003/11/10 16:23:41 jakob Exp $"); 3658582Skris 3758592Skris#include <openssl/evp.h> 3876262Sgreen 3958582Skris#include "xmalloc.h" 4058582Skris#include "key.h" 4176262Sgreen#include "rsa.h" 4260576Skris#include "uuencode.h" 4376262Sgreen#include "buffer.h" 4476262Sgreen#include "bufaux.h" 4576262Sgreen#include "log.h" 4658582Skris 4758582SkrisKey * 4858582Skriskey_new(int type) 4958582Skris{ 5058582Skris Key *k; 5158582Skris RSA *rsa; 5258582Skris DSA *dsa; 5358582Skris k = xmalloc(sizeof(*k)); 5458582Skris k->type = type; 5592559Sdes k->flags = 0; 5660576Skris k->dsa = NULL; 5760576Skris k->rsa = NULL; 5858582Skris switch (k->type) { 5976262Sgreen case KEY_RSA1: 6058582Skris case KEY_RSA: 6192559Sdes if ((rsa = RSA_new()) == NULL) 6292559Sdes fatal("key_new: RSA_new failed"); 6392559Sdes if ((rsa->n = BN_new()) == NULL) 6492559Sdes fatal("key_new: BN_new failed"); 6592559Sdes if ((rsa->e = BN_new()) == NULL) 6692559Sdes fatal("key_new: BN_new failed"); 6758582Skris k->rsa = rsa; 6858582Skris break; 6958582Skris case KEY_DSA: 7092559Sdes if ((dsa = DSA_new()) == NULL) 7192559Sdes fatal("key_new: DSA_new failed"); 7292559Sdes if ((dsa->p = BN_new()) == NULL) 7392559Sdes fatal("key_new: BN_new failed"); 7492559Sdes if ((dsa->q = BN_new()) == NULL) 7592559Sdes fatal("key_new: BN_new failed"); 7692559Sdes if ((dsa->g = BN_new()) == NULL) 7792559Sdes fatal("key_new: BN_new failed"); 7892559Sdes if ((dsa->pub_key = BN_new()) == NULL) 7992559Sdes fatal("key_new: BN_new failed"); 8058582Skris k->dsa = dsa; 8158582Skris break; 8276262Sgreen case KEY_UNSPEC: 8358582Skris break; 8458582Skris default: 8558582Skris fatal("key_new: bad key type %d", k->type); 8658582Skris break; 8758582Skris } 8858582Skris return k; 8958582Skris} 9099063Sdes 9176262SgreenKey * 9276262Sgreenkey_new_private(int type) 9376262Sgreen{ 9476262Sgreen Key *k = key_new(type); 9576262Sgreen switch (k->type) { 9676262Sgreen case KEY_RSA1: 9776262Sgreen case KEY_RSA: 9892559Sdes if ((k->rsa->d = BN_new()) == NULL) 9992559Sdes fatal("key_new_private: BN_new failed"); 10092559Sdes if ((k->rsa->iqmp = BN_new()) == NULL) 10192559Sdes fatal("key_new_private: BN_new failed"); 10292559Sdes if ((k->rsa->q = BN_new()) == NULL) 10392559Sdes fatal("key_new_private: BN_new failed"); 10492559Sdes if ((k->rsa->p = BN_new()) == NULL) 10592559Sdes fatal("key_new_private: BN_new failed"); 10692559Sdes if ((k->rsa->dmq1 = BN_new()) == NULL) 10792559Sdes fatal("key_new_private: BN_new failed"); 10892559Sdes if ((k->rsa->dmp1 = BN_new()) == NULL) 10992559Sdes fatal("key_new_private: BN_new failed"); 11076262Sgreen break; 11176262Sgreen case KEY_DSA: 11292559Sdes if ((k->dsa->priv_key = BN_new()) == NULL) 11392559Sdes fatal("key_new_private: BN_new failed"); 11476262Sgreen break; 11576262Sgreen case KEY_UNSPEC: 11676262Sgreen break; 11776262Sgreen default: 11876262Sgreen break; 11976262Sgreen } 12076262Sgreen return k; 12176262Sgreen} 12299063Sdes 12358582Skrisvoid 12458582Skriskey_free(Key *k) 12558582Skris{ 12658582Skris switch (k->type) { 12776262Sgreen case KEY_RSA1: 12858582Skris case KEY_RSA: 12958582Skris if (k->rsa != NULL) 13058582Skris RSA_free(k->rsa); 13158582Skris k->rsa = NULL; 13258582Skris break; 13358582Skris case KEY_DSA: 13458582Skris if (k->dsa != NULL) 13558582Skris DSA_free(k->dsa); 13658582Skris k->dsa = NULL; 13758582Skris break; 13876262Sgreen case KEY_UNSPEC: 13976262Sgreen break; 14058582Skris default: 14158582Skris fatal("key_free: bad key type %d", k->type); 14258582Skris break; 14358582Skris } 14458582Skris xfree(k); 14558582Skris} 146126277Sdes 14758582Skrisint 148126277Sdeskey_equal(const Key *a, const Key *b) 14958582Skris{ 15058582Skris if (a == NULL || b == NULL || a->type != b->type) 15158582Skris return 0; 15258582Skris switch (a->type) { 15376262Sgreen case KEY_RSA1: 15458582Skris case KEY_RSA: 15558582Skris return a->rsa != NULL && b->rsa != NULL && 15658582Skris BN_cmp(a->rsa->e, b->rsa->e) == 0 && 15758582Skris BN_cmp(a->rsa->n, b->rsa->n) == 0; 15858582Skris break; 15958582Skris case KEY_DSA: 16058582Skris return a->dsa != NULL && b->dsa != NULL && 16158582Skris BN_cmp(a->dsa->p, b->dsa->p) == 0 && 16258582Skris BN_cmp(a->dsa->q, b->dsa->q) == 0 && 16358582Skris BN_cmp(a->dsa->g, b->dsa->g) == 0 && 16458582Skris BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 16558582Skris break; 16658582Skris default: 16760576Skris fatal("key_equal: bad key type %d", a->type); 16858582Skris break; 16958582Skris } 17058582Skris return 0; 17158582Skris} 17258582Skris 173124211Sdesu_char* 174126277Sdeskey_fingerprint_raw(const Key *k, enum fp_type dgst_type, 175126277Sdes u_int *dgst_raw_length) 17658582Skris{ 17792559Sdes const EVP_MD *md = NULL; 17876262Sgreen EVP_MD_CTX ctx; 17976262Sgreen u_char *blob = NULL; 18076262Sgreen u_char *retval = NULL; 18192559Sdes u_int len = 0; 18260576Skris int nlen, elen; 18358582Skris 18476262Sgreen *dgst_raw_length = 0; 18576262Sgreen 18676262Sgreen switch (dgst_type) { 18776262Sgreen case SSH_FP_MD5: 18876262Sgreen md = EVP_md5(); 18976262Sgreen break; 19076262Sgreen case SSH_FP_SHA1: 19176262Sgreen md = EVP_sha1(); 19276262Sgreen break; 19376262Sgreen default: 19476262Sgreen fatal("key_fingerprint_raw: bad digest type %d", 19576262Sgreen dgst_type); 19676262Sgreen } 19758582Skris switch (k->type) { 19876262Sgreen case KEY_RSA1: 19958582Skris nlen = BN_num_bytes(k->rsa->n); 20058582Skris elen = BN_num_bytes(k->rsa->e); 20158582Skris len = nlen + elen; 20260576Skris blob = xmalloc(len); 20360576Skris BN_bn2bin(k->rsa->n, blob); 20460576Skris BN_bn2bin(k->rsa->e, blob + nlen); 20558582Skris break; 20658582Skris case KEY_DSA: 20776262Sgreen case KEY_RSA: 20876262Sgreen key_to_blob(k, &blob, &len); 20958582Skris break; 21076262Sgreen case KEY_UNSPEC: 21176262Sgreen return retval; 21276262Sgreen break; 21358582Skris default: 21476262Sgreen fatal("key_fingerprint_raw: bad key type %d", k->type); 21558582Skris break; 21658582Skris } 21760576Skris if (blob != NULL) { 21876262Sgreen retval = xmalloc(EVP_MAX_MD_SIZE); 21965674Skris EVP_DigestInit(&ctx, md); 22065674Skris EVP_DigestUpdate(&ctx, blob, len); 22192559Sdes EVP_DigestFinal(&ctx, retval, dgst_raw_length); 22260576Skris memset(blob, 0, len); 22360576Skris xfree(blob); 22476262Sgreen } else { 22576262Sgreen fatal("key_fingerprint_raw: blob is null"); 22658582Skris } 22758582Skris return retval; 22858582Skris} 22958582Skris 230106130Sdesstatic char * 231106130Sdeskey_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) 23276262Sgreen{ 23376262Sgreen char *retval; 23476262Sgreen int i; 23576262Sgreen 23676262Sgreen retval = xmalloc(dgst_raw_len * 3 + 1); 23776262Sgreen retval[0] = '\0'; 23892559Sdes for (i = 0; i < dgst_raw_len; i++) { 23976262Sgreen char hex[4]; 24076262Sgreen snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); 241124211Sdes strlcat(retval, hex, dgst_raw_len * 3 + 1); 24276262Sgreen } 243124211Sdes 244124211Sdes /* Remove the trailing ':' character */ 24576262Sgreen retval[(dgst_raw_len * 3) - 1] = '\0'; 24676262Sgreen return retval; 24776262Sgreen} 24876262Sgreen 249106130Sdesstatic char * 250106130Sdeskey_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) 25176262Sgreen{ 25276262Sgreen char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; 25376262Sgreen char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 25476262Sgreen 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; 25576262Sgreen u_int i, j = 0, rounds, seed = 1; 25676262Sgreen char *retval; 25776262Sgreen 25876262Sgreen rounds = (dgst_raw_len / 2) + 1; 25976262Sgreen retval = xmalloc(sizeof(char) * (rounds*6)); 26076262Sgreen retval[j++] = 'x'; 26176262Sgreen for (i = 0; i < rounds; i++) { 26276262Sgreen u_int idx0, idx1, idx2, idx3, idx4; 26376262Sgreen if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { 26476262Sgreen idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + 26576262Sgreen seed) % 6; 26676262Sgreen idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; 26776262Sgreen idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + 26876262Sgreen (seed / 6)) % 6; 26976262Sgreen retval[j++] = vowels[idx0]; 27076262Sgreen retval[j++] = consonants[idx1]; 27176262Sgreen retval[j++] = vowels[idx2]; 27276262Sgreen if ((i + 1) < rounds) { 27376262Sgreen idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; 27476262Sgreen idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; 27576262Sgreen retval[j++] = consonants[idx3]; 27676262Sgreen retval[j++] = '-'; 27776262Sgreen retval[j++] = consonants[idx4]; 27876262Sgreen seed = ((seed * 5) + 27976262Sgreen ((((u_int)(dgst_raw[2 * i])) * 7) + 28076262Sgreen ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; 28176262Sgreen } 28276262Sgreen } else { 28376262Sgreen idx0 = seed % 6; 28476262Sgreen idx1 = 16; 28576262Sgreen idx2 = seed / 6; 28676262Sgreen retval[j++] = vowels[idx0]; 28776262Sgreen retval[j++] = consonants[idx1]; 28876262Sgreen retval[j++] = vowels[idx2]; 28976262Sgreen } 29076262Sgreen } 29176262Sgreen retval[j++] = 'x'; 29276262Sgreen retval[j++] = '\0'; 29376262Sgreen return retval; 29476262Sgreen} 29576262Sgreen 296106130Sdeschar * 297126277Sdeskey_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) 29876262Sgreen{ 29976262Sgreen char *retval = NULL; 30076262Sgreen u_char *dgst_raw; 30192559Sdes u_int dgst_raw_len; 30292559Sdes 30376262Sgreen dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); 30476262Sgreen if (!dgst_raw) 30576262Sgreen fatal("key_fingerprint: null from key_fingerprint_raw()"); 30692559Sdes switch (dgst_rep) { 30776262Sgreen case SSH_FP_HEX: 30876262Sgreen retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); 30976262Sgreen break; 31076262Sgreen case SSH_FP_BUBBLEBABBLE: 31176262Sgreen retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 31276262Sgreen break; 31376262Sgreen default: 31476262Sgreen fatal("key_fingerprint_ex: bad digest representation %d", 31576262Sgreen dgst_rep); 31676262Sgreen break; 31776262Sgreen } 31876262Sgreen memset(dgst_raw, 0, dgst_raw_len); 31976262Sgreen xfree(dgst_raw); 32076262Sgreen return retval; 32176262Sgreen} 32276262Sgreen 32358582Skris/* 32458582Skris * Reads a multiple-precision integer in decimal from the buffer, and advances 32558582Skris * the pointer. The integer must already be initialized. This function is 32658582Skris * permitted to modify the buffer. This leaves *cpp to point just beyond the 32758582Skris * last processed (and maybe modified) character. Note that this may modify 32858582Skris * the buffer containing the number. 32958582Skris */ 33092559Sdesstatic int 33158582Skrisread_bignum(char **cpp, BIGNUM * value) 33258582Skris{ 33358582Skris char *cp = *cpp; 33458582Skris int old; 33558582Skris 33658582Skris /* Skip any leading whitespace. */ 33758582Skris for (; *cp == ' ' || *cp == '\t'; cp++) 33858582Skris ; 33958582Skris 34058582Skris /* Check that it begins with a decimal digit. */ 34158582Skris if (*cp < '0' || *cp > '9') 34258582Skris return 0; 34358582Skris 34458582Skris /* Save starting position. */ 34558582Skris *cpp = cp; 34658582Skris 34758582Skris /* Move forward until all decimal digits skipped. */ 34858582Skris for (; *cp >= '0' && *cp <= '9'; cp++) 34958582Skris ; 35058582Skris 35158582Skris /* Save the old terminating character, and replace it by \0. */ 35258582Skris old = *cp; 35358582Skris *cp = 0; 35458582Skris 35558582Skris /* Parse the number. */ 35658582Skris if (BN_dec2bn(&value, *cpp) == 0) 35758582Skris return 0; 35858582Skris 35958582Skris /* Restore old terminating character. */ 36058582Skris *cp = old; 36158582Skris 36258582Skris /* Move beyond the number and return success. */ 36358582Skris *cpp = cp; 36458582Skris return 1; 36558582Skris} 36699063Sdes 36792559Sdesstatic int 36858582Skriswrite_bignum(FILE *f, BIGNUM *num) 36958582Skris{ 37058582Skris char *buf = BN_bn2dec(num); 37158582Skris if (buf == NULL) { 37258582Skris error("write_bignum: BN_bn2dec() failed"); 37358582Skris return 0; 37458582Skris } 37558582Skris fprintf(f, " %s", buf); 37692559Sdes OPENSSL_free(buf); 37758582Skris return 1; 37858582Skris} 37976262Sgreen 38092559Sdes/* returns 1 ok, -1 error */ 38176262Sgreenint 38260576Skriskey_read(Key *ret, char **cpp) 38358582Skris{ 38460576Skris Key *k; 38576262Sgreen int success = -1; 38676262Sgreen char *cp, *space; 38776262Sgreen int len, n, type; 38876262Sgreen u_int bits; 38976262Sgreen u_char *blob; 39060576Skris 39160576Skris cp = *cpp; 39260576Skris 39392559Sdes switch (ret->type) { 39476262Sgreen case KEY_RSA1: 39560576Skris /* Get number of bits. */ 39660576Skris if (*cp < '0' || *cp > '9') 39776262Sgreen return -1; /* Bad bit count... */ 39860576Skris for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 39960576Skris bits = 10 * bits + *cp - '0'; 40058582Skris if (bits == 0) 40176262Sgreen return -1; 40260576Skris *cpp = cp; 40358582Skris /* Get public exponent, public modulus. */ 40458582Skris if (!read_bignum(cpp, ret->rsa->e)) 40576262Sgreen return -1; 40658582Skris if (!read_bignum(cpp, ret->rsa->n)) 40776262Sgreen return -1; 40876262Sgreen success = 1; 40958582Skris break; 41076262Sgreen case KEY_UNSPEC: 41176262Sgreen case KEY_RSA: 41258582Skris case KEY_DSA: 41376262Sgreen space = strchr(cp, ' '); 41476262Sgreen if (space == NULL) { 415113911Sdes debug3("key_read: missing whitespace"); 41676262Sgreen return -1; 41776262Sgreen } 41876262Sgreen *space = '\0'; 41976262Sgreen type = key_type_from_name(cp); 42076262Sgreen *space = ' '; 42176262Sgreen if (type == KEY_UNSPEC) { 422113911Sdes debug3("key_read: missing keytype"); 42376262Sgreen return -1; 42476262Sgreen } 42576262Sgreen cp = space+1; 42676262Sgreen if (*cp == '\0') { 42776262Sgreen debug3("key_read: short string"); 42876262Sgreen return -1; 42976262Sgreen } 43076262Sgreen if (ret->type == KEY_UNSPEC) { 43176262Sgreen ret->type = type; 43276262Sgreen } else if (ret->type != type) { 43376262Sgreen /* is a key, but different type */ 43476262Sgreen debug3("key_read: type mismatch"); 43592559Sdes return -1; 43676262Sgreen } 43760576Skris len = 2*strlen(cp); 43860576Skris blob = xmalloc(len); 43960576Skris n = uudecode(cp, blob, len); 44060576Skris if (n < 0) { 44161203Skris error("key_read: uudecode %s failed", cp); 44292559Sdes xfree(blob); 44376262Sgreen return -1; 44460576Skris } 445124211Sdes k = key_from_blob(blob, (u_int)n); 44692559Sdes xfree(blob); 44761203Skris if (k == NULL) { 44876262Sgreen error("key_read: key_from_blob %s failed", cp); 44976262Sgreen return -1; 45061203Skris } 45176262Sgreen if (k->type != type) { 45276262Sgreen error("key_read: type mismatch: encoding error"); 45376262Sgreen key_free(k); 45476262Sgreen return -1; 45576262Sgreen } 45676262Sgreen/*XXXX*/ 45776262Sgreen if (ret->type == KEY_RSA) { 45876262Sgreen if (ret->rsa != NULL) 45976262Sgreen RSA_free(ret->rsa); 46076262Sgreen ret->rsa = k->rsa; 46176262Sgreen k->rsa = NULL; 46276262Sgreen success = 1; 46376262Sgreen#ifdef DEBUG_PK 46476262Sgreen RSA_print_fp(stderr, ret->rsa, 8); 46576262Sgreen#endif 46676262Sgreen } else { 46776262Sgreen if (ret->dsa != NULL) 46876262Sgreen DSA_free(ret->dsa); 46976262Sgreen ret->dsa = k->dsa; 47076262Sgreen k->dsa = NULL; 47176262Sgreen success = 1; 47276262Sgreen#ifdef DEBUG_PK 47376262Sgreen DSA_print_fp(stderr, ret->dsa, 8); 47476262Sgreen#endif 47576262Sgreen } 47676262Sgreen/*XXXX*/ 47792559Sdes key_free(k); 47876262Sgreen if (success != 1) 47976262Sgreen break; 48061203Skris /* advance cp: skip whitespace and data */ 48161203Skris while (*cp == ' ' || *cp == '\t') 48261203Skris cp++; 48361203Skris while (*cp != '\0' && *cp != ' ' && *cp != '\t') 48461203Skris cp++; 48561203Skris *cpp = cp; 48658582Skris break; 48758582Skris default: 48860576Skris fatal("key_read: bad key type: %d", ret->type); 48958582Skris break; 49058582Skris } 49176262Sgreen return success; 49258582Skris} 49399063Sdes 49458582Skrisint 495126277Sdeskey_write(const Key *key, FILE *f) 49658582Skris{ 49792559Sdes int n, success = 0; 49892559Sdes u_int len, bits = 0; 499106130Sdes u_char *blob; 500106130Sdes char *uu; 50158582Skris 50276262Sgreen if (key->type == KEY_RSA1 && key->rsa != NULL) { 50358582Skris /* size of modulus 'n' */ 50458582Skris bits = BN_num_bits(key->rsa->n); 50558582Skris fprintf(f, "%u", bits); 50658582Skris if (write_bignum(f, key->rsa->e) && 50758582Skris write_bignum(f, key->rsa->n)) { 50858582Skris success = 1; 50958582Skris } else { 51058582Skris error("key_write: failed for RSA key"); 51158582Skris } 51276262Sgreen } else if ((key->type == KEY_DSA && key->dsa != NULL) || 51376262Sgreen (key->type == KEY_RSA && key->rsa != NULL)) { 51476262Sgreen key_to_blob(key, &blob, &len); 51560576Skris uu = xmalloc(2*len); 51660576Skris n = uuencode(blob, len, uu, 2*len); 51760576Skris if (n > 0) { 51876262Sgreen fprintf(f, "%s %s", key_ssh_name(key), uu); 51958582Skris success = 1; 52058582Skris } 52160576Skris xfree(blob); 52260576Skris xfree(uu); 52358582Skris } 52458582Skris return success; 52558582Skris} 52699063Sdes 527126277Sdesconst char * 528126277Sdeskey_type(const Key *k) 52960576Skris{ 53060576Skris switch (k->type) { 53176262Sgreen case KEY_RSA1: 53276262Sgreen return "RSA1"; 53376262Sgreen break; 53460576Skris case KEY_RSA: 53560576Skris return "RSA"; 53660576Skris break; 53760576Skris case KEY_DSA: 53860576Skris return "DSA"; 53960576Skris break; 54060576Skris } 54160576Skris return "unknown"; 54260576Skris} 54399063Sdes 544126277Sdesconst char * 545126277Sdeskey_ssh_name(const Key *k) 54676262Sgreen{ 54776262Sgreen switch (k->type) { 54876262Sgreen case KEY_RSA: 54976262Sgreen return "ssh-rsa"; 55076262Sgreen break; 55176262Sgreen case KEY_DSA: 55276262Sgreen return "ssh-dss"; 55376262Sgreen break; 55476262Sgreen } 55576262Sgreen return "ssh-unknown"; 55676262Sgreen} 55799063Sdes 55876262Sgreenu_int 559126277Sdeskey_size(const Key *k) 56092559Sdes{ 56165674Skris switch (k->type) { 56276262Sgreen case KEY_RSA1: 56365674Skris case KEY_RSA: 56465674Skris return BN_num_bits(k->rsa->n); 56565674Skris break; 56665674Skris case KEY_DSA: 56765674Skris return BN_num_bits(k->dsa->p); 56865674Skris break; 56965674Skris } 57065674Skris return 0; 57165674Skris} 57276262Sgreen 57392559Sdesstatic RSA * 57476262Sgreenrsa_generate_private_key(u_int bits) 57576262Sgreen{ 57676262Sgreen RSA *private; 57776262Sgreen private = RSA_generate_key(bits, 35, NULL, NULL); 57876262Sgreen if (private == NULL) 57976262Sgreen fatal("rsa_generate_private_key: key generation failed."); 58076262Sgreen return private; 58176262Sgreen} 58276262Sgreen 58392559Sdesstatic DSA* 58476262Sgreendsa_generate_private_key(u_int bits) 58576262Sgreen{ 58676262Sgreen DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); 58776262Sgreen if (private == NULL) 58876262Sgreen fatal("dsa_generate_private_key: DSA_generate_parameters failed"); 58976262Sgreen if (!DSA_generate_key(private)) 59076262Sgreen fatal("dsa_generate_private_key: DSA_generate_key failed."); 59176262Sgreen if (private == NULL) 59276262Sgreen fatal("dsa_generate_private_key: NULL."); 59376262Sgreen return private; 59476262Sgreen} 59576262Sgreen 59676262SgreenKey * 59776262Sgreenkey_generate(int type, u_int bits) 59876262Sgreen{ 59976262Sgreen Key *k = key_new(KEY_UNSPEC); 60076262Sgreen switch (type) { 60176262Sgreen case KEY_DSA: 60276262Sgreen k->dsa = dsa_generate_private_key(bits); 60376262Sgreen break; 60476262Sgreen case KEY_RSA: 60576262Sgreen case KEY_RSA1: 60676262Sgreen k->rsa = rsa_generate_private_key(bits); 60776262Sgreen break; 60876262Sgreen default: 60976262Sgreen fatal("key_generate: unknown type %d", type); 61076262Sgreen } 61176262Sgreen k->type = type; 61276262Sgreen return k; 61376262Sgreen} 61476262Sgreen 61576262SgreenKey * 616126277Sdeskey_from_private(const Key *k) 61776262Sgreen{ 61876262Sgreen Key *n = NULL; 61976262Sgreen switch (k->type) { 62076262Sgreen case KEY_DSA: 62176262Sgreen n = key_new(k->type); 62276262Sgreen BN_copy(n->dsa->p, k->dsa->p); 62376262Sgreen BN_copy(n->dsa->q, k->dsa->q); 62476262Sgreen BN_copy(n->dsa->g, k->dsa->g); 62576262Sgreen BN_copy(n->dsa->pub_key, k->dsa->pub_key); 62676262Sgreen break; 62776262Sgreen case KEY_RSA: 62876262Sgreen case KEY_RSA1: 62976262Sgreen n = key_new(k->type); 63076262Sgreen BN_copy(n->rsa->n, k->rsa->n); 63176262Sgreen BN_copy(n->rsa->e, k->rsa->e); 63276262Sgreen break; 63376262Sgreen default: 63476262Sgreen fatal("key_from_private: unknown type %d", k->type); 63576262Sgreen break; 63676262Sgreen } 63776262Sgreen return n; 63876262Sgreen} 63976262Sgreen 64076262Sgreenint 64176262Sgreenkey_type_from_name(char *name) 64276262Sgreen{ 64392559Sdes if (strcmp(name, "rsa1") == 0) { 64476262Sgreen return KEY_RSA1; 64592559Sdes } else if (strcmp(name, "rsa") == 0) { 64676262Sgreen return KEY_RSA; 64792559Sdes } else if (strcmp(name, "dsa") == 0) { 64876262Sgreen return KEY_DSA; 64992559Sdes } else if (strcmp(name, "ssh-rsa") == 0) { 65076262Sgreen return KEY_RSA; 65192559Sdes } else if (strcmp(name, "ssh-dss") == 0) { 65276262Sgreen return KEY_DSA; 65376262Sgreen } 65476262Sgreen debug2("key_type_from_name: unknown key type '%s'", name); 65576262Sgreen return KEY_UNSPEC; 65676262Sgreen} 65776262Sgreen 65876262Sgreenint 65976262Sgreenkey_names_valid2(const char *names) 66076262Sgreen{ 66176262Sgreen char *s, *cp, *p; 66276262Sgreen 66376262Sgreen if (names == NULL || strcmp(names, "") == 0) 66476262Sgreen return 0; 66576262Sgreen s = cp = xstrdup(names); 66676262Sgreen for ((p = strsep(&cp, ",")); p && *p != '\0'; 66792559Sdes (p = strsep(&cp, ","))) { 66876262Sgreen switch (key_type_from_name(p)) { 66976262Sgreen case KEY_RSA1: 67076262Sgreen case KEY_UNSPEC: 67176262Sgreen xfree(s); 67276262Sgreen return 0; 67376262Sgreen } 67476262Sgreen } 67576262Sgreen debug3("key names ok: [%s]", names); 67676262Sgreen xfree(s); 67776262Sgreen return 1; 67876262Sgreen} 67976262Sgreen 68076262SgreenKey * 681126277Sdeskey_from_blob(const u_char *blob, u_int blen) 68276262Sgreen{ 68376262Sgreen Buffer b; 68476262Sgreen char *ktype; 68576262Sgreen int rlen, type; 68676262Sgreen Key *key = NULL; 68776262Sgreen 68876262Sgreen#ifdef DEBUG_PK 68976262Sgreen dump_base64(stderr, blob, blen); 69076262Sgreen#endif 69176262Sgreen buffer_init(&b); 69276262Sgreen buffer_append(&b, blob, blen); 69376262Sgreen ktype = buffer_get_string(&b, NULL); 69476262Sgreen type = key_type_from_name(ktype); 69576262Sgreen 69692559Sdes switch (type) { 69776262Sgreen case KEY_RSA: 69876262Sgreen key = key_new(type); 69976262Sgreen buffer_get_bignum2(&b, key->rsa->e); 70076262Sgreen buffer_get_bignum2(&b, key->rsa->n); 70176262Sgreen#ifdef DEBUG_PK 70276262Sgreen RSA_print_fp(stderr, key->rsa, 8); 70376262Sgreen#endif 70476262Sgreen break; 70576262Sgreen case KEY_DSA: 70676262Sgreen key = key_new(type); 70776262Sgreen buffer_get_bignum2(&b, key->dsa->p); 70876262Sgreen buffer_get_bignum2(&b, key->dsa->q); 70976262Sgreen buffer_get_bignum2(&b, key->dsa->g); 71076262Sgreen buffer_get_bignum2(&b, key->dsa->pub_key); 71176262Sgreen#ifdef DEBUG_PK 71276262Sgreen DSA_print_fp(stderr, key->dsa, 8); 71376262Sgreen#endif 71476262Sgreen break; 71576262Sgreen case KEY_UNSPEC: 71676262Sgreen key = key_new(type); 71776262Sgreen break; 71876262Sgreen default: 71976262Sgreen error("key_from_blob: cannot handle type %s", ktype); 72076262Sgreen break; 72176262Sgreen } 72276262Sgreen rlen = buffer_len(&b); 72376262Sgreen if (key != NULL && rlen != 0) 72476262Sgreen error("key_from_blob: remaining bytes in key blob %d", rlen); 72576262Sgreen xfree(ktype); 72676262Sgreen buffer_free(&b); 72776262Sgreen return key; 72876262Sgreen} 72976262Sgreen 73076262Sgreenint 731126277Sdeskey_to_blob(const Key *key, u_char **blobp, u_int *lenp) 73276262Sgreen{ 73376262Sgreen Buffer b; 73476262Sgreen int len; 73576262Sgreen 73676262Sgreen if (key == NULL) { 73776262Sgreen error("key_to_blob: key == NULL"); 73876262Sgreen return 0; 73976262Sgreen } 74076262Sgreen buffer_init(&b); 74192559Sdes switch (key->type) { 74276262Sgreen case KEY_DSA: 74376262Sgreen buffer_put_cstring(&b, key_ssh_name(key)); 74476262Sgreen buffer_put_bignum2(&b, key->dsa->p); 74576262Sgreen buffer_put_bignum2(&b, key->dsa->q); 74676262Sgreen buffer_put_bignum2(&b, key->dsa->g); 74776262Sgreen buffer_put_bignum2(&b, key->dsa->pub_key); 74876262Sgreen break; 74976262Sgreen case KEY_RSA: 75076262Sgreen buffer_put_cstring(&b, key_ssh_name(key)); 75176262Sgreen buffer_put_bignum2(&b, key->rsa->e); 75276262Sgreen buffer_put_bignum2(&b, key->rsa->n); 75376262Sgreen break; 75476262Sgreen default: 75592559Sdes error("key_to_blob: unsupported key type %d", key->type); 75692559Sdes buffer_free(&b); 75792559Sdes return 0; 75876262Sgreen } 75976262Sgreen len = buffer_len(&b); 760106130Sdes if (lenp != NULL) 761106130Sdes *lenp = len; 762106130Sdes if (blobp != NULL) { 763106130Sdes *blobp = xmalloc(len); 764106130Sdes memcpy(*blobp, buffer_ptr(&b), len); 765106130Sdes } 76676262Sgreen memset(buffer_ptr(&b), 0, len); 76776262Sgreen buffer_free(&b); 76876262Sgreen return len; 76976262Sgreen} 77076262Sgreen 77176262Sgreenint 77276262Sgreenkey_sign( 773126277Sdes const Key *key, 77492559Sdes u_char **sigp, u_int *lenp, 775126277Sdes const u_char *data, u_int datalen) 77676262Sgreen{ 77792559Sdes switch (key->type) { 77876262Sgreen case KEY_DSA: 77976262Sgreen return ssh_dss_sign(key, sigp, lenp, data, datalen); 78076262Sgreen break; 78176262Sgreen case KEY_RSA: 78276262Sgreen return ssh_rsa_sign(key, sigp, lenp, data, datalen); 78376262Sgreen break; 78476262Sgreen default: 78576262Sgreen error("key_sign: illegal key type %d", key->type); 78676262Sgreen return -1; 78776262Sgreen break; 78876262Sgreen } 78976262Sgreen} 79076262Sgreen 79198684Sdes/* 79298684Sdes * key_verify returns 1 for a correct signature, 0 for an incorrect signature 79398684Sdes * and -1 on error. 79498684Sdes */ 79576262Sgreenint 79676262Sgreenkey_verify( 797126277Sdes const Key *key, 798126277Sdes const u_char *signature, u_int signaturelen, 799126277Sdes const u_char *data, u_int datalen) 80076262Sgreen{ 80192559Sdes if (signaturelen == 0) 80292559Sdes return -1; 80392559Sdes 80492559Sdes switch (key->type) { 80576262Sgreen case KEY_DSA: 80676262Sgreen return ssh_dss_verify(key, signature, signaturelen, data, datalen); 80776262Sgreen break; 80876262Sgreen case KEY_RSA: 80976262Sgreen return ssh_rsa_verify(key, signature, signaturelen, data, datalen); 81076262Sgreen break; 81176262Sgreen default: 81276262Sgreen error("key_verify: illegal key type %d", key->type); 81376262Sgreen return -1; 81476262Sgreen break; 81576262Sgreen } 81676262Sgreen} 81798684Sdes 81898684Sdes/* Converts a private to a public key */ 81998684SdesKey * 820126277Sdeskey_demote(const Key *k) 82198684Sdes{ 82298684Sdes Key *pk; 82398684Sdes 82498684Sdes pk = xmalloc(sizeof(*pk)); 82598684Sdes pk->type = k->type; 82698684Sdes pk->flags = k->flags; 82798684Sdes pk->dsa = NULL; 82898684Sdes pk->rsa = NULL; 82998684Sdes 83098684Sdes switch (k->type) { 83198684Sdes case KEY_RSA1: 83298684Sdes case KEY_RSA: 83398684Sdes if ((pk->rsa = RSA_new()) == NULL) 83498684Sdes fatal("key_demote: RSA_new failed"); 83598684Sdes if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL) 83698684Sdes fatal("key_demote: BN_dup failed"); 83798684Sdes if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) 83898684Sdes fatal("key_demote: BN_dup failed"); 83998684Sdes break; 84098684Sdes case KEY_DSA: 84198684Sdes if ((pk->dsa = DSA_new()) == NULL) 84298684Sdes fatal("key_demote: DSA_new failed"); 84398684Sdes if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL) 84498684Sdes fatal("key_demote: BN_dup failed"); 84598684Sdes if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL) 84698684Sdes fatal("key_demote: BN_dup failed"); 84798684Sdes if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL) 84898684Sdes fatal("key_demote: BN_dup failed"); 84998684Sdes if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) 85098684Sdes fatal("key_demote: BN_dup failed"); 85198684Sdes break; 85298684Sdes default: 85398684Sdes fatal("key_free: bad key type %d", k->type); 85498684Sdes break; 85598684Sdes } 85698684Sdes 85798684Sdes return (pk); 85898684Sdes} 859