Mercurial > dropbear
comparison common-algo.c @ 801:7dcb46da72d9 ecc
merge in HEAD
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 21 May 2013 12:09:35 +0800 |
parents | 7f604f9b3756 077bbe1eb220 |
children | 5128e525c8fa |
comparison
equal
deleted
inserted
replaced
799:c344607b7341 | 801:7dcb46da72d9 |
---|---|
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
24 * SOFTWARE. */ | 24 * SOFTWARE. */ |
25 | 25 |
26 #include "includes.h" | 26 #include "includes.h" |
27 #include "algo.h" | 27 #include "algo.h" |
28 #include "session.h" | |
28 #include "dbutil.h" | 29 #include "dbutil.h" |
29 #include "kex.h" | 30 #include "kex.h" |
30 #include "ltc_prng.h" | 31 #include "ltc_prng.h" |
31 #include "ecc.h" | 32 #include "ecc.h" |
32 | 33 |
255 {"ecdh-sha2-nistp521", 0, &kex_ecdh_nistp521, 1, NULL}, | 256 {"ecdh-sha2-nistp521", 0, &kex_ecdh_nistp521, 1, NULL}, |
256 #endif | 257 #endif |
257 #endif | 258 #endif |
258 {"diffie-hellman-group1-sha1", 0, &kex_dh_group1, 1, NULL}, | 259 {"diffie-hellman-group1-sha1", 0, &kex_dh_group1, 1, NULL}, |
259 {"diffie-hellman-group14-sha1", 0, &kex_dh_group14, 1, NULL}, | 260 {"diffie-hellman-group14-sha1", 0, &kex_dh_group14, 1, NULL}, |
261 #ifdef USE_KEXGUESS2 | |
262 {KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL}, | |
263 #endif | |
260 {NULL, 0, NULL, 0, NULL} | 264 {NULL, 0, NULL, 0, NULL} |
261 }; | 265 }; |
262 | 266 |
263 /* algolen specifies the length of algo, algos is our local list to match | 267 /* algolen specifies the length of algo, algos is our local list to match |
264 * against. | 268 * against. |
295 buf_putbytes(algolist, localalgos[i].name, len); | 299 buf_putbytes(algolist, localalgos[i].name, len); |
296 } | 300 } |
297 } | 301 } |
298 buf_putstring(buf, algolist->data, algolist->len); | 302 buf_putstring(buf, algolist->data, algolist->len); |
299 buf_free(algolist); | 303 buf_free(algolist); |
304 } | |
305 | |
306 /* match the first algorithm in the comma-separated list in buf which is | |
307 * also in localalgos[], or return NULL on failure. | |
308 * (*goodguess) is set to 1 if the preferred client/server algos match, | |
309 * 0 otherwise. This is used for checking if the kexalgo/hostkeyalgos are | |
310 * guessed correctly */ | |
311 algo_type * buf_match_algo(buffer* buf, algo_type localalgos[], | |
312 enum kexguess2_used *kexguess2, int *goodguess) | |
313 { | |
314 | |
315 unsigned char * algolist = NULL; | |
316 const unsigned char *remotenames[MAX_PROPOSED_ALGO], *localnames[MAX_PROPOSED_ALGO]; | |
317 unsigned int len; | |
318 unsigned int remotecount, localcount, clicount, servcount, i, j; | |
319 algo_type * ret = NULL; | |
320 const unsigned char **clinames, **servnames; | |
321 | |
322 if (goodguess) { | |
323 *goodguess = 0; | |
324 } | |
325 | |
326 /* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */ | |
327 algolist = buf_getstring(buf, &len); | |
328 TRACE(("buf_match_algo: %s", algolist)) | |
329 if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) { | |
330 goto out; | |
331 } | |
332 | |
333 /* remotenames will contain a list of the strings parsed out */ | |
334 /* We will have at least one string (even if it's just "") */ | |
335 remotenames[0] = algolist; | |
336 remotecount = 1; | |
337 for (i = 0; i < len; i++) { | |
338 if (algolist[i] == '\0') { | |
339 /* someone is trying something strange */ | |
340 goto out; | |
341 } | |
342 if (algolist[i] == ',') { | |
343 algolist[i] = '\0'; | |
344 remotenames[remotecount] = &algolist[i+1]; | |
345 remotecount++; | |
346 } | |
347 if (remotecount >= MAX_PROPOSED_ALGO) { | |
348 break; | |
349 } | |
350 } | |
351 if (kexguess2 && *kexguess2 == KEXGUESS2_LOOK) { | |
352 for (i = 0; i < remotecount; i++) | |
353 { | |
354 if (strcmp(remotenames[i], KEXGUESS2_ALGO_NAME) == 0) { | |
355 *kexguess2 = KEXGUESS2_YES; | |
356 break; | |
357 } | |
358 } | |
359 if (*kexguess2 == KEXGUESS2_LOOK) { | |
360 *kexguess2 = KEXGUESS2_NO; | |
361 } | |
362 } | |
363 | |
364 for (i = 0; localalgos[i].name != NULL; i++) { | |
365 if (localalgos[i].usable) { | |
366 localnames[i] = localalgos[i].name; | |
367 } else { | |
368 localnames[i] = NULL; | |
369 } | |
370 } | |
371 localcount = i; | |
372 | |
373 if (IS_DROPBEAR_SERVER) { | |
374 clinames = remotenames; | |
375 clicount = remotecount; | |
376 servnames = localnames; | |
377 servcount = localcount; | |
378 } else { | |
379 clinames = localnames; | |
380 clicount = localcount; | |
381 servnames = remotenames; | |
382 servcount = remotecount; | |
383 } | |
384 | |
385 /* iterate and find the first match */ | |
386 for (i = 0; i < clicount; i++) { | |
387 for (j = 0; j < servcount; j++) { | |
388 if (!(servnames[j] && clinames[i])) { | |
389 // unusable algos are NULL | |
390 continue; | |
391 } | |
392 if (strcmp(servnames[j], clinames[i]) == 0) { | |
393 /* set if it was a good guess */ | |
394 if (goodguess && kexguess2) { | |
395 if (*kexguess2 == KEXGUESS2_YES) { | |
396 if (i == 0) { | |
397 *goodguess = 1; | |
398 } | |
399 | |
400 } else { | |
401 if (i == 0 && j == 0) { | |
402 *goodguess = 1; | |
403 } | |
404 } | |
405 } | |
406 /* set the algo to return */ | |
407 if (IS_DROPBEAR_SERVER) { | |
408 ret = &localalgos[j]; | |
409 } else { | |
410 ret = &localalgos[i]; | |
411 } | |
412 goto out; | |
413 } | |
414 } | |
415 } | |
416 | |
417 out: | |
418 m_free(algolist); | |
419 return ret; | |
300 } | 420 } |
301 | 421 |
302 #ifdef DROPBEAR_NONE_CIPHER | 422 #ifdef DROPBEAR_NONE_CIPHER |
303 | 423 |
304 void | 424 void |