On Thu, Jan 27, 2022 at 09:38:54AM +0100, Claudio Jeker wrote:
> On Thu, Jan 27, 2022 at 07:46:32AM +0100, Theo Buehler wrote:
> > On Wed, Jan 26, 2022 at 04:42:04PM +0100, Claudio Jeker wrote:
> > > 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.
> >
> > This seems to work fine here. I have read the diff and it looks good,
> > but have not reviewed it thoroughly. Do you consider it ready for that?
>
> I have parts I'm not super happy with but have no better idea yet.
> Mainly the changes to parse_entity() make that function even more complex
> and error prone. proc_parser_mft_check() is the other function where I'm
> not sure. So happy for any feedback to improve those bits.
The only suggestion I have is the usual one: factor the complicated bits
into a function. The diff below changes two things:
1. Add error checking to mft_compare()
2. Factor the RTYPE_MFT handling into parse_load_mft()
I think I like the more symmetric ownership handling of the two files
better this way. This could probably be improved quite a bit by tweaking
mft_compare() and by choosing better variable names than foo1 and foo2.
In a next pass we could polish the other RTYPE_* cases in entity_parse()
to resemble each other more.
I'm also happy to land your initial diff (ok tb for that) and improve
things in tree.
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 27 Jan 2022 09:13:19 -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 27 Jan 2022 09:13:19 -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 28 Jan 2022 08:21:08 -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,43 @@ 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;
+
+ if (!BN_hex2bn(&abn, a->seqnum))
+ errx(1, "BN_hex2bn");
+ if (!BN_hex2bn(&bbn, b->seqnum))
+ errx(1, "BN_hex2bn");
+ 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 28 Jan 2022 08:13:29 -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)
@@ -376,6 +416,57 @@ proc_parser_mft(char *file, const unsign
return mft;
}
+static char *
+parse_load_mft(struct entity *entp, unsigned char **f, size_t *flen,
+ struct mft **mft)
+{
+ char *file, *file1, *file2;
+ struct mft *mft1 = NULL, *mft2 = NULL;
+ unsigned char *f1, *f2;
+ size_t flen1, flen2;
+
+ file1 = parse_filepath(entp->repoid, entp->path, entp->file, DIR_VALID);
+ if (file1 != NULL) {
+ f1 = load_file(file1, &flen1);
+ if (f1 == NULL && errno != ENOENT)
+ warn("parse file %s", file1);
+ mft1 = proc_parser_mft_pre(file1, f1, flen1);
+ }
+
+ file2 = parse_filepath(entp->repoid, entp->path, entp->file, DIR_TEMP);
+ if (file2 != NULL) {
+ f2 = load_file(file2, &flen2);
+ if (f2 == NULL && errno != ENOENT)
+ warn("parse file %s", file2);
+ mft2 = proc_parser_mft_pre(file2, f2, flen2);
+ }
+
+ if (mft_compare(mft1, mft2) == 0) {
+ free(f1);
+ free(file1);
+ mft_free(mft1);
+
+ *f = f2;
+ *flen = flen2;
+ *mft = mft2;
+
+ file = file2;
+ } else {
+ free(f2);
+ free(file2);
+ mft_free(mft2);
+
+ *f = f1;
+ *flen = flen1;
+ *mft = mft1;
+
+ file = file1;
+ }
+
+ *mft = proc_parser_mft_post(file, *mft, entp->path, entp->repoid);
+
+ return file;
+}
/*
* Validate a certificate, if invalid free the resouces and return NULL.
*/
@@ -388,7 +479,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 +628,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 +690,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);
+ char *file;
- /* TAL files include the data already */
- if (entp->type == RTYPE_TAL) {
- *f = NULL;
- *flen = 0;
- return file;
- }
+ 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 (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;
+ if (*f == NULL)
+ warn("parse file %s", file);
- *f = load_file(file, flen);
- if (*f != NULL)
- return file;
-
-fail:
- warn("parse file %s", file);
return file;
}
@@ -664,15 +737,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 +755,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 +770,17 @@ 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,
- entp->path, entp->repoid);
+ file = parse_load_mft(entp, &f, &flen, &mft);
+ io_str_buffer(b, file);
c = (mft != NULL);
io_simple_buffer(b, &c, sizeof(int));
if (mft != NULL)
@@ -711,6 +788,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 +798,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 +1062,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");