upstream: Support for KRL extensions.

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
This commit is contained in:
djm@openbsd.org 2023-07-17 03:57:21 +00:00 committed by Damien Miller
parent 18ea857770
commit 449566f64c
No known key found for this signature in database
3 changed files with 137 additions and 4 deletions

View File

@ -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
@ -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
@ -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
@ -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
@ -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
krl.c
View File

@ -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"
@ -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)
{
@ -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;
@ -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,
@ -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);

4
krl.h
View File

@ -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
@ -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;