11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: kexdhs.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2001 Markus Friedl. All rights reserved. 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/dh.h> 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h" 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h" 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h" 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "dh.h" 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h" 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh-gss.h" 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "monitor_wrap.h" 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkexdh_server(Kex *kex) 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DH *dh; 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *server_host_public, *server_host_private; 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int sbloblen, klen, hashlen, slen; 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int kout; 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* generate server DH public key */ 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (kex->kex_type) { 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEX_DH_GRP1_SHA1: 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh = dh_new_group1(); 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEX_DH_GRP14_SHA1: 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh = dh_new_group14(); 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh_gen_key(dh, kex->we_need * 8); 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("expecting SSH2_MSG_KEXDH_INIT"); 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_read_expect(SSH2_MSG_KEXDH_INIT); 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kex->load_host_public_key == NULL || 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->load_host_private_key == NULL) 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Cannot load hostkey"); 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_public = kex->load_host_public_key(kex->hostkey_type); 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (server_host_public == NULL) 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Unsupported hostkey type %d", kex->hostkey_type); 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_private = kex->load_host_private_key(kex->hostkey_type); 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (server_host_private == NULL) 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Missing private key for hostkey type %d", 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->hostkey_type); 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* key, cert */ 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((dh_client_pub = BN_new()) == NULL) 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("dh_client_pub == NULL"); 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_bignum2(dh_client_pub); 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXDH 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "dh_client_pub= "); 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_print_fp(stderr, dh_client_pub); 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "\n"); 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("bits %d", BN_num_bits(dh_client_pub)); 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXDH 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DHparams_print_fp(stderr, dh); 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "pub= "); 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_print_fp(stderr, dh->pub_key); 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "\n"); 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!dh_pub_is_valid(dh, dh_client_pub)) 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_disconnect("bad client public DH value"); 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood klen = DH_size(dh); 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kbuf = xmalloc(klen); 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((kout = DH_compute_key(kbuf, dh_client_pub, dh)) < 0) 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("DH_compute_key: failed"); 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXDH 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dump_digest("shared secret", kbuf, kout); 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((shared_secret = BN_new()) == NULL) 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("kexdh_server: BN_new failed"); 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("kexdh_server: BN_bin2bn failed"); 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(kbuf, 0, klen); 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(kbuf); 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* calc H */ 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_dh_hash( 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->client_version_string, 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->server_version_string, 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&kex->peer), buffer_len(&kex->peer), 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&kex->my), buffer_len(&kex->my), 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_key_blob, sbloblen, 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh_client_pub, 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh->pub_key, 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shared_secret, 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &hash, &hashlen 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ); 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_clear_free(dh_client_pub); 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* save session id := H */ 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kex->session_id == NULL) { 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->session_id_len = hashlen; 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->session_id = xmalloc(kex->session_id_len); 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(kex->session_id, hash, kex->session_id_len); 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* sign H */ 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hashlen)) < 0) 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("kexdh_server: key_sign failed"); 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* destroy_sensitive_data(); */ 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* send server hostkey, DH pubkey 'f' and singed H */ 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_KEXDH_REPLY); 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(server_host_key_blob, sbloblen); 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_bignum2(dh->pub_key); /* f */ 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(signature, slen); 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(signature); 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(server_host_key_blob); 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* have keys, free DH */ 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DH_free(dh); 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_derive_keys(kex, hash, hashlen, shared_secret); 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_clear_free(shared_secret); 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_finish(kex); 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 169