11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: key.c,v 1.97 2011/05/17 07:13:31 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * read_bignum(): 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose. Any derived versions of this 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell". 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h> 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/evp.h> 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openbsd-compat/openssl-compat.h> 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "rsa.h" 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "uuencode.h" 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h" 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic struct KeyCert * 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcert_new(void) 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct KeyCert *cert; 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert = xcalloc(1, sizeof(*cert)); 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&cert->certblob); 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&cert->critical); 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&cert->extensions); 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert->key_id = NULL; 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert->principals = NULL; 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert->signature_key = NULL; 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return cert; 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodKey * 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_new(int type) 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *k; 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood RSA *rsa; 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DSA *dsa; 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k = xcalloc(1, sizeof(*k)); 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = type; 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa = NULL; 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa_nid = -1; 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->dsa = NULL; 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->rsa = NULL; 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->cert = NULL; 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((rsa = RSA_new()) == NULL) 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: RSA_new failed"); 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((rsa->n = BN_new()) == NULL) 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: BN_new failed"); 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((rsa->e = BN_new()) == NULL) 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: BN_new failed"); 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->rsa = rsa; 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((dsa = DSA_new()) == NULL) 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: DSA_new failed"); 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((dsa->p = BN_new()) == NULL) 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: BN_new failed"); 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((dsa->q = BN_new()) == NULL) 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: BN_new failed"); 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((dsa->g = BN_new()) == NULL) 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: BN_new failed"); 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((dsa->pub_key = BN_new()) == NULL) 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: BN_new failed"); 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->dsa = dsa; 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Cannot do anything until we know the group */ 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_UNSPEC: 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new: bad key type %d", k->type); 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_is_cert(k)) 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->cert = cert_new(); 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return k; 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_add_private(Key *k) 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k->rsa->d = BN_new()) == NULL) 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new_private: BN_new failed"); 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k->rsa->iqmp = BN_new()) == NULL) 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new_private: BN_new failed"); 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k->rsa->q = BN_new()) == NULL) 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new_private: BN_new failed"); 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k->rsa->p = BN_new()) == NULL) 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new_private: BN_new failed"); 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k->rsa->dmq1 = BN_new()) == NULL) 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new_private: BN_new failed"); 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k->rsa->dmp1 = BN_new()) == NULL) 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new_private: BN_new failed"); 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((k->dsa->priv_key = BN_new()) == NULL) 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_new_private: BN_new failed"); 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Cannot do anything until we know the group */ 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_UNSPEC: 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodKey * 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_new_private(int type) 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *k = key_new(type); 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_add_private(k); 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return k; 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcert_free(struct KeyCert *cert) 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&cert->certblob); 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&cert->critical); 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&cert->extensions); 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cert->key_id != NULL) 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(cert->key_id); 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < cert->nprincipals; i++) 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(cert->principals[i]); 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cert->principals != NULL) 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(cert->principals); 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cert->signature_key != NULL) 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(cert->signature_key); 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_free(Key *k) 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k == NULL) 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_free: key is NULL"); 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->rsa != NULL) 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood RSA_free(k->rsa); 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->rsa = NULL; 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->dsa != NULL) 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DSA_free(k->dsa); 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->dsa = NULL; 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->ecdsa != NULL) 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_free(k->ecdsa); 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa = NULL; 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_UNSPEC: 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_free: bad key type %d", k->type); 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_is_cert(k)) { 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->cert != NULL) 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert_free(k->cert); 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->cert = NULL; 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(k); 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcert_compare(struct KeyCert *a, struct KeyCert *b) 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (a == NULL && b == NULL) 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (a == NULL || b == NULL) 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&a->certblob) != buffer_len(&b->certblob)) 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (timingsafe_bcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob), 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&a->certblob)) != 0) 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Compare public portions of key only, allowing comparisons between 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * certificates and plain keys too. 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_equal_public(const Key *a, const Key *b) 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX *bnctx; 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (a == NULL || b == NULL || 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_type_plain(a->type) != key_type_plain(b->type)) 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (a->type) { 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return a->rsa != NULL && b->rsa != NULL && 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_cmp(a->rsa->e, b->rsa->e) == 0 && 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_cmp(a->rsa->n, b->rsa->n) == 0; 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return a->dsa != NULL && b->dsa != NULL && 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_cmp(a->dsa->p, b->dsa->p) == 0 && 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_cmp(a->dsa->q, b->dsa->q) == 0 && 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_cmp(a->dsa->g, b->dsa->g) == 0 && 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (a->ecdsa == NULL || b->ecdsa == NULL || 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(a->ecdsa) == NULL || 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(b->ecdsa) == NULL) 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((bnctx = BN_CTX_new()) == NULL) 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_new failed", __func__); 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(a->ecdsa), 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_free(bnctx); 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_free(bnctx); 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* OPENSSL_HAS_ECC */ 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_equal: bad key type %d", a->type); 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* NOTREACHED */ 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_equal(const Key *a, const Key *b) 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (a == NULL || b == NULL || a->type != b->type) 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_is_cert(a)) { 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!cert_compare(a->cert, b->cert)) 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return key_equal_public(a, b); 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_char* 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const EVP_MD *md = NULL; 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EVP_MD_CTX ctx; 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *blob = NULL; 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *retval = NULL; 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len = 0; 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int nlen, elen, otype; 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *dgst_raw_length = 0; 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (dgst_type) { 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_FP_MD5: 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood md = EVP_md5(); 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_FP_SHA1: 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood md = EVP_sha1(); 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_fingerprint_raw: bad digest type %d", 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dgst_type); 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nlen = BN_num_bytes(k->rsa->n); 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood elen = BN_num_bytes(k->rsa->e); 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = nlen + elen; 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood blob = xmalloc(len); 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_bn2bin(k->rsa->n, blob); 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_bn2bin(k->rsa->e, blob + nlen); 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_to_blob(k, &blob, &len); 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* We want a fingerprint of the _key_ not of the cert */ 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood otype = k->type; 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = key_type_plain(k->type); 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_to_blob(k, &blob, &len); 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = otype; 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_UNSPEC: 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return retval; 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_fingerprint_raw: bad key type %d", k->type); 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (blob != NULL) { 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval = xmalloc(EVP_MAX_MD_SIZE); 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EVP_DigestInit(&ctx, md); 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EVP_DigestUpdate(&ctx, blob, len); 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EVP_DigestFinal(&ctx, retval, dgst_raw_length); 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(blob, 0, len); 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_fingerprint_raw: blob is null"); 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return retval; 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *retval; 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval = xcalloc(1, dgst_raw_len * 3 + 1); 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < dgst_raw_len; i++) { 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char hex[4]; 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(retval, hex, dgst_raw_len * 3 + 1); 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Remove the trailing ':' character */ 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[(dgst_raw_len * 3) - 1] = '\0'; 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return retval; 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' }; 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, j = 0, rounds, seed = 1; 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *retval; 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rounds = (dgst_raw_len / 2) + 1; 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval = xcalloc((rounds * 6), sizeof(char)); 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = 'x'; 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < rounds; i++) { 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int idx0, idx1, idx2, idx3, idx4; 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) { 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) + 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood seed) % 6; 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15; 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) + 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (seed / 6)) % 6; 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = vowels[idx0]; 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = consonants[idx1]; 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = vowels[idx2]; 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((i + 1) < rounds) { 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15; 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15; 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = consonants[idx3]; 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = '-'; 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = consonants[idx4]; 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood seed = ((seed * 5) + 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ((((u_int)(dgst_raw[2 * i])) * 7) + 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ((u_int)(dgst_raw[(2 * i) + 1])))) % 36; 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx0 = seed % 6; 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx1 = 16; 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood idx2 = seed / 6; 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = vowels[idx0]; 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = consonants[idx1]; 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = vowels[idx2]; 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = 'x'; 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval[j++] = '\0'; 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return retval; 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Draw an ASCII-Art representing the fingerprint so human brain can 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * profit from its built-in pattern recognition ability. 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This technique is called "random art" and can be found in some 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * scientific publications like this original paper: 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * "Hash Visualization: a New Technique to improve Real-World Security", 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Perrig A. and Song D., 1999, International Workshop on Cryptographic 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Techniques and E-Commerce (CrypTEC '99) 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The subject came up in a talk by Dan Kaminsky, too. 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If you see the picture is different, the key is different. 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If the picture looks the same, you still know nothing. 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The algorithm used here is a worm crawling over a discrete plane, 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * leaving a trace (augmenting the field) everywhere it goes. 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Movement is taken from dgst_raw 2bit-wise. Bumping into walls 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * makes the respective movement vector be ignored for this turn. 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Graphs are not unambiguous, because circles in graphs can be 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * walked in either direction. 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Field sizes for the random art. Have to be odd, so the starting point 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be in the exact middle of the picture, and FLDBASE should be >=8 . 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Else pictures would be too dense, and drawing the frame would 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * fail, too, because the key type would not fit in anymore. 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define FLDBASE 8 4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define FLDSIZE_Y (FLDBASE + 1) 4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define FLDSIZE_X (FLDBASE * 2 + 1) 4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) 4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Chars to be used after each other every time the worm 4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * intersects with itself. Matter of taste. 4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *augmentation_string = " .o+=*BOX@%&#/^SE"; 4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *retval, *p; 5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char field[FLDSIZE_X][FLDSIZE_Y]; 5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, b; 5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int x, y; 5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t len = strlen(augmentation_string) - 1; 5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); 5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* initialize field */ 5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); 5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x = FLDSIZE_X / 2; 5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood y = FLDSIZE_Y / 2; 5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* process raw key */ 5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < dgst_raw_len; i++) { 5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int input; 5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* each byte conveys four 2-bit move commands */ 5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input = dgst_raw[i]; 5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (b = 0; b < 4; b++) { 5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* evaluate 2 bit, rest is shifted later */ 5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x += (input & 0x1) ? 1 : -1; 5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood y += (input & 0x2) ? 1 : -1; 5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* assure we are still in bounds */ 5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x = MAX(x, 0); 5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood y = MAX(y, 0); 5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x = MIN(x, FLDSIZE_X - 1); 5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood y = MIN(y, FLDSIZE_Y - 1); 5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* augment the field */ 5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (field[x][y] < len - 2) 5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood field[x][y]++; 5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input = input >> 2; 5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* mark starting point and end point*/ 5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; 5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood field[x][y] = len; 5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* fill in retval */ 5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k)); 5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = strchr(retval, '\0'); 5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* output upper border */ 5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = p - retval - 1; i < FLDSIZE_X; i++) 5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '-'; 5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '+'; 5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '\n'; 5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* output content */ 5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (y = 0; y < FLDSIZE_Y; y++) { 5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '|'; 5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (x = 0; x < FLDSIZE_X; x++) 5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = augmentation_string[MIN(field[x][y], len)]; 5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '|'; 5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '\n'; 5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* output lower border */ 5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '+'; 5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < FLDSIZE_X; i++) 5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '-'; 5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *p++ = '+'; 5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return retval; 5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) 5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *retval = NULL; 5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *dgst_raw; 5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int dgst_raw_len; 5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); 5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!dgst_raw) 5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_fingerprint: null from key_fingerprint_raw()"); 5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (dgst_rep) { 5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_FP_HEX: 5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); 5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_FP_BUBBLEBABBLE: 5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); 5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_FP_RANDOMART: 5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k); 5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_fingerprint: bad digest representation %d", 5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dgst_rep); 5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(dgst_raw, 0, dgst_raw_len); 5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(dgst_raw); 5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return retval; 5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Reads a multiple-precision integer in decimal from the buffer, and advances 5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the pointer. The integer must already be initialized. This function is 6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * permitted to modify the buffer. This leaves *cpp to point just beyond the 6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * last processed (and maybe modified) character. Note that this may modify 6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the buffer containing the number. 6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodread_bignum(char **cpp, BIGNUM * value) 6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp = *cpp; 6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int old; 6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Skip any leading whitespace. */ 6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (; *cp == ' ' || *cp == '\t'; cp++) 6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Check that it begins with a decimal digit. */ 6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp < '0' || *cp > '9') 6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Save starting position. */ 6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cpp = cp; 6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Move forward until all decimal digits skipped. */ 6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (; *cp >= '0' && *cp <= '9'; cp++) 6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Save the old terminating character, and replace it by \0. */ 6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood old = *cp; 6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cp = 0; 6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Parse the number. */ 6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_dec2bn(&value, *cpp) == 0) 6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Restore old terminating character. */ 6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cp = old; 6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Move beyond the number and return success. */ 6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cpp = cp; 6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodwrite_bignum(FILE *f, BIGNUM *num) 6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *buf = BN_bn2dec(num); 6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buf == NULL) { 6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("write_bignum: BN_bn2dec() failed"); 6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, " %s", buf); 6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood OPENSSL_free(buf); 6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* returns 1 ok, -1 error */ 6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_read(Key *ret, char **cpp) 6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *k; 6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success = -1; 6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp, *space; 6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int len, n, type; 6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int bits; 6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *blob; 6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int curve_nid = -1; 6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = *cpp; 6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (ret->type) { 6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Get number of bits. */ 6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp < '0' || *cp > '9') 6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; /* Bad bit count... */ 6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bits = 10 * bits + *cp - '0'; 6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bits == 0) 6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cpp = cp; 6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Get public exponent, public modulus. */ 6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!read_bignum(cpp, ret->rsa->e)) 6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!read_bignum(cpp, ret->rsa->n)) 6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* validate the claimed number of bits */ 6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((u_int)BN_num_bits(ret->rsa->n) != bits) { 6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood verbose("key_read: claimed key size %d does not match " 6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "actual %d", bits, BN_num_bits(ret->rsa->n)); 6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_UNSPEC: 6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood space = strchr(cp, ' '); 7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (space == NULL) { 7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("key_read: missing whitespace"); 7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *space = '\0'; 7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood type = key_type_from_name(cp); 7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_type_plain(type) == KEY_ECDSA && 7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) { 7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("key_read: invalid curve"); 7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *space = ' '; 7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (type == KEY_UNSPEC) { 7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("key_read: missing keytype"); 7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = space+1; 7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp == '\0') { 7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("key_read: short string"); 7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret->type == KEY_UNSPEC) { 7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->type = type; 7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (ret->type != type) { 7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* is a key, but different type */ 7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("key_read: type mismatch"); 7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = 2*strlen(cp); 7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood blob = xmalloc(len); 7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood n = uudecode(cp, blob, len); 7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (n < 0) { 7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_read: uudecode %s failed", cp); 7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k = key_from_blob(blob, (u_int)n); 7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k == NULL) { 7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_read: key_from_blob %s failed", cp); 7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->type != type) { 7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_read: type mismatch: encoding error"); 7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(k); 7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_type_plain(type) == KEY_ECDSA && 7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood curve_nid != k->ecdsa_nid) { 7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_read: type mismatch: EC curve mismatch"); 7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(k); 7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*XXXX*/ 7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_is_cert(ret)) { 7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!key_is_cert(k)) { 7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_read: loaded key is not a cert"); 7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(k); 7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret->cert != NULL) 7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert_free(ret->cert); 7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->cert = k->cert; 7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->cert = NULL; 7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_type_plain(ret->type) == KEY_RSA) { 7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret->rsa != NULL) 7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood RSA_free(ret->rsa); 7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->rsa = k->rsa; 7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->rsa = NULL; 7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood RSA_print_fp(stderr, ret->rsa, 8); 7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_type_plain(ret->type) == KEY_DSA) { 7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret->dsa != NULL) 7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DSA_free(ret->dsa); 7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->dsa = k->dsa; 7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->dsa = NULL; 7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DSA_print_fp(stderr, ret->dsa, 8); 7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_type_plain(ret->type) == KEY_ECDSA) { 7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret->ecdsa != NULL) 7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_free(ret->ecdsa); 7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->ecdsa = k->ecdsa; 7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->ecdsa_nid = k->ecdsa_nid; 7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa = NULL; 7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa_nid = -1; 7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_dump_ec_key(ret->ecdsa); 8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*XXXX*/ 8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(k); 8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (success != 1) 8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* advance cp: skip whitespace and data */ 8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (*cp == ' ' || *cp == '\t') 8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp++; 8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (*cp != '\0' && *cp != ' ' && *cp != '\t') 8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp++; 8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cpp = cp; 8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_read: bad key type: %d", ret->type); 8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return success; 8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_write(const Key *key, FILE *f) 8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int n, success = 0; 8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len, bits = 0; 8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *blob; 8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *uu; 8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_is_cert(key)) { 8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->cert == NULL) { 8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: no cert data", __func__); 8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&key->cert->certblob) == 0) { 8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: no signed certificate blob", __func__); 8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (key->type) { 8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->rsa == NULL) 8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* size of modulus 'n' */ 8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bits = BN_num_bits(key->rsa->n); 8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, "%u", bits); 8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (write_bignum(f, key->rsa->e) && 8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood write_bignum(f, key->rsa->n)) 8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_write: failed for RSA key"); 8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->dsa == NULL) 8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->ecdsa == NULL) 8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->rsa == NULL) 8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_to_blob(key, &blob, &len); 8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood uu = xmalloc(2*len); 8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood n = uuencode(blob, len, uu, 2*len); 8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (n > 0) { 8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, "%s %s", key_ssh_name(key), uu); 8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(uu); 8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return success; 8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst char * 8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_type(const Key *k) 8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "RSA1"; 8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "RSA"; 8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "DSA"; 8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ECDSA"; 9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "RSA-CERT-V00"; 9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "DSA-CERT-V00"; 9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "RSA-CERT"; 9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "DSA-CERT"; 9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ECDSA-CERT"; 9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "unknown"; 9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst char * 9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_cert_type(const Key *k) 9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->cert->type) { 9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_CERT_TYPE_USER: 9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "user"; 9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH2_CERT_TYPE_HOST: 9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "host"; 9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "unknown"; 9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic const char * 9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ssh_name_from_type_nid(int type, int nid) 9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (type) { 9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ssh-rsa"; 9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ssh-dss"; 9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ssh-rsa-cert-v00@openssh.com"; 9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ssh-dss-cert-v00@openssh.com"; 9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ssh-rsa-cert-v01@openssh.com"; 9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ssh-dss-cert-v01@openssh.com"; 9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (nid) { 9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_X9_62_prime256v1: 9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ecdsa-sha2-nistp256"; 9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_secp384r1: 9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ecdsa-sha2-nistp384"; 9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_secp521r1: 9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ecdsa-sha2-nistp521"; 9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (nid) { 9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_X9_62_prime256v1: 9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ecdsa-sha2-nistp256-cert-v01@openssh.com"; 9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_secp384r1: 9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ecdsa-sha2-nistp384-cert-v01@openssh.com"; 9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_secp521r1: 9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ecdsa-sha2-nistp521-cert-v01@openssh.com"; 9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* OPENSSL_HAS_ECC */ 9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "ssh-unknown"; 9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst char * 9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ssh_name(const Key *k) 9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return key_ssh_name_from_type_nid(k->type, k->ecdsa_nid); 9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst char * 9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ssh_name_plain(const Key *k) 9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return key_ssh_name_from_type_nid(key_type_plain(k->type), 9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa_nid); 9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int 9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_size(const Key *k) 9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return BN_num_bits(k->rsa->n); 10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return BN_num_bits(k->dsa->p); 10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return key_curve_nid_to_bits(k->ecdsa_nid); 10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic RSA * 10141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodrsa_generate_private_key(u_int bits) 10151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood RSA *private = RSA_new(); 10171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *f4 = BN_new(); 10181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (private == NULL) 10201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: RSA_new failed", __func__); 10211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (f4 == NULL) 10221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_new failed", __func__); 10231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!BN_set_word(f4, RSA_F4)) 10241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_new failed", __func__); 10251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!RSA_generate_key_ex(private, bits, f4, NULL)) 10261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: key generation failed.", __func__); 10271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_free(f4); 10281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return private; 10291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic DSA* 10321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddsa_generate_private_key(u_int bits) 10331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DSA *private = DSA_new(); 10351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (private == NULL) 10371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: DSA_new failed", __func__); 10381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, 10391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL, NULL)) 10401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: DSA_generate_parameters failed", __func__); 10411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!DSA_generate_key(private)) 10421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: DSA_generate_key failed.", __func__); 10431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return private; 10441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 10471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ecdsa_bits_to_nid(int bits) 10481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (bits) { 10501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 10511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 256: 10521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_X9_62_prime256v1; 10531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 384: 10541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_secp384r1; 10551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 521: 10561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_secp521r1; 10571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 10581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 10591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 10601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 10641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 10651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ecdsa_key_to_nid(EC_KEY *k) 10661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_GROUP *eg; 10681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int nids[] = { 10691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NID_X9_62_prime256v1, 10701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NID_secp384r1, 10711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NID_secp521r1, 10721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood -1 10731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood }; 10741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int nid; 10751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 10761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX *bnctx; 10771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const EC_GROUP *g = EC_KEY_get0_group(k); 10781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 10801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The group may be stored in a ASN.1 encoded private key in one of two 10811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ways: as a "named group", which is reconstituted by ASN.1 object ID 10821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * or explicit group parameters encoded into the key blob. Only the 10831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * "named group" case sets the group NID for us, but we can figure 10841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * it out for the other case by comparing against all the groups that 10851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are supported. 10861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 10871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((nid = EC_GROUP_get_curve_name(g)) > 0) 10881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return nid; 10891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((bnctx = BN_CTX_new()) == NULL) 10901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_new() failed", __func__); 10911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; nids[i] != -1; i++) { 10921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) 10931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_GROUP_new_by_curve_name failed", 10941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 10951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_GROUP_cmp(g, eg, bnctx) == 0) 10961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 10971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_GROUP_free(eg); 10981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_free(bnctx); 11001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: nid = %d", __func__, nids[i]); 11011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (nids[i] != -1) { 11021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Use the group with the NID attached */ 11031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); 11041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_set_group(k, eg) != 1) 11051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_set_group", __func__); 11061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return nids[i]; 11081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic EC_KEY* 11111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodecdsa_generate_private_key(u_int bits, int *nid) 11121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY *private; 11141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1) 11161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: invalid key length", __func__); 11171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) 11181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_new_by_curve_name failed", __func__); 11191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_generate_key(private) != 1) 11201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_generate_key failed", __func__); 11211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); 11221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return private; 11231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* OPENSSL_HAS_ECC */ 11251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11261305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodKey * 11271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_generate(int type, u_int bits) 11281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *k = key_new(KEY_UNSPEC); 11301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (type) { 11311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 11321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->dsa = dsa_generate_private_key(bits); 11331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 11351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 11361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid); 11371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 11391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 11401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 11411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->rsa = rsa_generate_private_key(bits); 11421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 11441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 11451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 11461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 11471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_generate: cert keys cannot be generated directly"); 11481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 11491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_generate: unknown type %d", type); 11501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = type; 11521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return k; 11531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 11561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_cert_copy(const Key *from_key, struct Key *to_key) 11571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 11591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const struct KeyCert *from; 11601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct KeyCert *to; 11611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (to_key->cert != NULL) { 11631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert_free(to_key->cert); 11641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to_key->cert = NULL; 11651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((from = from_key->cert) == NULL) 11681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 11691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to = to_key->cert = cert_new(); 11711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&to->certblob, buffer_ptr(&from->certblob), 11731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&from->certblob)); 11741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&to->critical, 11761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&from->critical), buffer_len(&from->critical)); 11771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&to->extensions, 11781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&from->extensions), buffer_len(&from->extensions)); 11791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->serial = from->serial; 11811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->type = from->type; 11821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id); 11831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->valid_after = from->valid_after; 11841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->valid_before = from->valid_before; 11851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->signature_key = from->signature_key == NULL ? 11861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL : key_from_private(from->signature_key); 11871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->nprincipals = from->nprincipals; 11891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (to->nprincipals > CERT_MAX_PRINCIPALS) 11901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)", 11911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, to->nprincipals, CERT_MAX_PRINCIPALS); 11921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (to->nprincipals > 0) { 11931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->principals = xcalloc(from->nprincipals, 11941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sizeof(*to->principals)); 11951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < to->nprincipals; i++) 11961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood to->principals[i] = xstrdup(from->principals[i]); 11971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12001305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodKey * 12011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_from_private(const Key *k) 12021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 12031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *n = NULL; 12041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 12051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 12061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 12071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 12081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood n = key_new(k->type); 12091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || 12101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (BN_copy(n->dsa->q, k->dsa->q) == NULL) || 12111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (BN_copy(n->dsa->g, k->dsa->g) == NULL) || 12121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) 12131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_from_private: BN_copy failed"); 12141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 12151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 12161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 12171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 12181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood n = key_new(k->type); 12191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood n->ecdsa_nid = k->ecdsa_nid; 12201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) 12211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_new_by_curve_name failed", __func__); 12221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_set_public_key(n->ecdsa, 12231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(k->ecdsa)) != 1) 12241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_set_public_key failed", __func__); 12251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 12261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 12271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 12281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 12291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 12301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 12311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood n = key_new(k->type); 12321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || 12331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (BN_copy(n->rsa->e, k->rsa->e) == NULL)) 12341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_from_private: BN_copy failed"); 12351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 12361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 12371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_from_private: unknown type %d", k->type); 12381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 12391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_is_cert(k)) 12411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_cert_copy(k, n); 12421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return n; 12431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 12441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 12461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_type_from_name(char *name) 12471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 12481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(name, "rsa1") == 0) { 12491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_RSA1; 12501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "rsa") == 0) { 12511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_RSA; 12521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "dsa") == 0) { 12531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_DSA; 12541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "ssh-rsa") == 0) { 12551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_RSA; 12561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "ssh-dss") == 0) { 12571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_DSA; 12581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 12591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "ecdsa") == 0 || 12601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(name, "ecdsa-sha2-nistp256") == 0 || 12611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(name, "ecdsa-sha2-nistp384") == 0 || 12621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(name, "ecdsa-sha2-nistp521") == 0) { 12631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_ECDSA; 12641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 12651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { 12661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_RSA_CERT_V00; 12671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { 12681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_DSA_CERT_V00; 12691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "ssh-rsa-cert-v01@openssh.com") == 0) { 12701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_RSA_CERT; 12711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) { 12721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_DSA_CERT; 12731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 12741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0 || 12751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0 || 12761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) { 12771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_ECDSA_CERT; 12781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 12791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("key_type_from_name: unknown key type '%s'", name); 12821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_UNSPEC; 12831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 12841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 12861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ecdsa_nid_from_name(const char *name) 12871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 12881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 12891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(name, "ecdsa-sha2-nistp256") == 0 || 12901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0) 12911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_X9_62_prime256v1; 12921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(name, "ecdsa-sha2-nistp384") == 0 || 12931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0) 12941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_secp384r1; 12951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(name, "ecdsa-sha2-nistp521") == 0 || 12961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) 12971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_secp521r1; 12981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* OPENSSL_HAS_ECC */ 12991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name); 13011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 13021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 13051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_names_valid2(const char *names) 13061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *s, *cp, *p; 13081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (names == NULL || strcmp(names, "") == 0) 13101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 13111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s = cp = xstrdup(names); 13121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for ((p = strsep(&cp, ",")); p && *p != '\0'; 13131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (p = strsep(&cp, ","))) { 13141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (key_type_from_name(p)) { 13151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 13161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_UNSPEC: 13171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s); 13181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 13191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("key names ok: [%s]", names); 13221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s); 13231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 13241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 13271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) 13281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *principals, *critical, *exts, *sig_key, *sig; 13301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int signed_len, plen, clen, sklen, slen, kidlen, elen; 13311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer tmp; 13321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *principal; 13331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret = -1; 13341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int v00 = key->type == KEY_DSA_CERT_V00 || 13351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->type == KEY_RSA_CERT_V00; 13361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&tmp); 13381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Copy the entire key blob for verification and later serialisation */ 13401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&key->cert->certblob, blob, blen); 13411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood elen = 0; /* Not touched for v00 certs */ 13431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood principals = exts = critical = sig_key = sig = NULL; 13441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) || 13451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_int_ret(&key->cert->type, b) != 0 || 13461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL || 13471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (principals = buffer_get_string_ret(b, &plen)) == NULL || 13481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || 13491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || 13501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (critical = buffer_get_string_ret(b, &clen)) == NULL || 13511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) || 13521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */ 13531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */ 13541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) { 13551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: parse error", __func__); 13561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 13571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kidlen != strlen(key->cert->key_id)) { 13601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: key ID contains \\0 character", __func__); 13611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 13621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Signature is left in the buffer so we can calculate this length */ 13651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); 13661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((sig = buffer_get_string_ret(b, &slen)) == NULL) { 13681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: parse error", __func__); 13691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 13701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->cert->type != SSH2_CERT_TYPE_USER && 13731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->cert->type != SSH2_CERT_TYPE_HOST) { 13741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Unknown certificate type %u", key->cert->type); 13751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 13761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&tmp, principals, plen); 13791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (buffer_len(&tmp) > 0) { 13801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { 13811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: Too many principals", __func__); 13821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 13831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) { 13851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: Principals data invalid", __func__); 13861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 13871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->cert->principals = xrealloc(key->cert->principals, 13891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->cert->nprincipals + 1, sizeof(*key->cert->principals)); 13901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->cert->principals[key->cert->nprincipals++] = principal; 13911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&tmp); 13941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&key->cert->critical, critical, clen); 13961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&tmp, critical, clen); 13971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* validate structure */ 13981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (buffer_len(&tmp) != 0) { 13991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || 14001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { 14011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: critical option data invalid", __func__); 14021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 14031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&tmp); 14061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&key->cert->extensions, exts, elen); 14081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&tmp, exts, elen); 14091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* validate structure */ 14101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (buffer_len(&tmp) != 0) { 14111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || 14121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { 14131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: extension data invalid", __func__); 14141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 14151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&tmp); 14181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((key->cert->signature_key = key_from_blob(sig_key, 14201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sklen)) == NULL) { 14211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: Signature key invalid", __func__); 14221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 14231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->cert->signature_key->type != KEY_RSA && 14251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->cert->signature_key->type != KEY_DSA && 14261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->cert->signature_key->type != KEY_ECDSA) { 14271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: Invalid signature key type %s (%d)", __func__, 14281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_type(key->cert->signature_key), 14291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->cert->signature_key->type); 14301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 14311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (key_verify(key->cert->signature_key, sig, slen, 14341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&key->cert->certblob), signed_len)) { 14351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 1: 14361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = 0; 14371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; /* Good signature */ 14381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 0: 14391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: Invalid signature on certificate", __func__); 14401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 14411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case -1: 14421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: Certificate signature verification failed", 14431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 14441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 14451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood out: 14481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&tmp); 14491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (principals != NULL) 14501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(principals); 14511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (critical != NULL) 14521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(critical); 14531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (exts != NULL) 14541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(exts); 14551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sig_key != NULL) 14561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(sig_key); 14571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sig != NULL) 14581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(sig); 14591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 14601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 14611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14621305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodKey * 14631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_from_blob(const u_char *blob, u_int blen) 14641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 14651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer b; 14661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int rlen, type; 14671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *ktype = NULL, *curve = NULL; 14681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key = NULL; 14691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 14701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT *q = NULL; 14711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int nid = -1; 14721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 14731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 14751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dump_base64(stderr, blob, blen); 14761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 14771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&b); 14781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&b, blob, blen); 14791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) { 14801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: can't read key type"); 14811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 14821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood type = key_type_from_name(ktype); 14851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 14861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_type_plain(type) == KEY_ECDSA) 14871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nid = key_ecdsa_nid_from_name(ktype); 14881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 14891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (type) { 14911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 14921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ 14931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* FALLTHROUGH */ 14941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 14951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 14961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_new(type); 14971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || 14981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { 14991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: can't read rsa key"); 15001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood badkey: 15011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(key); 15021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = NULL; 15031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 15041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 15061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood RSA_print_fp(stderr, key->rsa, 8); 15071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 15091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 15101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ 15111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* FALLTHROUGH */ 15121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 15131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 15141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_new(type); 15151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || 15161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || 15171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || 15181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { 15191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: can't read dsa key"); 15201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto badkey; 15211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 15231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DSA_print_fp(stderr, key->dsa, 8); 15241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 15261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 15271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 15281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ 15291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* FALLTHROUGH */ 15301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 15311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_new(type); 15321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->ecdsa_nid = nid; 15331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) { 15341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: can't read ecdsa curve"); 15351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto badkey; 15361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->ecdsa_nid != key_curve_name_to_nid(curve)) { 15381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: ecdsa curve doesn't match type"); 15391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto badkey; 15401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->ecdsa != NULL) 15421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_free(key->ecdsa); 15431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) 15441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood == NULL) 15451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_from_blob: EC_KEY_new_by_curve_name failed"); 15461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) 15471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_from_blob: EC_POINT_new failed"); 15481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa), 15491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood q) == -1) { 15501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: can't read ecdsa key point"); 15511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto badkey; 15521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa), 15541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood q) != 0) 15551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto badkey; 15561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_set_public_key(key->ecdsa, q) != 1) 15571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_from_blob: EC_KEY_set_public_key failed"); 15581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 15591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); 15601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 15621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* OPENSSL_HAS_ECC */ 15631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_UNSPEC: 15641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = key_new(type); 15651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 15661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 15671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: cannot handle type %s", ktype); 15681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 15691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) { 15711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: can't parse cert data"); 15721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto badkey; 15731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rlen = buffer_len(&b); 15751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key != NULL && rlen != 0) 15761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_from_blob: remaining bytes in key blob %d", rlen); 15771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood out: 15781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ktype != NULL) 15791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(ktype); 15801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (curve != NULL) 15811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(curve); 15821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 15831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (q != NULL) 15841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT_free(q); 15851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 15871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return key; 15881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 15891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 15911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_to_blob(const Key *key, u_char **blobp, u_int *lenp) 15921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 15931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer b; 15941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int len; 15951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key == NULL) { 15971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_to_blob: key == NULL"); 15981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 15991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&b); 16011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (key->type) { 16021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 16031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 16041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 16051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 16061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 16071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Use the existing blob */ 16081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&b, buffer_ptr(&key->cert->certblob), 16091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&key->cert->certblob)); 16101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 16111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 16121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, key_ssh_name(key)); 16131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&b, key->dsa->p); 16141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&b, key->dsa->q); 16151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&b, key->dsa->g); 16161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&b, key->dsa->pub_key); 16171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 16181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 16191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 16201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, key_ssh_name(key)); 16211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid)); 16221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa), 16231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(key->ecdsa)); 16241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 16251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 16261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 16271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, key_ssh_name(key)); 16281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&b, key->rsa->e); 16291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&b, key->rsa->n); 16301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 16311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 16321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_to_blob: unsupported key type %d", key->type); 16331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 16341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 16351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = buffer_len(&b); 16371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (lenp != NULL) 16381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *lenp = len; 16391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (blobp != NULL) { 16401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *blobp = xmalloc(len); 16411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(*blobp, buffer_ptr(&b), len); 16421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(buffer_ptr(&b), 0, len); 16441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 16451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return len; 16461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 16471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 16491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_sign( 16501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const Key *key, 16511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char **sigp, u_int *lenp, 16521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const u_char *data, u_int datalen) 16531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 16541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (key->type) { 16551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 16561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 16571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 16581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ssh_dss_sign(key, sigp, lenp, data, datalen); 16591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 16601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 16611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 16621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ssh_ecdsa_sign(key, sigp, lenp, data, datalen); 16631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 16641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 16651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 16661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 16671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ssh_rsa_sign(key, sigp, lenp, data, datalen); 16681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 16691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_sign: invalid key type %d", key->type); 16701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 16711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 16731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 16751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * key_verify returns 1 for a correct signature, 0 for an incorrect signature 16761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and -1 on error. 16771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 16791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_verify( 16801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const Key *key, 16811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const u_char *signature, u_int signaturelen, 16821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const u_char *data, u_int datalen) 16831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 16841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signaturelen == 0) 16851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 16861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (key->type) { 16881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 16891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 16901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 16911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ssh_dss_verify(key, signature, signaturelen, data, datalen); 16921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 16931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 16941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 16951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen); 16961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 16971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 16981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 16991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 17001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ssh_rsa_verify(key, signature, signaturelen, data, datalen); 17011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 17021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_verify: invalid key type %d", key->type); 17031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 17041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 17061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Converts a private to a public key */ 17081305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodKey * 17091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_demote(const Key *k) 17101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 17111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *pk; 17121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pk = xcalloc(1, sizeof(*pk)); 17141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pk->type = k->type; 17151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pk->flags = k->flags; 17161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pk->ecdsa_nid = k->ecdsa_nid; 17171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pk->dsa = NULL; 17181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pk->ecdsa = NULL; 17191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pk->rsa = NULL; 17201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 17221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 17231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 17241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_cert_copy(k, pk); 17251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* FALLTHROUGH */ 17261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA1: 17271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 17281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->rsa = RSA_new()) == NULL) 17291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: RSA_new failed"); 17301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL) 17311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: BN_dup failed"); 17321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) 17331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: BN_dup failed"); 17341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 17351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 17361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 17371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_cert_copy(k, pk); 17381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* FALLTHROUGH */ 17391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 17401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->dsa = DSA_new()) == NULL) 17411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: DSA_new failed"); 17421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL) 17431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: BN_dup failed"); 17441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL) 17451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: BN_dup failed"); 17461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL) 17471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: BN_dup failed"); 17481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) 17491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: BN_dup failed"); 17501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 17511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 17521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 17531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_cert_copy(k, pk); 17541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* FALLTHROUGH */ 17551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 17561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL) 17571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: EC_KEY_new_by_curve_name failed"); 17581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_set_public_key(pk->ecdsa, 17591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(k->ecdsa)) != 1) 17601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_demote: EC_KEY_set_public_key failed"); 17611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 17621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 17631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 17641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_free: bad key type %d", k->type); 17651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 17661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (pk); 17691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 17701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 17721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_is_cert(const Key *k) 17731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 17741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k == NULL) 17751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 17761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 17771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 17781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 17791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 17801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 17811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 17821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 17831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 17841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 17851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 17871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Return the cert-less equivalent to a certified key type */ 17891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 17901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_type_plain(int type) 17911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 17921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (type) { 17931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 17941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 17951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_RSA; 17961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 17971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 17981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_DSA; 17991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 18001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return KEY_ECDSA; 18011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 18021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return type; 18031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */ 18071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 18081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_to_certified(Key *k, int legacy) 18091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 18111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA: 18121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->cert = cert_new(); 18131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT; 18141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA: 18161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->cert = cert_new(); 18171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT; 18181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA: 18201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (legacy) 18211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: legacy ECDSA certificates are not supported", 18221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 18231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->cert = cert_new(); 18241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = KEY_ECDSA_CERT; 18251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 18271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: key has incorrect type %s", __func__, key_type(k)); 18281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 18291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Convert a KEY_RSA_CERT or KEY_DSA_CERT to their raw key equivalent */ 18331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 18341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_drop_cert(Key *k) 18351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 18371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 18381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 18391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert_free(k->cert); 18401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = KEY_RSA; 18411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 18431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 18441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert_free(k->cert); 18451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = KEY_DSA; 18461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 18481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cert_free(k->cert); 18491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->type = KEY_ECDSA; 18501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 18521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: key has incorrect type %s", __func__, key_type(k)); 18531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 18541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 18581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Sign a KEY_RSA_CERT, KEY_DSA_CERT or KEY_ECDSA_CERT, (re-)generating 18591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the signed certblob 18601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 18611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 18621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_certify(Key *k, Key *ca) 18631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer principals; 18651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *ca_blob, *sig_blob, nonce[32]; 18661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, ca_len, sig_len; 18671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->cert == NULL) { 18691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: key lacks cert info", __func__); 18701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 18711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!key_is_cert(k)) { 18741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: certificate has unknown type %d", __func__, 18751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k->cert->type); 18761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 18771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ca->type != KEY_RSA && ca->type != KEY_DSA && 18801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ca->type != KEY_ECDSA) { 18811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: CA key has unsupported type %s", __func__, 18821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_type(ca)); 18831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 18841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_to_blob(ca, &ca_blob, &ca_len); 18871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&k->cert->certblob); 18891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); 18901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* -v01 certs put nonce first */ 18921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood arc4random_buf(&nonce, sizeof(nonce)); 18931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!key_cert_is_legacy(k)) 18941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); 18951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 18971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 18981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT: 18991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&k->cert->certblob, k->dsa->p); 19001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&k->cert->certblob, k->dsa->q); 19011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&k->cert->certblob, k->dsa->g); 19021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); 19031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 19041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 19051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_ECDSA_CERT: 19061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&k->cert->certblob, 19071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_curve_nid_to_name(k->ecdsa_nid)); 19081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_ecpoint(&k->cert->certblob, 19091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_group(k->ecdsa), 19101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(k->ecdsa)); 19111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 19121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 19131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 19141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT: 19151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&k->cert->certblob, k->rsa->e); 19161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_bignum2(&k->cert->certblob, k->rsa->n); 19171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 19181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 19191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: key has incorrect type %s", __func__, key_type(k)); 19201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&k->cert->certblob); 19211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(ca_blob); 19221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 19231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* -v01 certs have a serial number next */ 19261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!key_cert_is_legacy(k)) 19271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int64(&k->cert->certblob, k->cert->serial); 19281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&k->cert->certblob, k->cert->type); 19301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&k->cert->certblob, k->cert->key_id); 19311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&principals); 19331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < k->cert->nprincipals; i++) 19341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&principals, k->cert->principals[i]); 19351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&k->cert->certblob, buffer_ptr(&principals), 19361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&principals)); 19371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&principals); 19381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int64(&k->cert->certblob, k->cert->valid_after); 19401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int64(&k->cert->certblob, k->cert->valid_before); 19411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&k->cert->certblob, 19421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); 19431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* -v01 certs have non-critical options here */ 19451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!key_cert_is_legacy(k)) { 19461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&k->cert->certblob, 19471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&k->cert->extensions), 19481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&k->cert->extensions)); 19491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* -v00 certs put the nonce at the end */ 19521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_cert_is_legacy(k)) 19531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); 19541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ 19561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&k->cert->certblob, ca_blob, ca_len); 19571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(ca_blob); 19581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Sign the whole mess */ 19601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob), 19611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&k->cert->certblob)) != 0) { 19621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: signature operation failed", __func__); 19631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&k->cert->certblob); 19641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 19651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Append signature and we are done */ 19671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&k->cert->certblob, sig_blob, sig_len); 19681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(sig_blob); 19691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 19711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 19741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_cert_check_authority(const Key *k, int want_host, int require_principal, 19751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *name, const char **reason) 19761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, principal_matches; 19781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood time_t now = time(NULL); 19791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (want_host) { 19811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->cert->type != SSH2_CERT_TYPE_HOST) { 19821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *reason = "Certificate invalid: not a host certificate"; 19831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 19841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 19861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->cert->type != SSH2_CERT_TYPE_USER) { 19871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *reason = "Certificate invalid: not a user certificate"; 19881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 19891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (now < 0) { 19921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: system clock lies before epoch", __func__); 19931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *reason = "Certificate invalid: not yet valid"; 19941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 19951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((u_int64_t)now < k->cert->valid_after) { 19971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *reason = "Certificate invalid: not yet valid"; 19981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 19991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((u_int64_t)now >= k->cert->valid_before) { 20011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *reason = "Certificate invalid: expired"; 20021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 20031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k->cert->nprincipals == 0) { 20051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (require_principal) { 20061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *reason = "Certificate lacks principal list"; 20071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 20081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (name != NULL) { 20101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood principal_matches = 0; 20111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < k->cert->nprincipals; i++) { 20121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(name, k->cert->principals[i]) == 0) { 20131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood principal_matches = 1; 20141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 20151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!principal_matches) { 20181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *reason = "Certificate invalid: name is not a listed " 20191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "principal"; 20201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 20211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 20241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 20271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_cert_is_legacy(Key *k) 20281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (k->type) { 20301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_DSA_CERT_V00: 20311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEY_RSA_CERT_V00: 20321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 20331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 20341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 20351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* XXX: these are really begging for a table-driven approach */ 20391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 20401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_curve_name_to_nid(const char *name) 20411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 20431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(name, "nistp256") == 0) 20441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_X9_62_prime256v1; 20451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (strcmp(name, "nistp384") == 0) 20461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_secp384r1; 20471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (strcmp(name, "nistp521") == 0) 20481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NID_secp521r1; 20491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 20501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: unsupported EC curve name \"%.100s\"", __func__, name); 20521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 20531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int 20561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_curve_nid_to_bits(int nid) 20571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (nid) { 20591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 20601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_X9_62_prime256v1: 20611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 256; 20621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_secp384r1: 20631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 384; 20641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case NID_secp521r1: 20651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 521; 20661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 20671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 20681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: unsupported EC curve nid %d", __func__, nid); 20691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 20701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst char * 20741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_curve_nid_to_name(int nid) 20751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 20771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (nid == NID_X9_62_prime256v1) 20781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "nistp256"; 20791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (nid == NID_secp384r1) 20801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "nistp384"; 20811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (nid == NID_secp521r1) 20821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "nistp521"; 20831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 20841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: unsupported EC curve nid %d", __func__, nid); 20851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 20861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 20891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst EVP_MD * 20901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ec_nid_to_evpmd(int nid) 20911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int kbits = key_curve_nid_to_bits(nid); 20931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kbits == 0) 20951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: invalid nid %d", __func__, nid); 20961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* RFC5656 section 6.2.1 */ 20971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kbits <= 256) 20981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return EVP_sha256(); 20991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (kbits <= 384) 21001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return EVP_sha384(); 21011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 21021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return EVP_sha512(); 21031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 21061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 21071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX *bnctx; 21091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT *nq = NULL; 21101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *order, *x, *y, *tmp; 21111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret = -1; 21121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((bnctx = BN_CTX_new()) == NULL) 21141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_new failed", __func__); 21151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_start(bnctx); 21161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 21181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We shouldn't ever hit this case because bignum_get_ecpoint() 21191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * refuses to load GF2m points. 21201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 21211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 21221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NID_X9_62_prime_field) { 21231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: group is not a prime field", __func__); 21241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 21251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Q != infinity */ 21281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_POINT_is_at_infinity(group, public)) { 21291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: received degenerate public key (infinity)", 21301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 21311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 21321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((x = BN_CTX_get(bnctx)) == NULL || 21351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (y = BN_CTX_get(bnctx)) == NULL || 21361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (order = BN_CTX_get(bnctx)) == NULL || 21371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (tmp = BN_CTX_get(bnctx)) == NULL) 21381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_get failed", __func__); 21391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ 21411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_GROUP_get_order(group, order, bnctx) != 1) 21421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_GROUP_get_order failed", __func__); 21431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_POINT_get_affine_coordinates_GFp(group, public, 21441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x, y, bnctx) != 1) 21451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); 21461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_num_bits(x) <= BN_num_bits(order) / 2) { 21471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: public key x coordinate too small: " 21481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "bits(x) = %d, bits(order)/2 = %d", __func__, 21491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_num_bits(x), BN_num_bits(order) / 2); 21501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 21511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_num_bits(y) <= BN_num_bits(order) / 2) { 21531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: public key y coordinate too small: " 21541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "bits(y) = %d, bits(order)/2 = %d", __func__, 21551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_num_bits(x), BN_num_bits(order) / 2); 21561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 21571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* nQ == infinity (n == order of subgroup) */ 21601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((nq = EC_POINT_new(group)) == NULL) 21611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_tmp failed", __func__); 21621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) 21631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_GROUP_mul failed", __func__); 21641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_POINT_is_at_infinity(group, nq) != 1) { 21651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: received degenerate public key (nQ != infinity)", 21661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 21671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 21681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* x < order - 1, y < order - 1 */ 21711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!BN_sub(tmp, order, BN_value_one())) 21721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_sub failed", __func__); 21731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_cmp(x, tmp) >= 0) { 21741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: public key x coordinate >= group order - 1", 21751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 21761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 21771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_cmp(y, tmp) >= 0) { 21791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: public key y coordinate >= group order - 1", 21801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__); 21811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 21821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = 0; 21841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood out: 21851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_free(bnctx); 21861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT_free(nq); 21871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 21881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 21911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_ec_validate_private(const EC_KEY *key) 21921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX *bnctx; 21941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *order, *tmp; 21951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret = -1; 21961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((bnctx = BN_CTX_new()) == NULL) 21981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_new failed", __func__); 21991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_start(bnctx); 22001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((order = BN_CTX_get(bnctx)) == NULL || 22021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (tmp = BN_CTX_get(bnctx)) == NULL) 22031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_get failed", __func__); 22041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* log2(private) > log2(order)/2 */ 22061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) 22071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_GROUP_get_order failed", __func__); 22081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_num_bits(EC_KEY_get0_private_key(key)) <= 22091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_num_bits(order) / 2) { 22101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: private key too small: " 22111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "bits(y) = %d, bits(order)/2 = %d", __func__, 22121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_num_bits(EC_KEY_get0_private_key(key)), 22131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_num_bits(order) / 2); 22141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 22151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* private < order - 1 */ 22181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!BN_sub(tmp, order, BN_value_one())) 22191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_sub failed", __func__); 22201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { 22211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: private key >= group order - 1", __func__); 22221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 22231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = 0; 22251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood out: 22261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_free(bnctx); 22271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 22281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 22291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(DEBUG_KEXECDH) || defined(DEBUG_PK) 22311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 22321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) 22331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 22341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *x, *y; 22351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX *bnctx; 22361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (point == NULL) { 22381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("point=(NULL)\n", stderr); 22391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 22401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((bnctx = BN_CTX_new()) == NULL) 22421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_new failed", __func__); 22431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_start(bnctx); 22441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL) 22451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_CTX_get failed", __func__); 22461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != 22471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NID_X9_62_prime_field) 22481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: group is not a prime field", __func__); 22491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1) 22501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); 22511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("x=", stderr); 22521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_print_fp(stderr, x); 22531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("\ny=", stderr); 22541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_print_fp(stderr, y); 22551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("\n", stderr); 22561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_CTX_free(bnctx); 22571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 22581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 22601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkey_dump_ec_key(const EC_KEY *key) 22611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 22621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const BIGNUM *exponent; 22631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key)); 22651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("exponent=", stderr); 22661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((exponent = EC_KEY_get0_private_key(key)) == NULL) 22671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("(NULL)", stderr); 22681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 22691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_print_fp(stderr, EC_KEY_get0_private_key(key)); 22701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("\n", stderr); 22711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 22721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ 22731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* OPENSSL_HAS_ECC */ 2274