*/
#include "includes.h"
-RCSID("$OpenBSD: kexgex.c,v 1.4 2001/04/04 22:04:35 markus Exp $");
+RCSID("$OpenBSD: kexgex.c,v 1.13 2001/12/28 12:14:27 markus Exp $");
#include <openssl/bn.h>
#include "ssh2.h"
#include "compat.h"
-u_char *
+static u_char *
kexgex_hash(
char *client_version_string,
char *server_version_string,
char *ckexinit, int ckexinitlen,
char *skexinit, int skexinitlen,
- char *serverhostkeyblob, int sbloblen,
+ u_char *serverhostkeyblob, int sbloblen,
int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen,
BIGNUM *client_dh_pub,
BIGNUM *server_dh_pub,
EVP_MD_CTX md;
buffer_init(&b);
- buffer_put_string(&b, client_version_string, strlen(client_version_string));
- buffer_put_string(&b, server_version_string, strlen(server_version_string));
+ buffer_put_cstring(&b, client_version_string);
+ buffer_put_cstring(&b, server_version_string);
/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
buffer_put_int(&b, ckexinitlen+1);
buffer_append(&b, skexinit, skexinitlen);
buffer_put_string(&b, serverhostkeyblob, sbloblen);
- if (min == -1 || max == -1)
+ if (min == -1 || max == -1)
buffer_put_int(&b, wantbits);
else {
buffer_put_int(&b, min);
/* client */
-void
+static void
kexgex_client(Kex *kex)
{
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
if ((g = BN_new()) == NULL)
fatal("BN_new");
packet_get_bignum2(g, &dlen);
- packet_done();
+ packet_check_eom();
if (BN_num_bits(p) < min || BN_num_bits(p) > max)
fatal("DH_GEX group out of range: %d !< %d !< %d",
if (server_host_key == NULL)
fatal("cannot decode server_host_key_blob");
- if (kex->check_host_key == NULL)
- fatal("cannot check server_host_key");
- kex->check_host_key(server_host_key);
+ if (kex->verify_host_key == NULL)
+ fatal("cannot verify server_host_key");
+ if (kex->verify_host_key(server_host_key) == -1)
+ fatal("server_host_key verification failed");
/* DH paramter f, server public DH key */
- dh_server_pub = BN_new();
- if (dh_server_pub == NULL)
+ if ((dh_server_pub = BN_new()) == NULL)
fatal("dh_server_pub == NULL");
packet_get_bignum2(dh_server_pub, &dlen);
/* signed H */
signature = packet_get_string(&slen);
- packet_done();
+ packet_check_eom();
if (!dh_pub_is_valid(dh, dh_server_pub))
packet_disconnect("bad server public DH value");
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_server_pub, dh);
#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
+ dump_digest("shared secret", kbuf, kout);
#endif
- shared_secret = BN_new();
+ if ((shared_secret = BN_new()) == NULL)
+ fatal("kexgex_client: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
/* have keys, free DH */
DH_free(dh);
xfree(server_host_key_blob);
- BN_free(dh_server_pub);
+ BN_clear_free(dh_server_pub);
- if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
+ if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
/* server */
-void
+static void
kexgex_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
fatal("Unsupported hostkey type %d", kex->hostkey_type);
type = packet_read(&plen);
- switch(type){
+ switch (type) {
case SSH2_MSG_KEX_DH_GEX_REQUEST:
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
min = packet_get_int();
default:
fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type);
}
- packet_done();
+ packet_check_eom();
if (max < min || nbits < min || max < nbits)
fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_INIT);
/* key, cert */
- dh_client_pub = BN_new();
- if (dh_client_pub == NULL)
+ if ((dh_client_pub = BN_new()) == NULL)
fatal("dh_client_pub == NULL");
packet_get_bignum2(dh_client_pub, &dlen);
kbuf = xmalloc(klen);
kout = DH_compute_key(kbuf, dh_client_pub, dh);
#ifdef DEBUG_KEXDH
- dump_digest("shared secret", kbuf, kout);
+ dump_digest("shared secret", kbuf, kout);
#endif
- shared_secret = BN_new();
+ if ((shared_secret = BN_new()) == NULL)
+ fatal("kexgex_server: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
buffer_ptr(&kex->my), buffer_len(&kex->my),
- (char *)server_host_key_blob, sbloblen,
+ server_host_key_blob, sbloblen,
min, nbits, max,
dh->p, dh->g,
dh_client_pub,
dh->pub_key,
shared_secret
);
- BN_free(dh_client_pub);
+ BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
/* send server hostkey, DH pubkey 'f' and singed H */
debug("SSH2_MSG_KEX_DH_GEX_REPLY sent");
packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
- packet_put_string((char *)server_host_key_blob, sbloblen);
+ packet_put_string(server_host_key_blob, sbloblen);
packet_put_bignum2(dh->pub_key); /* f */
- packet_put_string((char *)signature, slen);
+ packet_put_string(signature, slen);
packet_send();
xfree(signature);
xfree(server_host_key_blob);