-/* $OpenBSD: encoding.c,v 1.7 2021/10/27 21:56:58 beck Exp $ */
+/* $OpenBSD: encoding.c,v 1.8 2021/10/28 11:57:00 claudio Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
*
return NULL;
}
+/*
+ * Return the size of the data blob in outlen for an inlen sized base64 buffer.
+ * Returns 0 on success and -1 if inlen would overflow an int.
+ */
+int
+base64_decode_len(size_t inlen, size_t *outlen)
+{
+ *outlen = 0;
+ if (inlen >= INT_MAX - 3)
+ return -1;
+ *outlen = ((inlen + 3) / 4) * 3 + 1;
+ return 0;
+}
+
/*
* Decode base64 encoded string into binary buffer returned in out.
* The out buffer size is stored in outlen.
{
static EVP_ENCODE_CTX *ctx;
unsigned char *to;
- int tolen;
+ size_t tolen;
+ int evplen;
if (ctx == NULL && (ctx = EVP_ENCODE_CTX_new()) == NULL)
err(1, "EVP_ENCODE_CTX_new");
*out = NULL;
*outlen = 0;
- if (inlen >= INT_MAX - 3)
+ if (base64_decode_len(inlen, &tolen) == -1)
return -1;
- tolen = ((inlen + 3) / 4) * 3 + 1;
if ((to = malloc(tolen)) == NULL)
return -1;
+ evplen = tolen;
EVP_DecodeInit(ctx);
- if (EVP_DecodeUpdate(ctx, to, &tolen, in, inlen) == -1)
+ if (EVP_DecodeUpdate(ctx, to, &evplen, in, inlen) == -1)
goto fail;
- *outlen = tolen;
- if (EVP_DecodeFinal(ctx, to + tolen, &tolen) == -1)
+ *outlen = evplen;
+ if (EVP_DecodeFinal(ctx, to + evplen, &evplen) == -1)
goto fail;
- *outlen += tolen;
+ *outlen += evplen;
*out = to;
return 0;
return -1;
}
+/*
+ * Return the size of the base64 blob in outlen for a inlen sized binary buffer.
+ * Returns 0 on success and -1 if inlen would overflow the calculation.
+ */
+int
+base64_encode_len(size_t inlen, size_t *outlen)
+{
+ *outlen = 0;
+ if (inlen >= INT_MAX / 2)
+ return -1;
+ *outlen = ((inlen + 2) / 3) * 4 + 1;
+ return 0;
+}
+
+/*
+ * Encode a binary buffer into a base64 encoded string returned in out.
+ * Returns 0 on success or -1 for any errors.
+ */
int
base64_encode(const unsigned char *in, size_t inlen, char **out)
{
*out = NULL;
- if (inlen >= INT_MAX / 2)
+ if (base64_encode_len(inlen, &tolen) == -1)
return -1;
- tolen = ((inlen + 2) / 3) * 4 + 1;
if ((to = malloc(tolen)) == NULL)
return -1;
-/* $OpenBSD: extern.h,v 1.83 2021/10/28 09:02:19 beck Exp $ */
+/* $OpenBSD: extern.h,v 1.84 2021/10/28 11:57:00 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
/* Encoding functions for hex and base64. */
unsigned char *load_file(const char *, size_t *);
+int base64_decode_len(size_t, size_t *);
int base64_decode(const unsigned char *, size_t,
unsigned char **, size_t *);
+int base64_encode_len(size_t, size_t *);
int base64_encode(const unsigned char *, size_t, char **);
char *hex_encode(const unsigned char *, size_t);
-/* $OpenBSD: rrdp.c,v 1.15 2021/10/26 16:12:54 claudio Exp $ */
+/* $OpenBSD: rrdp.c,v 1.16 2021/10/28 11:57:00 claudio Exp $ */
/*
* Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
char *uri;
char *data;
char hash[SHA256_DIGEST_LENGTH];
- int data_length;
+ size_t data_length;
enum publish_type type;
};
* Add buf to the base64 data string, ensure that this remains a proper
* string by NUL-terminating the string.
*/
-void
+int
publish_add_content(struct publish_xml *pxml, const char *buf, int length)
{
- int new_length;
+ size_t newlen, outlen;
/*
* optmisiation, this often gets called with '\n' as the
* only data... seems wasteful
*/
if (length == 1 && buf[0] == '\n')
- return;
+ return 0;
/* append content to data */
- new_length = pxml->data_length + length;
- pxml->data = realloc(pxml->data, new_length + 1);
+ if (SIZE_MAX - length - 1 <= pxml->data_length)
+ return -1;
+ newlen = pxml->data_length + length;
+ if (base64_decode_len(newlen, &outlen) == -1 ||
+ outlen > MAX_FILE_SIZE)
+ return -1;
+
+ pxml->data = realloc(pxml->data, newlen + 1);
if (pxml->data == NULL)
err(1, "%s", __func__);
memcpy(pxml->data + pxml->data_length, buf, length);
- pxml->data[new_length] = '\0';
- pxml->data_length = new_length;
+ pxml->data[newlen] = '\0';
+ pxml->data_length = newlen;
+ return 0;
}
/*
-/* $OpenBSD: rrdp.h,v 1.4 2021/10/24 17:16:09 claudio Exp $ */
+/* $OpenBSD: rrdp.h,v 1.5 2021/10/28 11:57:00 claudio Exp $ */
/*
* Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
struct publish_xml *new_publish_xml(enum publish_type, char *,
char *, size_t);
void free_publish_xml(struct publish_xml *);
-void publish_add_content(struct publish_xml *,
+int publish_add_content(struct publish_xml *,
const char *, int);
int publish_done(struct rrdp *, struct publish_xml *);
-/* $OpenBSD: rrdp_delta.c,v 1.3 2021/10/24 17:16:09 claudio Exp $ */
+/* $OpenBSD: rrdp_delta.c,v 1.4 2021/10/28 11:57:00 claudio Exp $ */
/*
* Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
delta_content_handler(void *data, const char *content, int length)
{
struct delta_xml *dxml = data;
+ XML_Parser p = dxml->parser;
if (dxml->scope == DELTA_SCOPE_PUBLISH)
- publish_add_content(dxml->pxml, content, length);
+ if (publish_add_content(dxml->pxml, content, length) == -1)
+ PARSE_FAIL(p, "parse failed - content too big");
}
struct delta_xml *
-/* $OpenBSD: rrdp_snapshot.c,v 1.2 2021/10/24 17:16:09 claudio Exp $ */
+/* $OpenBSD: rrdp_snapshot.c,v 1.3 2021/10/28 11:57:00 claudio Exp $ */
/*
* Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
snapshot_content_handler(void *data, const char *content, int length)
{
struct snapshot_xml *sxml = data;
+ XML_Parser p = sxml->parser;
if (sxml->scope == SNAPSHOT_SCOPE_PUBLISH)
- publish_add_content(sxml->pxml, content, length);
+ if (publish_add_content(sxml->pxml, content, length) == -1)
+ PARSE_FAIL(p, "parse failed - content too big");
}
struct snapshot_xml *