[openssh-commits] [openssh] 03/05: upstream commit

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Jan 30 12:19:38 AEDT 2015


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 669aee994348468af8b4b2ebd29b602cf2860b22
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Fri Jan 30 01:10:33 2015 +0000

    upstream commit
    
    permit KRLs that revoke certificates by serial number or
     key ID without scoping to a particular CA; ok markus@
---
 PROTOCOL.krl |   9 ++++-
 krl.c        | 122 ++++++++++++++++++++++++++++++++++++-----------------------
 ssh-keygen.c |  26 +++++++------
 3 files changed, 96 insertions(+), 61 deletions(-)

diff --git a/PROTOCOL.krl b/PROTOCOL.krl
index e8caa45..b969510 100644
--- a/PROTOCOL.krl
+++ b/PROTOCOL.krl
@@ -37,7 +37,7 @@ The available section types are:
 #define KRL_SECTION_FINGERPRINT_SHA1		3
 #define KRL_SECTION_SIGNATURE			4
 
-3. Certificate serial section
+2. Certificate section
 
 These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by
 serial number or key ID. The consist of the CA key that issued the
@@ -47,6 +47,11 @@ ignored.
 	string ca_key
 	string reserved
 
+Where "ca_key" is the standard SSH wire serialisation of the CA's
+public key. Alternately, "ca_key" may be an empty string to indicate
+the certificate section applies to all CAs (this is most useful when
+revoking key IDs).
+
 Followed by one or more sections:
 
 	byte	cert_section_type
@@ -161,4 +166,4 @@ Implementations that retrieve KRLs over untrusted channels must verify
 signatures. Signature sections are optional for KRLs distributed by
 trusted means.
 
-$OpenBSD: PROTOCOL.krl,v 1.2 2013/01/18 00:24:58 djm Exp $
+$OpenBSD: PROTOCOL.krl,v 1.3 2015/01/30 01:10:33 djm Exp $
diff --git a/krl.c b/krl.c
index 3fe29c8..4bbaa20 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $OpenBSD: krl.c,v 1.30 2015/01/26 02:59:11 djm Exp $ */
+/* $OpenBSD: krl.c,v 1.31 2015/01/30 01:10:33 djm Exp $ */
 
 #include "includes.h"
 
@@ -156,8 +156,7 @@ revoked_certs_free(struct revoked_certs *rc)
 		free(rki->key_id);
 		free(rki);
 	}
-	if (rc->ca_key != NULL)
-		sshkey_free(rc->ca_key);
+	sshkey_free(rc->ca_key);
 }
 
 void
@@ -214,7 +213,8 @@ revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key,
 
 	*rcp = NULL;
 	TAILQ_FOREACH(rc, &krl->revoked_certs, entry) {
-		if (sshkey_equal(rc->ca_key, ca_key)) {
+		if ((ca_key == NULL && rc->ca_key == NULL) ||
+		    sshkey_equal(rc->ca_key, ca_key)) {
 			*rcp = rc;
 			return 0;
 		}
@@ -224,14 +224,17 @@ revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key,
 	/* If this CA doesn't exist in the list then add it now */
 	if ((rc = calloc(1, sizeof(*rc))) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
-	if ((r = sshkey_from_private(ca_key, &rc->ca_key)) != 0) {
+	if (ca_key == NULL)
+		rc->ca_key = NULL;
+	else if ((r = sshkey_from_private(ca_key, &rc->ca_key)) != 0) {
 		free(rc);
 		return r;
 	}
 	RB_INIT(&rc->revoked_serials);
 	RB_INIT(&rc->revoked_key_ids);
 	TAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry);
-	KRL_DBG(("%s: new CA %s", __func__, sshkey_type(ca_key)));
+	KRL_DBG(("%s: new CA %s", __func__,
+	    ca_key == NULL ? "*" : sshkey_type(ca_key)));
 	*rcp = rc;
 	return 0;
 }
@@ -554,9 +557,15 @@ revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)
 	if ((sect = sshbuf_new()) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
 
-	/* Store the header: CA scope key, reserved */
-	if ((r = sshkey_puts(rc->ca_key, buf)) != 0 ||
-	    (r = sshbuf_put_string(buf, NULL, 0)) != 0)
+	/* Store the header: optional CA scope key, reserved */
+	if (rc->ca_key == NULL) {
+		if ((r = sshbuf_put_string(buf, NULL, 0)) != 0)
+			goto out;
+	} else {
+		if ((r = sshkey_puts(rc->ca_key, buf)) != 0)
+			goto out;
+	}
+	if ((r = sshbuf_put_string(buf, NULL, 0)) != 0)
 		goto out;
 
 	/* Store the revoked serials.  */
@@ -813,7 +822,7 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)
 	if ((r = sshbuf_get_string_direct(buf, &blob, &blen)) != 0 ||
 	    (r = sshbuf_skip_string(buf)) != 0)
 		goto out;
-	if ((r = sshkey_from_blob(blob, blen, &ca_key)) != 0)
+	if (blen != 0 && (r = sshkey_from_blob(blob, blen, &ca_key)) != 0)
 		goto out;
 
 	while (sshbuf_len(buf) > 0) {
@@ -1154,48 +1163,12 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
 	return r;
 }
 
-/* Checks whether a given key/cert is revoked. Does not check its CA */
+/* Checks certificate serial number and key ID revocation */
 static int
-is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
+is_cert_revoked(const struct sshkey *key, struct revoked_certs *rc)
 {
-	struct revoked_blob rb, *erb;
 	struct revoked_serial rs, *ers;
 	struct revoked_key_id rki, *erki;
-	struct revoked_certs *rc;
-	int r;
-
-	/* Check explicitly revoked hashes first */
-	memset(&rb, 0, sizeof(rb));
-	if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
-	    &rb.blob, &rb.len)) != 0)
-		return r;
-	erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
-	free(rb.blob);
-	if (erb != NULL) {
-		KRL_DBG(("%s: revoked by key SHA1", __func__));
-		return SSH_ERR_KEY_REVOKED;
-	}
-
-	/* Next, explicit keys */
-	memset(&rb, 0, sizeof(rb));
-	if ((r = plain_key_blob(key, &rb.blob, &rb.len)) != 0)
-		return r;
-	erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
-	free(rb.blob);
-	if (erb != NULL) {
-		KRL_DBG(("%s: revoked by explicit key", __func__));
-		return SSH_ERR_KEY_REVOKED;
-	}
-
-	if (!sshkey_is_cert(key))
-		return 0;
-
-	/* Check cert revocation */
-	if ((r = revoked_certs_for_ca_key(krl, key->cert->signature_key,
-	    &rc, 0)) != 0)
-		return r;
-	if (rc == NULL)
-		return 0; /* No entry for this CA */
 
 	/* Check revocation by cert key ID */
 	memset(&rki, 0, sizeof(rki));
@@ -1221,6 +1194,59 @@ is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
 		    key->cert->serial, ers->lo, ers->hi));
 		return SSH_ERR_KEY_REVOKED;
 	}
+	return 0;
+}
+
+/* Checks whether a given key/cert is revoked. Does not check its CA */
+static int
+is_key_revoked(struct ssh_krl *krl, const struct sshkey *key)
+{
+	struct revoked_blob rb, *erb;
+	struct revoked_certs *rc;
+	int r;
+
+	/* Check explicitly revoked hashes first */
+	memset(&rb, 0, sizeof(rb));
+	if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,
+	    &rb.blob, &rb.len)) != 0)
+		return r;
+	erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);
+	free(rb.blob);
+	if (erb != NULL) {
+		KRL_DBG(("%s: revoked by key SHA1", __func__));
+		return SSH_ERR_KEY_REVOKED;
+	}
+
+	/* Next, explicit keys */
+	memset(&rb, 0, sizeof(rb));
+	if ((r = plain_key_blob(key, &rb.blob, &rb.len)) != 0)
+		return r;
+	erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);
+	free(rb.blob);
+	if (erb != NULL) {
+		KRL_DBG(("%s: revoked by explicit key", __func__));
+		return SSH_ERR_KEY_REVOKED;
+	}
+
+	if (!sshkey_is_cert(key))
+		return 0;
+
+	/* Check cert revocation for the specified CA */
+	if ((r = revoked_certs_for_ca_key(krl, key->cert->signature_key,
+	    &rc, 0)) != 0)
+		return r;
+	if (rc != NULL) {
+		if ((r = is_cert_revoked(key, rc)) != 0)
+			return r;
+	}
+	/* Check cert revocation for the wildcard CA */
+	if ((r = revoked_certs_for_ca_key(krl, NULL, &rc, 0)) != 0)
+		return r;
+	if (rc != NULL) {
+		if ((r = is_cert_revoked(key, rc)) != 0)
+			return r;
+	}
+
 	KRL_DBG(("%s: %llu no match", __func__, key->cert->serial));
 	return 0;
 }
diff --git a/ssh-keygen.c b/ssh-keygen.c
index b435498..2c6a568 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.260 2015/01/30 00:59:19 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.261 2015/01/30 01:10:33 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -1973,7 +1973,7 @@ load_krl(const char *path, struct ssh_krl **krlp)
 }
 
 static void
-update_krl_from_file(struct passwd *pw, const char *file,
+update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
     const struct sshkey *ca, struct ssh_krl *krl)
 {
 	struct sshkey *key = NULL;
@@ -2015,7 +2015,7 @@ update_krl_from_file(struct passwd *pw, const char *file,
 		if (*cp == '\0')
 			continue;
 		if (strncasecmp(cp, "serial:", 7) == 0) {
-			if (ca == NULL) {
+			if (ca == NULL && !wild_ca) {
 				fatal("revoking certificates by serial number "
 				    "requires specification of a CA key");
 			}
@@ -2052,7 +2052,7 @@ update_krl_from_file(struct passwd *pw, const char *file,
 				    __func__);
 			}
 		} else if (strncasecmp(cp, "id:", 3) == 0) {
-			if (ca == NULL) {
+			if (ca == NULL && !wild_ca) {
 				fatal("revoking certificates by key ID "
 				    "requires specification of a CA key");
 			}
@@ -2103,7 +2103,7 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
 	struct ssh_krl *krl;
 	struct stat sb;
 	struct sshkey *ca = NULL;
-	int fd, i, r;
+	int fd, i, r, wild_ca = 0;
 	char *tmp;
 	struct sshbuf *kbuf;
 
@@ -2117,11 +2117,15 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
 			fatal("KRL \"%s\" does not exist", identity_file);
 	}
 	if (ca_key_path != NULL) {
-		tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
-		if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
-			fatal("Cannot load CA public key %s: %s",
-			    tmp, ssh_err(r));
-		free(tmp);
+		if (strcasecmp(ca_key_path, "none") == 0)
+			wild_ca = 1;
+		else {
+			tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
+			if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
+				fatal("Cannot load CA public key %s: %s",
+				    tmp, ssh_err(r));
+			free(tmp);
+		}
 	}
 
 	if (updating)
@@ -2135,7 +2139,7 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
 		ssh_krl_set_comment(krl, identity_comment);
 
 	for (i = 0; i < argc; i++)
-		update_krl_from_file(pw, argv[i], ca, krl);
+		update_krl_from_file(pw, argv[i], wild_ca, ca, krl);
 
 	if ((kbuf = sshbuf_new()) == NULL)
 		fatal("sshbuf_new failed");

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list