Mercurial > dropbear
comparison signkey.c @ 1916:3f4cdf839a1a
Make SHA1 optional, implement SHA256 fingerprints
SHA256 is always compiled and only enable SHA1 when needed. Fingerprints
are always SHA256: base64 format, md5 and sha1 are removed. dbrandom now
uses sha256 its hash function.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 30 Mar 2022 11:44:04 +0800 |
parents | 35d504d59c05 |
children |
comparison
equal
deleted
inserted
replaced
1915:13cb8cc1b0e4 | 1916:3f4cdf839a1a |
---|---|
542 | 542 |
543 m_free(key); | 543 m_free(key); |
544 TRACE2(("leave sign_key_free")) | 544 TRACE2(("leave sign_key_free")) |
545 } | 545 } |
546 | 546 |
547 static char hexdig(unsigned char x) { | 547 static char * sign_key_sha256_fingerprint(const unsigned char* keyblob, |
548 if (x > 0xf) | |
549 return 'X'; | |
550 | |
551 if (x < 10) | |
552 return '0' + x; | |
553 else | |
554 return 'a' + x - 10; | |
555 } | |
556 | |
557 /* Since we're not sure if we'll have md5 or sha1, we present both. | |
558 * MD5 is used in preference, but sha1 could still be useful */ | |
559 #if DROPBEAR_MD5_HMAC | |
560 static char * sign_key_md5_fingerprint(const unsigned char* keyblob, | |
561 unsigned int keybloblen) { | 548 unsigned int keybloblen) { |
562 | 549 |
563 char * ret; | 550 char * ret; |
564 hash_state hs; | 551 hash_state hs; |
565 unsigned char hash[MD5_HASH_SIZE]; | 552 unsigned char hash[SHA256_HASH_SIZE]; |
566 unsigned int i; | 553 unsigned int b64chars, start; |
567 unsigned int buflen; | 554 unsigned long b64size; |
568 | 555 const char *prefix = "SHA256:"; |
569 md5_init(&hs); | 556 int err; |
570 | 557 |
571 /* skip the size int of the string - this is a bit messy */ | 558 sha256_init(&hs); |
572 md5_process(&hs, keyblob, keybloblen); | 559 sha256_process(&hs, keyblob, keybloblen); |
573 | 560 sha256_done(&hs, hash); |
574 md5_done(&hs, hash); | 561 |
575 | 562 /* eg "SHA256:P9szN0L2ls6KxkVv7Bppv3asnZCn03rY7Msm/c8+ZgA" |
576 /* "md5 hexfingerprinthere\0", each hex digit is "AB:" etc */ | 563 * 256/6 = 42.66 => 43 base64 chars. OpenSSH discards |
577 buflen = 4 + 3*MD5_HASH_SIZE; | 564 * base64 padding output. */ |
578 ret = (char*)m_malloc(buflen); | 565 start = strlen(prefix); |
579 | 566 b64chars = 43; |
580 memset(ret, 'Z', buflen); | 567 /* space for discarded b64 padding and null terminator */ |
581 strcpy(ret, "md5 "); | 568 b64size = b64chars + 4; |
582 | 569 ret = m_malloc(start + b64size); |
583 for (i = 0; i < MD5_HASH_SIZE; i++) { | 570 |
584 unsigned int pos = 4 + i*3; | 571 memcpy(ret, prefix, start); |
585 ret[pos] = hexdig(hash[i] >> 4); | 572 err = base64_encode(hash, SHA256_HASH_SIZE, &ret[start], &b64size); |
586 ret[pos+1] = hexdig(hash[i] & 0x0f); | 573 if (err != CRYPT_OK) { |
587 ret[pos+2] = ':'; | 574 dropbear_exit("base64 failed"); |
588 } | 575 } |
589 ret[buflen-1] = 0x0; | 576 ret[start + b64chars] = '\0'; |
590 | |
591 return ret; | 577 return ret; |
592 } | 578 } |
593 | 579 |
594 #else /* use SHA1 rather than MD5 for fingerprint */ | 580 /* This will return a freshly malloced string */ |
595 static char * sign_key_sha1_fingerprint(const unsigned char* keyblob, | |
596 unsigned int keybloblen) { | |
597 | |
598 char * ret; | |
599 hash_state hs; | |
600 unsigned char hash[SHA1_HASH_SIZE]; | |
601 unsigned int i; | |
602 unsigned int buflen; | |
603 | |
604 sha1_init(&hs); | |
605 | |
606 /* skip the size int of the string - this is a bit messy */ | |
607 sha1_process(&hs, keyblob, keybloblen); | |
608 | |
609 sha1_done(&hs, hash); | |
610 | |
611 /* "sha1!! hexfingerprinthere\0", each hex digit is "AB:" etc */ | |
612 buflen = 7 + 3*SHA1_HASH_SIZE; | |
613 ret = (char*)m_malloc(buflen); | |
614 | |
615 strcpy(ret, "sha1 "); | |
616 | |
617 for (i = 0; i < SHA1_HASH_SIZE; i++) { | |
618 unsigned int pos = 7 + 3*i; | |
619 ret[pos] = hexdig(hash[i] >> 4); | |
620 ret[pos+1] = hexdig(hash[i] & 0x0f); | |
621 ret[pos+2] = ':'; | |
622 } | |
623 ret[buflen-1] = 0x0; | |
624 | |
625 return ret; | |
626 } | |
627 | |
628 #endif /* MD5/SHA1 switch */ | |
629 | |
630 /* This will return a freshly malloced string, containing a fingerprint | |
631 * in either sha1 or md5 */ | |
632 char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloblen) { | 581 char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloblen) { |
633 | 582 return sign_key_sha256_fingerprint(keyblob, keybloblen); |
634 #if DROPBEAR_MD5_HMAC | |
635 return sign_key_md5_fingerprint(keyblob, keybloblen); | |
636 #else | |
637 return sign_key_sha1_fingerprint(keyblob, keybloblen); | |
638 #endif | |
639 } | 583 } |
640 | 584 |
641 void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype, | 585 void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype, |
642 const buffer *data_buf) { | 586 const buffer *data_buf) { |
643 buffer *sigblob = buf_new(MAX_PUBKEY_SIZE); | 587 buffer *sigblob = buf_new(MAX_PUBKEY_SIZE); |