summaryrefslogtreecommitdiff
path: root/kexdhs.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexdhs.c')
-rw-r--r--kexdhs.c54
1 files changed, 12 insertions, 42 deletions
diff --git a/kexdhs.c b/kexdhs.c
index cd2e52e00..0f028aaeb 100644
--- a/kexdhs.c
+++ b/kexdhs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexdhs.c,v 1.33 2019/01/21 10:00:23 djm Exp $ */ 1/* $OpenBSD: kexdhs.c,v 1.34 2019/01/21 10:03:37 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -71,14 +71,15 @@ int
71input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh) 71input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
72{ 72{
73 struct kex *kex = ssh->kex; 73 struct kex *kex = ssh->kex;
74 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; 74 BIGNUM *dh_client_pub = NULL;
75 const BIGNUM *pub_key; 75 const BIGNUM *pub_key;
76 struct sshkey *server_host_public, *server_host_private; 76 struct sshkey *server_host_public, *server_host_private;
77 u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; 77 struct sshbuf *shared_secret = NULL;
78 u_char *signature = NULL, *server_host_key_blob = NULL;
78 u_char hash[SSH_DIGEST_MAX_LENGTH]; 79 u_char hash[SSH_DIGEST_MAX_LENGTH];
79 size_t sbloblen, slen; 80 size_t sbloblen, slen;
80 size_t klen = 0, hashlen; 81 size_t hashlen;
81 int kout, r; 82 int r;
82 83
83 if (kex->load_host_public_key == NULL || 84 if (kex->load_host_public_key == NULL ||
84 kex->load_host_private_key == NULL) { 85 kex->load_host_private_key == NULL) {
@@ -98,42 +99,17 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
98 if ((r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 || 99 if ((r = sshpkt_get_bignum2(ssh, &dh_client_pub)) != 0 ||
99 (r = sshpkt_get_end(ssh)) != 0) 100 (r = sshpkt_get_end(ssh)) != 0)
100 goto out; 101 goto out;
101 DH_get0_key(kex->dh, &pub_key, NULL); 102 if ((shared_secret = sshbuf_new()) == NULL) {
102
103#ifdef DEBUG_KEXDH
104 fprintf(stderr, "dh_client_pub= ");
105 BN_print_fp(stderr, dh_client_pub);
106 fprintf(stderr, "\n");
107 debug("bits %d", BN_num_bits(dh_client_pub));
108 DHparams_print_fp(stderr, kex->dh);
109 fprintf(stderr, "pub= ");
110 BN_print_fp(stderr, pub_key);
111 fprintf(stderr, "\n");
112#endif
113 if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
114 sshpkt_disconnect(ssh, "bad client public DH value");
115 r = SSH_ERR_MESSAGE_INCOMPLETE;
116 goto out;
117 }
118
119 klen = DH_size(kex->dh);
120 if ((kbuf = malloc(klen)) == NULL ||
121 (shared_secret = BN_new()) == NULL) {
122 r = SSH_ERR_ALLOC_FAIL; 103 r = SSH_ERR_ALLOC_FAIL;
123 goto out; 104 goto out;
124 } 105 }
125 if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 || 106 if ((r = kex_dh_compute_key(kex, dh_client_pub, shared_secret)) != 0)
126 BN_bin2bn(kbuf, kout, shared_secret) == NULL) {
127 r = SSH_ERR_LIBCRYPTO_ERROR;
128 goto out; 107 goto out;
129 }
130#ifdef DEBUG_KEXDH
131 dump_digest("shared secret", kbuf, kout);
132#endif
133 if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, 108 if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
134 &sbloblen)) != 0) 109 &sbloblen)) != 0)
135 goto out; 110 goto out;
136 /* calc H */ 111 /* calc H */
112 DH_get0_key(kex->dh, &pub_key, NULL);
137 hashlen = sizeof(hash); 113 hashlen = sizeof(hash);
138 if ((r = kex_dh_hash( 114 if ((r = kex_dh_hash(
139 kex->hash_alg, 115 kex->hash_alg,
@@ -144,7 +120,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
144 server_host_key_blob, sbloblen, 120 server_host_key_blob, sbloblen,
145 dh_client_pub, 121 dh_client_pub,
146 pub_key, 122 pub_key,
147 shared_secret, 123 sshbuf_ptr(shared_secret), sshbuf_len(shared_secret),
148 hash, &hashlen)) != 0) 124 hash, &hashlen)) != 0)
149 goto out; 125 goto out;
150 126
@@ -153,8 +129,6 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
153 &signature, &slen, hash, hashlen, kex->hostkey_alg)) < 0) 129 &signature, &slen, hash, hashlen, kex->hostkey_alg)) < 0)
154 goto out; 130 goto out;
155 131
156 /* destroy_sensitive_data(); */
157
158 /* send server hostkey, DH pubkey 'f' and signed H */ 132 /* send server hostkey, DH pubkey 'f' and signed H */
159 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || 133 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
160 (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || 134 (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
@@ -163,18 +137,14 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
163 (r = sshpkt_send(ssh)) != 0) 137 (r = sshpkt_send(ssh)) != 0)
164 goto out; 138 goto out;
165 139
166 if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) 140 if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
167 r = kex_send_newkeys(ssh); 141 r = kex_send_newkeys(ssh);
168 out: 142 out:
169 explicit_bzero(hash, sizeof(hash)); 143 explicit_bzero(hash, sizeof(hash));
170 DH_free(kex->dh); 144 DH_free(kex->dh);
171 kex->dh = NULL; 145 kex->dh = NULL;
172 BN_clear_free(dh_client_pub); 146 BN_clear_free(dh_client_pub);
173 if (kbuf) { 147 sshbuf_free(shared_secret);
174 explicit_bzero(kbuf, klen);
175 free(kbuf);
176 }
177 BN_clear_free(shared_secret);
178 free(server_host_key_blob); 148 free(server_host_key_blob);
179 free(signature); 149 free(signature);
180 return r; 150 return r;