key.c revision 162856
1162856Sdes/* $OpenBSD: key.c,v 1.67 2006/08/03 03:34:42 deraadt Exp $ */ 258582Skris/* 365674Skris * read_bignum(): 465674Skris * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 565674Skris * 665674Skris * As far as I am concerned, the code I have written for this software 765674Skris * can be used freely for any purpose. Any derived versions of this 865674Skris * software must be clearly marked as such, and if the derived work is 965674Skris * incompatible with the protocol description in the RFC file, it must be 1065674Skris * called by a name other than "ssh" or "Secure Shell". 1165674Skris * 1265674Skris * 1392559Sdes * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 1458582Skris * 1558582Skris * Redistribution and use in source and binary forms, with or without 1658582Skris * modification, are permitted provided that the following conditions 1758582Skris * are met: 1858582Skris * 1. Redistributions of source code must retain the above copyright 1958582Skris * notice, this list of conditions and the following disclaimer. 2058582Skris * 2. Redistributions in binary form must reproduce the above copyright 2158582Skris * notice, this list of conditions and the following disclaimer in the 2258582Skris * documentation and/or other materials provided with the distribution. 2358582Skris * 2458582Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2558582Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2658582Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2758582Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2858582Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2958582Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3058582Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3158582Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3258582Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3358582Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3458582Skris */ 35162856Sdes 3676262Sgreen#include "includes.h" 3758582Skris 38162856Sdes#include <sys/types.h> 39162856Sdes 4058592Skris#include <openssl/evp.h> 4176262Sgreen 42162856Sdes#include <stdarg.h> 43162856Sdes#include <stdio.h> 44162856Sdes#include <string.h> 45162856Sdes 4658582Skris#include "xmalloc.h" 4758582Skris#include "key.h" 4876262Sgreen#include "rsa.h" 4960576Skris#include "uuencode.h" 5076262Sgreen#include "buffer.h" 5176262Sgreen#include "log.h" 5258582Skris 5358582SkrisKey * 5458582Skriskey_new(int type) 5558582Skris{ 5658582Skris Key *k; 5758582Skris RSA *rsa; 5858582Skris DSA *dsa; 59162856Sdes k = xcalloc(1, sizeof(*k)); 6058582Skris k->type = type; 6160576Skris k->dsa = NULL; 6260576Skris k->rsa = NULL; 6358582Skris switch (k->type) { 6476262Sgreen case KEY_RSA1: 6558582Skris case KEY_RSA: 6692559Sdes if ((rsa = RSA_new()) == NULL) 6792559Sdes fatal("key_new: RSA_new failed"); 6892559Sdes if ((rsa->n = BN_new()) == NULL) 6992559Sdes fatal("key_new: BN_new failed"); 7092559Sdes if ((rsa->e = BN_new()) == NULL) 7192559Sdes fatal("key_new: BN_new failed"); 7258582Skris k->rsa = rsa; 7358582Skris break; 7458582Skris case KEY_DSA: 7592559Sdes if ((dsa = DSA_new()) == NULL) 7692559Sdes fatal("key_new: DSA_new failed"); 7792559Sdes if ((dsa->p = BN_new()) == NULL) 7892559Sdes fatal("key_new: BN_new failed"); 7992559Sdes if ((dsa->q = BN_new()) == NULL) 8092559Sdes fatal("key_new: BN_new failed"); 8192559Sdes if ((dsa->g = BN_new()) == NULL) 8292559Sdes fatal("key_new: BN_new failed"); 8392559Sdes if ((dsa->pub_key = BN_new()) == NULL) 8492559Sdes fatal("key_new: BN_new failed"); 8558582Skris k->dsa = dsa; 8658582Skris break; 8776262Sgreen case KEY_UNSPEC: 8858582Skris break; 8958582Skris default: 9058582Skris fatal("key_new: bad key type %d", k->type); 9158582Skris break; 9258582Skris } 9358582Skris return k; 9458582Skris} 9599063Sdes 9676262SgreenKey * 9776262Sgreenkey_new_private(int type) 9876262Sgreen{ 9976262Sgreen Key *k = key_new(type); 10076262Sgreen switch (k->type) { 10176262Sgreen case KEY_RSA1: 10276262Sgreen case KEY_RSA: 10392559Sdes if ((k->rsa->d = BN_new()) == NULL) 10492559Sdes fatal("key_new_private: BN_new failed"); 10592559Sdes if ((k->rsa->iqmp = BN_new()) == NULL) 10692559Sdes fatal("key_new_private: BN_new failed"); 10792559Sdes if ((k->rsa->q = BN_new()) == NULL) 10892559Sdes fatal("key_new_private: BN_new failed"); 10992559Sdes if ((k->rsa->p = BN_new()) == NULL) 11092559Sdes fatal("key_new_private: BN_new failed"); 11192559Sdes if ((k->rsa->dmq1 = BN_new()) == NULL) 11292559Sdes fatal("key_new_private: BN_new failed"); 11392559Sdes if ((k->rsa->dmp1 = BN_new()) == NULL) 11492559Sdes fatal("key_new_private: BN_new failed"); 11576262Sgreen break; 11676262Sgreen case KEY_DSA: 11792559Sdes if ((k->dsa->priv_key = BN_new()) == NULL) 11892559Sdes fatal("key_new_private: BN_new failed"); 11976262Sgreen break; 12076262Sgreen case KEY_UNSPEC: 12176262Sgreen break; 12276262Sgreen default: 12376262Sgreen break; 12476262Sgreen } 12576262Sgreen return k; 12676262Sgreen} 12799063Sdes 12858582Skrisvoid 12958582Skriskey_free(Key *k) 13058582Skris{ 131162856Sdes if (k == NULL) 132162856Sdes fatal("key_free: key is NULL"); 13358582Skris switch (k->type) { 13476262Sgreen case KEY_RSA1: 13558582Skris case KEY_RSA: 13658582Skris if (k->rsa != NULL) 13758582Skris RSA_free(k->rsa); 13858582Skris k->rsa = NULL; 13958582Skris break; 14058582Skris case KEY_DSA: 14158582Skris if (k->dsa != NULL) 14258582Skris DSA_free(k->dsa); 14358582Skris k->dsa = NULL; 14458582Skris break; 14576262Sgreen case KEY_UNSPEC: 14676262Sgreen break; 14758582Skris default: 14858582Skris fatal("key_free: bad key type %d", k->type); 14958582Skris break; 15058582Skris } 15158582Skris xfree(k); 15258582Skris} 153126277Sdes 15458582Skrisint 155126277Sdeskey_equal(const Key *a, const Key *b) 15658582Skris{ 15758582Skris if (a == NULL || b == NULL || a->type != b->type) 15858582Skris return 0; 15958582Skris switch (a->type) { 16076262Sgreen case KEY_RSA1: 16158582Skris case KEY_RSA: 16258582Skris return a->rsa != NULL && b->rsa != NULL && 16358582Skris BN_cmp(a->rsa->e, b->rsa->e) == 0 && 16458582Skris BN_cmp(a->rsa->n, b->rsa->n) == 0; 16558582Skris case KEY_DSA: 16658582Skris return a->dsa != NULL && b->dsa != NULL && 16758582Skris BN_cmp(a->dsa->p, b->dsa->p) == 0 && 16858582Skris BN_cmp(a->dsa->q, b->dsa->q) == 0 && 16958582Skris BN_cmp(a->dsa->g, b->dsa->g) == 0 && 17058582Skris BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 17158582Skris default: 17260576Skris fatal("key_equal: bad key type %d", a->type); 17358582Skris break; 17458582Skris } 17558582Skris return 0; 17658582Skris} 17758582Skris 178124211Sdesu_char* 179126277Sdeskey_fingerprint_raw(const Key *k, enum fp_type dgst_type, 180126277Sdes u_int *dgst_raw_length) 18158582Skris{ 18292559Sdes const EVP_MD *md = NULL; 18376262Sgreen EVP_MD_CTX ctx; 18476262Sgreen u_char *blob = NULL; 18576262Sgreen u_char *retval = NULL; 18692559Sdes u_int len = 0; 18760576Skris int nlen, elen; 18858582Skris 18976262Sgreen *dgst_raw_length = 0; 19076262Sgreen 19176262Sgreen switch (dgst_type) { 19276262Sgreen case SSH_FP_MD5: 19376262Sgreen md = EVP_md5(); 19476262Sgreen break; 19576262Sgreen case SSH_FP_SHA1: 19676262Sgreen md = EVP_sha1(); 19776262Sgreen break; 19876262Sgreen default: 19976262Sgreen fatal("key_fingerprint_raw: bad digest type %d", 20076262Sgreen dgst_type); 20176262Sgreen } 20258582Skris switch (k->type) { 20376262Sgreen case KEY_RSA1: 20458582Skris nlen = BN_num_bytes(k->rsa->n); 20558582Skris elen = BN_num_bytes(k->rsa->e); 20658582Skris len = nlen + elen; 20760576Skris blob = xmalloc(len); 20860576Skris BN_bn2bin(k->rsa->n, blob); 20960576Skris BN_bn2bin(k->rsa->e, blob + nlen); 21058582Skris break; 21158582Skris case KEY_DSA: 21276262Sgreen case KEY_RSA: 21376262Sgreen key_to_blob(k, &blob, &len); 21458582Skris break; 21576262Sgreen case KEY_UNSPEC: 21676262Sgreen return retval; 21758582Skris default: 21876262Sgreen fatal("key_fingerprint_raw: bad key type %d", k->type); 21958582Skris break; 22058582Skris } 22160576Skris if (blob != NULL) { 22276262Sgreen retval = xmalloc(EVP_MAX_MD_SIZE); 22365674Skris EVP_DigestInit(&ctx, md); 22465674Skris EVP_DigestUpdate(&ctx, blob, len); 22592559Sdes EVP_DigestFinal(&ctx, retval, dgst_raw_length); 22660576Skris memset(blob, 0, len); 22760576Skris xfree(blob); 22876262Sgreen } else { 22976262Sgreen fatal("key_fingerprint_raw: blob is null"); 23058582Skris } 23158582Skris return retval; 23258582Skris} 23358582Skris 234106130Sdesstatic char * 235106130Sdeskey_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) 23676262Sgreen{ 23776262Sgreen char *retval; 238149753Sdes u_int i; 23976262Sgreen 240162856Sdes retval = xcalloc(1, dgst_raw_len * 3 + 1); 24192559Sdes for (i = 0; i < dgst_raw_len; i++) { 24276262Sgreen char hex[4]; 24376262Sgreen snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); 244124211Sdes strlcat(retval, hex, dgst_raw_len * 3 + 1); 24576262Sgreen } 246124211Sdes 247124211Sdes /* Remove the trailing ':' character */ 24876262Sgreen retval[(dgst_raw_len * 3) - 1] = '\0'; 24976262Sgreen return retval; 25076262Sgreen} 25176262Sgreen 252106130Sdesstatic char * 253106130Sdeskey_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) 25476262Sgreen{ 25576262Sgreen char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; 25676262Sgreen char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 25776262Sgreen 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; 25876262Sgreen u_int i, j = 0, rounds, seed = 1; 25976262Sgreen char *retval; 26076262Sgreen 26176262Sgreen rounds = (dgst_raw_len / 2) + 1; 262162856Sdes retval = xcalloc((rounds * 6), sizeof(char)); 26376262Sgreen retval[j++] = 'x'; 26476262Sgreen for (i = 0; i < rounds; i++) { 26576262Sgreen u_int idx0, idx1, idx2, idx3, idx4; 26676262Sgreen if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { 26776262Sgreen idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + 26876262Sgreen seed) % 6; 26976262Sgreen idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; 27076262Sgreen idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + 27176262Sgreen (seed / 6)) % 6; 27276262Sgreen retval[j++] = vowels[idx0]; 27376262Sgreen retval[j++] = consonants[idx1]; 27476262Sgreen retval[j++] = vowels[idx2]; 27576262Sgreen if ((i + 1) < rounds) { 27676262Sgreen idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; 27776262Sgreen idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; 27876262Sgreen retval[j++] = consonants[idx3]; 27976262Sgreen retval[j++] = '-'; 28076262Sgreen retval[j++] = consonants[idx4]; 28176262Sgreen seed = ((seed * 5) + 28276262Sgreen ((((u_int)(dgst_raw[2 * i])) * 7) + 28376262Sgreen ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; 28476262Sgreen } 28576262Sgreen } else { 28676262Sgreen idx0 = seed % 6; 28776262Sgreen idx1 = 16; 28876262Sgreen idx2 = seed / 6; 28976262Sgreen retval[j++] = vowels[idx0]; 29076262Sgreen retval[j++] = consonants[idx1]; 29176262Sgreen retval[j++] = vowels[idx2]; 29276262Sgreen } 29376262Sgreen } 29476262Sgreen retval[j++] = 'x'; 29576262Sgreen retval[j++] = '\0'; 29676262Sgreen return retval; 29776262Sgreen} 29876262Sgreen 299106130Sdeschar * 300126277Sdeskey_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) 30176262Sgreen{ 30276262Sgreen char *retval = NULL; 30376262Sgreen u_char *dgst_raw; 30492559Sdes u_int dgst_raw_len; 30592559Sdes 30676262Sgreen dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); 30776262Sgreen if (!dgst_raw) 30876262Sgreen fatal("key_fingerprint: null from key_fingerprint_raw()"); 30992559Sdes switch (dgst_rep) { 31076262Sgreen case SSH_FP_HEX: 31176262Sgreen retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); 31276262Sgreen break; 31376262Sgreen case SSH_FP_BUBBLEBABBLE: 31476262Sgreen retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 31576262Sgreen break; 31676262Sgreen default: 31776262Sgreen fatal("key_fingerprint_ex: bad digest representation %d", 31876262Sgreen dgst_rep); 31976262Sgreen break; 32076262Sgreen } 32176262Sgreen memset(dgst_raw, 0, dgst_raw_len); 32276262Sgreen xfree(dgst_raw); 32376262Sgreen return retval; 32476262Sgreen} 32576262Sgreen 32658582Skris/* 32758582Skris * Reads a multiple-precision integer in decimal from the buffer, and advances 32858582Skris * the pointer. The integer must already be initialized. This function is 32958582Skris * permitted to modify the buffer. This leaves *cpp to point just beyond the 33058582Skris * last processed (and maybe modified) character. Note that this may modify 33158582Skris * the buffer containing the number. 33258582Skris */ 33392559Sdesstatic int 33458582Skrisread_bignum(char **cpp, BIGNUM * value) 33558582Skris{ 33658582Skris char *cp = *cpp; 33758582Skris int old; 33858582Skris 33958582Skris /* Skip any leading whitespace. */ 34058582Skris for (; *cp == ' ' || *cp == '\t'; cp++) 34158582Skris ; 34258582Skris 34358582Skris /* Check that it begins with a decimal digit. */ 34458582Skris if (*cp < '0' || *cp > '9') 34558582Skris return 0; 34658582Skris 34758582Skris /* Save starting position. */ 34858582Skris *cpp = cp; 34958582Skris 35058582Skris /* Move forward until all decimal digits skipped. */ 35158582Skris for (; *cp >= '0' && *cp <= '9'; cp++) 35258582Skris ; 35358582Skris 35458582Skris /* Save the old terminating character, and replace it by \0. */ 35558582Skris old = *cp; 35658582Skris *cp = 0; 35758582Skris 35858582Skris /* Parse the number. */ 35958582Skris if (BN_dec2bn(&value, *cpp) == 0) 36058582Skris return 0; 36158582Skris 36258582Skris /* Restore old terminating character. */ 36358582Skris *cp = old; 36458582Skris 36558582Skris /* Move beyond the number and return success. */ 36658582Skris *cpp = cp; 36758582Skris return 1; 36858582Skris} 36999063Sdes 37092559Sdesstatic int 37158582Skriswrite_bignum(FILE *f, BIGNUM *num) 37258582Skris{ 37358582Skris char *buf = BN_bn2dec(num); 37458582Skris if (buf == NULL) { 37558582Skris error("write_bignum: BN_bn2dec() failed"); 37658582Skris return 0; 37758582Skris } 37858582Skris fprintf(f, " %s", buf); 37992559Sdes OPENSSL_free(buf); 38058582Skris return 1; 38158582Skris} 38276262Sgreen 38392559Sdes/* returns 1 ok, -1 error */ 38476262Sgreenint 38560576Skriskey_read(Key *ret, char **cpp) 38658582Skris{ 38760576Skris Key *k; 38876262Sgreen int success = -1; 38976262Sgreen char *cp, *space; 39076262Sgreen int len, n, type; 39176262Sgreen u_int bits; 39276262Sgreen u_char *blob; 39360576Skris 39460576Skris cp = *cpp; 39560576Skris 39692559Sdes switch (ret->type) { 39776262Sgreen case KEY_RSA1: 39860576Skris /* Get number of bits. */ 39960576Skris if (*cp < '0' || *cp > '9') 40076262Sgreen return -1; /* Bad bit count... */ 40160576Skris for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 40260576Skris bits = 10 * bits + *cp - '0'; 40358582Skris if (bits == 0) 40476262Sgreen return -1; 40560576Skris *cpp = cp; 40658582Skris /* Get public exponent, public modulus. */ 40758582Skris if (!read_bignum(cpp, ret->rsa->e)) 40876262Sgreen return -1; 40958582Skris if (!read_bignum(cpp, ret->rsa->n)) 41076262Sgreen return -1; 41176262Sgreen success = 1; 41258582Skris break; 41376262Sgreen case KEY_UNSPEC: 41476262Sgreen case KEY_RSA: 41558582Skris case KEY_DSA: 41676262Sgreen space = strchr(cp, ' '); 41776262Sgreen if (space == NULL) { 418113911Sdes debug3("key_read: missing whitespace"); 41976262Sgreen return -1; 42076262Sgreen } 42176262Sgreen *space = '\0'; 42276262Sgreen type = key_type_from_name(cp); 42376262Sgreen *space = ' '; 42476262Sgreen if (type == KEY_UNSPEC) { 425113911Sdes debug3("key_read: missing keytype"); 42676262Sgreen return -1; 42776262Sgreen } 42876262Sgreen cp = space+1; 42976262Sgreen if (*cp == '\0') { 43076262Sgreen debug3("key_read: short string"); 43176262Sgreen return -1; 43276262Sgreen } 43376262Sgreen if (ret->type == KEY_UNSPEC) { 43476262Sgreen ret->type = type; 43576262Sgreen } else if (ret->type != type) { 43676262Sgreen /* is a key, but different type */ 43776262Sgreen debug3("key_read: type mismatch"); 43892559Sdes return -1; 43976262Sgreen } 44060576Skris len = 2*strlen(cp); 44160576Skris blob = xmalloc(len); 44260576Skris n = uudecode(cp, blob, len); 44360576Skris if (n < 0) { 44461203Skris error("key_read: uudecode %s failed", cp); 44592559Sdes xfree(blob); 44676262Sgreen return -1; 44760576Skris } 448124211Sdes k = key_from_blob(blob, (u_int)n); 44992559Sdes xfree(blob); 45061203Skris if (k == NULL) { 45176262Sgreen error("key_read: key_from_blob %s failed", cp); 45276262Sgreen return -1; 45361203Skris } 45476262Sgreen if (k->type != type) { 45576262Sgreen error("key_read: type mismatch: encoding error"); 45676262Sgreen key_free(k); 45776262Sgreen return -1; 45876262Sgreen } 45976262Sgreen/*XXXX*/ 46076262Sgreen if (ret->type == KEY_RSA) { 46176262Sgreen if (ret->rsa != NULL) 46276262Sgreen RSA_free(ret->rsa); 46376262Sgreen ret->rsa = k->rsa; 46476262Sgreen k->rsa = NULL; 46576262Sgreen success = 1; 46676262Sgreen#ifdef DEBUG_PK 46776262Sgreen RSA_print_fp(stderr, ret->rsa, 8); 46876262Sgreen#endif 46976262Sgreen } else { 47076262Sgreen if (ret->dsa != NULL) 47176262Sgreen DSA_free(ret->dsa); 47276262Sgreen ret->dsa = k->dsa; 47376262Sgreen k->dsa = NULL; 47476262Sgreen success = 1; 47576262Sgreen#ifdef DEBUG_PK 47676262Sgreen DSA_print_fp(stderr, ret->dsa, 8); 47776262Sgreen#endif 47876262Sgreen } 47976262Sgreen/*XXXX*/ 48092559Sdes key_free(k); 48176262Sgreen if (success != 1) 48276262Sgreen break; 48361203Skris /* advance cp: skip whitespace and data */ 48461203Skris while (*cp == ' ' || *cp == '\t') 48561203Skris cp++; 48661203Skris while (*cp != '\0' && *cp != ' ' && *cp != '\t') 48761203Skris cp++; 48861203Skris *cpp = cp; 48958582Skris break; 49058582Skris default: 49160576Skris fatal("key_read: bad key type: %d", ret->type); 49258582Skris break; 49358582Skris } 49476262Sgreen return success; 49558582Skris} 49699063Sdes 49758582Skrisint 498126277Sdeskey_write(const Key *key, FILE *f) 49958582Skris{ 50092559Sdes int n, success = 0; 50192559Sdes u_int len, bits = 0; 502106130Sdes u_char *blob; 503106130Sdes char *uu; 50458582Skris 50576262Sgreen if (key->type == KEY_RSA1 && key->rsa != NULL) { 50658582Skris /* size of modulus 'n' */ 50758582Skris bits = BN_num_bits(key->rsa->n); 50858582Skris fprintf(f, "%u", bits); 50958582Skris if (write_bignum(f, key->rsa->e) && 51058582Skris write_bignum(f, key->rsa->n)) { 51158582Skris success = 1; 51258582Skris } else { 51358582Skris error("key_write: failed for RSA key"); 51458582Skris } 51576262Sgreen } else if ((key->type == KEY_DSA && key->dsa != NULL) || 51676262Sgreen (key->type == KEY_RSA && key->rsa != NULL)) { 51776262Sgreen key_to_blob(key, &blob, &len); 51860576Skris uu = xmalloc(2*len); 51960576Skris n = uuencode(blob, len, uu, 2*len); 52060576Skris if (n > 0) { 52176262Sgreen fprintf(f, "%s %s", key_ssh_name(key), uu); 52258582Skris success = 1; 52358582Skris } 52460576Skris xfree(blob); 52560576Skris xfree(uu); 52658582Skris } 52758582Skris return success; 52858582Skris} 52999063Sdes 530126277Sdesconst char * 531126277Sdeskey_type(const Key *k) 53260576Skris{ 53360576Skris switch (k->type) { 53476262Sgreen case KEY_RSA1: 53576262Sgreen return "RSA1"; 53660576Skris case KEY_RSA: 53760576Skris return "RSA"; 53860576Skris case KEY_DSA: 53960576Skris return "DSA"; 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 case KEY_DSA: 55176262Sgreen return "ssh-dss"; 55276262Sgreen } 55376262Sgreen return "ssh-unknown"; 55476262Sgreen} 55599063Sdes 55676262Sgreenu_int 557126277Sdeskey_size(const Key *k) 55892559Sdes{ 55965674Skris switch (k->type) { 56076262Sgreen case KEY_RSA1: 56165674Skris case KEY_RSA: 56265674Skris return BN_num_bits(k->rsa->n); 56365674Skris case KEY_DSA: 56465674Skris return BN_num_bits(k->dsa->p); 56565674Skris } 56665674Skris return 0; 56765674Skris} 56876262Sgreen 56992559Sdesstatic RSA * 57076262Sgreenrsa_generate_private_key(u_int bits) 57176262Sgreen{ 57276262Sgreen RSA *private; 573162856Sdes 57476262Sgreen private = RSA_generate_key(bits, 35, NULL, NULL); 57576262Sgreen if (private == NULL) 57676262Sgreen fatal("rsa_generate_private_key: key generation failed."); 57776262Sgreen return private; 57876262Sgreen} 57976262Sgreen 58092559Sdesstatic DSA* 58176262Sgreendsa_generate_private_key(u_int bits) 58276262Sgreen{ 58376262Sgreen DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); 584162856Sdes 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 * 614126277Sdeskey_from_private(const 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 * 679126277Sdeskey_from_blob(const u_char *blob, u_int blen) 68076262Sgreen{ 68176262Sgreen Buffer b; 68276262Sgreen int rlen, type; 683147005Sdes char *ktype = NULL; 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); 691147005Sdes if ((ktype = buffer_get_string_ret(&b, NULL)) == NULL) { 692147005Sdes error("key_from_blob: can't read key type"); 693147005Sdes goto out; 694147005Sdes } 695147005Sdes 69676262Sgreen type = key_type_from_name(ktype); 69776262Sgreen 69892559Sdes switch (type) { 69976262Sgreen case KEY_RSA: 70076262Sgreen key = key_new(type); 701147005Sdes if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || 702147005Sdes buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { 703147005Sdes error("key_from_blob: can't read rsa key"); 704147005Sdes key_free(key); 705147005Sdes key = NULL; 706147005Sdes goto out; 707147005Sdes } 70876262Sgreen#ifdef DEBUG_PK 70976262Sgreen RSA_print_fp(stderr, key->rsa, 8); 71076262Sgreen#endif 71176262Sgreen break; 71276262Sgreen case KEY_DSA: 71376262Sgreen key = key_new(type); 714147005Sdes if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || 715147005Sdes buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || 716147005Sdes buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || 717147005Sdes buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { 718147005Sdes error("key_from_blob: can't read dsa key"); 719147005Sdes key_free(key); 720147005Sdes key = NULL; 721147005Sdes goto out; 722147005Sdes } 72376262Sgreen#ifdef DEBUG_PK 72476262Sgreen DSA_print_fp(stderr, key->dsa, 8); 72576262Sgreen#endif 72676262Sgreen break; 72776262Sgreen case KEY_UNSPEC: 72876262Sgreen key = key_new(type); 72976262Sgreen break; 73076262Sgreen default: 73176262Sgreen error("key_from_blob: cannot handle type %s", ktype); 732147005Sdes goto out; 73376262Sgreen } 73476262Sgreen rlen = buffer_len(&b); 73576262Sgreen if (key != NULL && rlen != 0) 73676262Sgreen error("key_from_blob: remaining bytes in key blob %d", rlen); 737147005Sdes out: 738147005Sdes if (ktype != NULL) 739147005Sdes xfree(ktype); 74076262Sgreen buffer_free(&b); 74176262Sgreen return key; 74276262Sgreen} 74376262Sgreen 74476262Sgreenint 745126277Sdeskey_to_blob(const Key *key, u_char **blobp, u_int *lenp) 74676262Sgreen{ 74776262Sgreen Buffer b; 74876262Sgreen int len; 74976262Sgreen 75076262Sgreen if (key == NULL) { 75176262Sgreen error("key_to_blob: key == NULL"); 75276262Sgreen return 0; 75376262Sgreen } 75476262Sgreen buffer_init(&b); 75592559Sdes switch (key->type) { 75676262Sgreen case KEY_DSA: 75776262Sgreen buffer_put_cstring(&b, key_ssh_name(key)); 75876262Sgreen buffer_put_bignum2(&b, key->dsa->p); 75976262Sgreen buffer_put_bignum2(&b, key->dsa->q); 76076262Sgreen buffer_put_bignum2(&b, key->dsa->g); 76176262Sgreen buffer_put_bignum2(&b, key->dsa->pub_key); 76276262Sgreen break; 76376262Sgreen case KEY_RSA: 76476262Sgreen buffer_put_cstring(&b, key_ssh_name(key)); 76576262Sgreen buffer_put_bignum2(&b, key->rsa->e); 76676262Sgreen buffer_put_bignum2(&b, key->rsa->n); 76776262Sgreen break; 76876262Sgreen default: 76992559Sdes error("key_to_blob: unsupported key type %d", key->type); 77092559Sdes buffer_free(&b); 77192559Sdes return 0; 77276262Sgreen } 77376262Sgreen len = buffer_len(&b); 774106130Sdes if (lenp != NULL) 775106130Sdes *lenp = len; 776106130Sdes if (blobp != NULL) { 777106130Sdes *blobp = xmalloc(len); 778106130Sdes memcpy(*blobp, buffer_ptr(&b), len); 779106130Sdes } 78076262Sgreen memset(buffer_ptr(&b), 0, len); 78176262Sgreen buffer_free(&b); 78276262Sgreen return len; 78376262Sgreen} 78476262Sgreen 78576262Sgreenint 78676262Sgreenkey_sign( 787126277Sdes const Key *key, 78892559Sdes u_char **sigp, u_int *lenp, 789126277Sdes const u_char *data, u_int datalen) 79076262Sgreen{ 79192559Sdes switch (key->type) { 79276262Sgreen case KEY_DSA: 79376262Sgreen return ssh_dss_sign(key, sigp, lenp, data, datalen); 79476262Sgreen case KEY_RSA: 79576262Sgreen return ssh_rsa_sign(key, sigp, lenp, data, datalen); 79676262Sgreen default: 797137019Sdes error("key_sign: invalid key type %d", key->type); 79876262Sgreen return -1; 79976262Sgreen } 80076262Sgreen} 80176262Sgreen 80298684Sdes/* 80398684Sdes * key_verify returns 1 for a correct signature, 0 for an incorrect signature 80498684Sdes * and -1 on error. 80598684Sdes */ 80676262Sgreenint 80776262Sgreenkey_verify( 808126277Sdes const Key *key, 809126277Sdes const u_char *signature, u_int signaturelen, 810126277Sdes const u_char *data, u_int datalen) 81176262Sgreen{ 81292559Sdes if (signaturelen == 0) 81392559Sdes return -1; 81492559Sdes 81592559Sdes switch (key->type) { 81676262Sgreen case KEY_DSA: 81776262Sgreen return ssh_dss_verify(key, signature, signaturelen, data, datalen); 81876262Sgreen case KEY_RSA: 81976262Sgreen return ssh_rsa_verify(key, signature, signaturelen, data, datalen); 82076262Sgreen default: 821137019Sdes error("key_verify: invalid key type %d", key->type); 82276262Sgreen return -1; 82376262Sgreen } 82476262Sgreen} 82598684Sdes 82698684Sdes/* Converts a private to a public key */ 82798684SdesKey * 828126277Sdeskey_demote(const Key *k) 82998684Sdes{ 83098684Sdes Key *pk; 83198684Sdes 832162856Sdes pk = xcalloc(1, sizeof(*pk)); 83398684Sdes pk->type = k->type; 83498684Sdes pk->flags = k->flags; 83598684Sdes pk->dsa = NULL; 83698684Sdes pk->rsa = NULL; 83798684Sdes 83898684Sdes switch (k->type) { 83998684Sdes case KEY_RSA1: 84098684Sdes case KEY_RSA: 84198684Sdes if ((pk->rsa = RSA_new()) == NULL) 84298684Sdes fatal("key_demote: RSA_new failed"); 84398684Sdes if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL) 84498684Sdes fatal("key_demote: BN_dup failed"); 84598684Sdes if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) 84698684Sdes fatal("key_demote: BN_dup failed"); 84798684Sdes break; 84898684Sdes case KEY_DSA: 84998684Sdes if ((pk->dsa = DSA_new()) == NULL) 85098684Sdes fatal("key_demote: DSA_new failed"); 85198684Sdes if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL) 85298684Sdes fatal("key_demote: BN_dup failed"); 85398684Sdes if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL) 85498684Sdes fatal("key_demote: BN_dup failed"); 85598684Sdes if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL) 85698684Sdes fatal("key_demote: BN_dup failed"); 85798684Sdes if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) 85898684Sdes fatal("key_demote: BN_dup failed"); 85998684Sdes break; 86098684Sdes default: 86198684Sdes fatal("key_free: bad key type %d", k->type); 86298684Sdes break; 86398684Sdes } 86498684Sdes 86598684Sdes return (pk); 86698684Sdes} 867