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);