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