Validate the session_id to be a real UUID.
authorclaudio <claudio@openbsd.org>
Wed, 4 Jan 2023 14:22:43 +0000 (14:22 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 4 Jan 2023 14:22:43 +0000 (14:22 +0000)
RFC 8182 requires the session_id to be a version 4 random UUID (using
variant 1). Now checking the version and variant is currently disabled
because there is at least one CA with a session_id that is all random
and therefor the version check triggers there.
Joint work with job@. OK job@, tb@

usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/rrdp_delta.c
usr.sbin/rpki-client/rrdp_notification.c
usr.sbin/rpki-client/rrdp_snapshot.c
usr.sbin/rpki-client/validate.c

index 6bd5632..ed76f35 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.165 2022/12/28 21:30:18 jmc Exp $ */
+/*     $OpenBSD: extern.h,v 1.166 2023/01/04 14:22:43 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -659,6 +659,7 @@ int          valid_rsc(const char *, struct cert *, struct rsc *);
 int             valid_econtent_version(const char *, const ASN1_INTEGER *);
 int             valid_aspa(const char *, struct cert *, struct aspa *);
 int             valid_geofeed(const char *, struct cert *, struct geofeed *);
+int             valid_uuid(const char *);
 
 /* Working with CMS. */
 unsigned char  *cms_parse_validate(X509 **, const char *,
index 97b563d..d8b12ae 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rrdp_delta.c,v 1.8 2022/05/15 16:43:35 tb Exp $ */
+/*     $OpenBSD: rrdp_delta.c,v 1.9 2023/01/04 14:22:43 claudio Exp $ */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -77,7 +77,8 @@ start_delta_elem(struct delta_xml *dxml, const char **attr)
                        if (errstr == NULL)
                                continue;
                }
-               if (strcmp("session_id", attr[i]) == 0) {
+               if (strcmp("session_id", attr[i]) == 0 &&
+                   valid_uuid(attr[i + 1])) {
                        dxml->session_id = xstrdup(attr[i + 1]);
                        continue;
                }
index 016385d..b135eca 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rrdp_notification.c,v 1.16 2022/06/16 16:09:56 claudio Exp $ */
+/*     $OpenBSD: rrdp_notification.c,v 1.17 2023/01/04 14:22:43 claudio Exp $ */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -125,7 +125,8 @@ start_notification_elem(struct notification_xml *nxml, const char **attr)
                        has_xmlns = 1;
                        continue;
                }
-               if (strcmp("session_id", attr[i]) == 0) {
+               if (strcmp("session_id", attr[i]) == 0 &&
+                   valid_uuid(attr[i + 1])) {
                        nxml->session_id = xstrdup(attr[i + 1]);
                        continue;
                }
index 47423c1..2d27642 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rrdp_snapshot.c,v 1.6 2022/02/03 18:19:32 claudio Exp $ */
+/*     $OpenBSD: rrdp_snapshot.c,v 1.7 2023/01/04 14:22:43 claudio Exp $ */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -69,7 +69,8 @@ start_snapshot_elem(struct snapshot_xml *sxml, const char **attr)
                        if (errstr == NULL)
                                continue;
                }
-               if (strcmp("session_id", attr[i]) == 0) {
+               if (strcmp("session_id", attr[i]) == 0 &&
+                   valid_uuid(attr[i + 1])) {
                        sxml->session_id = xstrdup(attr[i + 1]);
                        continue;
                }
index f363dfa..7183ffc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: validate.c,v 1.51 2022/11/30 08:17:21 job Exp $ */
+/*     $OpenBSD: validate.c,v 1.52 2023/01/04 14:22:43 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -546,3 +546,46 @@ valid_geofeed(const char *fn, struct cert *cert, struct geofeed *g)
 
        return 1;
 }
+
+/*
+ * Validate whether a given string is a valid UUID.
+ * Returns 1 if valid, 0 otherwise.
+ */
+int
+valid_uuid(const char *s)
+{
+       int n = 0;
+
+       while (1) {
+               switch (n) {
+               case 8:
+               case 13:
+               case 18:
+               case 23:
+                       if (s[n] != '-')
+                               return 0;
+                       break;
+#ifdef NOTYET  /* World is not yet ready to enfoce UUID version and variant */
+               /* Check UUID is version 4 */
+               case 14:
+                       if (s[n] != '4')
+                               return 0;
+                       break;
+               /* Check UUID variant is 1 */
+               case 19:
+                       if (s[n] != '8' && s[n] != '9' && s[n] != 'a' &&
+                           s[n] != 'A' && s[n] != 'b' && s[n] != 'B')
+                               return 0;
+                       break;
+#endif
+               case 36:
+                       return s[n] == '\0';
+               default:
+                       if (!isxdigit((unsigned char)s[n]))
+                               return 0;
+                       break;
+               }
+               n++;
+       }
+}
+