svnno****@sourc*****
svnno****@sourc*****
2014年 3月 16日 (日) 18:09:53 JST
Revision: 5540 http://sourceforge.jp/projects/ttssh2/scm/svn/commits/5540 Author: yutakapon Date: 2014-03-16 18:09:52 +0900 (Sun, 16 Mar 2014) Log Message: ----------- RSA, DSA秘密鍵ファイルの読み込み処理で、 bcrypt KDF 形式に対応した。 ECDSA はなぜか動かないので、現状未対応。 Modified Paths: -------------- branches/ssh_ed25519/ttssh2/ttxssh/buffer.c branches/ssh_ed25519/ttssh2/ttxssh/buffer.h branches/ssh_ed25519/ttssh2/ttxssh/key.c branches/ssh_ed25519/ttssh2/ttxssh/key.h branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.c -------------- next part -------------- Modified: branches/ssh_ed25519/ttssh2/ttxssh/buffer.c =================================================================== --- branches/ssh_ed25519/ttssh2/ttxssh/buffer.c 2014-03-15 15:24:02 UTC (rev 5539) +++ branches/ssh_ed25519/ttssh2/ttxssh/buffer.c 2014-03-16 09:09:52 UTC (rev 5540) @@ -409,6 +409,17 @@ *data = buf; } +void buffer_get_bignum2_msg(buffer_t *msg, BIGNUM *value) +{ + char *data, *olddata; + int off; + + data = olddata = buffer_tail_ptr(msg); + buffer_get_bignum2(&data, value); + off = data - olddata; + msg->offset += off; +} + void buffer_get_bignum_SECSH(buffer_t *buffer, BIGNUM *value) { char *buf; @@ -481,6 +492,17 @@ BN_CTX_free(bnctx); } +void buffer_get_ecpoint_msg(buffer_t *msg, const EC_GROUP *curve, EC_POINT *point) +{ + char *data, *olddata; + int off; + + data = olddata = buffer_tail_ptr(msg); + buffer_get_ecpoint(&data, curve, point); + off = data - olddata; + msg->offset += off; +} + void buffer_dump(FILE *fp, buffer_t *buf) { int i; Modified: branches/ssh_ed25519/ttssh2/ttxssh/buffer.h =================================================================== --- branches/ssh_ed25519/ttssh2/ttxssh/buffer.h 2014-03-15 15:24:02 UTC (rev 5539) +++ branches/ssh_ed25519/ttssh2/ttxssh/buffer.h 2014-03-16 09:09:52 UTC (rev 5540) @@ -30,9 +30,11 @@ void buffer_put_bignum(buffer_t *buffer, BIGNUM *value); void buffer_put_bignum2(buffer_t *msg, BIGNUM *value); void buffer_get_bignum2(char **data, BIGNUM *value); +void buffer_get_bignum2_msg(buffer_t *msg, BIGNUM *value); void buffer_get_bignum_SECSH(buffer_t *buffer, BIGNUM *value); void buffer_put_ecpoint(buffer_t *msg, const EC_GROUP *curve, const EC_POINT *point); void buffer_get_ecpoint(char **data, const EC_GROUP *curve, EC_POINT *point); +void buffer_get_ecpoint_msg(buffer_t *msg, const EC_GROUP *curve, EC_POINT *point); char *buffer_tail_ptr(buffer_t *msg); int buffer_overflow_verify(buffer_t *msg, int len); void buffer_consume(buffer_t *buf, int shift_byte); Modified: branches/ssh_ed25519/ttssh2/ttxssh/key.c =================================================================== --- branches/ssh_ed25519/ttssh2/ttxssh/key.c 2014-03-15 15:24:02 UTC (rev 5539) +++ branches/ssh_ed25519/ttssh2/ttxssh/key.c 2014-03-16 09:09:52 UTC (rev 5540) @@ -763,7 +763,164 @@ return (retval); } +// +// \x83L\x81[\x82̃\x81\x83\x82\x83\x8A\x97̈\xE6\x8Am\x95\xDB +// +static void key_add_private(Key *k) +{ + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + k->rsa->d = BN_new(); + k->rsa->iqmp = BN_new(); + k->rsa->q = BN_new(); + k->rsa->p = BN_new(); + k->rsa->dmq1 = BN_new(); + k->rsa->dmp1 = BN_new(); + if (k->rsa->d == NULL || k->rsa->iqmp == NULL || k->rsa->q == NULL || + k->rsa->p == NULL || k->rsa->dmq1 == NULL || k->rsa->dmp1 == NULL) + goto error; + break; + case KEY_DSA: + k->dsa->priv_key = BN_new(); + if (k->dsa->priv_key == NULL) + goto error; + break; + + case KEY_ECDSA256: + case KEY_ECDSA384: + case KEY_ECDSA521: + /* Cannot do anything until we know the group */ + break; + + case KEY_ED25519: + /* no need to prealloc */ + break; + + case KEY_UNSPEC: + break; + + default: + goto error; + break; + } + return; + +error: + if (k->rsa->d) { + BN_free(k->rsa->d); + k->rsa->d = NULL; + } + if (k->rsa->iqmp) { + BN_free(k->rsa->iqmp); + k->rsa->iqmp = NULL; + } + if (k->rsa->q) { + BN_free(k->rsa->q); + k->rsa->q = NULL; + } + if (k->rsa->p) { + BN_free(k->rsa->p); + k->rsa->p = NULL; + } + if (k->rsa->dmq1) { + BN_free(k->rsa->dmq1); + k->rsa->dmq1 = NULL; + } + if (k->rsa->dmp1) { + BN_free(k->rsa->dmp1); + k->rsa->dmp1 = NULL; + } + + + if (k->dsa->priv_key == NULL) { + BN_free(k->dsa->priv_key); + k->dsa->priv_key = NULL; + } + +} + +Key *key_new_private(int type) +{ + Key *k = key_new(type); + + key_add_private(k); + return (k); +} + + +Key *key_new(int type) +{ + int success = 0; + Key *k = NULL; + RSA *rsa; + DSA *dsa; + + k = calloc(1, sizeof(Key)); + if (k == NULL) + goto error; + k->type = type; + k->ecdsa = NULL; + k->dsa = NULL; + k->rsa = NULL; + k->ed25519_pk = NULL; + k->ed25519_sk = NULL; + + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + rsa = RSA_new(); + if (rsa == NULL) + goto error; + rsa->n = BN_new(); + rsa->e = BN_new(); + if (rsa->n == NULL || rsa->e == NULL) + goto error; + k->rsa = rsa; + break; + + case KEY_DSA: + dsa = DSA_new(); + if (dsa == NULL) + goto error; + dsa->p = BN_new(); + dsa->q = BN_new(); + dsa->g = BN_new(); + dsa->pub_key = BN_new(); + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL) + goto error; + k->dsa = dsa; + break; + + case KEY_ECDSA256: + case KEY_ECDSA384: + case KEY_ECDSA521: + /* Cannot do anything until we know the group */ + break; + + case KEY_ED25519: + /* no need to prealloc */ + break; + + case KEY_UNSPEC: + break; + + default: + goto error; + break; + } + success = 1; + +error: + if (success == 0) { + key_free(k); + k = NULL; + } + return (k); +} + + // // \x83L\x81[\x82̃\x81\x83\x82\x83\x8A\x97̈\xE6\x89\xF0\x95\xFA // @@ -1424,28 +1581,28 @@ switch (key->type) { case KEY_RSA: buffer_put_bignum2(b, key->rsa->n); - buffer_put_bignum2(b, key->rsa->e); - buffer_put_bignum2(b, key->rsa->d); - buffer_put_bignum2(b, key->rsa->iqmp); - buffer_put_bignum2(b, key->rsa->p); - buffer_put_bignum2(b, key->rsa->q); + buffer_put_bignum2(b, key->rsa->e); + buffer_put_bignum2(b, key->rsa->d); + buffer_put_bignum2(b, key->rsa->iqmp); + buffer_put_bignum2(b, key->rsa->p); + buffer_put_bignum2(b, key->rsa->q); break; case KEY_DSA: - buffer_put_bignum2(b, key->dsa->p); - buffer_put_bignum2(b, key->dsa->q); - buffer_put_bignum2(b, key->dsa->g); - buffer_put_bignum2(b, key->dsa->pub_key); - buffer_put_bignum2(b, key->dsa->priv_key); + buffer_put_bignum2(b, key->dsa->p); + buffer_put_bignum2(b, key->dsa->q); + buffer_put_bignum2(b, key->dsa->g); + buffer_put_bignum2(b, key->dsa->pub_key); + buffer_put_bignum2(b, key->dsa->priv_key); break; case KEY_ECDSA256: case KEY_ECDSA384: case KEY_ECDSA521: - buffer_put_cstring(b, curve_keytype_to_name(key->type)); - buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), - EC_KEY_get0_public_key(key->ecdsa)); - buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa)); + buffer_put_cstring(b, curve_keytype_to_name(key->type)); + buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), + EC_KEY_get0_public_key(key->ecdsa)); + buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa)); break; case KEY_ED25519: @@ -1458,66 +1615,66 @@ } } -/* calculate p-1 and q-1 */ -static void rsa_generate_additional_parameters(RSA *rsa) +/* calculate p-1 and q-1 */ +static void rsa_generate_additional_parameters(RSA *rsa) { - BIGNUM *aux = NULL; - BN_CTX *ctx = NULL; - - if ((aux = BN_new()) == NULL) - goto error; - if ((ctx = BN_CTX_new()) == NULL) - goto error; - - if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || - (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || - (BN_sub(aux, rsa->p, BN_value_one()) == 0) || - (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) - goto error; - -error: - if (aux) - BN_clear_free(aux); - if (ctx) - BN_CTX_free(ctx); + BIGNUM *aux = NULL; + BN_CTX *ctx = NULL; + + if ((aux = BN_new()) == NULL) + goto error; + if ((ctx = BN_CTX_new()) == NULL) + goto error; + + if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || + (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || + (BN_sub(aux, rsa->p, BN_value_one()) == 0) || + (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) + goto error; + +error: + if (aux) + BN_clear_free(aux); + if (ctx) + BN_CTX_free(ctx); } -static int key_ec_validate_private(EC_KEY *key) -{ - BN_CTX *bnctx = NULL; - BIGNUM *order, *tmp; - int ret = -1; - - if ((bnctx = BN_CTX_new()) == NULL) - goto out; - BN_CTX_start(bnctx); - - if ((order = BN_CTX_get(bnctx)) == NULL || - (tmp = BN_CTX_get(bnctx)) == NULL) - goto out; - - /* log2(private) > log2(order)/2 */ - if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) - goto out; - if (BN_num_bits(EC_KEY_get0_private_key(key)) <= - BN_num_bits(order) / 2) { - goto out; - } - - /* private < order - 1 */ - if (!BN_sub(tmp, order, BN_value_one())) - goto out; - if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { - goto out; - } - ret = 0; - -out: - if (bnctx) - BN_CTX_free(bnctx); - return ret; -} +static int key_ec_validate_private(EC_KEY *key) +{ + BN_CTX *bnctx = NULL; + BIGNUM *order, *tmp; + int ret = -1; + if ((bnctx = BN_CTX_new()) == NULL) + goto out; + BN_CTX_start(bnctx); + + if ((order = BN_CTX_get(bnctx)) == NULL || + (tmp = BN_CTX_get(bnctx)) == NULL) + goto out; + + /* log2(private) > log2(order)/2 */ + if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) + goto out; + if (BN_num_bits(EC_KEY_get0_private_key(key)) <= + BN_num_bits(order) / 2) { + goto out; + } + + /* private < order - 1 */ + if (!BN_sub(tmp, order, BN_value_one())) + goto out; + if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { + goto out; + } + ret = 0; + +out: + if (bnctx) + BN_CTX_free(bnctx); + return ret; +} + Key *key_private_deserialize(buffer_t *blob) { int success = 0; @@ -1525,36 +1682,33 @@ Key *k = NULL; unsigned int pklen, sklen; int type; - char *data; type_name = buffer_get_string_msg(blob, NULL); + if (type_name == NULL) + goto error; type = get_keytype_from_name(type_name); - k = malloc(sizeof(Key)); - memset(k, 0, sizeof(Key)); - k->type = type; + k = key_new_private(type); switch (type) { case KEY_RSA: - data = buffer_ptr(blob); - buffer_get_bignum2(&data, k->rsa->n); - buffer_get_bignum2(&data, k->rsa->e); - buffer_get_bignum2(&data, k->rsa->d); - buffer_get_bignum2(&data, k->rsa->iqmp); - buffer_get_bignum2(&data, k->rsa->p); - buffer_get_bignum2(&data, k->rsa->q); - - /* Generate additional parameters */ - rsa_generate_additional_parameters(k->rsa); + buffer_get_bignum2_msg(blob, k->rsa->n); + buffer_get_bignum2_msg(blob, k->rsa->e); + buffer_get_bignum2_msg(blob, k->rsa->d); + buffer_get_bignum2_msg(blob, k->rsa->iqmp); + buffer_get_bignum2_msg(blob, k->rsa->p); + buffer_get_bignum2_msg(blob, k->rsa->q); + + /* Generate additional parameters */ + rsa_generate_additional_parameters(k->rsa); break; case KEY_DSA: - data = buffer_ptr(blob); - buffer_get_bignum2(&data, k->dsa->p); - buffer_get_bignum2(&data, k->dsa->q); - buffer_get_bignum2(&data, k->dsa->g); - buffer_get_bignum2(&data, k->dsa->pub_key); - buffer_get_bignum2(&data, k->dsa->priv_key); + buffer_get_bignum2_msg(blob, k->dsa->p); + buffer_get_bignum2_msg(blob, k->dsa->q); + buffer_get_bignum2_msg(blob, k->dsa->g); + buffer_get_bignum2_msg(blob, k->dsa->pub_key); + buffer_get_bignum2_msg(blob, k->dsa->priv_key); break; case KEY_ECDSA256: @@ -1565,14 +1719,11 @@ unsigned int nid; char *curve = NULL; ssh_keytype skt; - BIGNUM *exponent = NULL; + BIGNUM *exponent = NULL; EC_POINT *q = NULL; - char *data; - data = buffer_ptr(blob); - nid = keytype_to_hash_nid(type); - curve = buffer_get_string(&data, NULL); + curve = buffer_get_string_msg(blob, NULL); skt = key_curve_name_to_keytype(curve); if (nid != keytype_to_hash_nid(skt)) goto ecdsa_error; @@ -1585,19 +1736,19 @@ if (q == NULL) goto ecdsa_error; - if ((exponent = BN_new()) == NULL) + if ((exponent = BN_new()) == NULL) goto ecdsa_error; - buffer_get_ecpoint(&data, - EC_KEY_get0_group(k->ecdsa), q); - buffer_get_bignum2(&data, exponent); - if (EC_KEY_set_public_key(k->ecdsa, q) != 1) + buffer_get_ecpoint_msg(blob, + EC_KEY_get0_group(k->ecdsa), q); + buffer_get_bignum2_msg(blob, exponent); + if (EC_KEY_set_public_key(k->ecdsa, q) != 1) goto ecdsa_error; - if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) + if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) goto ecdsa_error; - if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), - EC_KEY_get0_public_key(k->ecdsa)) != 0) + if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), + EC_KEY_get0_public_key(k->ecdsa)) != 0) goto ecdsa_error; - if (key_ec_validate_private(k->ecdsa) != 0) + if (key_ec_validate_private(k->ecdsa) != 0) goto ecdsa_error; success = 1; @@ -1605,9 +1756,9 @@ ecdsa_error: free(curve); if (exponent) - BN_clear_free(exponent); - if (q) - EC_POINT_free(q); + BN_clear_free(exponent); + if (q) + EC_POINT_free(q); if (success == 0) goto error; } @@ -1626,6 +1777,16 @@ goto error; break; } + + /* enable blinding */ + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + if (RSA_blinding_on(k->rsa, NULL) != 1) + goto error; + break; + } + success = 1; error: Modified: branches/ssh_ed25519/ttssh2/ttxssh/key.h =================================================================== --- branches/ssh_ed25519/ttssh2/ttxssh/key.h 2014-03-15 15:24:02 UTC (rev 5539) +++ branches/ssh_ed25519/ttssh2/ttxssh/key.h 2014-03-16 09:09:52 UTC (rev 5540) @@ -50,6 +50,8 @@ enum hostkey_type get_keytype_from_name(char *name); char *curve_keytype_to_name(ssh_keytype type); +Key *key_new_private(int type); +Key *key_new(int type); void key_free(Key *key); int key_to_blob(Key *key, char **blobp, int *lenp); Key *key_from_blob(char *data, int blen); Modified: branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.c =================================================================== --- branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.c 2014-03-15 15:24:02 UTC (rev 5539) +++ branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.c 2014-03-16 09:09:52 UTC (rev 5540) @@ -342,7 +342,7 @@ // SSH2 // -// ED25519 \x8C`\x8E\xAE\x82œǂ\xDE +// bcrypt KDF \x8C`\x8E\xAE\x82œǂ\xDE // based on key_parse_private2() @ OpenSSH 6.5 static Key *read_SSH2_private2_key(PTInstVar pvar, FILE * fp,