Introduce and use mft_compare_issued()
authortb <tb@openbsd.org>
Wed, 31 Jan 2024 06:57:21 +0000 (06:57 +0000)
committertb <tb@openbsd.org>
Wed, 31 Jan 2024 06:57:21 +0000 (06:57 +0000)
Newly issued manifests should not only have a higher manifestNumber,
their issuance time should also be later. Add corresponding checks
and warnings when comparing a newly fetched manifest to a manifest
from the cache.

ok job (who noticed that such a check was missing)

usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/mft.c
usr.sbin/rpki-client/parser.c

index 7245536..9912ebc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.200 2024/01/31 06:54:43 tb Exp $ */
+/*     $OpenBSD: extern.h,v 1.201 2024/01/31 06:57:21 tb Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -629,6 +629,7 @@ void                 mft_free(struct mft *);
 struct mft     *mft_parse(X509 **, const char *, int, const unsigned char *,
                    size_t);
 struct mft     *mft_read(struct ibuf *);
+int             mft_compare_issued(const struct mft *, const struct mft *);
 int             mft_compare_seqnum(const struct mft *, const struct mft *);
 
 void            roa_buffer(struct ibuf *, const struct roa *);
index 17ddda6..a98e6ac 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mft.c,v 1.101 2024/01/31 06:54:43 tb Exp $ */
+/*     $OpenBSD: mft.c,v 1.102 2024/01/31 06:57:21 tb Exp $ */
 /*
  * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -544,6 +544,19 @@ mft_read(struct ibuf *b)
        return p;
 }
 
+/*
+ * Compare the thisupdate time of two mft files.
+ */
+int
+mft_compare_issued(const struct mft *a, const struct mft *b)
+{
+       if (a->thisupdate > b->thisupdate)
+               return 1;
+       if (a->thisupdate < b->thisupdate)
+               return -1;
+       return 0;
+}
+
 /*
  * Compare the manifestNumber of two mft files.
  */
index ab57a2e..36924cd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parser.c,v 1.112 2024/01/31 06:54:43 tb Exp $ */
+/*     $OpenBSD: parser.c,v 1.113 2024/01/31 06:57:21 tb Exp $ */
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -266,7 +266,7 @@ proc_parser_mft_pre(struct entity *entp, enum location loc, char **file,
        struct auth     *a;
        unsigned char   *der;
        size_t           len;
-       int              seqnum_cmp;
+       int              issued_cmp, seqnum_cmp;
 
        *crl = NULL;
        *crlfile = NULL;
@@ -311,16 +311,35 @@ proc_parser_mft_pre(struct entity *entp, enum location loc, char **file,
                return mft;
 
        /*
-        * Check that the cached manifest is older in the sense that it has
-        * a smaller sequence number.
+        * Check that the cached manifest is older in the sense that it was
+        * issued earlier and that it has a smaller sequence number.
         */
 
+       if ((issued_cmp = mft_compare_issued(mft, cached_mft)) < 0) {
+               warnx("%s: unexpected manifest issuance time (want >= %lld, "
+                   "got %lld)", *file, (long long)cached_mft->thisupdate,
+                   (long long)mft->thisupdate);
+               goto err;
+       }
        if ((seqnum_cmp = mft_compare_seqnum(mft, cached_mft)) < 0) {
                warnx("%s: unexpected manifest number (want >= #%s, got #%s)",
                    *file, cached_mft->seqnum, mft->seqnum);
                goto err;
        }
-       if (seqnum_cmp == 0 && memcmp(mft->mfthash,
+       if (issued_cmp > 0 && seqnum_cmp == 0) {
+               warnx("%s#%s: reissued manifest at %lld and %lld with same "
+                   "sequence number", *file, cached_mft->seqnum,
+                   (long long)mft->thisupdate,
+                   (long long)cached_mft->thisupdate);
+               goto err;
+       }
+       if (issued_cmp == 0 && seqnum_cmp > 0) {
+               warnx("%s#%s: reissued manifest same issuance time %lld as #%s",
+                   *file, mft->seqnum, (long long)mft->thisupdate,
+                   cached_mft->seqnum);
+               goto err;
+       }
+       if (issued_cmp == 0 && seqnum_cmp == 0 && memcmp(mft->mfthash,
            cached_mft->mfthash, SHA256_DIGEST_LENGTH) != 0) {
                warnx("%s: manifest misissuance, #%s was recycled",
                    *file, mft->seqnum);