passing as done for the other parsers.
OK job@ tb@
-/* $OpenBSD: encoding.c,v 1.4 2021/10/11 16:06:36 claudio Exp $ */
+/* $OpenBSD: encoding.c,v 1.5 2021/10/26 16:12:54 claudio Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
*
* Returns 0 on success or -1 for any errors.
*/
int
-base64_decode(const unsigned char *in, unsigned char **out, size_t *outlen)
+base64_decode(const unsigned char *in, size_t inlen,
+ unsigned char **out, size_t *outlen)
{
static EVP_ENCODE_CTX *ctx;
unsigned char *to;
- size_t inlen;
int tolen;
if (ctx == NULL && (ctx = EVP_ENCODE_CTX_new()) == NULL)
*out = NULL;
*outlen = 0;
- inlen = strlen(in);
if (inlen >= INT_MAX - 3)
return -1;
tolen = ((inlen + 3) / 4) * 3 + 1;
-/* $OpenBSD: extern.h,v 1.79 2021/10/26 13:31:05 claudio Exp $ */
+/* $OpenBSD: extern.h,v 1.80 2021/10/26 16:12:54 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
* and parsed.
*/
struct entity {
- enum rtype type; /* type of entity (not RTYPE_EOF) */
- char *file; /* local path to file */
- int has_pkey; /* whether pkey/sz is specified */
- unsigned char *pkey; /* public key (optional) */
- size_t pkeysz; /* public key length (optional) */
- char *descr; /* tal description */
+ enum rtype type; /* type of entity (not RTYPE_EOF) */
+ char *file; /* local path to file */
+ int has_data; /* whether data blob is specified */
+ unsigned char *data; /* optional data blob */
+ size_t datasz; /* length of optional data blob */
+ char *descr; /* tal description */
TAILQ_ENTRY(entity) entries;
};
TAILQ_HEAD(entityq, entity);
void tal_buffer(struct ibuf *, const struct tal *);
void tal_free(struct tal *);
-struct tal *tal_parse(const char *, char *);
-char *tal_read_file(const char *);
+struct tal *tal_parse(const char *, char *, size_t);
struct tal *tal_read(struct ibuf *);
void cert_buffer(struct ibuf *, const struct cert *);
/* Encoding functions for hex and base64. */
-int base64_decode(const unsigned char *, unsigned char **,
- size_t *);
+int base64_decode(const unsigned char *, size_t,
+ unsigned char **, size_t *);
int base64_encode(const unsigned char *, size_t, char **);
char *hex_encode(const unsigned char *, size_t);
int output_json(FILE *, struct vrp_tree *, struct brk_tree *,
struct stats *);
-void logx(const char *fmt, ...)
+void logx(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
+unsigned char *load_file(const char *, size_t *);
int mkpath(const char *);
-/* $OpenBSD: main.c,v 1.154 2021/10/24 21:24:19 deraadt Exp $ */
+/* $OpenBSD: main.c,v 1.155 2021/10/26 16:12:54 claudio Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/resource.h>
+#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/tree.h>
#include <sys/wait.h>
}
}
+unsigned char *
+load_file(const char *name, size_t *len)
+{
+ unsigned char *buf = NULL;
+ struct stat st;
+ ssize_t n;
+ size_t size;
+ int fd;
+
+ *len = 0;
+
+ if ((fd = open(name, O_RDONLY)) == -1)
+ return NULL;
+ if (fstat(fd, &st) != 0)
+ goto err;
+ if (st.st_size < 0)
+ goto err;
+ size = (size_t)st.st_size;
+ if ((buf = malloc(size)) == NULL)
+ goto err;
+ n = read(fd, buf, size);
+ if (n < 0 || (size_t)n != size)
+ goto err;
+ close(fd);
+ *len = size;
+ return buf;
+
+err:
+ close(fd);
+ free(buf);
+ return NULL;
+}
+
void
entity_free(struct entity *ent)
{
if (ent == NULL)
return;
- free(ent->pkey);
+ free(ent->data);
free(ent->file);
free(ent->descr);
free(ent);
{
io_read_buf(b, &ent->type, sizeof(ent->type));
io_read_str(b, &ent->file);
- io_read_buf(b, &ent->has_pkey, sizeof(ent->has_pkey));
- if (ent->has_pkey)
- io_read_buf_alloc(b, (void **)&ent->pkey, &ent->pkeysz);
io_read_str(b, &ent->descr);
+ io_read_buf(b, &ent->has_data, sizeof(ent->has_data));
+ if (ent->has_data)
+ io_read_buf_alloc(b, (void **)&ent->data, &ent->datasz);
}
/*
b = io_new_buffer();
io_simple_buffer(b, &ent->type, sizeof(ent->type));
io_str_buffer(b, ent->file);
- io_simple_buffer(b, &ent->has_pkey, sizeof(int));
- if (ent->has_pkey)
- io_buf_buffer(b, ent->pkey, ent->pkeysz);
io_str_buffer(b, ent->descr);
+ io_simple_buffer(b, &ent->has_data, sizeof(int));
+ if (ent->has_data)
+ io_buf_buffer(b, ent->data, ent->datasz);
io_close_buffer(&procq, b);
}
*/
static void
entityq_add(char *file, enum rtype type, struct repo *rp,
- const unsigned char *pkey, size_t pkeysz, char *descr)
+ unsigned char *data, size_t datasz, char *descr)
{
struct entity *p;
p->type = type;
p->file = file;
- p->has_pkey = pkey != NULL;
- if (p->has_pkey) {
- p->pkeysz = pkeysz;
- if ((p->pkey = malloc(pkeysz)) == NULL)
- err(1, NULL);
- memcpy(p->pkey, pkey, pkeysz);
+ p->has_data = data != NULL;
+ if (p->has_data) {
+ p->data = data;
+ p->datasz = datasz;
}
if (descr != NULL)
if ((p->descr = strdup(descr)) == NULL)
static void
queue_add_tal(const char *file)
{
- char *nfile, *buf;
+ unsigned char *buf;
+ char *nfile;
+ size_t len;
if ((nfile = strdup(file)) == NULL)
err(1, NULL);
- buf = tal_read_file(file);
+ buf = load_file(file, &len);
/* Record tal for later reporting */
if (stats.talnames == NULL) {
}
/* Not in a repository, so directly add to queue. */
- entityq_add(nfile, RTYPE_TAL, NULL, NULL, 0, buf);
- /* entityq_add makes a copy of buf */
- free(buf);
+ entityq_add(nfile, RTYPE_TAL, NULL, buf, len, buf);
}
/*
queue_add_from_tal(struct tal *tal)
{
struct repo *repo;
+ unsigned char *data;
assert(tal->urisz);
/* Look up the repository. */
repo = ta_lookup(tal);
- entityq_add(NULL, RTYPE_CER, repo, tal->pkey,
+ /* steal the pkey from the tal structure */
+ data = tal->pkey;
+ tal->pkey = NULL;
+ entityq_add(NULL, RTYPE_CER, repo, data,
tal->pkeysz, tal->descr);
}
char *bind_addr = NULL;
const char *cachedir = NULL, *outputdir = NULL;
const char *tals[TALSZ_MAX], *errs, *name;
+ const char *file = NULL;
struct vrp_tree vrps = RB_INITIALIZER(&vrps);
struct brk_tree brks = RB_INITIALIZER(&brks);
struct rusage ru;
"proc exec unveil", NULL) == -1)
err(1, "pledge");
- while ((c = getopt(argc, argv, "b:Bcd:e:jnorRs:t:T:vV")) != -1)
+ while ((c = getopt(argc, argv, "b:Bcd:e:f:jnorRs:t:T:vV")) != -1)
switch (c) {
case 'b':
bind_addr = optarg;
case 'e':
rsync_prog = optarg;
break;
+ case 'f':
+ file = optarg;
+ noop = 1;
+ break;
case 'j':
outformats |= FORMAT_JSON;
break;
-/* $OpenBSD: parser.c,v 1.19 2021/10/26 13:31:05 claudio Exp $ */
+/* $OpenBSD: parser.c,v 1.20 2021/10/26 16:12:54 claudio Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*/
#include <sys/queue.h>
-#include <sys/stat.h>
#include <sys/tree.h>
#include <sys/types.h>
#include <assert.h>
#include <err.h>
-#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
STACK_OF(X509) *chain;
STACK_OF(X509_CRL) *crls;
- assert(!entp->has_pkey);
+ assert(!entp->has_data);
/* Extract certificate data and X509. */
struct auth *na;
char *tal;
- assert(entp->has_pkey);
+ assert(entp->has_data);
/* Extract certificate data and X509. */
- cert = ta_parse(&x509, entp->file, der, len, entp->pkey, entp->pkeysz);
+ cert = ta_parse(&x509, entp->file, der, len, entp->data, entp->datasz);
if (cert == NULL)
return NULL;
err(1, "sk_X509_CRL_push");
}
-static unsigned char *
-load_file(const char *name, size_t *len)
-{
- unsigned char *buf = NULL;
- struct stat st;
- ssize_t n;
- size_t size;
- int fd;
-
- *len = 0;
-
- if ((fd = open(name, O_RDONLY)) == -1)
- return NULL;
- if (fstat(fd, &st) != 0)
- goto err;
- if (st.st_size < 0)
- goto err;
- size = (size_t)st.st_size;
- if ((buf = malloc(size)) == NULL)
- goto err;
- n = read(fd, buf, size);
- if (n < 0 || (size_t)n != size)
- goto err;
- close(fd);
- *len = size;
- return buf;
-
-err:
- close(fd);
- free(buf);
- return NULL;
-}
-
static void
parse_entity(struct entityq *q, struct msgbuf *msgq)
{
switch (entp->type) {
case RTYPE_TAL:
- if ((tal = tal_parse(entp->file, entp->descr)) == NULL)
+ if ((tal = tal_parse(entp->file, entp->data,
+ entp->datasz)) == NULL)
errx(1, "%s: could not parse tal file",
entp->file);
tal_buffer(b, tal);
tal_free(tal);
break;
case RTYPE_CER:
- if (entp->has_pkey)
+ if (entp->has_data)
cert = proc_parser_root_cert(entp, f, flen);
else
cert = proc_parser_cert(entp, f, flen);
-/* $OpenBSD: rrdp.c,v 1.14 2021/10/23 20:01:16 claudio Exp $ */
+/* $OpenBSD: rrdp.c,v 1.15 2021/10/26 16:12:54 claudio Exp $ */
/*
* Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
size_t datasz = 0;
if (pxml->data_length > 0)
- if ((base64_decode(pxml->data, &data, &datasz)) == -1)
+ if ((base64_decode(pxml->data, pxml->data_length,
+ &data, &datasz)) == -1)
return -1;
/* only send files if the fetch did not fail already */
-/* $OpenBSD: tal.c,v 1.31 2021/10/23 16:06:04 claudio Exp $ */
+/* $OpenBSD: tal.c,v 1.32 2021/10/26 16:12:54 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
* The pointer must be freed with tal_free().
*/
static struct tal *
-tal_parse_buffer(const char *fn, char *buf)
+tal_parse_buffer(const char *fn, char *buf, size_t len)
{
char *nl, *line, *f, *file = NULL;
unsigned char *der;
int rc = 0;
struct tal *tal = NULL;
EVP_PKEY *pkey = NULL;
+ int optcomment = 1;
if ((tal = calloc(1, sizeof(struct tal))) == NULL)
err(1, NULL);
/* Begin with the URI section, comment section already removed. */
- while ((nl = strchr(buf, '\n')) != NULL) {
+ while ((nl = memchr(buf, '\n', len)) != NULL) {
line = buf;
+
+ /* replace LF and optional CR with NUL */
*nl = '\0';
+ if (nl > line && nl[-1] == '\r')
+ nl[-1] = '\0';
/* advance buffer to next line */
+ len -= nl + 1 - buf;
buf = nl + 1;
+ if (optcomment) {
+ /* if this is a comment, just eat the line */
+ if (line[0] == '#')
+ continue;
+ optcomment = 0;
+ }
+
/* Zero-length line is end of section. */
if (*line == '\0')
break;
qsort(tal->uri, tal->urisz, sizeof(tal->uri[0]), tal_cmp);
/* Now the Base64-encoded public key. */
- if ((base64_decode(buf, &der, &dersz)) == -1) {
+ if ((base64_decode(buf, len, &der, &dersz)) == -1) {
warnx("%s: RFC 7730 section 2.1: subjectPublicKeyInfo: "
"bad public key", fn);
goto out;
* Returns the encoded data or NULL on syntax failure.
*/
struct tal *
-tal_parse(const char *fn, char *buf)
+tal_parse(const char *fn, char *buf, size_t len)
{
struct tal *p;
const char *d;
size_t dlen;
- p = tal_parse_buffer(fn, buf);
+ p = tal_parse_buffer(fn, buf, len);
if (p == NULL)
return NULL;
return p;
}
-/*
- * Read the file named "file" into a returned, NUL-terminated buffer.
- * This replaces CRLF terminators with plain LF, if found, and also
- * elides document-leading comment lines starting with "#".
- * Files may not exceeds 4096 bytes.
- * This function exits on failure, so it always returns a buffer with
- * TAL data.
- */
-char *
-tal_read_file(const char *file)
-{
- char *nbuf, *line = NULL, *buf = NULL;
- FILE *in;
- ssize_t n, i;
- size_t sz = 0, bsz = 0;
- int optcomment = 1;
-
- if ((in = fopen(file, "r")) == NULL)
- err(1, "fopen: %s", file);
-
- while ((n = getline(&line, &sz, in)) != -1) {
- /* replace CRLF with just LF */
- if (n > 1 && line[n - 1] == '\n' && line[n - 2] == '\r') {
- line[n - 2] = '\n';
- line[n - 1] = '\0';
- n--;
- }
- if (optcomment) {
- /* if this is comment, just eat the line */
- if (line[0] == '#')
- continue;
- optcomment = 0;
- /*
- * Empty line is end of section and needs
- * to be eaten as well.
- */
- if (line[0] == '\n')
- continue;
- }
-
- /* make sure every line is valid ascii */
- for (i = 0; i < n; i++)
- if (!isprint((unsigned char)line[i]) &&
- !isspace((unsigned char)line[i]))
- errx(1, "getline: %s: "
- "invalid content", file);
-
- /* concat line to buf */
- if ((nbuf = realloc(buf, bsz + n + 1)) == NULL)
- err(1, NULL);
- if (buf == NULL)
- nbuf[0] = '\0'; /* initialize buffer */
- buf = nbuf;
- bsz += n + 1;
- if (strlcat(buf, line, bsz) >= bsz)
- errx(1, "strlcat overflow");
- /* limit the buffer size */
- if (bsz > 4096)
- errx(1, "%s: file too big", file);
- }
-
- free(line);
- if (ferror(in))
- err(1, "getline: %s", file);
- fclose(in);
- if (buf == NULL)
- errx(1, "%s: no data", file);
- return buf;
-}
-
/*
* Free a TAL pointer.
* Safe to call with NULL.