-/* $OpenBSD: cert.c,v 1.27 2021/02/18 16:23:17 claudio Exp $ */
+/* $OpenBSD: cert.c,v 1.28 2021/03/05 17:15:19 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
#include <arpa/inet.h>
#include <assert.h>
-#include <ctype.h>
#include <err.h>
#include <inttypes.h>
#include <stdarg.h>
* Returns zero on failure, non-zero on success.
*/
static int
-sbgp_sia_resource_notify(struct parse *p,
- const unsigned char *d, size_t dsz)
+sbgp_sia_resource_notify(struct parse *p, const char *d, size_t dsz)
{
- size_t i;
-
if (p->res->notify != NULL) {
warnx("%s: RFC 6487 section 4.8.8: SIA: "
"Notify location already specified", p->fn);
}
/* Make sure it's a https:// address. */
- if (dsz <= 8 || strncasecmp(d, "https://", 8)) {
- warnx("%s: RFC 8182 section 3.2: not using https schema",
- p->fn);
- return 0;
- }
- /* make sure only US-ASCII chars are in the URL */
- for (i = 0; i < dsz; i++) {
- if (isalnum(d[i]) || ispunct(d[i]))
- continue;
- warnx("%s: invalid URI", p->fn);
+ if (!valid_uri(d, dsz, "https://")) {
+ warnx("%s: RFC 8182 section 3.2: bad Notify URI", p->fn);
return 0;
}
-
- if ((p->res->notify = strndup((const char *)d, dsz)) == NULL)
+ if ((p->res->notify = strndup(d, dsz)) == NULL)
err(1, NULL);
return 1;
* Returns zero on failure, non-zero on success.
*/
static int
-sbgp_sia_resource_mft(struct parse *p,
- const unsigned char *d, size_t dsz)
+sbgp_sia_resource_mft(struct parse *p, const char *d, size_t dsz)
{
- size_t i;
-
if (p->res->mft != NULL) {
warnx("%s: RFC 6487 section 4.8.8: SIA: "
"MFT location already specified", p->fn);
}
/* Make sure it's an MFT rsync address. */
- if (dsz <= 8 || strncasecmp(d, "rsync://", 8)) {
- warnx("%s: RFC 6487 section 4.8.8: not using rsync schema",
- p->fn);
+ if (!valid_uri(d, dsz, "rsync://")) {
+ warnx("%s: RFC 6487 section 4.8.8: bad MFT location", p->fn);
return 0;
}
- if (strcasecmp(d + dsz - 4, ".mft") != 0) {
+ if (dsz < 4 || strcasecmp(d + dsz - 4, ".mft") != 0) {
warnx("%s: RFC 6487 section 4.8.8: SIA: "
- "invalid rsync URI suffix", p->fn);
- return 0;
- }
- /* make sure only US-ASCII chars are in the URL */
- for (i = 0; i < dsz; i++) {
- if (isalnum(d[i]) || ispunct(d[i]))
- continue;
- warnx("%s: invalid URI", p->fn);
+ "not an MFT file", p->fn);
return 0;
}
- if ((p->res->mft = strndup((const char *)d, dsz)) == NULL)
+ if ((p->res->mft = strndup(d, dsz)) == NULL)
err(1, NULL);
return 1;
* Returns zero on failure, non-zero on success.
*/
static int
-sbgp_sia_resource_carepo(struct parse *p,
- const unsigned char *d, size_t dsz)
+sbgp_sia_resource_carepo(struct parse *p, const char *d, size_t dsz)
{
- size_t i;
-
if (p->res->repo != NULL) {
warnx("%s: RFC 6487 section 4.8.8: SIA: "
"CA repository already specified", p->fn);
}
/* Make sure it's an rsync:// address. */
- if (dsz <= 8 || strncasecmp(d, "rsync://", 8)) {
- warnx("%s: RFC 6487 section 4.8.8: not using rsync schema",
+ if (!valid_uri(d, dsz, "rsync://")) {
+ warnx("%s: RFC 6487 section 4.8.8: bad CA repository URI",
p->fn);
return 0;
}
- /* make sure only US-ASCII chars are in the URL */
- for (i = 0; i < dsz; i++) {
- if (isalnum(d[i]) || ispunct(d[i]))
- continue;
- warnx("%s: invalid URI", p->fn);
- return 0;
- }
-
- if ((p->res->repo = strndup((const char *)d, dsz)) == NULL)
+ if ((p->res->repo = strndup(d, dsz)) == NULL)
err(1, NULL);
return 1;
struct cert *
cert_parse(X509 **xp, const char *fn)
{
-
return cert_parse_inner(xp, fn, 0);
}
-/* $OpenBSD: validate.c,v 1.12 2021/03/05 16:00:00 claudio Exp $ */
+/* $OpenBSD: validate.c,v 1.13 2021/03/05 17:15:19 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
#include <arpa/inet.h>
#include <assert.h>
+#include <ctype.h>
#include <err.h>
#include <fcntl.h>
#include <inttypes.h>
return 1;
}
+
+/*
+ * Validate a URI to make sure it is pure ASCII and does not point backwards
+ * or doing some other silly tricks. To enforce the protocol pass either
+ * https:// or rsync:// as proto, if NULL is passed no protocol is enforced.
+ * Returns 1 if valid, 0 otherwise.
+ */
+int
+valid_uri(const char *uri, size_t usz, const char *proto)
+{
+ size_t s;
+
+ for (s = 0; s < usz; s++)
+ if (!isalnum((unsigned char)uri[s]) &&
+ !ispunct((unsigned char)uri[s]))
+ return 0;
+
+ if (proto != NULL) {
+ s = strlen(proto);
+ if (strncasecmp(uri, proto, s) != 0)
+ return 0;
+ }
+
+ /* do not allow files or directories to start with a '.' */
+ if (strstr(uri, "/.") != NULL)
+ return 0;
+
+ return 1;
+}