svnno****@sourc*****
svnno****@sourc*****
2014年 3月 15日 (土) 18:06:31 JST
Revision: 5535 http://sourceforge.jp/projects/ttssh2/scm/svn/commits/5535 Author: yutakapon Date: 2014-03-15 18:06:31 +0900 (Sat, 15 Mar 2014) Log Message: ----------- 接続処理の ED25519 対応を更新中。 CDCまで。 Modified Paths: -------------- branches/ssh_ed25519/ttssh2/ttxssh/hosts.c branches/ssh_ed25519/ttssh2/ttxssh/key.c -------------- next part -------------- Modified: branches/ssh_ed25519/ttssh2/ttxssh/hosts.c =================================================================== --- branches/ssh_ed25519/ttssh2/ttxssh/hosts.c 2014-03-13 15:39:48 UTC (rev 5534) +++ branches/ssh_ed25519/ttssh2/ttxssh/hosts.c 2014-03-15 09:06:31 UTC (rev 5535) @@ -645,6 +645,7 @@ pvar->hosts_state.hostkey.dsa = key->dsa; pvar->hosts_state.hostkey.rsa = key->rsa; pvar->hosts_state.hostkey.ecdsa = key->ecdsa; + pvar->hosts_state.hostkey.ed25519_pk = key->ed25519_pk; index += eat_base64(data + index); index += eat_spaces(data + index); @@ -837,8 +838,8 @@ case KEY_ED25519: a = key; b = &pvar->hosts_state.hostkey; - return a->ed25519_pk != NULL && b->ed25519_pk != NULL && - memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0; + return a->ed25519_pk != NULL && b->ed25519_pk != NULL && + memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0; default: return FALSE; Modified: branches/ssh_ed25519/ttssh2/ttxssh/key.c =================================================================== --- branches/ssh_ed25519/ttssh2/ttxssh/key.c 2014-03-13 15:39:48 UTC (rev 5534) +++ branches/ssh_ed25519/ttssh2/ttxssh/key.c 2014-03-15 09:06:31 UTC (rev 5535) @@ -351,6 +351,75 @@ return ret; } +static int ssh_ed25519_verify(Key *key, unsigned char *signature, unsigned int signaturelen, + unsigned char *data, unsigned int datalen) +{ + buffer_t *b; + char *ktype = NULL; + unsigned char *sigblob = NULL, *sm = NULL, *m = NULL; + unsigned int len; + unsigned long long smlen, mlen; + int rlen, ret; + + ret = -1; + b = buffer_init(); + if (b == NULL) + goto error; + + buffer_append(b, signature, signaturelen); + ktype = buffer_get_string_msg(b, NULL); + if (strcmp("ssh-ed25519", ktype) != 0) { + goto error; + } + sigblob = buffer_get_string_msg(b, &len); + rlen = buffer_remain_len(b); + if (rlen != 0) { + goto error; + } + if (len > crypto_sign_ed25519_BYTES) { + goto error; + } + + smlen = len + datalen; + sm = malloc((size_t)smlen); + memcpy(sm, sigblob, len); + memcpy(sm+len, data, datalen); + mlen = smlen; + m = malloc((size_t)mlen); + + if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen, + key->ed25519_pk)) != 0) { + //debug2("%s: crypto_sign_ed25519_open failed: %d", + // __func__, ret); + } + if (ret == 0 && mlen != datalen) { + //debug2("%s: crypto_sign_ed25519_open " + // "mlen != datalen (%llu != %u)", __func__, mlen, datalen); + ret = -1; + } + /* XXX compare 'm' and 'data' ? */ + +error: + buffer_free(b); + free(ktype); + + if (sigblob) { + memset(sigblob, 's', len); + free(sigblob); + } + if (sm) { + memset(sm, 'S', (size_t)smlen); + free(sm); + } + if (m) { + memset(m, 'm', (size_t)smlen); /* NB. mlen may be invalid if ret != 0 */ + free(m); + } + + /* translate return code carefully */ + return (ret == 0) ? 1 : -1; +} + int key_verify(Key *key, unsigned char *signature, unsigned int signaturelen, unsigned char *data, unsigned int datalen) @@ -370,7 +439,7 @@ ret = ssh_ecdsa_verify(key->ecdsa, key->type, signature, signaturelen, data, datalen); break; case KEY_ED25519: - // \x82܂\xBE + ret = ssh_ed25519_verify(key, signature, signaturelen, data, datalen); break; default: return -1; @@ -875,7 +944,7 @@ // Key *key_from_blob(char *data, int blen) { - int keynamelen; + int keynamelen, len; char key[128]; RSA *rsa = NULL; DSA *dsa = NULL; @@ -884,6 +953,7 @@ char *curve = NULL; Key *hostkey; // hostkey ssh_keytype type; + unsigned char *pk = NULL; hostkey = malloc(sizeof(Key)); if (hostkey == NULL) @@ -978,7 +1048,15 @@ break; case KEY_ED25519: - // \x82܂\xBE + pk = buffer_get_string(&data, &len); + if (pk == NULL) + goto error; + if (len != ED25519_PK_SZ) + goto error; + + hostkey->type = type; + hostkey->ed25519_pk = pk; + pk = NULL; break; default: // unknown key @@ -995,14 +1073,53 @@ if (ecdsa != NULL) EC_KEY_free(ecdsa); + free(hostkey); + return NULL; } +static int ssh_ed25519_sign(Key *key, char **sigp, int *lenp, char *data, int datalen) +{ + char *sig; + int slen, len; + unsigned long long smlen; + int ret; + buffer_t *b; + + smlen = slen = datalen + crypto_sign_ed25519_BYTES; + sig = malloc(slen); + + if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen, + key->ed25519_sk)) != 0 || smlen <= datalen) { + //error("%s: crypto_sign_ed25519 failed: %d", __func__, ret); + free(sig); + return -1; + } + /* encode signature */ + b = buffer_init(); + buffer_put_cstring(b, "ssh-ed25519"); + buffer_put_string(b, sig, (int)(smlen - datalen)); + len = buffer_len(b); + if (lenp != NULL) + *lenp = len; + if (sigp != NULL) { + *sigp = malloc(len); + memcpy(*sigp, buffer_ptr(b), len); + } + buffer_free(b); + memset(sig, 's', slen); + free(sig); + + return 0; +} + + BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen) { buffer_t *msg = NULL; char *s; + int ret; msg = buffer_init(); if (msg == NULL) { @@ -1168,7 +1285,9 @@ } case KEY_ED25519: - // \x82܂\xBE + ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen); + if (ret != 0) + goto error; break; default: