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

Collapse All | Expand All

(-)a/authfd.c (-2 / +2 lines)
Lines 326-332 ssh_free_identitylist(struct ssh_identitylist *idl) Link Here
326
326
327
/* encode signature algoritm in flag bits, so we can keep the msg format */
327
/* encode signature algoritm in flag bits, so we can keep the msg format */
328
static u_int
328
static u_int
329
agent_encode_alg(struct sshkey *key, const char *alg)
329
agent_encode_alg(const struct sshkey *key, const char *alg)
330
{
330
{
331
	if (alg != NULL && key->type == KEY_RSA) {
331
	if (alg != NULL && key->type == KEY_RSA) {
332
		if (strcmp(alg, "rsa-sha2-256") == 0)
332
		if (strcmp(alg, "rsa-sha2-256") == 0)
Lines 339-345 agent_encode_alg(struct sshkey *key, const char *alg) Link Here
339
339
340
/* ask agent to sign data, returns err.h code on error, 0 on success */
340
/* ask agent to sign data, returns err.h code on error, 0 on success */
341
int
341
int
342
ssh_agent_sign(int sock, struct sshkey *key,
342
ssh_agent_sign(int sock, const struct sshkey *key,
343
    u_char **sigp, size_t *lenp,
343
    u_char **sigp, size_t *lenp,
344
    const u_char *data, size_t datalen, const char *alg, u_int compat)
344
    const u_char *data, size_t datalen, const char *alg, u_int compat)
345
{
345
{
(-)a/authfd.h (-1 / +1 lines)
Lines 38-44 int ssh_remove_all_identities(int sock, int version); Link Here
38
38
39
int	ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
39
int	ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
40
	    u_char session_id[16], u_char response[16]);
40
	    u_char session_id[16], u_char response[16]);
41
int	ssh_agent_sign(int sock, struct sshkey *key,
41
int	ssh_agent_sign(int sock, const struct sshkey *key,
42
	    u_char **sigp, size_t *lenp,
42
	    u_char **sigp, size_t *lenp,
43
	    const u_char *data, size_t datalen, const char *alg, u_int compat);
43
	    const u_char *data, size_t datalen, const char *alg, u_int compat);
44
44
(-)a/ssh-keygen.1 (+18 lines)
Lines 114-119 Link Here
114
.Fl s Ar ca_key
114
.Fl s Ar ca_key
115
.Fl I Ar certificate_identity
115
.Fl I Ar certificate_identity
116
.Op Fl h
116
.Op Fl h
117
.Op Fl U
118
.Op Fl D Ar pkcs11_provider
117
.Op Fl n Ar principals
119
.Op Fl n Ar principals
118
.Op Fl O Ar option
120
.Op Fl O Ar option
119
.Op Fl V Ar validity_interval
121
.Op Fl V Ar validity_interval
Lines 558-563 The possible values are Link Here
558
.Dq ed25519 ,
560
.Dq ed25519 ,
559
or
561
or
560
.Dq rsa .
562
.Dq rsa .
563
.It Fl U
564
When used in combination with
565
.Fl s ,
566
this option indicates that a CA key resides in a
567
.Xr ssh-agent 1 .
568
See the
569
.Sx CERTIFICATES
570
section for more information.
561
.It Fl u
571
.It Fl u
562
Update a KRL.
572
Update a KRL.
563
When specified with
573
When specified with
Lines 705-710 to Link Here
705
.Pp
715
.Pp
706
.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub
716
.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub
707
.Pp
717
.Pp
718
Similarly, it is possible for the CA key to be hosted in a
719
.Xr ssh-agent 1 .
720
This is indicated by the
721
.Fl U
722
flag and, again, the CA key must be identified by its public half.
723
.Pp
724
.Dl $ ssh-keygen -Us ca_key.pub -I key_id user_key.pub
725
.Pp
708
In all cases,
726
In all cases,
709
.Ar key_id
727
.Ar key_id
710
is a "key identifier" that is logged by the server when the certificate
728
is a "key identifier" that is logged by the server when the certificate
(-)a/ssh-keygen.c (-8 / +66 lines)
Lines 59-64 Link Here
59
#include "krl.h"
59
#include "krl.h"
60
#include "digest.h"
60
#include "digest.h"
61
#include "utf8.h"
61
#include "utf8.h"
62
#include "authfd.h"
62
63
63
#ifdef WITH_OPENSSL
64
#ifdef WITH_OPENSSL
64
# define DEFAULT_KEY_TYPE_NAME "rsa"
65
# define DEFAULT_KEY_TYPE_NAME "rsa"
Lines 121-126 char *identity_comment = NULL; Link Here
121
/* Path to CA key when certifying keys. */
122
/* Path to CA key when certifying keys. */
122
char *ca_key_path = NULL;
123
char *ca_key_path = NULL;
123
124
125
/* Prefer to use agent keys for CA signing */
126
int prefer_agent = 0;
127
124
/* Certificate serial number */
128
/* Certificate serial number */
125
unsigned long long cert_serial = 0;
129
unsigned long long cert_serial = 0;
126
130
Lines 1597-1620 load_pkcs11_key(char *path) Link Here
1597
#endif /* ENABLE_PKCS11 */
1601
#endif /* ENABLE_PKCS11 */
1598
}
1602
}
1599
1603
1604
/* Signer for sshkey_certify that uses the agent */
1605
static int
1606
agent_signer(const struct sshkey *key, u_char **sigp, size_t *lenp,
1607
    const u_char *data, size_t datalen,
1608
    const char *alg, u_int compat, void *ctx)
1609
{
1610
	int *agent_fdp = (int *)ctx;
1611
1612
	return ssh_agent_sign(*agent_fdp, key, sigp, lenp,
1613
	    data, datalen, alg, compat);
1614
}
1615
1600
static void
1616
static void
1601
do_ca_sign(struct passwd *pw, int argc, char **argv)
1617
do_ca_sign(struct passwd *pw, int argc, char **argv)
1602
{
1618
{
1603
	int r, i, fd;
1619
	int r, i, fd, found, agent_fd = -1;
1604
	u_int n;
1620
	u_int n;
1605
	struct sshkey *ca, *public;
1621
	struct sshkey *ca, *public;
1606
	char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1622
	char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1607
	FILE *f;
1623
	FILE *f;
1624
	struct ssh_identitylist *agent_ids;
1625
	size_t j;
1608
1626
1609
#ifdef ENABLE_PKCS11
1627
#ifdef ENABLE_PKCS11
1610
	pkcs11_init(1);
1628
	pkcs11_init(1);
1611
#endif
1629
#endif
1612
	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1630
	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1613
	if (pkcs11provider != NULL) {
1631
	if (pkcs11provider != NULL) {
1632
		/* If a PKCS#11 token was specified then try to use it */
1614
		if ((ca = load_pkcs11_key(tmp)) == NULL)
1633
		if ((ca = load_pkcs11_key(tmp)) == NULL)
1615
			fatal("No PKCS#11 key matching %s found", ca_key_path);
1634
			fatal("No PKCS#11 key matching %s found", ca_key_path);
1616
	} else
1635
	} else if (prefer_agent) {
1636
		/*
1637
		 * Agent signature requested. Try to use agent after making
1638
		 * sure the public key specified is actually present in the
1639
		 * agent.
1640
		 */
1641
		if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
1642
			fatal("Cannot load CA public key %s: %s",
1643
			    tmp, ssh_err(r));
1644
		if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
1645
			fatal("Cannot use public key for CA signature: %s",
1646
			    ssh_err(r));
1647
		if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0)
1648
			fatal("Retrieve agent key list: %s", ssh_err(r));
1649
		found = 0;
1650
		for (j = 0; j < agent_ids->nkeys; j++) {
1651
			if (sshkey_equal(ca, agent_ids->keys[j])) {
1652
				found = 1;
1653
				break;
1654
			}
1655
		}
1656
		if (!found)
1657
			fatal("CA key %s not found in agent", tmp);
1658
		ssh_free_identitylist(agent_ids);
1659
		ca->flags |= SSHKEY_FLAG_EXT;
1660
	} else {
1661
		/* CA key is assumed to be a private key on the filesystem */
1617
		ca = load_identity(tmp);
1662
		ca = load_identity(tmp);
1663
	}
1618
	free(tmp);
1664
	free(tmp);
1619
1665
1620
	if (key_type_name != NULL &&
1666
	if (key_type_name != NULL &&
Lines 1664-1671 do_ca_sign(struct passwd *pw, int argc, char **argv) Link Here
1664
		    &public->cert->signature_key)) != 0)
1710
		    &public->cert->signature_key)) != 0)
1665
			fatal("key_from_private (ca key): %s", ssh_err(r));
1711
			fatal("key_from_private (ca key): %s", ssh_err(r));
1666
1712
1667
		if ((r = sshkey_certify(public, ca, key_type_name)) != 0)
1713
		if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
1668
			fatal("Couldn't certify key %s: %s", tmp, ssh_err(r));
1714
			if ((r = sshkey_certify_custom(public, ca,
1715
			    key_type_name, agent_signer, &agent_fd)) != 0)
1716
				fatal("Couldn't certify key %s via agent: %s",
1717
				    tmp, ssh_err(r));
1718
		} else {
1719
			if ((sshkey_certify(public, ca, key_type_name)) != 0)
1720
				fatal("Couldn't certify key %s: %s",
1721
				    tmp, ssh_err(r));
1722
		}
1669
1723
1670
		if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1724
		if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1671
			*cp = '\0';
1725
			*cp = '\0';
Lines 2261-2268 usage(void) Link Here
2261
	    "       ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"
2315
	    "       ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"
2262
	    "                  [-j start_line] [-K checkpt] [-W generator]\n"
2316
	    "                  [-j start_line] [-K checkpt] [-W generator]\n"
2263
#endif
2317
#endif
2264
	    "       ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n"
2318
	    "       ssh-keygen -s ca_key -I certificate_identity [-h] [-U]\n"
2265
	    "                  [-O option] [-V validity_interval] [-z serial_number] file ...\n"
2319
	    "                  [-D pkcs11_provider] [-n principals] [-O option]\n"
2320
	    "                  [-V validity_interval] [-z serial_number] file ...\n"
2266
	    "       ssh-keygen -L [-f input_keyfile]\n"
2321
	    "       ssh-keygen -L [-f input_keyfile]\n"
2267
	    "       ssh-keygen -A\n"
2322
	    "       ssh-keygen -A\n"
2268
	    "       ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
2323
	    "       ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
Lines 2320-2327 main(int argc, char **argv) Link Here
2320
	if (gethostname(hostname, sizeof(hostname)) < 0)
2375
	if (gethostname(hostname, sizeof(hostname)) < 0)
2321
		fatal("gethostname: %s", strerror(errno));
2376
		fatal("gethostname: %s", strerror(errno));
2322
2377
2323
	/* Remaining characters: UYdw */
2378
	/* Remaining characters: Ydw */
2324
	while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy"
2379
	while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy"
2325
	    "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:"
2380
	    "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:"
2326
	    "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
2381
	    "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
2327
		switch (opt) {
2382
		switch (opt) {
Lines 2448-2453 main(int argc, char **argv) Link Here
2448
		case 'D':
2503
		case 'D':
2449
			pkcs11provider = optarg;
2504
			pkcs11provider = optarg;
2450
			break;
2505
			break;
2506
		case 'U':
2507
			prefer_agent = 1;
2508
			break;
2451
		case 'u':
2509
		case 'u':
2452
			update_krl = 1;
2510
			update_krl = 1;
2453
			break;
2511
			break;
(-)a/sshkey.c (-3 / +20 lines)
Lines 2252-2258 sshkey_drop_cert(struct sshkey *k) Link Here
2252
2252
2253
/* Sign a certified key, (re-)generating the signed certblob. */
2253
/* Sign a certified key, (re-)generating the signed certblob. */
2254
int
2254
int
2255
sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2255
sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2256
    sshkey_certify_signer *signer, void *signer_ctx)
2256
{
2257
{
2257
	struct sshbuf *principals = NULL;
2258
	struct sshbuf *principals = NULL;
2258
	u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2259
	u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
Lines 2341-2348 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) Link Here
2341
		goto out;
2342
		goto out;
2342
2343
2343
	/* Sign the whole mess */
2344
	/* Sign the whole mess */
2344
	if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2345
	if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2345
	    sshbuf_len(cert), alg, 0)) != 0)
2346
	    sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
2346
		goto out;
2347
		goto out;
2347
2348
2348
	/* Append signature and we are done */
2349
	/* Append signature and we are done */
Lines 2358-2363 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) Link Here
2358
	return ret;
2359
	return ret;
2359
}
2360
}
2360
2361
2362
static int
2363
default_key_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
2364
    const u_char *data, size_t datalen,
2365
    const char *alg, u_int compat, void *ctx)
2366
{
2367
	if (ctx != NULL)
2368
		return SSH_ERR_INVALID_ARGUMENT;
2369
	return sshkey_sign(key, sigp, lenp, data, datalen, alg, compat);
2370
}
2371
2372
int
2373
sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2374
{
2375
	return sshkey_certify_custom(k, ca, alg, default_key_sign, NULL);
2376
}
2377
2361
int
2378
int
2362
sshkey_cert_check_authority(const struct sshkey *k,
2379
sshkey_cert_check_authority(const struct sshkey *k,
2363
    int want_host, int require_principal,
2380
    int want_host, int require_principal,
(-)a/sshkey.h (-1 / +7 lines)
Lines 136-148 int sshkey_type_is_cert(int); Link Here
136
int	 sshkey_type_plain(int);
136
int	 sshkey_type_plain(int);
137
int	 sshkey_to_certified(struct sshkey *);
137
int	 sshkey_to_certified(struct sshkey *);
138
int	 sshkey_drop_cert(struct sshkey *);
138
int	 sshkey_drop_cert(struct sshkey *);
139
int	 sshkey_certify(struct sshkey *, struct sshkey *, const char *);
140
int	 sshkey_cert_copy(const struct sshkey *, struct sshkey *);
139
int	 sshkey_cert_copy(const struct sshkey *, struct sshkey *);
141
int	 sshkey_cert_check_authority(const struct sshkey *, int, int,
140
int	 sshkey_cert_check_authority(const struct sshkey *, int, int,
142
    const char *, const char **);
141
    const char *, const char **);
143
size_t	 sshkey_format_cert_validity(const struct sshkey_cert *,
142
size_t	 sshkey_format_cert_validity(const struct sshkey_cert *,
144
    char *, size_t) __attribute__((__bounded__(__string__, 2, 3)));
143
    char *, size_t) __attribute__((__bounded__(__string__, 2, 3)));
145
144
145
int	 sshkey_certify(struct sshkey *, struct sshkey *, const char *);
146
/* Variant allowing use of a custom signature function (e.g. for ssh-agent) */
147
typedef int sshkey_certify_signer(const struct sshkey *, u_char **, size_t *,
148
    const u_char *, size_t, const char *, u_int, void *);
149
int	 sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *,
150
    sshkey_certify_signer *, void *);
151
146
int		 sshkey_ecdsa_nid_from_name(const char *);
152
int		 sshkey_ecdsa_nid_from_name(const char *);
147
int		 sshkey_curve_name_to_nid(const char *);
153
int		 sshkey_curve_name_to_nid(const char *);
148
const char *	 sshkey_curve_nid_to_name(int);
154
const char *	 sshkey_curve_nid_to_name(int);

Return to bug 2377