Mercurial > dropbear
diff 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 |
line wrap: on
line diff
--- a/signkey.c Wed Mar 30 10:23:39 2022 +0800 +++ b/signkey.c Wed Mar 30 11:44:04 2022 +0800 @@ -544,98 +544,42 @@ TRACE2(("leave sign_key_free")) } -static char hexdig(unsigned char x) { - if (x > 0xf) - return 'X'; - - if (x < 10) - return '0' + x; - else - return 'a' + x - 10; -} - -/* Since we're not sure if we'll have md5 or sha1, we present both. - * MD5 is used in preference, but sha1 could still be useful */ -#if DROPBEAR_MD5_HMAC -static char * sign_key_md5_fingerprint(const unsigned char* keyblob, +static char * sign_key_sha256_fingerprint(const unsigned char* keyblob, unsigned int keybloblen) { char * ret; hash_state hs; - unsigned char hash[MD5_HASH_SIZE]; - unsigned int i; - unsigned int buflen; + unsigned char hash[SHA256_HASH_SIZE]; + unsigned int b64chars, start; + unsigned long b64size; + const char *prefix = "SHA256:"; + int err; - md5_init(&hs); - - /* skip the size int of the string - this is a bit messy */ - md5_process(&hs, keyblob, keybloblen); - - md5_done(&hs, hash); + sha256_init(&hs); + sha256_process(&hs, keyblob, keybloblen); + sha256_done(&hs, hash); - /* "md5 hexfingerprinthere\0", each hex digit is "AB:" etc */ - buflen = 4 + 3*MD5_HASH_SIZE; - ret = (char*)m_malloc(buflen); - - memset(ret, 'Z', buflen); - strcpy(ret, "md5 "); + /* eg "SHA256:P9szN0L2ls6KxkVv7Bppv3asnZCn03rY7Msm/c8+ZgA" + * 256/6 = 42.66 => 43 base64 chars. OpenSSH discards + * base64 padding output. */ + start = strlen(prefix); + b64chars = 43; + /* space for discarded b64 padding and null terminator */ + b64size = b64chars + 4; + ret = m_malloc(start + b64size); - for (i = 0; i < MD5_HASH_SIZE; i++) { - unsigned int pos = 4 + i*3; - ret[pos] = hexdig(hash[i] >> 4); - ret[pos+1] = hexdig(hash[i] & 0x0f); - ret[pos+2] = ':'; + memcpy(ret, prefix, start); + err = base64_encode(hash, SHA256_HASH_SIZE, &ret[start], &b64size); + if (err != CRYPT_OK) { + dropbear_exit("base64 failed"); } - ret[buflen-1] = 0x0; - + ret[start + b64chars] = '\0'; return ret; } -#else /* use SHA1 rather than MD5 for fingerprint */ -static char * sign_key_sha1_fingerprint(const unsigned char* keyblob, - unsigned int keybloblen) { - - char * ret; - hash_state hs; - unsigned char hash[SHA1_HASH_SIZE]; - unsigned int i; - unsigned int buflen; - - sha1_init(&hs); - - /* skip the size int of the string - this is a bit messy */ - sha1_process(&hs, keyblob, keybloblen); - - sha1_done(&hs, hash); - - /* "sha1!! hexfingerprinthere\0", each hex digit is "AB:" etc */ - buflen = 7 + 3*SHA1_HASH_SIZE; - ret = (char*)m_malloc(buflen); - - strcpy(ret, "sha1 "); - - for (i = 0; i < SHA1_HASH_SIZE; i++) { - unsigned int pos = 7 + 3*i; - ret[pos] = hexdig(hash[i] >> 4); - ret[pos+1] = hexdig(hash[i] & 0x0f); - ret[pos+2] = ':'; - } - ret[buflen-1] = 0x0; - - return ret; -} - -#endif /* MD5/SHA1 switch */ - -/* This will return a freshly malloced string, containing a fingerprint - * in either sha1 or md5 */ +/* This will return a freshly malloced string */ char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloblen) { - -#if DROPBEAR_MD5_HMAC - return sign_key_md5_fingerprint(keyblob, keybloblen); -#else - return sign_key_sha1_fingerprint(keyblob, keybloblen); -#endif + return sign_key_sha256_fingerprint(keyblob, keybloblen); } void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,