diff options
author | des <des@FreeBSD.org> | 2008-07-22 18:58:19 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2008-07-22 18:58:19 +0000 |
commit | 666aa9cc1660793c97ef29a6cb66dfbb894dde8f (patch) | |
tree | 209e642fbe2a816041f67bc27c9800879f5541bc /crypto/openssh/kexdhs.c | |
parent | 624d93001f28e236c027516d88282351eb7bffbe (diff) | |
download | FreeBSD-src-666aa9cc1660793c97ef29a6cb66dfbb894dde8f.zip FreeBSD-src-666aa9cc1660793c97ef29a6cb66dfbb894dde8f.tar.gz |
Revert part of 180714 - the intent was to flatten dist, not to nuke it.
Diffstat (limited to 'crypto/openssh/kexdhs.c')
-rw-r--r-- | crypto/openssh/kexdhs.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/crypto/openssh/kexdhs.c b/crypto/openssh/kexdhs.c new file mode 100644 index 0000000..8617088 --- /dev/null +++ b/crypto/openssh/kexdhs.c @@ -0,0 +1,159 @@ +/* $OpenBSD: kexdhs.c,v 1.9 2006/11/06 21:25:28 markus Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <stdarg.h> +#include <string.h> +#include <signal.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +void +kexdh_server(Kex *kex) +{ + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + DH *dh; + Key *server_host_key; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int sbloblen, klen, hashlen, slen; + int kout; + + /* generate server DH public key */ + switch (kex->kex_type) { + case KEX_DH_GRP1_SHA1: + dh = dh_new_group1(); + break; + case KEX_DH_GRP14_SHA1: + dh = dh_new_group14(); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } + dh_gen_key(dh, kex->we_need * 8); + + debug("expecting SSH2_MSG_KEXDH_INIT"); + packet_read_expect(SSH2_MSG_KEXDH_INIT); + + if (kex->load_host_key == NULL) + fatal("Cannot load hostkey"); + server_host_key = kex->load_host_key(kex->hostkey_type); + if (server_host_key == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + + /* key, cert */ + if ((dh_client_pub = BN_new()) == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub); + packet_check_eom(); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_client_pub= "); + BN_print_fp(stderr, dh_client_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_client_pub)); +#endif + +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + if ((kout = DH_compute_key(kbuf, dh_client_pub, dh)) < 0) + fatal("DH_compute_key: failed"); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexdh_server: BN_new failed"); + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) + fatal("kexdh_server: BN_bin2bn failed"); + memset(kbuf, 0, klen); + xfree(kbuf); + + key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); + + /* calc H */ + kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + dh_client_pub, + dh->pub_key, + shared_secret, + &hash, &hashlen + ); + BN_clear_free(dh_client_pub); + + /* save session id := H */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen)); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, DH pubkey 'f' and singed H */ + packet_start(SSH2_MSG_KEXDH_REPLY); + packet_put_string(server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string(signature, slen); + packet_send(); + + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free DH */ + DH_free(dh); + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} |