diff options
Diffstat (limited to 'kexdhc.c')
-rw-r--r-- | kexdhc.c | 45 |
1 files changed, 11 insertions, 34 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexdhc.c,v 1.27 2019/01/21 10:00:23 djm Exp $ */ | 1 | /* $OpenBSD: kexdhc.c,v 1.28 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 | * |
@@ -86,13 +86,14 @@ static int | |||
86 | input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) | 86 | input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) |
87 | { | 87 | { |
88 | struct kex *kex = ssh->kex; | 88 | struct kex *kex = ssh->kex; |
89 | BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; | 89 | BIGNUM *dh_server_pub = NULL; |
90 | const BIGNUM *pub_key; | 90 | const BIGNUM *pub_key; |
91 | struct sshkey *server_host_key = NULL; | 91 | struct sshkey *server_host_key = NULL; |
92 | u_char *kbuf = NULL, *server_host_key_blob = NULL, *signature = NULL; | 92 | struct sshbuf *shared_secret = NULL; |
93 | u_char *server_host_key_blob = NULL, *signature = NULL; | ||
93 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | 94 | u_char hash[SSH_DIGEST_MAX_LENGTH]; |
94 | size_t klen = 0, slen, sbloblen, hashlen; | 95 | size_t slen, sbloblen, hashlen; |
95 | int kout, r; | 96 | int r; |
96 | 97 | ||
97 | if (kex->verify_host_key == NULL) { | 98 | if (kex->verify_host_key == NULL) { |
98 | r = SSH_ERR_INVALID_ARGUMENT; | 99 | r = SSH_ERR_INVALID_ARGUMENT; |
@@ -119,32 +120,12 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) | |||
119 | (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || | 120 | (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || |
120 | (r = sshpkt_get_end(ssh)) != 0) | 121 | (r = sshpkt_get_end(ssh)) != 0) |
121 | goto out; | 122 | goto out; |
122 | #ifdef DEBUG_KEXDH | 123 | if ((shared_secret = sshbuf_new()) == NULL) { |
123 | fprintf(stderr, "dh_server_pub= "); | ||
124 | BN_print_fp(stderr, dh_server_pub); | ||
125 | fprintf(stderr, "\n"); | ||
126 | debug("bits %d", BN_num_bits(dh_server_pub)); | ||
127 | #endif | ||
128 | if (!dh_pub_is_valid(kex->dh, dh_server_pub)) { | ||
129 | sshpkt_disconnect(ssh, "bad server public DH value"); | ||
130 | r = SSH_ERR_MESSAGE_INCOMPLETE; | ||
131 | goto out; | ||
132 | } | ||
133 | |||
134 | klen = DH_size(kex->dh); | ||
135 | if ((kbuf = malloc(klen)) == NULL || | ||
136 | (shared_secret = BN_new()) == NULL) { | ||
137 | r = SSH_ERR_ALLOC_FAIL; | 124 | r = SSH_ERR_ALLOC_FAIL; |
138 | goto out; | 125 | goto out; |
139 | } | 126 | } |
140 | if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0 || | 127 | if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) |
141 | BN_bin2bn(kbuf, kout, shared_secret) == NULL) { | ||
142 | r = SSH_ERR_LIBCRYPTO_ERROR; | ||
143 | goto out; | 128 | goto out; |
144 | } | ||
145 | #ifdef DEBUG_KEXDH | ||
146 | dump_digest("shared secret", kbuf, kout); | ||
147 | #endif | ||
148 | 129 | ||
149 | /* calc and verify H */ | 130 | /* calc and verify H */ |
150 | DH_get0_key(kex->dh, &pub_key, NULL); | 131 | DH_get0_key(kex->dh, &pub_key, NULL); |
@@ -158,7 +139,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) | |||
158 | server_host_key_blob, sbloblen, | 139 | server_host_key_blob, sbloblen, |
159 | pub_key, | 140 | pub_key, |
160 | dh_server_pub, | 141 | dh_server_pub, |
161 | shared_secret, | 142 | sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), |
162 | hash, &hashlen)) != 0) | 143 | hash, &hashlen)) != 0) |
163 | goto out; | 144 | goto out; |
164 | 145 | ||
@@ -166,18 +147,14 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) | |||
166 | kex->hostkey_alg, ssh->compat)) != 0) | 147 | kex->hostkey_alg, ssh->compat)) != 0) |
167 | goto out; | 148 | goto out; |
168 | 149 | ||
169 | if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) | 150 | if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) |
170 | r = kex_send_newkeys(ssh); | 151 | r = kex_send_newkeys(ssh); |
171 | out: | 152 | out: |
172 | explicit_bzero(hash, sizeof(hash)); | 153 | explicit_bzero(hash, sizeof(hash)); |
173 | DH_free(kex->dh); | 154 | DH_free(kex->dh); |
174 | kex->dh = NULL; | 155 | kex->dh = NULL; |
175 | BN_clear_free(dh_server_pub); | 156 | BN_clear_free(dh_server_pub); |
176 | if (kbuf) { | 157 | sshbuf_free(shared_secret); |
177 | explicit_bzero(kbuf, klen); | ||
178 | free(kbuf); | ||
179 | } | ||
180 | BN_clear_free(shared_secret); | ||
181 | sshkey_free(server_host_key); | 158 | sshkey_free(server_host_key); |
182 | free(server_host_key_blob); | 159 | free(server_host_key_blob); |
183 | free(signature); | 160 | free(signature); |