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