comparison signkey.c @ 51:095d689fed16

- Hostkey checking is mostly there, just aren't appending yet. - Rearranged various bits of the fingerprint/base64 type code, so it can be shared between versions
author Matt Johnston <matt@ucc.asn.au>
date Sun, 08 Aug 2004 16:17:05 +0000
parents 45edf30ea0a6
children b0316ce64e4b
comparison
equal deleted inserted replaced
49:cc59bfcdee17 51:095d689fed16
270 } 270 }
271 271
272 /* Since we're not sure if we'll have md5 or sha1, we present both. 272 /* Since we're not sure if we'll have md5 or sha1, we present both.
273 * MD5 is used in preference, but sha1 could still be useful */ 273 * MD5 is used in preference, but sha1 could still be useful */
274 #ifdef DROPBEAR_MD5_HMAC 274 #ifdef DROPBEAR_MD5_HMAC
275 static char * sign_key_md5_fingerprint(sign_key *key, int type) { 275 static char * sign_key_md5_fingerprint(unsigned char* keyblob,
276 unsigned int keybloblen) {
276 277
277 char * ret; 278 char * ret;
278 hash_state hs; 279 hash_state hs;
279 buffer *pubkeys;
280 unsigned char hash[MD5_HASH_SIZE]; 280 unsigned char hash[MD5_HASH_SIZE];
281 unsigned int h, i; 281 unsigned int h, i;
282 unsigned int buflen; 282 unsigned int buflen;
283 283
284 md5_init(&hs); 284 md5_init(&hs);
285 285
286 pubkeys = buf_new(1000);
287 buf_put_pub_key(pubkeys, key, type);
288 /* skip the size int of the string - this is a bit messy */ 286 /* skip the size int of the string - this is a bit messy */
289 buf_setpos(pubkeys, 4); 287 md5_process(&hs, keyblob, keybloblen);
290 md5_process(&hs, buf_getptr(pubkeys, pubkeys->len-pubkeys->pos), 288
291 pubkeys->len-pubkeys->pos);
292
293 buf_free(pubkeys);
294 md5_done(&hs, hash); 289 md5_done(&hs, hash);
295 290
296 /* "md5 hexfingerprinthere\0", each hex digit is "AB:" etc */ 291 /* "md5 hexfingerprinthere\0", each hex digit is "AB:" etc */
297 buflen = 4 + 3*MD5_HASH_SIZE; 292 buflen = 4 + 3*MD5_HASH_SIZE;
298 ret = (char*)m_malloc(buflen); 293 ret = (char*)m_malloc(buflen);
309 304
310 return ret; 305 return ret;
311 } 306 }
312 307
313 #else /* use SHA1 rather than MD5 for fingerprint */ 308 #else /* use SHA1 rather than MD5 for fingerprint */
314 static char * sign_key_sha1_fingerprint(sign_key *key, int type) { 309 static char * sign_key_sha1_fingerprint(unsigned char* keyblob,
310 unsigned int keybloblen) {
315 311
316 char * ret; 312 char * ret;
317 hash_state hs; 313 hash_state hs;
318 buffer *pubkeys;
319 unsigned char hash[SHA1_HASH_SIZE]; 314 unsigned char hash[SHA1_HASH_SIZE];
320 unsigned int h, i; 315 unsigned int h, i;
321 unsigned int buflen; 316 unsigned int buflen;
322 317
323 sha1_init(&hs); 318 sha1_init(&hs);
324 319
325 pubkeys = buf_new(1000);
326 buf_put_pub_key(pubkeys, key, type);
327 buf_setpos(pubkeys, 4);
328 /* skip the size int of the string - this is a bit messy */ 320 /* skip the size int of the string - this is a bit messy */
329 sha1_process(&hs, buf_getptr(pubkeys, pubkeys->len-pubkeys->pos), 321 sha1_process(&hs, keyblob, keybloblen);
330 pubkeys->len-pubkeys->pos); 322
331
332 buf_free(pubkeys);
333 sha1_done(&hs, hash); 323 sha1_done(&hs, hash);
334 324
335 /* "sha1 hexfingerprinthere\0", each hex digit is "AB:" etc */ 325 /* "sha1 hexfingerprinthere\0", each hex digit is "AB:" etc */
336 buflen = 5 + 3*SHA1_HASH_SIZE; 326 buflen = 5 + 3*SHA1_HASH_SIZE;
337 ret = (char*)m_malloc(buflen); 327 ret = (char*)m_malloc(buflen);
350 340
351 #endif /* MD5/SHA1 switch */ 341 #endif /* MD5/SHA1 switch */
352 342
353 /* This will return a freshly malloced string, containing a fingerprint 343 /* This will return a freshly malloced string, containing a fingerprint
354 * in either sha1 or md5 */ 344 * in either sha1 or md5 */
355 char * sign_key_fingerprint(sign_key *key, int type) { 345 char * sign_key_fingerprint(unsigned char* keyblob, unsigned int keybloblen) {
356 346
357 #ifdef DROPBEAR_MD5_HMAC 347 #ifdef DROPBEAR_MD5_HMAC
358 return sign_key_md5_fingerprint(key, type); 348 return sign_key_md5_fingerprint(keyblob, keybloblen);
359 #else 349 #else
360 return sign_key_sha1_fingerprint(key, type); 350 return sign_key_sha1_fingerprint(keyblob, keybloblen);
361 #endif 351 #endif
362 } 352 }
363 353
364 void buf_put_sign(buffer* buf, sign_key *key, int type, 354 void buf_put_sign(buffer* buf, sign_key *key, int type,
365 const unsigned char *data, unsigned int len) { 355 const unsigned char *data, unsigned int len) {
425 m_free(ident); 415 m_free(ident);
426 dropbear_exit("non-matching signing type"); 416 dropbear_exit("non-matching signing type");
427 return DROPBEAR_FAILURE; 417 return DROPBEAR_FAILURE;
428 } 418 }
429 #endif /* DROPBEAR_SIGNKEY_VERIFY */ 419 #endif /* DROPBEAR_SIGNKEY_VERIFY */
420
421 #ifdef DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */
422
423 /* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE when given a buffer containing
424 * a key, a key, and a type. The buffer is positioned at the start of the
425 * base64 data, and contains no trailing data */
426 int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen,
427 const unsigned char* algoname, unsigned int algolen,
428 buffer * line) {
429
430 buffer * decodekey = NULL;
431 int ret = DROPBEAR_FAILURE;
432 unsigned int len, filealgolen;
433 unsigned long decodekeylen;
434 unsigned char* filealgo = NULL;
435
436 /* now we have the actual data */
437 len = line->len - line->pos;
438 decodekeylen = len * 2; /* big to be safe */
439 decodekey = buf_new(decodekeylen);
440
441 if (base64_decode(buf_getptr(line, len), len,
442 buf_getwriteptr(decodekey, decodekey->size),
443 &decodekeylen) != CRYPT_OK) {
444 TRACE(("checkpubkey: base64 decode failed"));
445 goto out;
446 }
447 TRACE(("checkpubkey: base64_decode success"));
448 buf_incrlen(decodekey, decodekeylen);
449
450 /* compare the keys */
451 if ( ( decodekeylen != keybloblen )
452 || memcmp( buf_getptr(decodekey, decodekey->len),
453 keyblob, decodekey->len) != 0) {
454 TRACE(("checkpubkey: compare failed"));
455 goto out;
456 }
457
458 /* ... and also check that the algo specified and the algo in the key
459 * itself match */
460 filealgolen = buf_getint(decodekey);
461 filealgo = buf_getptr(decodekey, filealgolen);
462 if (filealgolen != algolen || memcmp(filealgo, algoname, algolen) != 0) {
463 TRACE(("checkpubkey: algo match failed"));
464 goto out;
465 }
466
467 /* All checks passed */
468 ret = DROPBEAR_SUCCESS;
469
470 out:
471 buf_free(decodekey);
472 decodekey = NULL;
473 return ret;
474 }
475 #endif