key.c revision 124211
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" 35124211SdesRCSID("$OpenBSD: key.c,v 1.54 2003/07/09 13:58:19 avsm 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} 14658582Skrisint 14758582Skriskey_equal(Key *a, Key *b) 14858582Skris{ 14958582Skris if (a == NULL || b == NULL || a->type != b->type) 15058582Skris return 0; 15158582Skris switch (a->type) { 15276262Sgreen case KEY_RSA1: 15358582Skris case KEY_RSA: 15458582Skris return a->rsa != NULL && b->rsa != NULL && 15558582Skris BN_cmp(a->rsa->e, b->rsa->e) == 0 && 15658582Skris BN_cmp(a->rsa->n, b->rsa->n) == 0; 15758582Skris break; 15858582Skris case KEY_DSA: 15958582Skris return a->dsa != NULL && b->dsa != NULL && 16058582Skris BN_cmp(a->dsa->p, b->dsa->p) == 0 && 16158582Skris BN_cmp(a->dsa->q, b->dsa->q) == 0 && 16258582Skris BN_cmp(a->dsa->g, b->dsa->g) == 0 && 16358582Skris BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 16458582Skris break; 16558582Skris default: 16660576Skris fatal("key_equal: bad key type %d", a->type); 16758582Skris break; 16858582Skris } 16958582Skris return 0; 17058582Skris} 17158582Skris 172124211Sdesu_char* 17392559Sdeskey_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) 17458582Skris{ 17592559Sdes const EVP_MD *md = NULL; 17676262Sgreen EVP_MD_CTX ctx; 17776262Sgreen u_char *blob = NULL; 17876262Sgreen u_char *retval = NULL; 17992559Sdes u_int len = 0; 18060576Skris int nlen, elen; 18158582Skris 18276262Sgreen *dgst_raw_length = 0; 18376262Sgreen 18476262Sgreen switch (dgst_type) { 18576262Sgreen case SSH_FP_MD5: 18676262Sgreen md = EVP_md5(); 18776262Sgreen break; 18876262Sgreen case SSH_FP_SHA1: 18976262Sgreen md = EVP_sha1(); 19076262Sgreen break; 19176262Sgreen default: 19276262Sgreen fatal("key_fingerprint_raw: bad digest type %d", 19376262Sgreen dgst_type); 19476262Sgreen } 19558582Skris switch (k->type) { 19676262Sgreen case KEY_RSA1: 19758582Skris nlen = BN_num_bytes(k->rsa->n); 19858582Skris elen = BN_num_bytes(k->rsa->e); 19958582Skris len = nlen + elen; 20060576Skris blob = xmalloc(len); 20160576Skris BN_bn2bin(k->rsa->n, blob); 20260576Skris BN_bn2bin(k->rsa->e, blob + nlen); 20358582Skris break; 20458582Skris case KEY_DSA: 20576262Sgreen case KEY_RSA: 20676262Sgreen key_to_blob(k, &blob, &len); 20758582Skris break; 20876262Sgreen case KEY_UNSPEC: 20976262Sgreen return retval; 21076262Sgreen break; 21158582Skris default: 21276262Sgreen fatal("key_fingerprint_raw: bad key type %d", k->type); 21358582Skris break; 21458582Skris } 21560576Skris if (blob != NULL) { 21676262Sgreen retval = xmalloc(EVP_MAX_MD_SIZE); 21765674Skris EVP_DigestInit(&ctx, md); 21865674Skris EVP_DigestUpdate(&ctx, blob, len); 21992559Sdes EVP_DigestFinal(&ctx, retval, dgst_raw_length); 22060576Skris memset(blob, 0, len); 22160576Skris xfree(blob); 22276262Sgreen } else { 22376262Sgreen fatal("key_fingerprint_raw: blob is null"); 22458582Skris } 22558582Skris return retval; 22658582Skris} 22758582Skris 228106130Sdesstatic char * 229106130Sdeskey_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) 23076262Sgreen{ 23176262Sgreen char *retval; 23276262Sgreen int i; 23376262Sgreen 23476262Sgreen retval = xmalloc(dgst_raw_len * 3 + 1); 23576262Sgreen retval[0] = '\0'; 23692559Sdes for (i = 0; i < dgst_raw_len; i++) { 23776262Sgreen char hex[4]; 23876262Sgreen snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); 239124211Sdes strlcat(retval, hex, dgst_raw_len * 3 + 1); 24076262Sgreen } 241124211Sdes 242124211Sdes /* Remove the trailing ':' character */ 24376262Sgreen retval[(dgst_raw_len * 3) - 1] = '\0'; 24476262Sgreen return retval; 24576262Sgreen} 24676262Sgreen 247106130Sdesstatic char * 248106130Sdeskey_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) 24976262Sgreen{ 25076262Sgreen char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; 25176262Sgreen char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 25276262Sgreen 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; 25376262Sgreen u_int i, j = 0, rounds, seed = 1; 25476262Sgreen char *retval; 25576262Sgreen 25676262Sgreen rounds = (dgst_raw_len / 2) + 1; 25776262Sgreen retval = xmalloc(sizeof(char) * (rounds*6)); 25876262Sgreen retval[j++] = 'x'; 25976262Sgreen for (i = 0; i < rounds; i++) { 26076262Sgreen u_int idx0, idx1, idx2, idx3, idx4; 26176262Sgreen if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { 26276262Sgreen idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + 26376262Sgreen seed) % 6; 26476262Sgreen idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; 26576262Sgreen idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + 26676262Sgreen (seed / 6)) % 6; 26776262Sgreen retval[j++] = vowels[idx0]; 26876262Sgreen retval[j++] = consonants[idx1]; 26976262Sgreen retval[j++] = vowels[idx2]; 27076262Sgreen if ((i + 1) < rounds) { 27176262Sgreen idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; 27276262Sgreen idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; 27376262Sgreen retval[j++] = consonants[idx3]; 27476262Sgreen retval[j++] = '-'; 27576262Sgreen retval[j++] = consonants[idx4]; 27676262Sgreen seed = ((seed * 5) + 27776262Sgreen ((((u_int)(dgst_raw[2 * i])) * 7) + 27876262Sgreen ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; 27976262Sgreen } 28076262Sgreen } else { 28176262Sgreen idx0 = seed % 6; 28276262Sgreen idx1 = 16; 28376262Sgreen idx2 = seed / 6; 28476262Sgreen retval[j++] = vowels[idx0]; 28576262Sgreen retval[j++] = consonants[idx1]; 28676262Sgreen retval[j++] = vowels[idx2]; 28776262Sgreen } 28876262Sgreen } 28976262Sgreen retval[j++] = 'x'; 29076262Sgreen retval[j++] = '\0'; 29176262Sgreen return retval; 29276262Sgreen} 29376262Sgreen 294106130Sdeschar * 29576262Sgreenkey_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) 29676262Sgreen{ 29776262Sgreen char *retval = NULL; 29876262Sgreen u_char *dgst_raw; 29992559Sdes u_int dgst_raw_len; 30092559Sdes 30176262Sgreen dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); 30276262Sgreen if (!dgst_raw) 30376262Sgreen fatal("key_fingerprint: null from key_fingerprint_raw()"); 30492559Sdes switch (dgst_rep) { 30576262Sgreen case SSH_FP_HEX: 30676262Sgreen retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); 30776262Sgreen break; 30876262Sgreen case SSH_FP_BUBBLEBABBLE: 30976262Sgreen retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 31076262Sgreen break; 31176262Sgreen default: 31276262Sgreen fatal("key_fingerprint_ex: bad digest representation %d", 31376262Sgreen dgst_rep); 31476262Sgreen break; 31576262Sgreen } 31676262Sgreen memset(dgst_raw, 0, dgst_raw_len); 31776262Sgreen xfree(dgst_raw); 31876262Sgreen return retval; 31976262Sgreen} 32076262Sgreen 32158582Skris/* 32258582Skris * Reads a multiple-precision integer in decimal from the buffer, and advances 32358582Skris * the pointer. The integer must already be initialized. This function is 32458582Skris * permitted to modify the buffer. This leaves *cpp to point just beyond the 32558582Skris * last processed (and maybe modified) character. Note that this may modify 32658582Skris * the buffer containing the number. 32758582Skris */ 32892559Sdesstatic int 32958582Skrisread_bignum(char **cpp, BIGNUM * value) 33058582Skris{ 33158582Skris char *cp = *cpp; 33258582Skris int old; 33358582Skris 33458582Skris /* Skip any leading whitespace. */ 33558582Skris for (; *cp == ' ' || *cp == '\t'; cp++) 33658582Skris ; 33758582Skris 33858582Skris /* Check that it begins with a decimal digit. */ 33958582Skris if (*cp < '0' || *cp > '9') 34058582Skris return 0; 34158582Skris 34258582Skris /* Save starting position. */ 34358582Skris *cpp = cp; 34458582Skris 34558582Skris /* Move forward until all decimal digits skipped. */ 34658582Skris for (; *cp >= '0' && *cp <= '9'; cp++) 34758582Skris ; 34858582Skris 34958582Skris /* Save the old terminating character, and replace it by \0. */ 35058582Skris old = *cp; 35158582Skris *cp = 0; 35258582Skris 35358582Skris /* Parse the number. */ 35458582Skris if (BN_dec2bn(&value, *cpp) == 0) 35558582Skris return 0; 35658582Skris 35758582Skris /* Restore old terminating character. */ 35858582Skris *cp = old; 35958582Skris 36058582Skris /* Move beyond the number and return success. */ 36158582Skris *cpp = cp; 36258582Skris return 1; 36358582Skris} 36499063Sdes 36592559Sdesstatic int 36658582Skriswrite_bignum(FILE *f, BIGNUM *num) 36758582Skris{ 36858582Skris char *buf = BN_bn2dec(num); 36958582Skris if (buf == NULL) { 37058582Skris error("write_bignum: BN_bn2dec() failed"); 37158582Skris return 0; 37258582Skris } 37358582Skris fprintf(f, " %s", buf); 37492559Sdes OPENSSL_free(buf); 37558582Skris return 1; 37658582Skris} 37776262Sgreen 37892559Sdes/* returns 1 ok, -1 error */ 37976262Sgreenint 38060576Skriskey_read(Key *ret, char **cpp) 38158582Skris{ 38260576Skris Key *k; 38376262Sgreen int success = -1; 38476262Sgreen char *cp, *space; 38576262Sgreen int len, n, type; 38676262Sgreen u_int bits; 38776262Sgreen u_char *blob; 38860576Skris 38960576Skris cp = *cpp; 39060576Skris 39192559Sdes switch (ret->type) { 39276262Sgreen case KEY_RSA1: 39360576Skris /* Get number of bits. */ 39460576Skris if (*cp < '0' || *cp > '9') 39576262Sgreen return -1; /* Bad bit count... */ 39660576Skris for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 39760576Skris bits = 10 * bits + *cp - '0'; 39858582Skris if (bits == 0) 39976262Sgreen return -1; 40060576Skris *cpp = cp; 40158582Skris /* Get public exponent, public modulus. */ 40258582Skris if (!read_bignum(cpp, ret->rsa->e)) 40376262Sgreen return -1; 40458582Skris if (!read_bignum(cpp, ret->rsa->n)) 40576262Sgreen return -1; 40676262Sgreen success = 1; 40758582Skris break; 40876262Sgreen case KEY_UNSPEC: 40976262Sgreen case KEY_RSA: 41058582Skris case KEY_DSA: 41176262Sgreen space = strchr(cp, ' '); 41276262Sgreen if (space == NULL) { 413113911Sdes debug3("key_read: missing whitespace"); 41476262Sgreen return -1; 41576262Sgreen } 41676262Sgreen *space = '\0'; 41776262Sgreen type = key_type_from_name(cp); 41876262Sgreen *space = ' '; 41976262Sgreen if (type == KEY_UNSPEC) { 420113911Sdes debug3("key_read: missing keytype"); 42176262Sgreen return -1; 42276262Sgreen } 42376262Sgreen cp = space+1; 42476262Sgreen if (*cp == '\0') { 42576262Sgreen debug3("key_read: short string"); 42676262Sgreen return -1; 42776262Sgreen } 42876262Sgreen if (ret->type == KEY_UNSPEC) { 42976262Sgreen ret->type = type; 43076262Sgreen } else if (ret->type != type) { 43176262Sgreen /* is a key, but different type */ 43276262Sgreen debug3("key_read: type mismatch"); 43392559Sdes return -1; 43476262Sgreen } 43560576Skris len = 2*strlen(cp); 43660576Skris blob = xmalloc(len); 43760576Skris n = uudecode(cp, blob, len); 43860576Skris if (n < 0) { 43961203Skris error("key_read: uudecode %s failed", cp); 44092559Sdes xfree(blob); 44176262Sgreen return -1; 44260576Skris } 443124211Sdes k = key_from_blob(blob, (u_int)n); 44492559Sdes xfree(blob); 44561203Skris if (k == NULL) { 44676262Sgreen error("key_read: key_from_blob %s failed", cp); 44776262Sgreen return -1; 44861203Skris } 44976262Sgreen if (k->type != type) { 45076262Sgreen error("key_read: type mismatch: encoding error"); 45176262Sgreen key_free(k); 45276262Sgreen return -1; 45376262Sgreen } 45476262Sgreen/*XXXX*/ 45576262Sgreen if (ret->type == KEY_RSA) { 45676262Sgreen if (ret->rsa != NULL) 45776262Sgreen RSA_free(ret->rsa); 45876262Sgreen ret->rsa = k->rsa; 45976262Sgreen k->rsa = NULL; 46076262Sgreen success = 1; 46176262Sgreen#ifdef DEBUG_PK 46276262Sgreen RSA_print_fp(stderr, ret->rsa, 8); 46376262Sgreen#endif 46476262Sgreen } else { 46576262Sgreen if (ret->dsa != NULL) 46676262Sgreen DSA_free(ret->dsa); 46776262Sgreen ret->dsa = k->dsa; 46876262Sgreen k->dsa = NULL; 46976262Sgreen success = 1; 47076262Sgreen#ifdef DEBUG_PK 47176262Sgreen DSA_print_fp(stderr, ret->dsa, 8); 47276262Sgreen#endif 47376262Sgreen } 47476262Sgreen/*XXXX*/ 47592559Sdes key_free(k); 47676262Sgreen if (success != 1) 47776262Sgreen break; 47861203Skris /* advance cp: skip whitespace and data */ 47961203Skris while (*cp == ' ' || *cp == '\t') 48061203Skris cp++; 48161203Skris while (*cp != '\0' && *cp != ' ' && *cp != '\t') 48261203Skris cp++; 48361203Skris *cpp = cp; 48458582Skris break; 48558582Skris default: 48660576Skris fatal("key_read: bad key type: %d", ret->type); 48758582Skris break; 48858582Skris } 48976262Sgreen return success; 49058582Skris} 49199063Sdes 49258582Skrisint 49358582Skriskey_write(Key *key, FILE *f) 49458582Skris{ 49592559Sdes int n, success = 0; 49692559Sdes u_int len, bits = 0; 497106130Sdes u_char *blob; 498106130Sdes char *uu; 49958582Skris 50076262Sgreen if (key->type == KEY_RSA1 && key->rsa != NULL) { 50158582Skris /* size of modulus 'n' */ 50258582Skris bits = BN_num_bits(key->rsa->n); 50358582Skris fprintf(f, "%u", bits); 50458582Skris if (write_bignum(f, key->rsa->e) && 50558582Skris write_bignum(f, key->rsa->n)) { 50658582Skris success = 1; 50758582Skris } else { 50858582Skris error("key_write: failed for RSA key"); 50958582Skris } 51076262Sgreen } else if ((key->type == KEY_DSA && key->dsa != NULL) || 51176262Sgreen (key->type == KEY_RSA && key->rsa != NULL)) { 51276262Sgreen key_to_blob(key, &blob, &len); 51360576Skris uu = xmalloc(2*len); 51460576Skris n = uuencode(blob, len, uu, 2*len); 51560576Skris if (n > 0) { 51676262Sgreen fprintf(f, "%s %s", key_ssh_name(key), uu); 51758582Skris success = 1; 51858582Skris } 51960576Skris xfree(blob); 52060576Skris xfree(uu); 52158582Skris } 52258582Skris return success; 52358582Skris} 52499063Sdes 52560576Skrischar * 52660576Skriskey_type(Key *k) 52760576Skris{ 52860576Skris switch (k->type) { 52976262Sgreen case KEY_RSA1: 53076262Sgreen return "RSA1"; 53176262Sgreen break; 53260576Skris case KEY_RSA: 53360576Skris return "RSA"; 53460576Skris break; 53560576Skris case KEY_DSA: 53660576Skris return "DSA"; 53760576Skris break; 53860576Skris } 53960576Skris return "unknown"; 54060576Skris} 54199063Sdes 54276262Sgreenchar * 54376262Sgreenkey_ssh_name(Key *k) 54476262Sgreen{ 54576262Sgreen switch (k->type) { 54676262Sgreen case KEY_RSA: 54776262Sgreen return "ssh-rsa"; 54876262Sgreen break; 54976262Sgreen case KEY_DSA: 55076262Sgreen return "ssh-dss"; 55176262Sgreen break; 55276262Sgreen } 55376262Sgreen return "ssh-unknown"; 55476262Sgreen} 55599063Sdes 55676262Sgreenu_int 55792559Sdeskey_size(Key *k) 55892559Sdes{ 55965674Skris switch (k->type) { 56076262Sgreen case KEY_RSA1: 56165674Skris case KEY_RSA: 56265674Skris return BN_num_bits(k->rsa->n); 56365674Skris break; 56465674Skris case KEY_DSA: 56565674Skris return BN_num_bits(k->dsa->p); 56665674Skris break; 56765674Skris } 56865674Skris return 0; 56965674Skris} 57076262Sgreen 57192559Sdesstatic RSA * 57276262Sgreenrsa_generate_private_key(u_int bits) 57376262Sgreen{ 57476262Sgreen RSA *private; 57576262Sgreen private = RSA_generate_key(bits, 35, NULL, NULL); 57676262Sgreen if (private == NULL) 57776262Sgreen fatal("rsa_generate_private_key: key generation failed."); 57876262Sgreen return private; 57976262Sgreen} 58076262Sgreen 58192559Sdesstatic DSA* 58276262Sgreendsa_generate_private_key(u_int bits) 58376262Sgreen{ 58476262Sgreen DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); 58576262Sgreen if (private == NULL) 58676262Sgreen fatal("dsa_generate_private_key: DSA_generate_parameters failed"); 58776262Sgreen if (!DSA_generate_key(private)) 58876262Sgreen fatal("dsa_generate_private_key: DSA_generate_key failed."); 58976262Sgreen if (private == NULL) 59076262Sgreen fatal("dsa_generate_private_key: NULL."); 59176262Sgreen return private; 59276262Sgreen} 59376262Sgreen 59476262SgreenKey * 59576262Sgreenkey_generate(int type, u_int bits) 59676262Sgreen{ 59776262Sgreen Key *k = key_new(KEY_UNSPEC); 59876262Sgreen switch (type) { 59976262Sgreen case KEY_DSA: 60076262Sgreen k->dsa = dsa_generate_private_key(bits); 60176262Sgreen break; 60276262Sgreen case KEY_RSA: 60376262Sgreen case KEY_RSA1: 60476262Sgreen k->rsa = rsa_generate_private_key(bits); 60576262Sgreen break; 60676262Sgreen default: 60776262Sgreen fatal("key_generate: unknown type %d", type); 60876262Sgreen } 60976262Sgreen k->type = type; 61076262Sgreen return k; 61176262Sgreen} 61276262Sgreen 61376262SgreenKey * 61476262Sgreenkey_from_private(Key *k) 61576262Sgreen{ 61676262Sgreen Key *n = NULL; 61776262Sgreen switch (k->type) { 61876262Sgreen case KEY_DSA: 61976262Sgreen n = key_new(k->type); 62076262Sgreen BN_copy(n->dsa->p, k->dsa->p); 62176262Sgreen BN_copy(n->dsa->q, k->dsa->q); 62276262Sgreen BN_copy(n->dsa->g, k->dsa->g); 62376262Sgreen BN_copy(n->dsa->pub_key, k->dsa->pub_key); 62476262Sgreen break; 62576262Sgreen case KEY_RSA: 62676262Sgreen case KEY_RSA1: 62776262Sgreen n = key_new(k->type); 62876262Sgreen BN_copy(n->rsa->n, k->rsa->n); 62976262Sgreen BN_copy(n->rsa->e, k->rsa->e); 63076262Sgreen break; 63176262Sgreen default: 63276262Sgreen fatal("key_from_private: unknown type %d", k->type); 63376262Sgreen break; 63476262Sgreen } 63576262Sgreen return n; 63676262Sgreen} 63776262Sgreen 63876262Sgreenint 63976262Sgreenkey_type_from_name(char *name) 64076262Sgreen{ 64192559Sdes if (strcmp(name, "rsa1") == 0) { 64276262Sgreen return KEY_RSA1; 64392559Sdes } else if (strcmp(name, "rsa") == 0) { 64476262Sgreen return KEY_RSA; 64592559Sdes } else if (strcmp(name, "dsa") == 0) { 64676262Sgreen return KEY_DSA; 64792559Sdes } else if (strcmp(name, "ssh-rsa") == 0) { 64876262Sgreen return KEY_RSA; 64992559Sdes } else if (strcmp(name, "ssh-dss") == 0) { 65076262Sgreen return KEY_DSA; 65176262Sgreen } 65276262Sgreen debug2("key_type_from_name: unknown key type '%s'", name); 65376262Sgreen return KEY_UNSPEC; 65476262Sgreen} 65576262Sgreen 65676262Sgreenint 65776262Sgreenkey_names_valid2(const char *names) 65876262Sgreen{ 65976262Sgreen char *s, *cp, *p; 66076262Sgreen 66176262Sgreen if (names == NULL || strcmp(names, "") == 0) 66276262Sgreen return 0; 66376262Sgreen s = cp = xstrdup(names); 66476262Sgreen for ((p = strsep(&cp, ",")); p && *p != '\0'; 66592559Sdes (p = strsep(&cp, ","))) { 66676262Sgreen switch (key_type_from_name(p)) { 66776262Sgreen case KEY_RSA1: 66876262Sgreen case KEY_UNSPEC: 66976262Sgreen xfree(s); 67076262Sgreen return 0; 67176262Sgreen } 67276262Sgreen } 67376262Sgreen debug3("key names ok: [%s]", names); 67476262Sgreen xfree(s); 67576262Sgreen return 1; 67676262Sgreen} 67776262Sgreen 67876262SgreenKey * 679124211Sdeskey_from_blob(u_char *blob, u_int blen) 68076262Sgreen{ 68176262Sgreen Buffer b; 68276262Sgreen char *ktype; 68376262Sgreen int rlen, type; 68476262Sgreen Key *key = NULL; 68576262Sgreen 68676262Sgreen#ifdef DEBUG_PK 68776262Sgreen dump_base64(stderr, blob, blen); 68876262Sgreen#endif 68976262Sgreen buffer_init(&b); 69076262Sgreen buffer_append(&b, blob, blen); 69176262Sgreen ktype = buffer_get_string(&b, NULL); 69276262Sgreen type = key_type_from_name(ktype); 69376262Sgreen 69492559Sdes switch (type) { 69576262Sgreen case KEY_RSA: 69676262Sgreen key = key_new(type); 69776262Sgreen buffer_get_bignum2(&b, key->rsa->e); 69876262Sgreen buffer_get_bignum2(&b, key->rsa->n); 69976262Sgreen#ifdef DEBUG_PK 70076262Sgreen RSA_print_fp(stderr, key->rsa, 8); 70176262Sgreen#endif 70276262Sgreen break; 70376262Sgreen case KEY_DSA: 70476262Sgreen key = key_new(type); 70576262Sgreen buffer_get_bignum2(&b, key->dsa->p); 70676262Sgreen buffer_get_bignum2(&b, key->dsa->q); 70776262Sgreen buffer_get_bignum2(&b, key->dsa->g); 70876262Sgreen buffer_get_bignum2(&b, key->dsa->pub_key); 70976262Sgreen#ifdef DEBUG_PK 71076262Sgreen DSA_print_fp(stderr, key->dsa, 8); 71176262Sgreen#endif 71276262Sgreen break; 71376262Sgreen case KEY_UNSPEC: 71476262Sgreen key = key_new(type); 71576262Sgreen break; 71676262Sgreen default: 71776262Sgreen error("key_from_blob: cannot handle type %s", ktype); 71876262Sgreen break; 71976262Sgreen } 72076262Sgreen rlen = buffer_len(&b); 72176262Sgreen if (key != NULL && rlen != 0) 72276262Sgreen error("key_from_blob: remaining bytes in key blob %d", rlen); 72376262Sgreen xfree(ktype); 72476262Sgreen buffer_free(&b); 72576262Sgreen return key; 72676262Sgreen} 72776262Sgreen 72876262Sgreenint 72976262Sgreenkey_to_blob(Key *key, u_char **blobp, u_int *lenp) 73076262Sgreen{ 73176262Sgreen Buffer b; 73276262Sgreen int len; 73376262Sgreen 73476262Sgreen if (key == NULL) { 73576262Sgreen error("key_to_blob: key == NULL"); 73676262Sgreen return 0; 73776262Sgreen } 73876262Sgreen buffer_init(&b); 73992559Sdes switch (key->type) { 74076262Sgreen case KEY_DSA: 74176262Sgreen buffer_put_cstring(&b, key_ssh_name(key)); 74276262Sgreen buffer_put_bignum2(&b, key->dsa->p); 74376262Sgreen buffer_put_bignum2(&b, key->dsa->q); 74476262Sgreen buffer_put_bignum2(&b, key->dsa->g); 74576262Sgreen buffer_put_bignum2(&b, key->dsa->pub_key); 74676262Sgreen break; 74776262Sgreen case KEY_RSA: 74876262Sgreen buffer_put_cstring(&b, key_ssh_name(key)); 74976262Sgreen buffer_put_bignum2(&b, key->rsa->e); 75076262Sgreen buffer_put_bignum2(&b, key->rsa->n); 75176262Sgreen break; 75276262Sgreen default: 75392559Sdes error("key_to_blob: unsupported key type %d", key->type); 75492559Sdes buffer_free(&b); 75592559Sdes return 0; 75676262Sgreen } 75776262Sgreen len = buffer_len(&b); 758106130Sdes if (lenp != NULL) 759106130Sdes *lenp = len; 760106130Sdes if (blobp != NULL) { 761106130Sdes *blobp = xmalloc(len); 762106130Sdes memcpy(*blobp, buffer_ptr(&b), len); 763106130Sdes } 76476262Sgreen memset(buffer_ptr(&b), 0, len); 76576262Sgreen buffer_free(&b); 76676262Sgreen return len; 76776262Sgreen} 76876262Sgreen 76976262Sgreenint 77076262Sgreenkey_sign( 77176262Sgreen Key *key, 77292559Sdes u_char **sigp, u_int *lenp, 77392559Sdes u_char *data, u_int datalen) 77476262Sgreen{ 77592559Sdes switch (key->type) { 77676262Sgreen case KEY_DSA: 77776262Sgreen return ssh_dss_sign(key, sigp, lenp, data, datalen); 77876262Sgreen break; 77976262Sgreen case KEY_RSA: 78076262Sgreen return ssh_rsa_sign(key, sigp, lenp, data, datalen); 78176262Sgreen break; 78276262Sgreen default: 78376262Sgreen error("key_sign: illegal key type %d", key->type); 78476262Sgreen return -1; 78576262Sgreen break; 78676262Sgreen } 78776262Sgreen} 78876262Sgreen 78998684Sdes/* 79098684Sdes * key_verify returns 1 for a correct signature, 0 for an incorrect signature 79198684Sdes * and -1 on error. 79298684Sdes */ 79376262Sgreenint 79476262Sgreenkey_verify( 79576262Sgreen Key *key, 79692559Sdes u_char *signature, u_int signaturelen, 79792559Sdes u_char *data, u_int datalen) 79876262Sgreen{ 79992559Sdes if (signaturelen == 0) 80092559Sdes return -1; 80192559Sdes 80292559Sdes switch (key->type) { 80376262Sgreen case KEY_DSA: 80476262Sgreen return ssh_dss_verify(key, signature, signaturelen, data, datalen); 80576262Sgreen break; 80676262Sgreen case KEY_RSA: 80776262Sgreen return ssh_rsa_verify(key, signature, signaturelen, data, datalen); 80876262Sgreen break; 80976262Sgreen default: 81076262Sgreen error("key_verify: illegal key type %d", key->type); 81176262Sgreen return -1; 81276262Sgreen break; 81376262Sgreen } 81476262Sgreen} 81598684Sdes 81698684Sdes/* Converts a private to a public key */ 81798684SdesKey * 81898684Sdeskey_demote(Key *k) 81998684Sdes{ 82098684Sdes Key *pk; 82198684Sdes 82298684Sdes pk = xmalloc(sizeof(*pk)); 82398684Sdes pk->type = k->type; 82498684Sdes pk->flags = k->flags; 82598684Sdes pk->dsa = NULL; 82698684Sdes pk->rsa = NULL; 82798684Sdes 82898684Sdes switch (k->type) { 82998684Sdes case KEY_RSA1: 83098684Sdes case KEY_RSA: 83198684Sdes if ((pk->rsa = RSA_new()) == NULL) 83298684Sdes fatal("key_demote: RSA_new failed"); 83398684Sdes if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL) 83498684Sdes fatal("key_demote: BN_dup failed"); 83598684Sdes if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) 83698684Sdes fatal("key_demote: BN_dup failed"); 83798684Sdes break; 83898684Sdes case KEY_DSA: 83998684Sdes if ((pk->dsa = DSA_new()) == NULL) 84098684Sdes fatal("key_demote: DSA_new failed"); 84198684Sdes if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL) 84298684Sdes fatal("key_demote: BN_dup failed"); 84398684Sdes if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL) 84498684Sdes fatal("key_demote: BN_dup failed"); 84598684Sdes if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL) 84698684Sdes fatal("key_demote: BN_dup failed"); 84798684Sdes if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) 84898684Sdes fatal("key_demote: BN_dup failed"); 84998684Sdes break; 85098684Sdes default: 85198684Sdes fatal("key_free: bad key type %d", k->type); 85298684Sdes break; 85398684Sdes } 85498684Sdes 85598684Sdes return (pk); 85698684Sdes} 857