Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/kex.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10955 - (show annotations) (download) (as text)
Mon Oct 2 23:34:47 2023 UTC (7 months, 3 weeks ago) by nmaya
File MIME type: text/x-csrc
File size: 25672 byte(s)
myproposal についてのコメントを修正

r10949, ticket: #36111 関連
1 /*
2 * (C) 2011- TeraTerm Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "ttxssh.h"
30 #include "kex.h"
31
32
33 char *myproposal[PROPOSAL_MAX] = {
34 KEX_DEFAULT_KEX,
35 KEX_DEFAULT_PK_ALG,
36 KEX_DEFAULT_ENCRYPT,
37 KEX_DEFAULT_ENCRYPT,
38 KEX_DEFAULT_MAC,
39 KEX_DEFAULT_MAC,
40 KEX_DEFAULT_COMP,
41 KEX_DEFAULT_COMP,
42 KEX_DEFAULT_LANG,
43 KEX_DEFAULT_LANG,
44 };
45
46 struct ssh2_kex_algorithm_t {
47 kex_algorithm kextype;
48 char *name;
49 const EVP_MD *(*evp_md)(void);
50 };
51
52 static const struct ssh2_kex_algorithm_t ssh2_kex_algorithms[] = {
53 {KEX_DH_GRP1_SHA1, "diffie-hellman-group1-sha1", EVP_sha1}, // RFC4253
54 {KEX_DH_GRP14_SHA1, "diffie-hellman-group14-sha1", EVP_sha1}, // RFC4253
55 {KEX_DH_GEX_SHA1, "diffie-hellman-group-exchange-sha1", EVP_sha1}, // RFC4419
56 {KEX_DH_GEX_SHA256, "diffie-hellman-group-exchange-sha256", EVP_sha256}, // RFC4419
57 {KEX_ECDH_SHA2_256, "ecdh-sha2-nistp256", EVP_sha256}, // RFC5656
58 {KEX_ECDH_SHA2_384, "ecdh-sha2-nistp384", EVP_sha384}, // RFC5656
59 {KEX_ECDH_SHA2_521, "ecdh-sha2-nistp521", EVP_sha512}, // RFC5656
60 {KEX_DH_GRP14_SHA256, "diffie-hellman-group14-sha256", EVP_sha256}, // RFC8268
61 {KEX_DH_GRP16_SHA512, "diffie-hellman-group16-sha512", EVP_sha512}, // RFC8268
62 {KEX_DH_GRP18_SHA512, "diffie-hellman-group18-sha512", EVP_sha512}, // RFC8268
63 {KEX_DH_NONE , NULL, NULL},
64 };
65
66
67 char* get_kex_algorithm_name(kex_algorithm kextype)
68 {
69 const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
70
71 while (ptr->name != NULL) {
72 if (kextype == ptr->kextype) {
73 return ptr->name;
74 }
75 ptr++;
76 }
77
78 // not found.
79 return "unknown";
80 }
81
82 const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype)
83 {
84 const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
85
86 while (ptr->name != NULL) {
87 if (kextype == ptr->kextype) {
88 return ptr->evp_md();
89 }
90 ptr++;
91 }
92
93 // not found.
94 return EVP_md_null();
95 }
96
97 void normalize_kex_order(char *buf)
98 {
99 static char default_strings[] = {
100 KEX_ECDH_SHA2_256,
101 KEX_ECDH_SHA2_384,
102 KEX_ECDH_SHA2_521,
103 KEX_DH_GRP18_SHA512,
104 KEX_DH_GRP16_SHA512,
105 KEX_DH_GRP14_SHA256,
106 KEX_DH_GEX_SHA256,
107 KEX_DH_GRP14_SHA1,
108 KEX_DH_NONE,
109 KEX_DH_GEX_SHA1,
110 KEX_DH_GRP1_SHA1,
111 };
112
113 normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
114 }
115
116 kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal)
117 {
118 kex_algorithm type = KEX_DH_UNKNOWN;
119 char str_kextype[40];
120 const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
121
122 choose_SSH2_proposal(server_proposal, my_proposal, str_kextype, sizeof(str_kextype));
123
124 while (ptr->name != NULL) {
125 if (strcmp(ptr->name, str_kextype) == 0) {
126 type = ptr->kextype;
127 break;
128 }
129 ptr++;
130 }
131
132 return (type);
133 }
134
135 // KEX�A���S���Y���D���������������Amyproposal[]�������������B
136 // (2011.2.28 yutaka)
137 void SSH2_update_kex_myproposal(PTInstVar pvar)
138 {
139 static char buf[512]; // TODO: malloc()��������
140 int index;
141 int i;
142
143 // ���M�������������������������L�[������
144 if (pvar->socket != INVALID_SOCKET) {
145 if (pvar->kex_status & KEX_FLAG_REKEYING) {
146 // �L�[�����������������A�������� pvar->settings �����g������������ myproposal �������������B
147 // pvar->settings �� �������� myproposal �����������������l�����������������������������B
148 // ���x�g������������������������ myproposal �����������������������B
149 int pos = strlen(myproposal[PROPOSAL_KEX_ALGS]) - strlen(",ext-info-c");
150 if (strcmp(myproposal[PROPOSAL_KEX_ALGS] + pos, ",ext-info-c") == 0) {
151 myproposal[PROPOSAL_KEX_ALGS][pos] = '\0';
152 }
153 }
154 return;
155 }
156
157 buf[0] = '\0';
158 for (i = 0 ; pvar->settings.KexOrder[i] != 0 ; i++) {
159 index = pvar->settings.KexOrder[i] - '0';
160 if (index == KEX_DH_NONE) // disabled line
161 break;
162 strncat_s(buf, sizeof(buf), get_kex_algorithm_name(index), _TRUNCATE);
163 strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
164 }
165
166 // RFC 8308 Extension Negotiation
167 strncat_s(buf, sizeof(buf), "ext-info-c", _TRUNCATE);
168
169 myproposal[PROPOSAL_KEX_ALGS] = buf;
170 }
171
172
173 static DH *dh_new_group_asc(const char *gen, const char *modulus)
174 {
175 DH *dh = NULL;
176 BIGNUM *p = NULL, *g = NULL;
177
178 if ((dh = DH_new()) == NULL) {
179 printf("dh_new_group_asc: DH_new");
180 goto error;
181 }
182
183 // P��G�����J�����������f�����g��������
184 if (BN_hex2bn(&p, modulus) == 0) {
185 printf("BN_hex2bn p");
186 goto error;
187 }
188
189 if (BN_hex2bn(&g, gen) == 0) {
190 printf("BN_hex2bn g");
191 goto error;
192 }
193
194 // BN_hex2bn()�����������|�C���^��DH�\�������Z�b�g�����B
195 DH_set0_pqg(dh, p, NULL, g);
196
197 return (dh);
198
199 error:
200 BN_free(g);
201 BN_free(p);
202 DH_free(dh);
203 return (NULL);
204 }
205
206
207 DH *dh_new_group1(void)
208 {
209 static char *gen = "2", *group1 =
210 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
211 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
212 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
213 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
214 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
215 "FFFFFFFF" "FFFFFFFF";
216
217 return (dh_new_group_asc(gen, group1));
218 }
219
220
221 DH *dh_new_group14(void)
222 {
223 static char *gen = "2", *group14 =
224 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
225 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
226 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
227 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
228 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
229 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
230 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
231 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
232 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
233 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
234 "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
235
236 return (dh_new_group_asc(gen, group14));
237 }
238
239 // ���g�p
240 DH *dh_new_group15(void)
241 {
242 static char *gen = "2", *group15 =
243 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
244 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
245 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
246 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
247 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
248 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
249 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
250 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
251 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
252 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
253 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
254 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
255 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
256 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
257 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
258 "43DB5BFC" "E0FD108E" "4B82D120" "A93AD2CA" "FFFFFFFF" "FFFFFFFF";
259 return (dh_new_group_asc(gen, group15));
260 }
261
262 DH *dh_new_group16(void)
263 {
264 static char *gen = "2", *group16 =
265 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
266 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
267 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
268 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
269 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
270 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
271 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
272 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
273 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
274 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
275 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
276 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
277 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
278 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
279 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
280 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
281 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
282 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
283 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
284 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
285 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34063199"
286 "FFFFFFFF" "FFFFFFFF";
287 return (dh_new_group_asc(gen, group16));
288 }
289
290 // ���g�p
291 DH *dh_new_group17(void)
292 {
293 static char *gen = "2", *group17 =
294 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" "29024E08"
295 "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" "EF9519B3" "CD3A431B"
296 "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" "E485B576" "625E7EC6" "F44C42E9"
297 "A637ED6B" "0BFF5CB6" "F406B7ED" "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6"
298 "49286651" "ECE45B3D" "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8"
299 "FD24CF5F" "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
300 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" "E39E772C"
301 "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718"
302 "3995497C" "EA956AE5" "15D22618" "98FA0510" "15728E5A" "8AAAC42D" "AD33170D"
303 "04507A33" "A85521AB" "DF1CBA64" "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D"
304 "B3970F85" "A6E1E4C7" "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226"
305 "1AD2EE6B" "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
306 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31" "43DB5BFC"
307 "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7" "88719A10" "BDBA5B26"
308 "99C32718" "6AF4E23C" "1A946834" "B6150BDA" "2583E9CA" "2AD44CE8" "DBBBC2DB"
309 "04DE8EF9" "2E8EFC14" "1FBECAA6" "287C5947" "4E6BC05D" "99B2964F" "A090C3A2"
310 "233BA186" "515BE7ED" "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127"
311 "D5B05AA9" "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
312 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD" "F8FF9406"
313 "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831" "179727B0" "865A8918"
314 "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B" "DB7F1447" "E6CC254B" "33205151"
315 "2BD7AF42" "6FB8F401" "378CD2BF" "5983CA01" "C64B92EC" "F032EA15" "D1721D03"
316 "F482D7CE" "6E74FEF6" "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F"
317 "BEC7E8F3" "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
318 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328" "06A1D58B"
319 "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C" "DA56C9EC" "2EF29632"
320 "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE" "12BF2D5B" "0B7474D6" "E694F91E"
321 "6DCC4024" "FFFFFFFF" "FFFFFFFF";
322 return (dh_new_group_asc(gen, group17));
323 }
324
325 DH *dh_new_group18(void)
326 {
327 static char *gen = "2", *group18 =
328 "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
329 "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
330 "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
331 "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
332 "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
333 "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
334 "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
335 "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
336 "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
337 "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
338 "15728E5A" "8AAAC42D" "AD33170D" "04507A33" "A85521AB" "DF1CBA64"
339 "ECFB8504" "58DBEF0A" "8AEA7157" "5D060C7D" "B3970F85" "A6E1E4C7"
340 "ABF5AE8C" "DB0933D7" "1E8C94E0" "4A25619D" "CEE3D226" "1AD2EE6B"
341 "F12FFA06" "D98A0864" "D8760273" "3EC86A64" "521F2B18" "177B200C"
342 "BBE11757" "7A615D6C" "770988C0" "BAD946E2" "08E24FA0" "74E5AB31"
343 "43DB5BFC" "E0FD108E" "4B82D120" "A9210801" "1A723C12" "A787E6D7"
344 "88719A10" "BDBA5B26" "99C32718" "6AF4E23C" "1A946834" "B6150BDA"
345 "2583E9CA" "2AD44CE8" "DBBBC2DB" "04DE8EF9" "2E8EFC14" "1FBECAA6"
346 "287C5947" "4E6BC05D" "99B2964F" "A090C3A2" "233BA186" "515BE7ED"
347 "1F612970" "CEE2D7AF" "B81BDD76" "2170481C" "D0069127" "D5B05AA9"
348 "93B4EA98" "8D8FDDC1" "86FFB7DC" "90A6C08F" "4DF435C9" "34028492"
349 "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD"
350 "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831"
351 "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B"
352 "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF"
353 "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6"
354 "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3"
355 "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA"
356 "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328"
357 "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C"
358 "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE"
359 "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4"
360 "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300"
361 "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568"
362 "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9"
363 "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B"
364 "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A"
365 "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36"
366 "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1"
367 "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92"
368 "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47"
369 "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71"
370 "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF";
371 return (dh_new_group_asc(gen, group18));
372 }
373
374
375 // DH������������
376 void dh_gen_key(PTInstVar pvar, DH *dh, int we_need /* bytes */ )
377 {
378 int i;
379 BIGNUM *pub_key;
380 BIGNUM *priv_key;
381
382 priv_key = NULL;
383
384 // ����������������(X)������
385 for (i = 0 ; i < 10 ; i++) { // retry counter
386 if (priv_key != NULL) {
387 BN_clear_free(priv_key);
388 }
389 priv_key = BN_new();
390 DH_set0_key(dh, NULL, priv_key);
391 if (priv_key == NULL)
392 goto error;
393 if (BN_rand(priv_key, 2*(we_need*8), 0, 0) == 0)
394 goto error;
395 if (DH_generate_key(dh) == 0)
396 goto error;
397 DH_get0_key(dh, &pub_key, NULL);
398 if (dh_pub_is_valid(dh, pub_key))
399 break;
400 }
401 if (i >= 10) {
402 goto error;
403 }
404 return;
405
406 error:;
407 notify_fatal_error(pvar, "error occurred @ dh_gen_key()", TRUE);
408
409 }
410
411
412 int dh_estimate(int bits)
413 {
414 if (bits <= 112)
415 return 2048;
416 if (bits <= 128)
417 return 3072;
418 if (bits <= 192)
419 return 7680;
420 return 8192;
421 }
422
423
424 // shared secret ���v�Z���� (DH �����O���[�v�p)
425 unsigned char *kex_dh_hash(const EVP_MD *evp_md,
426 char *client_version_string,
427 char *server_version_string,
428 char *ckexinit, int ckexinitlen,
429 char *skexinit, int skexinitlen,
430 u_char *serverhostkeyblob, int sbloblen,
431 BIGNUM *client_dh_pub,
432 BIGNUM *server_dh_pub,
433 BIGNUM *shared_secret,
434 unsigned int *hashlen)
435 {
436 buffer_t *b;
437 static unsigned char digest[EVP_MAX_MD_SIZE];
438 EVP_MD_CTX *md = NULL;
439
440 md = EVP_MD_CTX_new();
441 if (md == NULL)
442 goto error;
443
444 b = buffer_init();
445 buffer_put_string(b, client_version_string, strlen(client_version_string));
446 buffer_put_string(b, server_version_string, strlen(server_version_string));
447
448 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
449 buffer_put_int(b, ckexinitlen+1);
450 buffer_put_char(b, SSH2_MSG_KEXINIT);
451 buffer_append(b, ckexinit, ckexinitlen);
452 buffer_put_int(b, skexinitlen+1);
453 buffer_put_char(b, SSH2_MSG_KEXINIT);
454 buffer_append(b, skexinit, skexinitlen);
455
456 buffer_put_string(b, serverhostkeyblob, sbloblen);
457 buffer_put_bignum2(b, client_dh_pub);
458 buffer_put_bignum2(b, server_dh_pub);
459 buffer_put_bignum2(b, shared_secret);
460
461 // yutaka
462 //debug_print(38, buffer_ptr(b), buffer_len(b));
463
464 EVP_DigestInit(md, evp_md);
465 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
466 EVP_DigestFinal(md, digest, NULL);
467
468 buffer_free(b);
469
470 //write_buffer_file(digest, EVP_MD_size(evp_md));
471
472 *hashlen = EVP_MD_size(evp_md);
473
474 error:
475 if (md)
476 EVP_MD_CTX_free(md);
477
478 return digest;
479 }
480
481
482 // shared secret ���v�Z���� (DH GEX�p)
483 unsigned char *kex_dh_gex_hash(const EVP_MD *evp_md,
484 char *client_version_string,
485 char *server_version_string,
486 char *ckexinit, int ckexinitlen,
487 char *skexinit, int skexinitlen,
488 u_char *serverhostkeyblob, int sbloblen,
489 int kexgex_min,
490 int kexgex_bits,
491 int kexgex_max,
492 BIGNUM *kexgex_p,
493 BIGNUM *kexgex_g,
494 BIGNUM *client_dh_pub,
495 BIGNUM *server_dh_pub,
496 BIGNUM *shared_secret,
497 unsigned int *hashlen)
498 {
499 buffer_t *b;
500 static unsigned char digest[EVP_MAX_MD_SIZE];
501 EVP_MD_CTX *md = NULL;
502
503 md = EVP_MD_CTX_new();
504 if (md == NULL)
505 goto error;
506
507 b = buffer_init();
508 buffer_put_string(b, client_version_string, strlen(client_version_string));
509 buffer_put_string(b, server_version_string, strlen(server_version_string));
510
511 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
512 buffer_put_int(b, ckexinitlen+1);
513 buffer_put_char(b, SSH2_MSG_KEXINIT);
514 buffer_append(b, ckexinit, ckexinitlen);
515 buffer_put_int(b, skexinitlen+1);
516 buffer_put_char(b, SSH2_MSG_KEXINIT);
517 buffer_append(b, skexinit, skexinitlen);
518
519 buffer_put_string(b, serverhostkeyblob, sbloblen);
520
521 // DH group size���r�b�g�������Z����
522 buffer_put_int(b, kexgex_min);
523 buffer_put_int(b, kexgex_bits);
524 buffer_put_int(b, kexgex_max);
525
526 // DH�����f���������������Z����
527 buffer_put_bignum2(b, kexgex_p);
528 buffer_put_bignum2(b, kexgex_g);
529
530 buffer_put_bignum2(b, client_dh_pub);
531 buffer_put_bignum2(b, server_dh_pub);
532 buffer_put_bignum2(b, shared_secret);
533
534 // yutaka
535 //debug_print(38, buffer_ptr(b), buffer_len(b));
536
537 EVP_DigestInit(md, evp_md);
538 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
539 EVP_DigestFinal(md, digest, NULL);
540
541 buffer_free(b);
542
543 //write_buffer_file(digest, EVP_MD_size(evp_md));
544
545 *hashlen = EVP_MD_size(evp_md);
546
547 error:
548 if (md)
549 EVP_MD_CTX_free(md);
550
551 return digest;
552 }
553
554
555 unsigned char *kex_ecdh_hash(const EVP_MD *evp_md,
556 const EC_GROUP *ec_group,
557 char *client_version_string,
558 char *server_version_string,
559 char *ckexinit, int ckexinitlen,
560 char *skexinit, int skexinitlen,
561 u_char *serverhostkeyblob, int sbloblen,
562 const EC_POINT *client_dh_pub,
563 const EC_POINT *server_dh_pub,
564 BIGNUM *shared_secret,
565 unsigned int *hashlen)
566 {
567 buffer_t *b;
568 static unsigned char digest[EVP_MAX_MD_SIZE];
569 EVP_MD_CTX *md = NULL;
570
571 md = EVP_MD_CTX_new();
572 if (md == NULL)
573 goto error;
574
575 b = buffer_init();
576 buffer_put_string(b, client_version_string, strlen(client_version_string));
577 buffer_put_string(b, server_version_string, strlen(server_version_string));
578
579 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
580 buffer_put_int(b, ckexinitlen+1);
581 buffer_put_char(b, SSH2_MSG_KEXINIT);
582 buffer_append(b, ckexinit, ckexinitlen);
583 buffer_put_int(b, skexinitlen+1);
584 buffer_put_char(b, SSH2_MSG_KEXINIT);
585 buffer_append(b, skexinit, skexinitlen);
586
587 buffer_put_string(b, serverhostkeyblob, sbloblen);
588
589 buffer_put_ecpoint(b, ec_group, client_dh_pub);
590 buffer_put_ecpoint(b, ec_group, server_dh_pub);
591 buffer_put_bignum2(b, shared_secret);
592
593 // yutaka
594 //debug_print(38, buffer_ptr(b), buffer_len(b));
595
596 EVP_DigestInit(md, evp_md);
597 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
598 EVP_DigestFinal(md, digest, NULL);
599
600 buffer_free(b);
601
602 //write_buffer_file(digest, EVP_MD_size(evp_md));
603
604 *hashlen = EVP_MD_size(evp_md);
605
606 error:
607 if (md)
608 EVP_MD_CTX_free(md);
609
610 return digest;
611 }
612
613
614 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
615 {
616 int i;
617 int n = BN_num_bits(dh_pub);
618 int bits_set = 0;
619 const BIGNUM *p;
620
621 // OpenSSL 1.1.0���ABIGNUM�\������neg�����o�[�������A�N�Z�X�������������������A
622 // BN_is_negative�������u�������BOpenSSL 1.0.2�����}�N�����`���������������A
623 // OpenSSL 1.0.2�����A�����������������B
624 if (BN_is_negative(dh_pub)) {
625 //logit("invalid public DH value: negativ");
626 return 0;
627 }
628 for (i = 0; i <= n; i++)
629 if (BN_is_bit_set(dh_pub, i))
630 bits_set++;
631 //debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
632
633 /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
634 DH_get0_pqg(dh, &p, NULL, NULL);
635 if (bits_set > 1 && (BN_cmp(dh_pub, p) == -1))
636 return 1;
637 //logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
638 return 0;
639 }
640
641
642 static u_char *derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret,
643 char *session_id, int session_id_len,
644 const EVP_MD *evp_md)
645 {
646 buffer_t *b;
647 EVP_MD_CTX *md = NULL;
648 char c = id;
649 int have;
650 int mdsz = EVP_MD_size(evp_md);
651 u_char *digest = malloc(roundup(need, mdsz));
652
653 md = EVP_MD_CTX_new();
654 if (md == NULL)
655 goto skip;
656
657 if (digest == NULL)
658 goto skip;
659
660 b = buffer_init();
661 if (b == NULL)
662 goto skip;
663
664 buffer_put_bignum2(b, shared_secret);
665
666 /* K1 = HASH(K || H || "A" || session_id) */
667 EVP_DigestInit(md, evp_md);
668 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
669 EVP_DigestUpdate(md, hash, mdsz);
670 EVP_DigestUpdate(md, &c, 1);
671 EVP_DigestUpdate(md, session_id, session_id_len);
672 EVP_DigestFinal(md, digest, NULL);
673
674 /*
675 * expand key:
676 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
677 * Key = K1 || K2 || ... || Kn
678 */
679 for (have = mdsz; need > have; have += mdsz) {
680 EVP_DigestInit(md, evp_md);
681 EVP_DigestUpdate(md, buffer_ptr(b), buffer_len(b));
682 EVP_DigestUpdate(md, hash, mdsz);
683 EVP_DigestUpdate(md, digest, have);
684 EVP_DigestFinal(md, digest + have, NULL);
685 }
686 buffer_free(b);
687
688 skip:;
689 if (md)
690 EVP_MD_CTX_free(md);
691
692 return digest;
693 }
694
695 /*
696 * �����������������e���������� newkeys ���Z�b�g���������B
697 */
698 void kex_derive_keys(PTInstVar pvar, SSHKeys *newkeys, int need, u_char *hash, BIGNUM *shared_secret,
699 char *session_id, int session_id_len)
700 {
701 #define NKEYS 6
702 u_char *keys[NKEYS];
703 int i, mode, ctos;
704
705 for (i = 0; i < NKEYS; i++) {
706 keys[i] = derive_key('A'+i, need, hash, shared_secret, session_id, session_id_len,
707 get_kex_algorithm_EVP_MD(pvar->kex_type));
708 //debug_print(i, keys[i], need);
709 }
710
711 for (mode = 0; mode < MODE_MAX; mode++) {
712 if (mode == MODE_OUT)
713 ctos = 1;
714 else
715 ctos = 0;
716
717 // setting
718 newkeys[mode].enc.iv = keys[ctos ? 0 : 1];
719 newkeys[mode].enc.key = keys[ctos ? 2 : 3];
720 newkeys[mode].mac.key = keys[ctos ? 4 : 5];
721
722 //debug_print(20 + mode*3, newkeys[mode]->enc.iv, 8);
723 //debug_print(21 + mode*3, newkeys[mode]->enc.key, 24);
724 //debug_print(22 + mode*3, newkeys[mode]->mac.key, 24);
725 }
726 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26