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

Collapse All | Expand All

(-)a/authfd.c (-1 / +1 lines)
Lines 121-127 ssh_get_authentication_socket(int *fdp) Link Here
121
}
121
}
122
122
123
/* Communicate with agent: send request and read reply */
123
/* Communicate with agent: send request and read reply */
124
static int
124
int
125
ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
125
ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
126
{
126
{
127
	int r;
127
	int r;
(-)a/authfd.h (+1 lines)
Lines 42-47 int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, Link Here
42
int	ssh_agent_sign(int sock, struct sshkey *key,
42
int	ssh_agent_sign(int sock, struct sshkey *key,
43
	    u_char **sigp, size_t *lenp,
43
	    u_char **sigp, size_t *lenp,
44
	    const u_char *data, size_t datalen, const char *alg, u_int compat);
44
	    const u_char *data, size_t datalen, const char *alg, u_int compat);
45
int	ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply);
45
46
46
/* Messages for the authentication agent connection. */
47
/* Messages for the authentication agent connection. */
47
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES	1
48
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES	1
(-)a/ssh-keygen.c (-15 / +97 lines)
Lines 57-62 Link Here
57
#include "atomicio.h"
57
#include "atomicio.h"
58
#include "krl.h"
58
#include "krl.h"
59
#include "digest.h"
59
#include "digest.h"
60
#include "authfd.h"
60
61
61
#ifdef WITH_OPENSSL
62
#ifdef WITH_OPENSSL
62
# define DEFAULT_KEY_TYPE_NAME "rsa"
63
# define DEFAULT_KEY_TYPE_NAME "rsa"
Lines 1579-1606 load_pkcs11_key(char *path) Link Here
1579
#endif /* ENABLE_PKCS11 */
1580
#endif /* ENABLE_PKCS11 */
1580
}
1581
}
1581
1582
1583
static int
1584
do_agent_sign(int agent_fd, struct sshkey *k, struct sshkey *ca_pk,
1585
    u_char *ca_blob, size_t ca_len)
1586
{
1587
	u_char type;
1588
	u_char *sig;
1589
	size_t slen;
1590
	struct sshbuf *msg, *cert_blob;
1591
	u_int flags = 0;
1592
	int ret = 0, r = 0;
1593
1594
	cert_blob = k->cert->certblob; /* for readability */
1595
	if ((msg = sshbuf_new()) == NULL)
1596
		fatal("%s: sshbuf_new failed", __func__);
1597
	if ((r = sshkey_cert_prepare_sign(k, ca_pk)) != 0)
1598
		ret = -1;
1599
1600
	if (ret == 0) {
1601
		if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
1602
		    (r = sshbuf_put_string(msg, ca_blob, ca_len)) != 0 ||
1603
		    (r = sshbuf_put_string(msg, sshbuf_ptr(cert_blob),
1604
		    sshbuf_len(cert_blob))) != 0 ||
1605
		    (r = sshbuf_put_u32(msg, flags)) != 0)
1606
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
1607
		if ((r = ssh_request_reply(agent_fd, msg, msg)) != 0)
1608
			ret = -1;
1609
		else if ((r = sshbuf_get_u8(msg, &type)) != 0)
1610
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
1611
		else if ((type == SSH_AGENT_FAILURE) || (type == SSH2_AGENT_FAILURE))
1612
			ret = -1;
1613
		else if ((r = sshbuf_get_string(msg, &sig, &slen)) != 0 ||
1614
		    (r = sshbuf_put_string(cert_blob, sig, slen)) != 0)
1615
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
1616
		else
1617
			free(sig);
1618
	}
1619
1620
	sshbuf_free(msg);
1621
	return ret;
1622
}
1623
1582
static void
1624
static void
1583
do_ca_sign(struct passwd *pw, int argc, char **argv)
1625
do_ca_sign(struct passwd *pw, int argc, char **argv)
1584
{
1626
{
1585
	int r, i, fd;
1627
	int r, i, fd, agent_fd;
1586
	u_int n;
1628
	u_int n;
1587
	struct sshkey *ca, *public;
1629
	struct sshkey *ca, *ca_pk, *public;
1588
	char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1630
	char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1589
	FILE *f;
1631
	FILE *f;
1632
	u_char *ca_blob;
1633
	size_t ca_len;
1634
	/* flag indicating whether to try the ssh-agent to sign certificates */
1635
	int try_agent = 0;
1590
1636
1591
#ifdef ENABLE_PKCS11
1637
#ifdef ENABLE_PKCS11
1592
	pkcs11_init(1);
1638
	pkcs11_init(1);
1593
#endif
1639
#endif
1640
1641
	/* load pubkey of CA first (ca_blob), if it works, try getting agent socket */
1594
	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1642
	tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1595
	if (pkcs11provider != NULL) {
1643
1596
		if ((ca = load_pkcs11_key(tmp)) == NULL)
1644
	if ((r = sshkey_load_public(tmp, &ca_pk, NULL)) == 0 &&
1597
			fatal("No PKCS#11 key matching %s found", ca_key_path);
1645
	    (r = sshkey_to_blob(ca_pk, &ca_blob, &ca_len)) == 0) {
1598
	} else
1646
		switch (r = ssh_get_authentication_socket(&agent_fd)) {
1599
		ca = load_identity(tmp);
1647
		case SSH_ERR_SUCCESS:
1600
	free(tmp);
1648
			try_agent = 1;
1649
			ca = NULL;
1650
			break;
1651
		case SSH_ERR_AGENT_NOT_PRESENT:
1652
			debug("Couldn't open connection to agent");
1653
			break;
1654
		default:
1655
			debug("Error connecting to agent");
1656
			break;
1657
		}
1658
	}
1659
1660
	if (!try_agent) {
1661
		if (pkcs11provider != NULL) {
1662
			if ((ca = load_pkcs11_key(tmp)) == NULL)
1663
				fatal("No PKCS#11 key matching %s found", ca_key_path);
1664
		} else
1665
			ca = load_identity(tmp);
1666
		free(tmp);
1667
	}
1601
1668
1602
	if (key_type_name != NULL &&
1669
	if (key_type_name != NULL &&
1603
	    sshkey_type_from_name(key_type_name) != ca->type)  {
1670
	    sshkey_type_from_name(key_type_name) != ca->type) {
1604
		fatal("CA key type %s doesn't match specified %s",
1671
		fatal("CA key type %s doesn't match specified %s",
1605
		    sshkey_ssh_name(ca), key_type_name);
1672
		    sshkey_ssh_name(ca), key_type_name);
1606
	}
1673
	}
Lines 1618-1624 do_ca_sign(struct passwd *pw, int argc, char **argv) Link Here
1618
			}
1685
			}
1619
			free(otmp);
1686
			free(otmp);
1620
		}
1687
		}
1621
	
1688
1622
		tmp = tilde_expand_filename(argv[i], pw->pw_uid);
1689
		tmp = tilde_expand_filename(argv[i], pw->pw_uid);
1623
		if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
1690
		if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
1624
			fatal("%s: unable to open \"%s\": %s",
1691
			fatal("%s: unable to open \"%s\": %s",
Lines 1642-1653 do_ca_sign(struct passwd *pw, int argc, char **argv) Link Here
1642
		prepare_options_buf(public->cert->critical, OPTIONS_CRITICAL);
1709
		prepare_options_buf(public->cert->critical, OPTIONS_CRITICAL);
1643
		prepare_options_buf(public->cert->extensions,
1710
		prepare_options_buf(public->cert->extensions,
1644
		    OPTIONS_EXTENSIONS);
1711
		    OPTIONS_EXTENSIONS);
1645
		if ((r = sshkey_from_private(ca,
1646
		    &public->cert->signature_key)) != 0)
1647
			fatal("key_from_private (ca key): %s", ssh_err(r));
1648
1712
1649
		if ((r = sshkey_certify(public, ca, key_type_name)) != 0)
1713
		if (try_agent &&
1650
			fatal("Couldn't certify key %s: %s", tmp, ssh_err(r));
1714
		    (r = do_agent_sign(agent_fd, public, ca_pk, ca_blob, ca_len)) != 0) {
1715
			try_agent = 0;
1716
			otmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1717
			if (pkcs11provider != NULL) {
1718
				if ((ca = load_pkcs11_key(otmp)) == NULL)
1719
					fatal("No PKCS#11 key matching %s found", ca_key_path);
1720
			} else
1721
				ca = load_identity(otmp);
1722
			free(otmp);
1723
		}
1724
1725
		if (!try_agent) {
1726
			if ((r = sshkey_from_private(ca,
1727
			    &public->cert->signature_key)) != 0)
1728
				fatal("key_from_private (ca key): %s", ssh_err(r));
1729
1730
			if ((r = sshkey_certify(public, ca, key_type_name)) != 0)
1731
				fatal("Couldn't certify key %s: %s", tmp, ssh_err(r));
1732
		}
1651
1733
1652
		if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1734
		if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1653
			*cp = '\0';
1735
			*cp = '\0';
(-)a/sshkey.c (-6 / +27 lines)
Lines 2369-2381 sshkey_drop_cert(struct sshkey *k) Link Here
2369
	return 0;
2369
	return 0;
2370
}
2370
}
2371
2371
2372
/* Sign a certified key, (re-)generating the signed certblob. */
2372
/* Prepare a certificate blob for CA signing. */
2373
int
2373
int
2374
sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2374
sshkey_cert_prepare_sign(struct sshkey *k, struct sshkey *ca)
2375
{
2375
{
2376
	struct sshbuf *principals = NULL;
2376
	struct sshbuf *principals = NULL;
2377
	u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
2377
	u_char *ca_blob = NULL, nonce[32];
2378
	size_t i, ca_len, sig_len;
2378
	size_t i, ca_len;
2379
	int ret = SSH_ERR_INTERNAL_ERROR;
2379
	int ret = SSH_ERR_INTERNAL_ERROR;
2380
	struct sshbuf *cert;
2380
	struct sshbuf *cert;
2381
2381
Lines 2458-2463 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) Link Here
2458
	    (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
2458
	    (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
2459
	    (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
2459
	    (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
2460
		goto out;
2460
		goto out;
2461
	ret = 0;
2462
 out:
2463
	if (ret != 0)
2464
		sshbuf_reset(cert);
2465
	if (ca_blob != NULL)
2466
		free(ca_blob);
2467
	if (principals != NULL)
2468
		sshbuf_free(principals);
2469
	return ret;
2470
}
2471
2472
/* Sign a certified key, (re-)generating the signed certblob. */
2473
int
2474
sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2475
{
2476
	u_char *sig_blob = NULL;
2477
	size_t sig_len;
2478
	int ret = SSH_ERR_INTERNAL_ERROR;
2479
	struct sshbuf *cert;
2480
2481
	cert = k->cert->certblob; /* for readability */
2482
	if ((ret = sshkey_cert_prepare_sign(k, ca)) != 0)
2483
		goto out;
2461
2484
2462
	/* Sign the whole mess */
2485
	/* Sign the whole mess */
2463
	if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2486
	if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
Lines 2472-2479 sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) Link Here
2472
	if (ret != 0)
2495
	if (ret != 0)
2473
		sshbuf_reset(cert);
2496
		sshbuf_reset(cert);
2474
	free(sig_blob);
2497
	free(sig_blob);
2475
	free(ca_blob);
2476
	sshbuf_free(principals);
2477
	return ret;
2498
	return ret;
2478
}
2499
}
2479
2500
(-)a/sshkey.h (+1 lines)
Lines 137-142 int sshkey_type_is_cert(int); Link Here
137
int	 sshkey_type_plain(int);
137
int	 sshkey_type_plain(int);
138
int	 sshkey_to_certified(struct sshkey *);
138
int	 sshkey_to_certified(struct sshkey *);
139
int	 sshkey_drop_cert(struct sshkey *);
139
int	 sshkey_drop_cert(struct sshkey *);
140
int	 sshkey_cert_prepare_sign(struct sshkey *, struct sshkey *);
140
int	 sshkey_certify(struct sshkey *, struct sshkey *, const char *);
141
int	 sshkey_certify(struct sshkey *, struct sshkey *, const char *);
141
int	 sshkey_cert_copy(const struct sshkey *, struct sshkey *);
142
int	 sshkey_cert_copy(const struct sshkey *, struct sshkey *);
142
int	 sshkey_cert_check_authority(const struct sshkey *, int, int,
143
int	 sshkey_cert_check_authority(const struct sshkey *, int, int,

Return to bug 2377