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

Collapse All | Expand All

(-)a/ssh-add.1 (+4 lines)
Lines 122-127 Remove keys provided by the PKCS#11 shared library Link Here
122
.It Fl k
122
.It Fl k
123
When loading keys into or deleting keys from the agent, process plain private
123
When loading keys into or deleting keys from the agent, process plain private
124
keys only and skip certificates.
124
keys only and skip certificates.
125
.It Fl p
126
Load additional certificate for already loaded private key.
127
Will refuse to load the certificate if no matching key is found.
128
Useful if the private key is stored on a PKCS#11 hardware token.
125
.It Fl L
129
.It Fl L
126
Lists public key parameters of all identities currently represented
130
Lists public key parameters of all identities currently represented
127
by the agent.
131
by the agent.
(-)a/ssh-add.c (-7 / +60 lines)
Lines 180-185 delete_all(int agent_fd) Link Here
180
}
180
}
181
181
182
static int
182
static int
183
add_certificate_only(int agent_fd, const char *filename)
184
{
185
	struct sshkey *cert = NULL;
186
	char *comment = NULL;
187
	int r, ret = -1;
188
189
	/* Load certificate */
190
	if ((r = sshkey_load_public(filename, &cert, &comment)) != 0) {
191
		if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT)
192
			error("Failed to load certificate \"%s\": %s",
193
			    filename, ssh_err(r));
194
		goto out;
195
	}
196
	if (!sshkey_is_cert(cert)) {
197
		error("Not a certificate: %s", filename);
198
		goto out;
199
	}
200
201
        /* Add empty private key fields for serialization */
202
	if ((r = sshkey_add_private(cert)) != 0)
203
		goto out;
204
205
	if ((r = ssh_add_identity_constrained(agent_fd, cert, comment,
206
	    lifetime, confirm)) != 0) {
207
		error("Certificate %s (%s) add failed: %s", filename,
208
		    cert->cert->key_id, ssh_err(r));
209
		goto out;
210
	}
211
	ret = 0;
212
	fprintf(stderr, "Certificate added: %s (%s)\n", filename,
213
	    cert->cert->key_id);
214
	if (lifetime != 0)
215
		fprintf(stderr, "Lifetime set to %d seconds\n", lifetime);
216
	if (confirm != 0)
217
		fprintf(stderr, "The user must confirm each use of the key\n");
218
 out:
219
	free(comment);
220
	sshkey_free(cert);
221
222
	return ret;
223
}
224
225
static int
183
add_file(int agent_fd, const char *filename, int key_only)
226
add_file(int agent_fd, const char *filename, int key_only)
184
{
227
{
185
	struct sshkey *private, *cert;
228
	struct sshkey *private, *cert;
Lines 442-454 lock_agent(int agent_fd, int lock) Link Here
442
}
485
}
443
486
444
static int
487
static int
445
do_file(int agent_fd, int deleting, int key_only, char *file)
488
do_file(int agent_fd, int deleting, int key_only, int cert_only, char *file)
446
{
489
{
447
	if (deleting) {
490
	if (deleting) {
448
		if (delete_file(agent_fd, file, key_only) == -1)
491
		if (delete_file(agent_fd, file, key_only) == -1)
449
			return -1;
492
			return -1;
450
	} else {
493
	} else {
451
		if (add_file(agent_fd, file, key_only) == -1)
494
		if (cert_only) {
495
			if (add_certificate_only(agent_fd, file) == -1)
496
				return -1;
497
		} else if (add_file(agent_fd, file, key_only) == -1)
452
			return -1;
498
			return -1;
453
	}
499
	}
454
	return 0;
500
	return 0;
Lines 463-468 usage(void) Link Here
463
	fprintf(stderr, "  -E hash     Specify hash algorithm used for fingerprints.\n");
509
	fprintf(stderr, "  -E hash     Specify hash algorithm used for fingerprints.\n");
464
	fprintf(stderr, "  -L          List public key parameters of all identities.\n");
510
	fprintf(stderr, "  -L          List public key parameters of all identities.\n");
465
	fprintf(stderr, "  -k          Load only keys and not certificates.\n");
511
	fprintf(stderr, "  -k          Load only keys and not certificates.\n");
512
	fprintf(stderr, "  -p          Load additional certificate. Private key must be loaded.\n");
466
	fprintf(stderr, "  -c          Require confirmation to sign using identities\n");
513
	fprintf(stderr, "  -c          Require confirmation to sign using identities\n");
467
	fprintf(stderr, "  -t life     Set lifetime (in seconds) when adding identities.\n");
514
	fprintf(stderr, "  -t life     Set lifetime (in seconds) when adding identities.\n");
468
	fprintf(stderr, "  -d          Delete identity.\n");
515
	fprintf(stderr, "  -d          Delete identity.\n");
Lines 480-486 main(int argc, char **argv) Link Here
480
	extern int optind;
527
	extern int optind;
481
	int agent_fd;
528
	int agent_fd;
482
	char *pkcs11provider = NULL;
529
	char *pkcs11provider = NULL;
483
	int r, i, ch, deleting = 0, ret = 0, key_only = 0;
530
	int r, i, ch, deleting = 0, ret = 0, key_only = 0, cert_only = 0;
484
	int xflag = 0, lflag = 0, Dflag = 0;
531
	int xflag = 0, lflag = 0, Dflag = 0;
485
532
486
	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
533
	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
Lines 508-514 main(int argc, char **argv) Link Here
508
		exit(2);
555
		exit(2);
509
	}
556
	}
510
557
511
	while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) {
558
	while ((ch = getopt(argc, argv, "kplLcdDxXE:e:s:t:")) != -1) {
512
		switch (ch) {
559
		switch (ch) {
513
		case 'E':
560
		case 'E':
514
			fingerprint_hash = ssh_digest_alg_by_name(optarg);
561
			fingerprint_hash = ssh_digest_alg_by_name(optarg);
Lines 516-523 main(int argc, char **argv) Link Here
516
				fatal("Invalid hash algorithm \"%s\"", optarg);
563
				fatal("Invalid hash algorithm \"%s\"", optarg);
517
			break;
564
			break;
518
		case 'k':
565
		case 'k':
566
			if (cert_only)
567
				fatal("-k and -p are incompatible");
519
			key_only = 1;
568
			key_only = 1;
520
			break;
569
			break;
570
		case 'p':
571
			if (key_only)
572
				fatal("-k and -p are incompatible");
573
			cert_only = 1;
574
			break;
521
		case 'l':
575
		case 'l':
522
		case 'L':
576
		case 'L':
523
			if (lflag != 0)
577
			if (lflag != 0)
Lines 601-607 main(int argc, char **argv) Link Here
601
			    default_files[i]);
655
			    default_files[i]);
602
			if (stat(buf, &st) < 0)
656
			if (stat(buf, &st) < 0)
603
				continue;
657
				continue;
604
			if (do_file(agent_fd, deleting, key_only, buf) == -1)
658
			if (do_file(agent_fd, deleting, key_only, cert_only, buf) == -1)
605
				ret = 1;
659
				ret = 1;
606
			else
660
			else
607
				count++;
661
				count++;
Lines 610-616 main(int argc, char **argv) Link Here
610
			ret = 1;
664
			ret = 1;
611
	} else {
665
	} else {
612
		for (i = 0; i < argc; i++) {
666
		for (i = 0; i < argc; i++) {
613
			if (do_file(agent_fd, deleting, key_only,
667
			if (do_file(agent_fd, deleting, key_only, cert_only,
614
			    argv[i]) == -1)
668
			    argv[i]) == -1)
615
				ret = 1;
669
				ret = 1;
616
		}
670
		}
617
- 

Return to bug 2472