Support for KRL extensions.
authordjm <djm@openbsd.org>
Mon, 17 Jul 2023 03:57:21 +0000 (03:57 +0000)
committerdjm <djm@openbsd.org>
Mon, 17 Jul 2023 03:57:21 +0000 (03:57 +0000)
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

usr.bin/ssh/PROTOCOL.krl
usr.bin/ssh/krl.c
usr.bin/ssh/krl.h

index 115f80e..f421315 100644 (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 $
index 6c4e372..4dad632 100644 (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 <sys/types.h>
 #include <sys/tree.h>
@@ -838,6 +838,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)
 {
@@ -929,6 +968,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;
@@ -975,6 +1018,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,
@@ -1142,6 +1222,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);
index ca6d3f2..d0f4698 100644 (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
 #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;