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");