So the RFC is not very clear but in general the idea is that if multiple
MFTs are available the newest one (highest manifest number) should be
used.

In our case there are two possible MFTs available the previously valid on
and the now downloaded one. So adjust the parser code so that both files
are opened and parsed and the x509 is verified. Checks like the
thisUpdate/nextUpdate validity and FileAndHash sequence are postponed.
Compare these two mfts and decide which one should be used.
Now check everything that was postponed.

When checking the hash of files in the MFT check both locations and
remember which file was the actual match. It is important that later on
the same file is opened.

The error checking around MFTs had to be adjusted in some places since it
turned out to be too noisy on stale caches.

Please test and report unexpected behaviour.
-- 
:wq Claudio

? obj
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.115
diff -u -p -r1.115 extern.h
--- extern.h    24 Jan 2022 17:29:37 -0000      1.115
+++ extern.h    26 Jan 2022 15:16:12 -0000
@@ -164,12 +164,19 @@ enum rtype {
        RTYPE_FILE,
 };
 
+enum location {
+       DIR_UNKNOWN,
+       DIR_TEMP,
+       DIR_VALID,
+};
+
 /*
  * Files specified in an MFT have their bodies hashed with SHA256.
  */
 struct mftfile {
        char            *file; /* filename (CER/ROA/CRL, no path) */
        enum rtype       type; /* file type as determined by extension */
+       enum location    location;      /* temporary or valid directory */
        unsigned char    hash[SHA256_DIGEST_LENGTH]; /* sha256 of body */
 };
 
@@ -181,11 +188,13 @@ struct mftfile {
 struct mft {
        char            *path; /* relative path to directory of the MFT */
        struct mftfile  *files; /* file and hash */
-       size_t           filesz; /* number of filenames */
        char            *seqnum; /* manifestNumber */
        char            *aia; /* AIA */
        char            *aki; /* AKI */
        char            *ski; /* SKI */
+       time_t           valid_from;
+       time_t           valid_until;
+       size_t           filesz; /* number of filenames */
        unsigned int     repoid;
        int              stale; /* if a stale manifest */
 };
@@ -349,6 +358,7 @@ struct entity {
        unsigned int     repoid;        /* repository identifier */
        int              talid;         /* tal identifier */
        enum rtype       type;          /* type of entity (not RTYPE_EOF) */
+       enum location    location;      /* which directroy the file lives in */
 };
 TAILQ_HEAD(entityq, entity);
 
@@ -416,12 +426,13 @@ struct cert       *ta_parse(const char *, cons
 struct cert    *cert_read(struct ibuf *);
 void            cert_insert_brks(struct brk_tree *, struct cert *);
 
+enum rtype      rtype_from_file_extension(const char *);
 void            mft_buffer(struct ibuf *, const struct mft *);
 void            mft_free(struct mft *);
 struct mft     *mft_parse(X509 **, const char *, const unsigned char *,
                    size_t);
 struct mft     *mft_read(struct ibuf *);
-enum rtype      rtype_from_file_extension(const char *);
+int             mft_compare(const struct mft *, const struct mft *);
 
 void            roa_buffer(struct ibuf *, const struct roa *);
 void            roa_free(struct roa *);
Index: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
retrieving revision 1.186
diff -u -p -r1.186 main.c
--- main.c      26 Jan 2022 14:42:39 -0000      1.186
+++ main.c      26 Jan 2022 15:16:13 -0000
@@ -120,6 +120,7 @@ void
 entity_read_req(struct ibuf *b, struct entity *ent)
 {
        io_read_buf(b, &ent->type, sizeof(ent->type));
+       io_read_buf(b, &ent->location, sizeof(ent->location));
        io_read_buf(b, &ent->repoid, sizeof(ent->repoid));
        io_read_buf(b, &ent->talid, sizeof(ent->talid));
        io_read_str(b, &ent->path);
@@ -138,6 +139,7 @@ entity_write_req(const struct entity *en
 
        b = io_new_buffer();
        io_simple_buffer(b, &ent->type, sizeof(ent->type));
+       io_simple_buffer(b, &ent->location, sizeof(ent->location));
        io_simple_buffer(b, &ent->repoid, sizeof(ent->repoid));
        io_simple_buffer(b, &ent->talid, sizeof(ent->talid));
        io_str_buffer(b, ent->path);
@@ -151,6 +153,7 @@ entity_write_repo(struct repo *rp)
 {
        struct ibuf *b;
        enum rtype type = RTYPE_REPO;
+       enum location loc = DIR_UNKNOWN;
        unsigned int repoid;
        char *path, *altpath;
        int talid = 0;
@@ -160,6 +163,7 @@ entity_write_repo(struct repo *rp)
        altpath = repo_basedir(rp, 1);
        b = io_new_buffer();
        io_simple_buffer(b, &type, sizeof(type));
+       io_simple_buffer(b, &loc, sizeof(loc));
        io_simple_buffer(b, &repoid, sizeof(repoid));
        io_simple_buffer(b, &talid, sizeof(talid));
        io_str_buffer(b, path);
@@ -192,8 +196,8 @@ entityq_flush(struct entityq *q, struct 
  * Add the heap-allocated file to the queue for processing.
  */
 static void
-entityq_add(char *path, char *file, enum rtype type, struct repo *rp,
-    unsigned char *data, size_t datasz, int talid)
+entityq_add(char *path, char *file, enum rtype type, enum location loc,
+    struct repo *rp, unsigned char *data, size_t datasz, int talid)
 {
        struct entity   *p;
 
@@ -201,6 +205,7 @@ entityq_add(char *path, char *file, enum
                err(1, NULL);
 
        p->type = type;
+       p->location = loc;
        p->talid = talid;
        p->path = path;
        if (rp != NULL)
@@ -341,7 +346,7 @@ queue_add_from_mft(const char *path, con
        if ((nfile = strdup(file->file)) == NULL)
                err(1, NULL);
 
-       entityq_add(npath, nfile, file->type, rp, NULL, 0, -1);
+       entityq_add(npath, nfile, file->type, file->location, rp, NULL, 0, -1);
 }
 
 /*
@@ -400,7 +405,7 @@ queue_add_file(const char *file, enum rt
        if ((nfile = strdup(file)) == NULL)
                err(1, NULL);
        /* Not in a repository, so directly add to queue. */
-       entityq_add(NULL, nfile, type, NULL, buf, len, talid);
+       entityq_add(NULL, nfile, type, DIR_UNKNOWN, NULL, buf, len, talid);
 }
 
 /*
@@ -434,7 +439,8 @@ queue_add_from_tal(struct tal *tal)
        /* steal the pkey from the tal structure */
        data = tal->pkey;
        tal->pkey = NULL;
-       entityq_add(NULL, nfile, RTYPE_CER, repo, data, tal->pkeysz, tal->id);
+       entityq_add(NULL, nfile, RTYPE_CER, DIR_VALID, repo, data,
+           tal->pkeysz, tal->id);
 }
 
 /*
@@ -477,7 +483,7 @@ queue_add_from_cert(const struct cert *c
                        err(1, NULL);
        }
 
-       entityq_add(npath, nfile, RTYPE_MFT, repo, NULL, 0, -1);
+       entityq_add(npath, nfile, RTYPE_MFT, DIR_UNKNOWN, repo, NULL, 0, -1);
 }
 
 /*
Index: mft.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
retrieving revision 1.51
diff -u -p -r1.51 mft.c
--- mft.c       24 Jan 2022 17:29:37 -0000      1.51
+++ mft.c       26 Jan 2022 15:16:13 -0000
@@ -42,23 +42,6 @@ struct       parse {
 
 extern ASN1_OBJECT    *mft_oid;
 
-static const char *
-gentime2str(const ASN1_GENERALIZEDTIME *time)
-{
-       static char     buf[64];
-       BIO             *mem;
-
-       if ((mem = BIO_new(BIO_s_mem())) == NULL)
-               cryptoerrx("BIO_new");
-       if (!ASN1_GENERALIZEDTIME_print(mem, time))
-               cryptoerrx("ASN1_GENERALIZEDTIME_print");
-       if (BIO_gets(mem, buf, sizeof(buf)) < 0)
-               cryptoerrx("BIO_gets");
-
-       BIO_free(mem);
-       return buf;
-}
-
 /*
  * Convert an ASN1_GENERALIZEDTIME to a struct tm.
  * Returns 1 on success, 0 on failure.
@@ -79,45 +62,33 @@ generalizedtime_to_tm(const ASN1_GENERAL
 
 /*
  * Validate and verify the time validity of the mft.
- * Returns 1 if all is good, 0 if mft is stale, any other case -1.
+ * Returns 1 if all is good and for any other case 0.
  */
 static int
-check_validity(const ASN1_GENERALIZEDTIME *from,
-    const ASN1_GENERALIZEDTIME *until, const char *fn)
+mft_parse_time(const ASN1_GENERALIZEDTIME *from,
+    const ASN1_GENERALIZEDTIME *until, struct parse *p)
 {
-       time_t now = time(NULL);
-       struct tm tm_from, tm_until, tm_now;
-
-       if (gmtime_r(&now, &tm_now) == NULL) {
-               warnx("%s: could not get current time", fn);
-               return -1;
-       }
+       struct tm tm_from, tm_until;
 
        if (!generalizedtime_to_tm(from, &tm_from)) {
-               warnx("%s: embedded from time format invalid", fn);
-               return -1;
+               warnx("%s: embedded from time format invalid", p->fn);
+               return 0;
        }
        if (!generalizedtime_to_tm(until, &tm_until)) {
-               warnx("%s: embedded until time format invalid", fn);
-               return -1;
+               warnx("%s: embedded until time format invalid", p->fn);
+               return 0;
        }
 
        /* check that until is not before from */
        if (ASN1_time_tm_cmp(&tm_until, &tm_from) < 0) {
-               warnx("%s: bad update interval", fn);
-               return -1;
-       }
-       /* check that now is not before from */
-       if (ASN1_time_tm_cmp(&tm_from, &tm_now) > 0) {
-               warnx("%s: mft not yet valid %s", fn, gentime2str(from));
-               return -1;
-       }
-       /* check that now is not after until */
-       if (ASN1_time_tm_cmp(&tm_until, &tm_now) < 0) {
-               warnx("%s: mft expired on %s", fn, gentime2str(until));
+               warnx("%s: bad update interval", p->fn);
                return 0;
        }
 
+       if ((p->res->valid_from = mktime(&tm_from)) == -1 ||
+           (p->res->valid_until = mktime(&tm_until)) == -1)
+               errx(1, "%s: mktime failed", p->fn);
+
        return 1;
 }
 
@@ -426,15 +397,8 @@ mft_parse_econtent(const unsigned char *
        }
        until = t->value.generalizedtime;
 
-       switch (check_validity(from, until, p->fn)) {
-       case 0:
-               p->res->stale = 1;
-               /* FALLTHROUGH */
-       case 1:
-               break;
-       case -1:
+       if (!mft_parse_time(from, until, p))
                goto out;
-       }
 
        /* File list algorithm. */
 
@@ -570,6 +534,8 @@ mft_buffer(struct ibuf *b, const struct 
                io_str_buffer(b, p->files[i].file);
                io_simple_buffer(b, &p->files[i].type,
                    sizeof(p->files[i].type));
+               io_simple_buffer(b, &p->files[i].location,
+                   sizeof(p->files[i].location));
                io_simple_buffer(b, p->files[i].hash, SHA256_DIGEST_LENGTH);
        }
 }
@@ -603,8 +569,41 @@ mft_read(struct ibuf *b)
        for (i = 0; i < p->filesz; i++) {
                io_read_str(b, &p->files[i].file);
                io_read_buf(b, &p->files[i].type, sizeof(p->files[i].type));
+               io_read_buf(b, &p->files[i].location,
+                   sizeof(p->files[i].location));
                io_read_buf(b, p->files[i].hash, SHA256_DIGEST_LENGTH);
        }
 
        return p;
+}
+
+/*
+ * Compare two MFT files, returns 1 if first MFT is better and 0 if second
+ * should be used.
+ */
+int
+mft_compare(const struct mft *a, const struct mft *b)
+{
+       BIGNUM *abn = NULL, *bbn = NULL;
+       int r;
+
+       if (b == NULL)
+               return 1;
+       if (a == NULL)
+               return 0;
+
+       BN_hex2bn(&abn, a->seqnum);
+       BN_hex2bn(&bbn, b->seqnum);
+       r = BN_cmp(abn, bbn);
+       BN_free(abn);
+       BN_free(bbn);
+
+       if (r < 0)
+               return 0;
+
+       /*
+        * Equal sequence numbers should not happen for different content.
+        * In this case we prefer the newer MFT.
+        */
+       return 1;
 }
Index: parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
retrieving revision 1.56
diff -u -p -r1.56 parser.c
--- parser.c    26 Jan 2022 14:42:39 -0000      1.56
+++ parser.c    26 Jan 2022 15:16:13 -0000
@@ -91,49 +91,48 @@ repo_add(unsigned int id, char *path, ch
                errx(1, "repository already added: id %d, %s", id, path);
 }
 
+static char *
+time2str(time_t t)
+{
+       static char buf[64];
+       struct tm tm;
+
+       if (gmtime_r(&t, &tm) == NULL)
+               return "could not convert time";
+
+       strftime(buf, sizeof(buf), "%h %d %T %Y %Z", &tm);
+       return buf;
+}
+
 /*
- * Build access path to file based on repoid, path and file values.
- * If wantalt == 1 the function can return NULL, if wantalt == 0 it
- * can not fail.
+ * Build access path to file based on repoid, path, location and file values.
  */
 static char *
 parse_filepath(unsigned int repoid, const char *path, const char *file,
-    int wantalt)
+    enum location loc)
 {
        struct parse_repo       *rp;
        char                    *fn, *repopath;
 
        /* build file path based on repoid, entity path and filename */
        rp = repo_get(repoid);
-       if (rp == NULL) {
-               /* no repo so no alternative path. */
-               if (wantalt)
-                       return NULL;
-
-               if (path == NULL) {
-                       if ((fn = strdup(file)) == NULL)
-                               err(1, NULL);
-               } else {
-                       if (asprintf(&fn, "%s/%s", path, file) == -1)
-                               err(1, NULL);
-               }
-       } else {
-               if (wantalt || rp->path == NULL)
-                       repopath = rp->validpath;
-               else
-                       repopath = rp->path;
+       if (rp == NULL)
+               return NULL;
+       
+       if (loc == DIR_VALID)
+               repopath = rp->validpath;
+       else
+               repopath = rp->path;
 
-               if (repopath == NULL)
-                       return NULL;
+       if (repopath == NULL)
+               return NULL;
 
-               if (path == NULL) {
-                       if (asprintf(&fn, "%s/%s", repopath, file) == -1)
-                               err(1, NULL);
-               } else {
-                       if (asprintf(&fn, "%s/%s/%s", repopath, path,
-                           file) == -1)
-                               err(1, NULL);
-               }
+       if (path == NULL) {
+               if (asprintf(&fn, "%s/%s", repopath, file) == -1)
+                       err(1, NULL);
+       } else {
+               if (asprintf(&fn, "%s/%s/%s", repopath, path, file) == -1)
+                       err(1, NULL);
        }
        return fn;
 }
@@ -205,7 +204,7 @@ verify_cb(int ok, X509_STORE_CTX *store_
  */
 static int
 valid_x509(char *file, X509 *x509, struct auth *a, struct crl *crl,
-    unsigned long flags)
+    unsigned long flags, int nowarn)
 {
        STACK_OF(X509)          *chain;
        STACK_OF(X509_CRL)      *crls = NULL;
@@ -229,7 +228,8 @@ valid_x509(char *file, X509 *x509, struc
 
        if (X509_verify_cert(ctx) <= 0) {
                c = X509_STORE_CTX_get_error(ctx);
-               warnx("%s: %s", file, X509_verify_cert_error_string(c));
+               if (!nowarn || verbose > 1)
+                       warnx("%s: %s", file, X509_verify_cert_error_string(c));
                X509_STORE_CTX_cleanup(ctx);
                sk_X509_free(chain);
                sk_X509_CRL_free(crls);
@@ -261,7 +261,7 @@ proc_parser_roa(char *file, const unsign
        a = valid_ski_aki(file, &auths, roa->ski, roa->aki);
        crl = get_crl(a);
 
-       if (!valid_x509(file, x509, a, crl, X509_V_FLAG_CRL_CHECK)) {
+       if (!valid_x509(file, x509, a, crl, X509_V_FLAG_CRL_CHECK, 0)) {
                X509_free(x509);
                roa_free(roa);
                return NULL;
@@ -303,28 +303,35 @@ proc_parser_roa(char *file, const unsign
 static int
 proc_parser_mft_check(const char *fn, struct mft *p)
 {
-       size_t  i;
-       int     rc = 1;
+       const enum location loc[2] = { DIR_TEMP, DIR_VALID };
+       size_t   i;
+       int      rc = 1;
        char    *path;
 
        for (i = 0; i < p->filesz; i++) {
-               const struct mftfile *m = &p->files[i];
-               int fd = -1, try = 0;
-
-               path = NULL;
-               do {
-                       free(path);
+               struct mftfile *m = &p->files[i];
+               int try, fd = -1, noent = 0, valid = 0;
+               for (try = 0; try < 2 && !valid; try++) {
                        if ((path = parse_filepath(p->repoid, p->path, m->file,
-                           try++)) == NULL)
-                               break;
+                           loc[try])) == NULL)
+                               continue;
                        fd = open(path, O_RDONLY);
-               } while (fd == -1 && try < 2);
+                       if (fd == -1 && errno == ENOENT)
+                               noent++;
+                       free(path);
 
-               free(path);
+                       /* remember which path was checked */
+                       m->location = loc[try];
+                       valid = valid_filehash(fd, m->hash, sizeof(m->hash));
+               }
 
-               if (!valid_filehash(fd, m->hash, sizeof(m->hash))) {
+               if (!valid) {
+                       /* silently skip not-existing unknown files */
+                       if (m->type == RTYPE_INVALID && noent == 2)
+                               continue;
                        warnx("%s: bad message digest for %s", fn, m->file);
                        rc = 0;
+                       continue;
                }
        }
 
@@ -332,7 +339,9 @@ proc_parser_mft_check(const char *fn, st
 }
 
 /*
- * Parse and validate a manifest file.
+ * Parse and validate a manifest file. Skip checking the fileandhash
+ * this is done in the post check. After this step we know the mft is
+ * valid and can be compared.
  * Here we *don't* validate against the list of CRLs, because the
  * certificate used to sign the manifest may specify a CRL that the root
  * certificate didn't, and we haven't scanned for it yet.
@@ -342,8 +351,7 @@ proc_parser_mft_check(const char *fn, st
  * Return the mft on success or NULL on failure.
  */
 static struct mft *
-proc_parser_mft(char *file, const unsigned char *der, size_t len,
-    const char *path, unsigned int repoid)
+proc_parser_mft_pre(char *file, const unsigned char *der, size_t len)
 {
        struct mft              *mft;
        X509                    *x509;
@@ -355,13 +363,45 @@ proc_parser_mft(char *file, const unsign
        a = valid_ski_aki(file, &auths, mft->ski, mft->aki);
 
        /* CRL checks disabled here because CRL is referenced from mft */
-       if (!valid_x509(file, x509, a, NULL, 0)) {
+       if (!valid_x509(file, x509, a, NULL, 0, 1)) {
                mft_free(mft);
                X509_free(x509);
                return NULL;
        }
        X509_free(x509);
 
+       return mft;
+}
+
+/*
+ * Do the end of manifest validation.
+ * Return the mft on success or NULL on failure.
+ */
+static struct mft *
+proc_parser_mft_post(char *file, struct mft *mft, const char *path,
+    unsigned int repoid)
+{
+       /* check that now is not before from */
+       time_t now = time(NULL);
+
+       if (mft == NULL) {
+               warnx("%s: no valid mft available", file);
+               return NULL;
+       }
+
+       /* check that now is not before from */
+       if (now < mft->valid_from) {
+               warnx("%s: mft not yet valid %s", file,
+                   time2str(mft->valid_from));
+               mft->stale = 1;
+       }
+       /* check that now is not after until */
+       if (now > mft->valid_until) {
+               warnx("%s: mft expired on %s", file,
+                   time2str(mft->valid_until));
+               mft->stale = 1;
+       }
+
        mft->repoid = repoid;
        if (path != NULL)
                if ((mft->path = strdup(path)) == NULL)
@@ -388,7 +428,7 @@ proc_parser_cert_validate(char *file, st
        a = valid_ski_aki(file, &auths, cert->ski, cert->aki);
        crl = get_crl(a);
 
-       if (!valid_x509(file, cert->x509, a, crl, X509_V_FLAG_CRL_CHECK)) {
+       if (!valid_x509(file, cert->x509, a, crl, X509_V_FLAG_CRL_CHECK, 0)) {
                cert_free(cert);
                return NULL;
        }
@@ -537,7 +577,7 @@ proc_parser_gbr(char *file, const unsign
        crl = get_crl(a);
 
        /* return value can be ignored since nothing happens here */
-       valid_x509(file, x509, a, crl, X509_V_FLAG_CRL_CHECK);
+       valid_x509(file, x509, a, crl, X509_V_FLAG_CRL_CHECK, 0);
 
        X509_free(x509);
        gbr_free(gbr);
@@ -599,41 +639,23 @@ build_crls(const struct crl *crl, STACK_
                err(1, "sk_X509_CRL_push");
 }
 
+/*
+ * Load the file specified by the entity information.
+ */
 static char *
 parse_load_file(struct entity *entp, unsigned char **f, size_t *flen)
 {
-       char *file, *nfile;
-
-       file = parse_filepath(entp->repoid, entp->path, entp->file, 0);
-
-       /* TAL files include the data already */
-       if (entp->type == RTYPE_TAL) {
-               *f = NULL;
-               *flen = 0;
-               return file;
-       }
+       char *file;
 
-       *f = load_file(file, flen);
-       if (*f != NULL)
-               return file;
-
-       if (errno != ENOENT)
-               goto fail;
-
-       /* try alternate file location */
-       nfile = parse_filepath(entp->repoid, entp->path, entp->file, 1);
-       if (nfile == NULL)
-               goto fail;
-
-       free(file);
-       file = nfile;
+       file = parse_filepath(entp->repoid, entp->path, entp->file,
+           entp->location);
+       if (file == NULL)
+               errx(1, "no path to file");
 
        *f = load_file(file, flen);
-       if (*f != NULL)
-               return file;
+       if (*f == NULL)
+               warn("parse file %s", file);
 
-fail:
-       warn("parse file %s", file);
        return file;
 }
 
@@ -646,12 +668,12 @@ parse_entity(struct entityq *q, struct m
        struct entity   *entp;
        struct tal      *tal;
        struct cert     *cert;
-       struct mft      *mft;
+       struct mft      *mft, *mft2;
        struct roa      *roa;
        struct ibuf     *b;
        unsigned char   *f;
        size_t           flen;
-       char            *file;
+       char            *file, *file2;
        int              c;
 
        while ((entp = TAILQ_FIRST(q)) != NULL) {
@@ -664,15 +686,15 @@ parse_entity(struct entityq *q, struct m
                        continue;
                }
 
-               file = parse_load_file(entp, &f, &flen);
-
                /* pass back at least type, repoid and filename */
                b = io_new_buffer();
                io_simple_buffer(b, &entp->type, sizeof(entp->type));
-               io_str_buffer(b, file);
+               file = NULL;
+               f = NULL;
 
                switch (entp->type) {
                case RTYPE_TAL:
+                       io_str_buffer(b, entp->file);
                        if ((tal = tal_parse(entp->file, entp->data,
                            entp->datasz)) == NULL)
                                errx(1, "%s: could not parse tal file",
@@ -682,6 +704,8 @@ parse_entity(struct entityq *q, struct m
                        tal_free(tal);
                        break;
                case RTYPE_CER:
+                       file = parse_load_file(entp, &f, &flen);
+                       io_str_buffer(b, file);
                        if (entp->data != NULL)
                                cert = proc_parser_root_cert(file,
                                    f, flen, entp->data, entp->datasz,
@@ -695,15 +719,49 @@ parse_entity(struct entityq *q, struct m
                        /*
                         * The parsed certificate data "cert" is now
                         * managed in the "auths" table, so don't free
-                        * it here (see the loop after "out").
+                        * it here.
                         */
                        break;
                case RTYPE_CRL:
+                       file = parse_load_file(entp, &f, &flen);
+                       io_str_buffer(b, file);
                        proc_parser_crl(file, f, flen);
                        break;
                case RTYPE_MFT:
-                       mft = proc_parser_mft(file, f, flen,
+                       file = parse_filepath(entp->repoid, entp->path,
+                           entp->file, DIR_VALID);
+                       if (file != NULL) {
+                               f = load_file(file, &flen);
+                               if (f == NULL && errno != ENOENT)
+                                       warn("parse file %s", file);
+                               mft = proc_parser_mft_pre(file, f, flen);
+                       } else
+                               mft = NULL;
+                       free(f);
+                       f = NULL;
+                       file2 = parse_filepath(entp->repoid, entp->path,
+                           entp->file, DIR_TEMP);
+                       if (file2 != NULL) {
+                               f = load_file(file2, &flen);
+                               if (f == NULL && errno != ENOENT)
+                                       warn("parse file %s", file2);
+                               mft2 = proc_parser_mft_pre(file2, f, flen);
+                       } else
+                               mft2 = NULL;
+
+                       if (mft_compare(mft, mft2) == 0) {
+                               mft_free(mft);
+                               free(file);
+                               mft = mft2;
+                               file = file2;
+                       } else {
+                               mft_free(mft2);
+                               free(file2);
+                       }
+
+                       mft = proc_parser_mft_post(file, mft,
                            entp->path, entp->repoid);
+                       io_str_buffer(b, file);
                        c = (mft != NULL);
                        io_simple_buffer(b, &c, sizeof(int));
                        if (mft != NULL)
@@ -711,6 +769,8 @@ parse_entity(struct entityq *q, struct m
                        mft_free(mft);
                        break;
                case RTYPE_ROA:
+                       file = parse_load_file(entp, &f, &flen);
+                       io_str_buffer(b, file);
                        roa = proc_parser_roa(file, f, flen);
                        c = (roa != NULL);
                        io_simple_buffer(b, &c, sizeof(int));
@@ -719,6 +779,8 @@ parse_entity(struct entityq *q, struct m
                        roa_free(roa);
                        break;
                case RTYPE_GBR:
+                       file = parse_load_file(entp, &f, &flen);
+                       io_str_buffer(b, file);
                        proc_parser_gbr(file, f, flen);
                        break;
                default:
@@ -981,7 +1043,7 @@ proc_parser_file(char *file, unsigned ch
                a = auth_find(&auths, aki);
                crl = get_crl(a);
 
-               if (valid_x509(file, x509, a, crl, verify_flags))
+               if (valid_x509(file, x509, a, crl, verify_flags, 0))
                        printf("Validation: OK\n");
                else
                        printf("Validation: Failed\n");

Reply via email to