View | Details | Raw Unified | Return to bug 1914 | Differences between
and this patch

Collapse All | Expand All

(-)openssh-5.8p2/regress/agent.sh (+6 lines)
Lines 25-30 Link Here
25
		rm -f $OBJ/$t-agent
25
		rm -f $OBJ/$t-agent
26
		${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\
26
		${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\
27
			 fail "ssh-keygen for $t-agent failed"
27
			 fail "ssh-keygen for $t-agent failed"
28
		# verify key is not loaded into agent
29
		${SSHADD} -v $OBJ/$t-agent.pub &&\
30
			fail "ssh-add -v verified unloaded key"
28
		# add to authorized keys
31
		# add to authorized keys
29
		cat $OBJ/$t-agent.pub >> $OBJ/authorized_keys_$USER
32
		cat $OBJ/$t-agent.pub >> $OBJ/authorized_keys_$USER
30
		# add privat key to agent
33
		# add privat key to agent
Lines 32-37 Link Here
32
		if [ $? -ne 0 ]; then
35
		if [ $? -ne 0 ]; then
33
			fail "ssh-add did succeed exit code 0"
36
			fail "ssh-add did succeed exit code 0"
34
		fi
37
		fi
38
		# verify if key is loaded into agent
39
		${SSHADD} -v $OBJ/$t-agent.pub ||\
40
			fail "ssh-add -v did not verify loaded key"
35
	done
41
	done
36
	${SSHADD} -l > /dev/null 2>&1
42
	${SSHADD} -l > /dev/null 2>&1
37
	if [ $? -ne 0 ]; then
43
	if [ $? -ne 0 ]; then
(-)openssh-5.8p2/ssh-add.0 (+3 lines)
Lines 59-64 Link Here
59
             lifetime may be specified in seconds or in a time format
59
             lifetime may be specified in seconds or in a time format
60
             specified in sshd_config(5).
60
             specified in sshd_config(5).
61
61
62
     -v pubkey
63
             Verify if the agent has access to the matching private key.     
64
62
     -X      Unlock the agent.
65
     -X      Unlock the agent.
63
66
64
     -x      Lock the agent with a password.
67
     -x      Lock the agent with a password.
(-)openssh-5.8p2/ssh-add.c (-1 / +110 lines)
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 329-334 Link Here
329
	return (ret);
330
	return (ret);
330
}
331
}
331
332
333
334
static int
335
verify_key_ssh1 (AuthenticationConnection *ac, Key *key)
336
{
337
338
	int ret = 0;
339
	BIGNUM *challenge, *encrypted_challenge;
340
	u_char session_id[16], response[16], token[32], mdbuf[16];
341
	MD5_CTX md;
342
343
	/* generate random session_id and token */
344
	arc4random_buf(session_id, sizeof(session_id));
345
	arc4random_buf(token, sizeof(token));
346
	if ((challenge = BN_bin2bn(token, sizeof(token), NULL)) == NULL) {
347
		fprintf(stderr, "%s: BNbin2bn failed", __func__);
348
		return ret;
349
	}
350
351
	/* Encrypt the challenge with the public key. */
352
	if ((encrypted_challenge = BN_new()) == NULL) {
353
		fprintf(stderr, "%s: BN_new failed", __func__);
354
		BN_clear_free(challenge);
355
		return ret;
356
	}
357
	rsa_public_encrypt(encrypted_challenge, challenge, key->rsa);
358
359
	/* send challenge to agent and expect response */
360
	ssh_decrypt_challenge(ac, key, encrypted_challenge, session_id, 1, response);
361
362
	MD5_Init(&md);
363
	MD5_Update(&md, token, sizeof(token));
364
	MD5_Update(&md, session_id, sizeof(session_id));
365
	MD5_Final(mdbuf, &md);
366
367
	/* Verify that the response is the original challenge. */
368
	if (timingsafe_bcmp(response, mdbuf, sizeof(mdbuf)) == 0) {
369
		ret = 1;
370
	}
371
372
	BN_clear_free(encrypted_challenge);
373
	BN_clear_free(challenge);
374
	
375
	return ret;
376
}
377
378
static int
379
verify_key_ssh2 (AuthenticationConnection *ac, Key *key)
380
{
381
	int ret = 0;
382
	u_char *signature, token[512];
383
	u_int slen;
384
	
385
	arc4random_buf(token, sizeof(token));
386
	
387
	/* let the agent sign the token */
388
	if (ssh_agent_sign(ac, key, &signature, &slen, token, sizeof(token)) == 0 ) {
389
		/* verify signature */
390
		if (key_verify(key, signature, slen, token, sizeof(token))) {
391
			ret = 1;
392
		}
393
		xfree(signature);
394
	}
395
	return ret;
396
}
397
398
static int
399
verify_key(AuthenticationConnection *ac, const char *filename)
400
{
401
	Key *public, *key;
402
	char *comment;
403
	int version, ret = -1;
404
405
	/* load public key */
406
	public = key_load_public(filename, NULL);
407
	if (public == NULL) {
408
		fprintf(stderr, "Could not read public key: %s\n", filename);
409
		return ret;
410
	}
411
	
412
	/* try to find public key in agent */
413
	for (version = 1; version <= 2 && ret != 0; version++) {
414
		for (key = ssh_get_first_identity(ac, &comment, version);
415
		    key != NULL && ret != 0;
416
		    key = ssh_get_next_identity(ac, &comment, version)) {
417
			if (key_equal_public(public, key)) {
418
				if (version == 1) {
419
					if (verify_key_ssh1(ac, public))
420
						ret = 0;
421
				} else {
422
					if (verify_key_ssh2(ac, public))
423
						ret = 0;
424
				}
425
			}
426
			key_free(key);
427
			xfree(comment);
428
		}
429
	}
430
431
	key_free(public);
432
	
433
	return ret;
434
}
435
332
static int
436
static int
333
do_file(AuthenticationConnection *ac, int deleting, char *file)
437
do_file(AuthenticationConnection *ac, int deleting, char *file)
334
{
438
{
Lines 357-362 Link Here
357
	fprintf(stderr, "  -c          Require confirmation to sign using identities\n");
461
	fprintf(stderr, "  -c          Require confirmation to sign using identities\n");
358
	fprintf(stderr, "  -s pkcs11   Add keys from PKCS#11 provider.\n");
462
	fprintf(stderr, "  -s pkcs11   Add keys from PKCS#11 provider.\n");
359
	fprintf(stderr, "  -e pkcs11   Remove keys provided by PKCS#11 provider.\n");
463
	fprintf(stderr, "  -e pkcs11   Remove keys provided by PKCS#11 provider.\n");
464
	fprintf(stderr, "  -v pubkey   Verify if agent can access matching private key.\n");
360
}
465
}
361
466
362
int
467
int
Lines 384-390 Link Here
384
		    "Could not open a connection to your authentication agent.\n");
489
		    "Could not open a connection to your authentication agent.\n");
385
		exit(2);
490
		exit(2);
386
	}
491
	}
387
	while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:")) != -1) {
492
	while ((ch = getopt(argc, argv, "lLcdDxXe:s:t:v:")) != -1) {
388
		switch (ch) {
493
		switch (ch) {
389
		case 'l':
494
		case 'l':
390
		case 'L':
495
		case 'L':
Lines 420-425 Link Here
420
				goto done;
525
				goto done;
421
			}
526
			}
422
			break;
527
			break;
528
		case 'v':
529
			if (verify_key(ac, optarg) == -1)
530
				ret = 1;
531
			goto done;
423
		default:
532
		default:
424
			usage();
533
			usage();
425
			ret = 1;
534
			ret = 1;

Return to bug 1914