| 2283 |
// クライアントからサーバへの提案事項 |
// クライアントからサーバへの提案事項 |
| 2284 |
#ifdef SSH2_DEBUG |
#ifdef SSH2_DEBUG |
| 2285 |
static char *myproposal[PROPOSAL_MAX] = { |
static char *myproposal[PROPOSAL_MAX] = { |
| 2286 |
"diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1", |
"diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1", |
| 2287 |
"ssh-rsa,ssh-dss", |
// "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1", |
| 2288 |
|
// "ssh-rsa,ssh-dss", |
| 2289 |
|
"ssh-dss,ssh-rsa", |
| 2290 |
"3des-cbc,aes128-cbc", |
"3des-cbc,aes128-cbc", |
| 2291 |
"3des-cbc,aes128-cbc", |
"3des-cbc,aes128-cbc", |
| 2292 |
"hmac-md5,hmac-sha1", |
"hmac-md5,hmac-sha1", |
| 3282 |
} |
} |
| 3283 |
|
|
| 3284 |
|
|
| 3285 |
|
////////////////////////////////////////////////////////////////////////////// |
| 3286 |
|
// |
| 3287 |
|
// Key verify function |
| 3288 |
|
// |
| 3289 |
|
////////////////////////////////////////////////////////////////////////////// |
| 3290 |
|
|
| 3291 |
|
// |
| 3292 |
|
// DSS |
| 3293 |
|
// |
| 3294 |
|
|
| 3295 |
|
static int ssh_dss_verify( |
| 3296 |
|
DSA *key, u_char *signature, u_int signaturelen, |
| 3297 |
|
u_char *data, u_int datalen) |
| 3298 |
|
{ |
| 3299 |
|
#define INTBLOB_LEN 20 |
| 3300 |
|
DSA_SIG *sig; |
| 3301 |
|
const EVP_MD *evp_md = EVP_sha1(); |
| 3302 |
|
EVP_MD_CTX md; |
| 3303 |
|
unsigned char digest[EVP_MAX_MD_SIZE], *sigblob; |
| 3304 |
|
unsigned int len, dlen; |
| 3305 |
|
int ret; |
| 3306 |
|
char *ptr; |
| 3307 |
|
|
| 3308 |
|
OpenSSL_add_all_digests(); |
| 3309 |
|
|
| 3310 |
|
if (key == NULL) { |
| 3311 |
|
return -1; |
| 3312 |
|
} |
| 3313 |
|
|
| 3314 |
|
ptr = signature; |
| 3315 |
|
|
| 3316 |
|
// step1 |
| 3317 |
|
len = get_uint32_MSBfirst(ptr); |
| 3318 |
|
ptr += 4; |
| 3319 |
|
if (strncmp("ssh-dss", ptr, len) != 0) { |
| 3320 |
|
return -1; |
| 3321 |
|
} |
| 3322 |
|
ptr += len; |
| 3323 |
|
|
| 3324 |
|
// step2 |
| 3325 |
|
len = get_uint32_MSBfirst(ptr); |
| 3326 |
|
ptr += 4; |
| 3327 |
|
sigblob = ptr; |
| 3328 |
|
ptr += len; |
| 3329 |
|
|
| 3330 |
|
if (len != (2*INTBLOB_LEN)) { |
| 3331 |
|
return -1; |
| 3332 |
|
} |
| 3333 |
|
|
| 3334 |
|
/* parse signature */ |
| 3335 |
|
if ((sig = DSA_SIG_new()) == NULL) |
| 3336 |
|
return -1; |
| 3337 |
|
if ((sig->r = BN_new()) == NULL) |
| 3338 |
|
return -1; |
| 3339 |
|
if ((sig->s = BN_new()) == NULL) |
| 3340 |
|
return -1; |
| 3341 |
|
BN_bin2bn(sigblob, INTBLOB_LEN, sig->r); |
| 3342 |
|
BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s); |
| 3343 |
|
|
| 3344 |
|
/* sha1 the data */ |
| 3345 |
|
EVP_DigestInit(&md, evp_md); |
| 3346 |
|
EVP_DigestUpdate(&md, data, datalen); |
| 3347 |
|
EVP_DigestFinal(&md, digest, &dlen); |
| 3348 |
|
|
| 3349 |
|
ret = DSA_do_verify(digest, dlen, sig, key); |
| 3350 |
|
memset(digest, 'd', sizeof(digest)); |
| 3351 |
|
|
| 3352 |
|
DSA_SIG_free(sig); |
| 3353 |
|
|
| 3354 |
|
return ret; |
| 3355 |
|
} |
| 3356 |
|
|
| 3357 |
|
|
| 3358 |
|
// |
| 3359 |
|
// RSA |
| 3360 |
|
// |
| 3361 |
|
|
| 3362 |
/* |
/* |
| 3363 |
* See: |
* See: |
| 3364 |
* http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/ |
* http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/ |
| 3365 |
* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn |
* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn |
| 3366 |
*/ |
*/ |
| 3367 |
/* |
/* |
| 3368 |
* id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) |
* id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) |
| 3369 |
* oiw(14) secsig(3) algorithms(2) 26 } |
* oiw(14) secsig(3) algorithms(2) 26 } |
| 3370 |
*/ |
*/ |
| 3371 |
static const u_char id_sha1[] = { |
static const u_char id_sha1[] = { |
| 3372 |
0x30, 0x21, /* type Sequence, length 0x21 (33) */ |
0x30, 0x21, /* type Sequence, length 0x21 (33) */ |
| 3373 |
0x30, 0x09, /* type Sequence, length 0x09 */ |
0x30, 0x09, /* type Sequence, length 0x09 */ |
| 3374 |
0x06, 0x05, /* type OID, length 0x05 */ |
0x06, 0x05, /* type OID, length 0x05 */ |
| 3375 |
0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */ |
0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */ |
| 3376 |
0x05, 0x00, /* NULL */ |
0x05, 0x00, /* NULL */ |
| 3377 |
0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ |
0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ |
| 3378 |
}; |
}; |
| 3379 |
/* |
/* |
| 3380 |
* id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) |
* id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) |
| 3381 |
* rsadsi(113549) digestAlgorithm(2) 5 } |
* rsadsi(113549) digestAlgorithm(2) 5 } |
| 3382 |
*/ |
*/ |
| 3383 |
static const u_char id_md5[] = { |
static const u_char id_md5[] = { |
| 3384 |
0x30, 0x20, /* type Sequence, length 0x20 (32) */ |
0x30, 0x20, /* type Sequence, length 0x20 (32) */ |
| 3385 |
0x30, 0x0c, /* type Sequence, length 0x09 */ |
0x30, 0x0c, /* type Sequence, length 0x09 */ |
| 3386 |
0x06, 0x08, /* type OID, length 0x05 */ |
0x06, 0x08, /* type OID, length 0x05 */ |
| 3387 |
0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */ |
0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */ |
| 3388 |
0x05, 0x00, /* NULL */ |
0x05, 0x00, /* NULL */ |
| 3389 |
0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */ |
0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */ |
| 3390 |
}; |
}; |
| 3391 |
|
|
| 3392 |
static int |
static int openssh_RSA_verify(int type, u_char *hash, u_int hashlen, |
| 3393 |
openssh_RSA_verify(int type, u_char *hash, u_int hashlen, |
u_char *sigbuf, u_int siglen, RSA *rsa) |
|
u_char *sigbuf, u_int siglen, RSA *rsa) |
|
| 3394 |
{ |
{ |
| 3395 |
u_int ret, rsasize, oidlen = 0, hlen = 0; |
u_int ret, rsasize, oidlen = 0, hlen = 0; |
| 3396 |
int len; |
int len; |
| 3427 |
return 1; // error |
return 1; // error |
| 3428 |
|
|
| 3429 |
if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, |
if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, |
| 3430 |
RSA_PKCS1_PADDING)) < 0) { |
RSA_PKCS1_PADDING)) < 0) { |
| 3431 |
//error("RSA_public_decrypt failed: %s", |
//error("RSA_public_decrypt failed: %s", |
| 3432 |
// ERR_error_string(ERR_get_error(), NULL)); |
// ERR_error_string(ERR_get_error(), NULL)); |
| 3433 |
goto done; |
goto done; |
| 3434 |
} |
} |
| 3435 |
if (len != hlen + oidlen) { |
if (len != hlen + oidlen) { |
| 3436 |
//error("bad decrypted len: %d != %d + %d", len, hlen, oidlen); |
//error("bad decrypted len: %d != %d + %d", len, hlen, oidlen); |
| 3437 |
goto done; |
goto done; |
| 3438 |
} |
} |
| 3439 |
if (memcmp(decrypted, oid, oidlen) != 0) { |
if (memcmp(decrypted, oid, oidlen) != 0) { |
| 3440 |
//error("oid mismatch"); |
//error("oid mismatch"); |
| 3441 |
goto done; |
goto done; |
| 3442 |
} |
} |
| 3443 |
if (memcmp(decrypted + oidlen, hash, hlen) != 0) { |
if (memcmp(decrypted + oidlen, hash, hlen) != 0) { |
| 3444 |
//error("hash mismatch"); |
//error("hash mismatch"); |
| 3445 |
goto done; |
goto done; |
| 3446 |
} |
} |
| 3447 |
ret = 1; |
ret = 1; |
| 3448 |
done: |
done: |
| 3449 |
if (decrypted) |
if (decrypted) |
| 3450 |
free(decrypted); |
free(decrypted); |
| 3451 |
return ret; |
return ret; |
| 3452 |
} |
} |
| 3453 |
|
|
| 3454 |
int ssh_rsa_verify(RSA *key, u_char *signature, u_int signaturelen, |
static int ssh_rsa_verify(RSA *key, u_char *signature, u_int signaturelen, |
| 3455 |
u_char *data, u_int datalen) |
u_char *data, u_int datalen) |
| 3456 |
{ |
{ |
| 3457 |
const EVP_MD *evp_md; |
const EVP_MD *evp_md; |
| 3458 |
EVP_MD_CTX md; |
EVP_MD_CTX md; |
| 3459 |
// char *ktype; |
// char *ktype; |
| 3460 |
u_char digest[EVP_MAX_MD_SIZE], *sigblob; |
u_char digest[EVP_MAX_MD_SIZE], *sigblob; |
| 3461 |
u_int len, dlen, modlen; |
u_int len, dlen, modlen; |
| 3462 |
int rlen, ret, nid; |
// int rlen, ret, nid; |
| 3463 |
|
int ret, nid; |
| 3464 |
char *ptr; |
char *ptr; |
| 3465 |
|
|
| 3466 |
OpenSSL_add_all_digests(); |
OpenSSL_add_all_digests(); |
| 3473 |
} |
} |
| 3474 |
//debug_print(41, signature, signaturelen); |
//debug_print(41, signature, signaturelen); |
| 3475 |
ptr = signature; |
ptr = signature; |
| 3476 |
|
|
| 3477 |
// step1 |
// step1 |
| 3478 |
len = get_uint32_MSBfirst(ptr); |
len = get_uint32_MSBfirst(ptr); |
| 3479 |
ptr += 4; |
ptr += 4; |
| 3487 |
ptr += 4; |
ptr += 4; |
| 3488 |
sigblob = ptr; |
sigblob = ptr; |
| 3489 |
ptr += len; |
ptr += len; |
| 3490 |
|
#if 0 |
| 3491 |
rlen = get_uint32_MSBfirst(ptr); |
rlen = get_uint32_MSBfirst(ptr); |
| 3492 |
if (rlen != 0) { |
if (rlen != 0) { |
| 3493 |
return -1; |
return -1; |
| 3494 |
} |
} |
| 3495 |
|
#endif |
| 3496 |
|
|
| 3497 |
/* RSA_verify expects a signature of RSA_size */ |
/* RSA_verify expects a signature of RSA_size */ |
| 3498 |
modlen = RSA_size(key); |
modlen = RSA_size(key); |
| 3506 |
memset(sigblob, 0, diff); |
memset(sigblob, 0, diff); |
| 3507 |
len = modlen; |
len = modlen; |
| 3508 |
} |
} |
| 3509 |
// nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; |
// nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; |
| 3510 |
nid = NID_sha1; |
nid = NID_sha1; |
| 3511 |
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { |
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { |
| 3512 |
//error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid); |
//error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid); |
| 3526 |
return ret; |
return ret; |
| 3527 |
} |
} |
| 3528 |
|
|
| 3529 |
int key_verify( |
static int key_verify( |
| 3530 |
RSA *rsa_key, |
RSA *rsa_key, |
| 3531 |
DSA *dsa_key, |
DSA *dsa_key, |
| 3532 |
unsigned char *signature, unsigned int signaturelen, |
unsigned char *signature, unsigned int signaturelen, |
| 3533 |
unsigned char *data, unsigned int datalen) |
unsigned char *data, unsigned int datalen) |
| 3534 |
{ |
{ |
| 3535 |
int ret = 0; |
int ret = 0; |
| 3536 |
|
|
| 3538 |
ret = ssh_rsa_verify(rsa_key, signature, signaturelen, data, datalen); |
ret = ssh_rsa_verify(rsa_key, signature, signaturelen, data, datalen); |
| 3539 |
|
|
| 3540 |
} else if (dsa_key != NULL) { |
} else if (dsa_key != NULL) { |
| 3541 |
// TODO: |
ret = ssh_dss_verify(dsa_key, signature, signaturelen, data, datalen); |
|
|
|
| 3542 |
|
|
| 3543 |
} else { |
} else { |
| 3544 |
return -1; |
return -1; |
| 3707 |
} |
} |
| 3708 |
} |
} |
| 3709 |
|
|
| 3710 |
#if 0 |
#if 1 |
| 3711 |
if (key_verify(rsa, dsa, signature, siglen, hash, 20) != 1) { |
if (key_verify(rsa, dsa, signature, siglen, hash, 20) != 1) { |
| 3712 |
emsg = "key verify error @ handle_SSH2_dh_kex_reply()"; |
emsg = "key verify error @ handle_SSH2_dh_kex_reply()"; |
| 3713 |
goto error; |
goto error; |
| 3998 |
} |
} |
| 3999 |
} |
} |
| 4000 |
|
|
| 4001 |
#if 0 |
#if 1 |
| 4002 |
if (key_verify(rsa, dsa, signature, siglen, hash, 20) != 1) { |
if (key_verify(rsa, dsa, signature, siglen, hash, 20) != 1) { |
| 4003 |
emsg = "key verify error @ handle_SSH2_dh_kex_reply()"; |
emsg = "key verify error @ handle_SSH2_dh_kex_reply()"; |
| 4004 |
goto error; |
goto error; |
| 4650 |
|
|
| 4651 |
/* |
/* |
| 4652 |
* $Log: not supported by cvs2svn $ |
* $Log: not supported by cvs2svn $ |
| 4653 |
|
* Revision 1.7 2004/12/17 14:28:36 yutakakn |
| 4654 |
|
* メッセージ認証アルゴリズムに HMAC-MD5 を追加。 |
| 4655 |
|
* TTSSHバージョンダイアログにHMACアルゴリズム表示を追加。 |
| 4656 |
|
* |
| 4657 |
* Revision 1.6 2004/12/17 14:05:55 yutakakn |
* Revision 1.6 2004/12/17 14:05:55 yutakakn |
| 4658 |
* パケット受信時のHMACチェックを追加。 |
* パケット受信時のHMACチェックを追加。 |
| 4659 |
* KEXにおけるHMACアルゴリズムチェックを追加。 |
* KEXにおけるHMACアルゴリズムチェックを追加。 |