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