Mercurial > dropbear
diff signkey.c @ 794:d386defb5376 ecc
more ecdsa signkey work, not correct
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 28 Apr 2013 23:17:43 +0800 |
parents | 70625eed40c9 |
children | 7f604f9b3756 |
line wrap: on
line diff
--- a/signkey.c Sun Apr 14 00:50:03 2013 +0800 +++ b/signkey.c Sun Apr 28 23:17:43 2013 +0800 @@ -27,6 +27,28 @@ #include "signkey.h" #include "buffer.h" #include "ssh.h" +#include "ecdsa.h" + +static const char *signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = { +#ifdef DROPBEAR_RSA + "ssh-rsa", +#endif +#ifdef DROPBEAR_DSS + "ssh-dss", +#endif +#ifdef DROPBEAR_ECDSA +#ifdef DROPBEAR_ECC_256 + "ecdsa-sha2-nistp256", +#endif +#ifdef DROPBEAR_ECC_384 + "ecdsa-sha2-nistp384", +#endif +#ifdef DROPBEAR_ECC_521 + "ecdsa-sha2-nistp521", +#endif + "ecdsa" // for keygen +#endif // DROPBEAR_ECDSA +}; /* malloc a new sign_key and set the dss and rsa keys to NULL */ sign_key * new_sign_key() { @@ -39,42 +61,29 @@ return ret; } -/* Returns "ssh-dss" or "ssh-rsa" corresponding to the type. Exits fatally +/* Returns key name corresponding to the type. Exits fatally * if the type is invalid */ -const char* signkey_name_from_type(int type, int *namelen) { - -#ifdef DROPBEAR_RSA - if (type == DROPBEAR_SIGNKEY_RSA) { - *namelen = SSH_SIGNKEY_RSA_LEN; - return SSH_SIGNKEY_RSA; +const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen) { + if (type >= DROPBEAR_SIGNKEY_NUM_NAMED) { + dropbear_exit("Bad key type %d", type); } -#endif -#ifdef DROPBEAR_DSS - if (type == DROPBEAR_SIGNKEY_DSS) { - *namelen = SSH_SIGNKEY_DSS_LEN; - return SSH_SIGNKEY_DSS; + + if (namelen) { + *namelen = strlen(signkey_names[type]); } -#endif - dropbear_exit("Bad key type %d", type); - return NULL; /* notreached */ + return signkey_names[type]; } -/* Returns DROPBEAR_SIGNKEY_RSA, DROPBEAR_SIGNKEY_DSS, - * or DROPBEAR_SIGNKEY_NONE */ -int signkey_type_from_name(const char* name, int namelen) { - -#ifdef DROPBEAR_RSA - if (namelen == SSH_SIGNKEY_RSA_LEN - && memcmp(name, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN) == 0) { - return DROPBEAR_SIGNKEY_RSA; +/* Returns DROPBEAR_SIGNKEY_NONE if none match */ +enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen) { + int i; + for (i = 0; i < DROPBEAR_SIGNKEY_NUM_NAMED; i++) { + const char *fixed_name = signkey_names[i]; + if (namelen == strlen(fixed_name) + && memcmp(fixed_name, name, namelen) == 0) { + return i; + } } -#endif -#ifdef DROPBEAR_DSS - if (namelen == SSH_SIGNKEY_DSS_LEN - && memcmp(name, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN) == 0) { - return DROPBEAR_SIGNKEY_DSS; - } -#endif TRACE(("signkey_type_from_name unexpected key type.")) @@ -129,6 +138,19 @@ } } #endif +#ifdef DROPBEAR_ECDSA + if (keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP256 + || keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP384 + || keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { + if (key->ecckey) { + ecc_free(key->ecckey); + } + key->ecckey = buf_get_ecdsa_pub_key(buf); + if (key->ecckey) { + ret = DROPBEAR_SUCCESS; + } + } +#endif TRACE(("leave buf_get_pub_key")) @@ -182,6 +204,19 @@ } } #endif +#ifdef DROPBEAR_ECDSA + if (keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP256 + || keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP384 + || keytype == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { + if (key->ecckey) { + ecc_free(key->ecckey); + } + key->ecckey = buf_get_ecdsa_priv_key(buf); + if (key->ecckey) { + ret = DROPBEAR_SUCCESS; + } + } +#endif TRACE(("leave buf_get_priv_key")) @@ -207,6 +242,13 @@ buf_put_rsa_pub_key(pubkeys, key->rsakey); } #endif +#ifdef DROPBEAR_ECDSA + if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 + || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 + || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { + buf_put_ecdsa_pub_key(pubkeys, key->ecckey); + } +#endif if (pubkeys->len == 0) { dropbear_exit("Bad key types in buf_put_pub_key"); } @@ -236,6 +278,14 @@ return; } #endif +#ifdef DROPBEAR_ECDSA + if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 + || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 + || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { + buf_put_ecdsa_pub_key(buf, key->ecckey); + return; + } +#endif dropbear_exit("Bad key types in put pub key"); } @@ -251,6 +301,12 @@ rsa_key_free(key->rsakey); key->rsakey = NULL; #endif +#ifdef DROPBEAR_ECDSA + if (key->ecckey) { + ecc_free(key->ecckey); + key->ecckey = NULL; + } +#endif m_free(key->filename); @@ -259,7 +315,6 @@ } static char hexdig(unsigned char x) { - if (x > 0xf) return 'X'; @@ -323,14 +378,14 @@ sha1_done(&hs, hash); - /* "sha1 hexfingerprinthere\0", each hex digit is "AB:" etc */ - buflen = 5 + 3*SHA1_HASH_SIZE; + /* "sha1!! hexfingerprinthere\0", each hex digit is "AB:" etc */ + buflen = 7 + 3*SHA1_HASH_SIZE; ret = (char*)m_malloc(buflen); - strcpy(ret, "sha1 "); + strcpy(ret, "sha1!! "); for (i = 0; i < SHA1_HASH_SIZE; i++) { - unsigned int pos = 5 + 3*i; + unsigned int pos = 7 + 3*i; ret[pos] = hexdig(hash[i] >> 4); ret[pos+1] = hexdig(hash[i] & 0x0f); ret[pos+2] = ':'; @@ -368,6 +423,13 @@ buf_put_rsa_sign(sigblob, key->rsakey, data_buf); } #endif +#ifdef DROPBEAR_ECDSA + if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 + || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 + || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { + buf_put_ecdsa_sign(sigblob, key->ecckey, data_buf); + } +#endif if (sigblob->len == 0) { dropbear_exit("Non-matching signing type"); } @@ -384,18 +446,18 @@ int buf_verify(buffer * buf, sign_key *key, buffer *data_buf) { unsigned int bloblen; - unsigned char * ident = NULL; - unsigned int identlen = 0; + unsigned char * type_name = NULL; + unsigned int type_name_len = 0; TRACE(("enter buf_verify")) bloblen = buf_getint(buf); - ident = buf_getstring(buf, &identlen); + type_name = buf_getstring(buf, &type_name_len); + enum signkey_type type = signkey_type_from_name(type_name, type_name_len); + m_free(type_name); #ifdef DROPBEAR_DSS - if (bloblen == DSS_SIGNATURE_SIZE && - memcmp(ident, SSH_SIGNKEY_DSS, identlen) == 0) { - m_free(ident); + if (type == DROPBEAR_SIGNKEY_DSS) { if (key->dsskey == NULL) { dropbear_exit("No DSS key to verify signature"); } @@ -404,16 +466,21 @@ #endif #ifdef DROPBEAR_RSA - if (memcmp(ident, SSH_SIGNKEY_RSA, identlen) == 0) { - m_free(ident); + if (type == DROPBEAR_SIGNKEY_RSA) { if (key->rsakey == NULL) { dropbear_exit("No RSA key to verify signature"); } return buf_rsa_verify(buf, key->rsakey, data_buf); } #endif +#ifdef DROPBEAR_ECDSA + if (type == DROPBEAR_SIGNKEY_ECDSA_NISTP256 + || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384 + || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) { + return buf_ecdsa_verify(buf, key->ecckey, data_buf); + } +#endif - m_free(ident); dropbear_exit("Non-matching signing type"); return DROPBEAR_FAILURE; }