11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: kexdhc.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 <openssl/dh.h> 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h" 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h" 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h" 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "dh.h" 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h" 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkexdh_client(Kex *kex) 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DH *dh; 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *server_host_key; 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *server_host_key_blob = NULL, *signature = NULL; 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *kbuf, *hash; 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int klen, slen, sbloblen, hashlen; 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int kout; 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* generate and send 'e', client DH public key */ 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (kex->kex_type) { 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEX_DH_GRP1_SHA1: 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh = dh_new_group1(); 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case KEX_DH_GRP14_SHA1: 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh = dh_new_group14(); 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh_gen_key(dh, kex->we_need * 8); 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_KEXDH_INIT); 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_bignum2(dh->pub_key); 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("sending SSH2_MSG_KEXDH_INIT"); 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXDH 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DHparams_print_fp(stderr, dh); 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "pub= "); 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_print_fp(stderr, dh->pub_key); 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "\n"); 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("expecting SSH2_MSG_KEXDH_REPLY"); 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_read_expect(SSH2_MSG_KEXDH_REPLY); 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* key, cert */ 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_key_blob = packet_get_string(&sbloblen); 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_key = key_from_blob(server_host_key_blob, sbloblen); 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (server_host_key == NULL) 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("cannot decode server_host_key_blob"); 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (server_host_key->type != kex->hostkey_type) 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("type mismatch for decoded server_host_key_blob"); 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kex->verify_host_key == NULL) 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("cannot verify server_host_key"); 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kex->verify_host_key(server_host_key) == -1) 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("server_host_key verification failed"); 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* DH parameter f, server public DH key */ 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((dh_server_pub = BN_new()) == NULL) 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("dh_server_pub == NULL"); 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_bignum2(dh_server_pub); 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXDH 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "dh_server_pub= "); 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_print_fp(stderr, dh_server_pub); 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "\n"); 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("bits %d", BN_num_bits(dh_server_pub)); 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* signed H */ 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signature = packet_get_string(&slen); 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!dh_pub_is_valid(dh, dh_server_pub)) 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_disconnect("bad server public DH value"); 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood klen = DH_size(dh); 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kbuf = xmalloc(klen); 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("DH_compute_key: failed"); 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXDH 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dump_digest("shared secret", kbuf, kout); 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((shared_secret = BN_new()) == NULL) 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("kexdh_client: BN_new failed"); 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("kexdh_client: BN_bin2bn failed"); 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(kbuf, 0, klen); 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(kbuf); 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* calc and verify H */ 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_dh_hash( 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->client_version_string, 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->server_version_string, 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&kex->my), buffer_len(&kex->my), 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&kex->peer), buffer_len(&kex->peer), 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_key_blob, sbloblen, 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh->pub_key, 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dh_server_pub, 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shared_secret, 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &hash, &hashlen 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ); 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(server_host_key_blob); 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_clear_free(dh_server_pub); 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood DH_free(dh); 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("key_verify failed for server_host_key"); 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(server_host_key); 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(signature); 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* save session id */ 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kex->session_id == NULL) { 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->session_id_len = hashlen; 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->session_id = xmalloc(kex->session_id_len); 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(kex->session_id, hash, kex->session_id_len); 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_derive_keys(kex, hash, hashlen, shared_secret); 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_clear_free(shared_secret); 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_finish(kex); 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 162