key.c revision 58582
158582Skris/* 258582Skris * Copyright (c) 2000 Markus Friedl. All rights reserved. 358582Skris * 458582Skris * Redistribution and use in source and binary forms, with or without 558582Skris * modification, are permitted provided that the following conditions 658582Skris * are met: 758582Skris * 1. Redistributions of source code must retain the above copyright 858582Skris * notice, this list of conditions and the following disclaimer. 958582Skris * 2. Redistributions in binary form must reproduce the above copyright 1058582Skris * notice, this list of conditions and the following disclaimer in the 1158582Skris * documentation and/or other materials provided with the distribution. 1258582Skris * 3. All advertising materials mentioning features or use of this software 1358582Skris * must display the following acknowledgement: 1458582Skris * This product includes software developed by Markus Friedl. 1558582Skris * 4. The name of the author may not be used to endorse or promote products 1658582Skris * derived from this software without specific prior written permission. 1758582Skris * 1858582Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1958582Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2058582Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2158582Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2258582Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2358582Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2458582Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2558582Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2658582Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2758582Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2858582Skris */ 2958582Skris/* 3058582Skris * read_bignum(): 3158582Skris * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3258582Skris */ 3358582Skris 3458582Skris#include "includes.h" 3558582Skris#include "ssh.h" 3658582Skris#include <ssl/rsa.h> 3758582Skris#include <ssl/dsa.h> 3858582Skris#include <ssl/evp.h> 3958582Skris#include "xmalloc.h" 4058582Skris#include "key.h" 4158582Skris 4258582SkrisKey * 4358582Skriskey_new(int type) 4458582Skris{ 4558582Skris Key *k; 4658582Skris RSA *rsa; 4758582Skris DSA *dsa; 4858582Skris k = xmalloc(sizeof(*k)); 4958582Skris k->type = type; 5058582Skris switch (k->type) { 5158582Skris case KEY_RSA: 5258582Skris rsa = RSA_new(); 5358582Skris rsa->n = BN_new(); 5458582Skris rsa->e = BN_new(); 5558582Skris k->rsa = rsa; 5658582Skris break; 5758582Skris case KEY_DSA: 5858582Skris dsa = DSA_new(); 5958582Skris dsa->p = BN_new(); 6058582Skris dsa->q = BN_new(); 6158582Skris dsa->g = BN_new(); 6258582Skris dsa->pub_key = BN_new(); 6358582Skris k->dsa = dsa; 6458582Skris break; 6558582Skris case KEY_EMPTY: 6658582Skris k->dsa = NULL; 6758582Skris k->rsa = NULL; 6858582Skris break; 6958582Skris default: 7058582Skris fatal("key_new: bad key type %d", k->type); 7158582Skris break; 7258582Skris } 7358582Skris return k; 7458582Skris} 7558582Skrisvoid 7658582Skriskey_free(Key *k) 7758582Skris{ 7858582Skris switch (k->type) { 7958582Skris case KEY_RSA: 8058582Skris if (k->rsa != NULL) 8158582Skris RSA_free(k->rsa); 8258582Skris k->rsa = NULL; 8358582Skris break; 8458582Skris case KEY_DSA: 8558582Skris if (k->dsa != NULL) 8658582Skris DSA_free(k->dsa); 8758582Skris k->dsa = NULL; 8858582Skris break; 8958582Skris default: 9058582Skris fatal("key_free: bad key type %d", k->type); 9158582Skris break; 9258582Skris } 9358582Skris xfree(k); 9458582Skris} 9558582Skrisint 9658582Skriskey_equal(Key *a, Key *b) 9758582Skris{ 9858582Skris if (a == NULL || b == NULL || a->type != b->type) 9958582Skris return 0; 10058582Skris switch (a->type) { 10158582Skris case KEY_RSA: 10258582Skris return a->rsa != NULL && b->rsa != NULL && 10358582Skris BN_cmp(a->rsa->e, b->rsa->e) == 0 && 10458582Skris BN_cmp(a->rsa->n, b->rsa->n) == 0; 10558582Skris break; 10658582Skris case KEY_DSA: 10758582Skris return a->dsa != NULL && b->dsa != NULL && 10858582Skris BN_cmp(a->dsa->p, b->dsa->p) == 0 && 10958582Skris BN_cmp(a->dsa->q, b->dsa->q) == 0 && 11058582Skris BN_cmp(a->dsa->g, b->dsa->g) == 0 && 11158582Skris BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 11258582Skris break; 11358582Skris default: 11458582Skris fatal("key_free: bad key type %d", a->type); 11558582Skris break; 11658582Skris } 11758582Skris return 0; 11858582Skris} 11958582Skris 12058582Skris#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" 12158582Skris 12258582Skris/* 12358582Skris * Generate key fingerprint in ascii format. 12458582Skris * Based on ideas and code from Bjoern Groenvall <bg@sics.se> 12558582Skris */ 12658582Skrischar * 12758582Skriskey_fingerprint(Key *k) 12858582Skris{ 12958582Skris static char retval[80]; 13058582Skris unsigned char *buf = NULL; 13158582Skris int len = 0; 13258582Skris int nlen, elen, plen, qlen, glen, publen; 13358582Skris 13458582Skris switch (k->type) { 13558582Skris case KEY_RSA: 13658582Skris nlen = BN_num_bytes(k->rsa->n); 13758582Skris elen = BN_num_bytes(k->rsa->e); 13858582Skris len = nlen + elen; 13958582Skris buf = xmalloc(len); 14058582Skris BN_bn2bin(k->rsa->n, buf); 14158582Skris BN_bn2bin(k->rsa->e, buf + nlen); 14258582Skris break; 14358582Skris case KEY_DSA: 14458582Skris plen = BN_num_bytes(k->dsa->p); 14558582Skris qlen = BN_num_bytes(k->dsa->q); 14658582Skris glen = BN_num_bytes(k->dsa->g); 14758582Skris publen = BN_num_bytes(k->dsa->pub_key); 14858582Skris len = qlen + qlen + glen + publen; 14958582Skris buf = xmalloc(len); 15058582Skris BN_bn2bin(k->dsa->p, buf); 15158582Skris BN_bn2bin(k->dsa->q, buf + plen); 15258582Skris BN_bn2bin(k->dsa->g, buf + plen + qlen); 15358582Skris BN_bn2bin(k->dsa->pub_key , buf + plen + qlen + glen); 15458582Skris break; 15558582Skris default: 15658582Skris fatal("key_fingerprint: bad key type %d", k->type); 15758582Skris break; 15858582Skris } 15958582Skris if (buf != NULL) { 16058582Skris unsigned char d[16]; 16158582Skris EVP_MD_CTX md; 16258582Skris EVP_DigestInit(&md, EVP_md5()); 16358582Skris EVP_DigestUpdate(&md, buf, len); 16458582Skris EVP_DigestFinal(&md, d, NULL); 16558582Skris snprintf(retval, sizeof(retval), FPRINT, 16658582Skris d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], 16758582Skris d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 16858582Skris memset(buf, 0, len); 16958582Skris xfree(buf); 17058582Skris } 17158582Skris return retval; 17258582Skris} 17358582Skris 17458582Skris/* 17558582Skris * Reads a multiple-precision integer in decimal from the buffer, and advances 17658582Skris * the pointer. The integer must already be initialized. This function is 17758582Skris * permitted to modify the buffer. This leaves *cpp to point just beyond the 17858582Skris * last processed (and maybe modified) character. Note that this may modify 17958582Skris * the buffer containing the number. 18058582Skris */ 18158582Skrisint 18258582Skrisread_bignum(char **cpp, BIGNUM * value) 18358582Skris{ 18458582Skris char *cp = *cpp; 18558582Skris int old; 18658582Skris 18758582Skris /* Skip any leading whitespace. */ 18858582Skris for (; *cp == ' ' || *cp == '\t'; cp++) 18958582Skris ; 19058582Skris 19158582Skris /* Check that it begins with a decimal digit. */ 19258582Skris if (*cp < '0' || *cp > '9') 19358582Skris return 0; 19458582Skris 19558582Skris /* Save starting position. */ 19658582Skris *cpp = cp; 19758582Skris 19858582Skris /* Move forward until all decimal digits skipped. */ 19958582Skris for (; *cp >= '0' && *cp <= '9'; cp++) 20058582Skris ; 20158582Skris 20258582Skris /* Save the old terminating character, and replace it by \0. */ 20358582Skris old = *cp; 20458582Skris *cp = 0; 20558582Skris 20658582Skris /* Parse the number. */ 20758582Skris if (BN_dec2bn(&value, *cpp) == 0) 20858582Skris return 0; 20958582Skris 21058582Skris /* Restore old terminating character. */ 21158582Skris *cp = old; 21258582Skris 21358582Skris /* Move beyond the number and return success. */ 21458582Skris *cpp = cp; 21558582Skris return 1; 21658582Skris} 21758582Skrisint 21858582Skriswrite_bignum(FILE *f, BIGNUM *num) 21958582Skris{ 22058582Skris char *buf = BN_bn2dec(num); 22158582Skris if (buf == NULL) { 22258582Skris error("write_bignum: BN_bn2dec() failed"); 22358582Skris return 0; 22458582Skris } 22558582Skris fprintf(f, " %s", buf); 22658582Skris free(buf); 22758582Skris return 1; 22858582Skris} 22958582Skrisint 23058582Skriskey_read(Key *ret, unsigned int bits, char **cpp) 23158582Skris{ 23258582Skris switch(ret->type) { 23358582Skris case KEY_RSA: 23458582Skris if (bits == 0) 23558582Skris return 0; 23658582Skris /* Get public exponent, public modulus. */ 23758582Skris if (!read_bignum(cpp, ret->rsa->e)) 23858582Skris return 0; 23958582Skris if (!read_bignum(cpp, ret->rsa->n)) 24058582Skris return 0; 24158582Skris break; 24258582Skris case KEY_DSA: 24358582Skris if (bits != 0) 24458582Skris return 0; 24558582Skris if (!read_bignum(cpp, ret->dsa->p)) 24658582Skris return 0; 24758582Skris if (!read_bignum(cpp, ret->dsa->q)) 24858582Skris return 0; 24958582Skris if (!read_bignum(cpp, ret->dsa->g)) 25058582Skris return 0; 25158582Skris if (!read_bignum(cpp, ret->dsa->pub_key)) 25258582Skris return 0; 25358582Skris break; 25458582Skris default: 25558582Skris fatal("bad key type: %d", ret->type); 25658582Skris break; 25758582Skris } 25858582Skris return 1; 25958582Skris} 26058582Skrisint 26158582Skriskey_write(Key *key, FILE *f) 26258582Skris{ 26358582Skris int success = 0; 26458582Skris unsigned int bits = 0; 26558582Skris 26658582Skris if (key->type == KEY_RSA && key->rsa != NULL) { 26758582Skris /* size of modulus 'n' */ 26858582Skris bits = BN_num_bits(key->rsa->n); 26958582Skris fprintf(f, "%u", bits); 27058582Skris if (write_bignum(f, key->rsa->e) && 27158582Skris write_bignum(f, key->rsa->n)) { 27258582Skris success = 1; 27358582Skris } else { 27458582Skris error("key_write: failed for RSA key"); 27558582Skris } 27658582Skris } else if (key->type == KEY_DSA && key->dsa != NULL) { 27758582Skris /* bits == 0 means DSA key */ 27858582Skris bits = 0; 27958582Skris fprintf(f, "%u", bits); 28058582Skris if (write_bignum(f, key->dsa->p) && 28158582Skris write_bignum(f, key->dsa->q) && 28258582Skris write_bignum(f, key->dsa->g) && 28358582Skris write_bignum(f, key->dsa->pub_key)) { 28458582Skris success = 1; 28558582Skris } else { 28658582Skris error("key_write: failed for DSA key"); 28758582Skris } 28858582Skris } 28958582Skris return success; 29058582Skris} 291