Skip to content

Commit

Permalink
upstream: Support for KRL extensions.
Browse files Browse the repository at this point in the history
This defines wire formats for optional KRL extensions and implements
parsing of the new submessages. No actual extensions are supported at
this point.

ok markus

OpenBSD-Commit-ID: ae2fcde9a22a9ba7f765bd4f36b3f5901d8c3fa7
  • Loading branch information
djmdjm committed Jul 17, 2023
1 parent 18ea857 commit 449566f
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 4 deletions.
51 changes: 49 additions & 2 deletions PROTOCOL.krl
Expand Up @@ -37,6 +37,7 @@ The available section types are:
#define KRL_SECTION_FINGERPRINT_SHA1 3
#define KRL_SECTION_SIGNATURE 4
#define KRL_SECTION_FINGERPRINT_SHA256 5
#define KRL_SECTION_EXTENSION 255

2. Certificate section

Expand Down Expand Up @@ -64,6 +65,7 @@ The certificate section types are:
#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
#define KRL_SECTION_CERT_KEY_ID 0x23
#define KRL_SECTION_CERT_EXTENSION 0x39

2.1 Certificate serial list section

Expand Down Expand Up @@ -114,6 +116,29 @@ associated with a particular identity, e.g. a host or a user.
This section must contain at least one "key_id". This section may appear
multiple times.

2.5. Certificate Extension subsections

This subsection type provides a generic extension mechanism to the
certificates KRL section that may be used to provide optional or critical
data.

Extensions are stored in subsections of type
KRL_SECTION_CERT_EXTENSION with the following contents:

string extension_name
boolean is_critical
string extension_contents.

Where "extension_name" describes the type of extension. It is
recommended that user extensions follow "cert-name@domain.org" naming.

The "is_critical" indicates whether this extension is mandatory or
optional. If true, then any unsupported extension encountered should
result in KRL parsing failure. If false, then it may be safely be
ignored.

The "extension_contents" contains the body of the extension.

3. Explicit key sections

These sections, identified as KRL_SECTION_EXPLICIT_KEY, revoke keys
Expand Down Expand Up @@ -144,7 +169,29 @@ as a big-endian integer.

This section may appear multiple times.

5. KRL signature sections
5. Extension sections

This section type provides a generic extension mechanism to the KRL
format that may be used to provide optional or critical data.

Extensions are recorded in sections of type KRL_SECTION_EXTENSION
with the following contents:

string extension_name
boolean is_critical
string extension_contents.

Where "extension_name" describes the type of extension. It is
recommended that user extensions follow "name@domain.org" naming.

The "is_critical" indicates whether this extension is mandatory or
optional. If true, then any unsupported extension encountered should
result in KRL parsing failure. If false, then it may be safely be
ignored.

The "extension_contents" contains the body of the extension.

6. KRL signature sections

The KRL_SECTION_SIGNATURE section serves a different purpose to the
preceding ones: to provide cryptographic authentication of a KRL that
Expand All @@ -168,4 +215,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.5 2018/09/12 01:21:34 djm Exp $
$OpenBSD: PROTOCOL.krl,v 1.6 2023/07/17 03:57:21 djm Exp $
86 changes: 85 additions & 1 deletion krl.c
Expand Up @@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/* $OpenBSD: krl.c,v 1.55 2023/03/14 07:28:47 dtucker Exp $ */
/* $OpenBSD: krl.c,v 1.56 2023/07/17 03:57:21 djm Exp $ */

#include "includes.h"

Expand Down Expand Up @@ -840,6 +840,45 @@ format_timestamp(u_int64_t timestamp, char *ts, size_t nts)
}
}

static int
cert_extension_subsection(struct sshbuf *subsect, struct ssh_krl *krl)
{
int r = SSH_ERR_INTERNAL_ERROR;
u_char critical = 1;
struct sshbuf *value = NULL;
char *name = NULL;

if ((r = sshbuf_get_cstring(subsect, &name, NULL)) != 0 ||
(r = sshbuf_get_u8(subsect, &critical)) != 0 ||
(r = sshbuf_froms(subsect, &value)) != 0) {
debug_fr(r, "parse");
error("KRL has invalid certificate extension subsection");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (sshbuf_len(subsect) != 0) {
error("KRL has invalid certificate extension subsection: "
"trailing data");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
debug_f("cert extension %s critical %u len %zu",
name, critical, sshbuf_len(value));
/* no extensions are currently supported */
if (critical) {
error("KRL contains unsupported critical certificate "
"subsection \"%s\"", name);
r = SSH_ERR_FEATURE_UNSUPPORTED;
goto out;
}
/* success */
r = 0;
out:
free(name);
sshbuf_free(value);
return r;
}

static int
parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)
{
Expand Down Expand Up @@ -931,6 +970,10 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)
key_id = NULL;
}
break;
case KRL_SECTION_CERT_EXTENSION:
if ((r = cert_extension_subsection(subsect, krl)) != 0)
goto out;
break;
default:
error("Unsupported KRL certificate section %u", type);
r = SSH_ERR_INVALID_FORMAT;
Expand Down Expand Up @@ -977,6 +1020,43 @@ blob_section(struct sshbuf *sect, struct revoked_blob_tree *target_tree,
return 0;
}

static int
extension_section(struct sshbuf *sect, struct ssh_krl *krl)
{
int r = SSH_ERR_INTERNAL_ERROR;
u_char critical = 1;
struct sshbuf *value = NULL;
char *name = NULL;

if ((r = sshbuf_get_cstring(sect, &name, NULL)) != 0 ||
(r = sshbuf_get_u8(sect, &critical)) != 0 ||
(r = sshbuf_froms(sect, &value)) != 0) {
debug_fr(r, "parse");
error("KRL has invalid extension section");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (sshbuf_len(sect) != 0) {
error("KRL has invalid extension section: trailing data");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
debug_f("extension %s critical %u len %zu",
name, critical, sshbuf_len(value));
/* no extensions are currently supported */
if (critical) {
error("KRL contains unsupported critical section \"%s\"", name);
r = SSH_ERR_FEATURE_UNSUPPORTED;
goto out;
}
/* success */
r = 0;
out:
free(name);
sshbuf_free(value);
return r;
}

/* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */
int
ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
Expand Down Expand Up @@ -1144,6 +1224,10 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
&krl->revoked_sha256s, 32)) != 0)
goto out;
break;
case KRL_SECTION_EXTENSION:
if ((r = extension_section(sect, krl)) != 0)
goto out;
break;
case KRL_SECTION_SIGNATURE:
/* Handled above, but still need to stay in synch */
sshbuf_free(sect);
Expand Down
4 changes: 3 additions & 1 deletion krl.h
Expand Up @@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/* $OpenBSD: krl.h,v 1.8 2020/04/03 02:26:56 djm Exp $ */
/* $OpenBSD: krl.h,v 1.9 2023/07/17 03:57:21 djm Exp $ */

#ifndef _KRL_H
#define _KRL_H
Expand All @@ -30,12 +30,14 @@
#define KRL_SECTION_FINGERPRINT_SHA1 3
#define KRL_SECTION_SIGNATURE 4
#define KRL_SECTION_FINGERPRINT_SHA256 5
#define KRL_SECTION_EXTENSION 255

/* KRL_SECTION_CERTIFICATES subsection types */
#define KRL_SECTION_CERT_SERIAL_LIST 0x20
#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
#define KRL_SECTION_CERT_KEY_ID 0x23
#define KRL_SECTION_CERT_EXTENSION 0x39

struct sshkey;
struct sshbuf;
Expand Down

0 comments on commit 449566f

Please sign in to comment.