|
Lines 42-47
Link Here
|
| 42 |
#include <sys/param.h> |
42 |
#include <sys/param.h> |
| 43 |
|
43 |
|
| 44 |
#include <openssl/evp.h> |
44 |
#include <openssl/evp.h> |
|
|
45 |
#include <openssl/md5.h> |
| 45 |
#include "openbsd-compat/openssl-compat.h" |
46 |
#include "openbsd-compat/openssl-compat.h" |
| 46 |
|
47 |
|
| 47 |
#include <fcntl.h> |
48 |
#include <fcntl.h> |
|
Lines 322-327
Link Here
|
| 322 |
return 0; |
323 |
return 0; |
| 323 |
} |
324 |
} |
| 324 |
|
325 |
|
|
|
326 |
|
| 327 |
static int |
| 328 |
verify_key_ssh1 (AuthenticationConnection *ac, Key *key) |
| 329 |
{ |
| 330 |
|
| 331 |
int ret = 0; |
| 332 |
BIGNUM *challenge, *encrypted_challenge; |
| 333 |
u_char session_id[16], response[16], token[32], mdbuf[16]; |
| 334 |
MD5_CTX md; |
| 335 |
|
| 336 |
/* generate random session_id and token */ |
| 337 |
arc4random_buf(session_id, sizeof(session_id)); |
| 338 |
arc4random_buf(token, sizeof(token)); |
| 339 |
if ((challenge = BN_bin2bn(token, sizeof(token), NULL)) == NULL) { |
| 340 |
fprintf(stderr, "%s: BNbin2bn failed", __func__); |
| 341 |
return ret; |
| 342 |
} |
| 343 |
|
| 344 |
/* Encrypt the challenge with the public key. */ |
| 345 |
if ((encrypted_challenge = BN_new()) == NULL) { |
| 346 |
fprintf(stderr, "%s: BN_new failed", __func__); |
| 347 |
BN_clear_free(challenge); |
| 348 |
return ret; |
| 349 |
} |
| 350 |
rsa_public_encrypt(encrypted_challenge, challenge, key->rsa); |
| 351 |
|
| 352 |
/* send challenge to agent and expect response */ |
| 353 |
ssh_decrypt_challenge(ac, key, encrypted_challenge, session_id, 1, response); |
| 354 |
|
| 355 |
MD5_Init(&md); |
| 356 |
MD5_Update(&md, token, sizeof(token)); |
| 357 |
MD5_Update(&md, session_id, sizeof(session_id)); |
| 358 |
MD5_Final(mdbuf, &md); |
| 359 |
|
| 360 |
/* Verify that the response is the original challenge. */ |
| 361 |
if (timingsafe_bcmp(response, mdbuf, sizeof(mdbuf)) == 0) { |
| 362 |
ret = 1; |
| 363 |
} |
| 364 |
|
| 365 |
BN_clear_free(encrypted_challenge); |
| 366 |
BN_clear_free(challenge); |
| 367 |
|
| 368 |
return ret; |
| 369 |
} |
| 370 |
|
| 371 |
static int |
| 372 |
verify_key_ssh2 (AuthenticationConnection *ac, Key *key) |
| 373 |
{ |
| 374 |
int ret = 0; |
| 375 |
u_char *signature, token[512]; |
| 376 |
u_int slen; |
| 377 |
|
| 378 |
arc4random_buf(token, sizeof(token)); |
| 379 |
|
| 380 |
/* let the agent sign the token */ |
| 381 |
if (ssh_agent_sign(ac, key, &signature, &slen, token, sizeof(token)) == 0 ) { |
| 382 |
/* verify signature */ |
| 383 |
if (key_verify(key, signature, slen, token, sizeof(token))) { |
| 384 |
ret = 1; |
| 385 |
} |
| 386 |
xfree(signature); |
| 387 |
} |
| 388 |
return ret; |
| 389 |
} |
| 390 |
|
| 391 |
static int |
| 392 |
verify_key(AuthenticationConnection *ac, const char *filename) |
| 393 |
{ |
| 394 |
Key *public; |
| 395 |
int ret = -1; |
| 396 |
|
| 397 |
/* load public key */ |
| 398 |
public = key_load_public(filename, NULL); |
| 399 |
if (public == NULL) { |
| 400 |
fprintf(stderr, "Could not read public key: %s\n", filename); |
| 401 |
return ret; |
| 402 |
} |
| 403 |
|
| 404 |
if (public->type == KEY_RSA1 |
| 405 |
? verify_key_ssh1(ac, public) |
| 406 |
: verify_key_ssh2(ac, public)) |
| 407 |
ret = 0; |
| 408 |
|
| 409 |
key_free(public); |
| 410 |
|
| 411 |
return ret; |
| 412 |
} |
| 413 |
|
| 325 |
static int |
414 |
static int |
| 326 |
lock_agent(AuthenticationConnection *ac, int lock) |
415 |
lock_agent(AuthenticationConnection *ac, int lock) |
| 327 |
{ |
416 |
{ |
|
Lines 379-384
Link Here
|
| 379 |
fprintf(stderr, " -X Unlock agent.\n"); |
468 |
fprintf(stderr, " -X Unlock agent.\n"); |
| 380 |
fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); |
469 |
fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); |
| 381 |
fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); |
470 |
fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); |
|
|
471 |
fprintf(stderr, " -v pubkey Verify if agent can access matching private key.\n"); |
| 382 |
} |
472 |
} |
| 383 |
|
473 |
|
| 384 |
int |
474 |
int |
|
Lines 405-411
Link Here
|
| 405 |
"Could not open a connection to your authentication agent.\n"); |
495 |
"Could not open a connection to your authentication agent.\n"); |
| 406 |
exit(2); |
496 |
exit(2); |
| 407 |
} |
497 |
} |
| 408 |
while ((ch = getopt(argc, argv, "klLcdDxXe:s:t:")) != -1) { |
498 |
while ((ch = getopt(argc, argv, "klLcdDxXe:s:t:v:")) != -1) { |
| 409 |
switch (ch) { |
499 |
switch (ch) { |
| 410 |
case 'k': |
500 |
case 'k': |
| 411 |
key_only = 1; |
501 |
key_only = 1; |
|
Lines 444-449
Link Here
|
| 444 |
goto done; |
534 |
goto done; |
| 445 |
} |
535 |
} |
| 446 |
break; |
536 |
break; |
|
|
537 |
case 'v': |
| 538 |
if (verify_key(ac, optarg) == -1) |
| 539 |
ret = 1; |
| 540 |
goto done; |
| 447 |
default: |
541 |
default: |
| 448 |
usage(); |
542 |
usage(); |
| 449 |
ret = 1; |
543 |
ret = 1; |