diff options
Diffstat (limited to 'kexdhs.c')
-rw-r--r-- | kexdhs.c | 54 |
1 files changed, 12 insertions, 42 deletions
@@ -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 | |||
71 | input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh) | 71 | input_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; |