summaryrefslogtreecommitdiff
path: root/usr.sbin/rpki-client/cms.c
diff options
context:
space:
mode:
authorjob <job@cvs.openbsd.org>2021-07-13 18:39:40 +0000
committerjob <job@cvs.openbsd.org>2021-07-13 18:39:40 +0000
commitf814bd42c0cebb1797064eb24ab55724ec3da565 (patch)
treec61afe5a3fbc1b408dc768319bd0c9bb7b922b66 /usr.sbin/rpki-client/cms.c
parent7315605705b717306f71702925b6dc82fdfc1f4f (diff)
Add more checks for eContent 'version' fields.
Input from deraadt@, tb@, claudio@ OK deraadt@ claudio@ tb@
Diffstat (limited to 'usr.sbin/rpki-client/cms.c')
-rw-r--r--usr.sbin/rpki-client/cms.c60
1 files changed, 59 insertions, 1 deletions
diff --git a/usr.sbin/rpki-client/cms.c b/usr.sbin/rpki-client/cms.c
index 593efa80684..3f617bb8c4c 100644
--- a/usr.sbin/rpki-client/cms.c
+++ b/usr.sbin/rpki-client/cms.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cms.c,v 1.8 2021/01/29 10:13:16 claudio Exp $ */
+/* $OpenBSD: cms.c,v 1.9 2021/07/13 18:39:39 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -144,3 +144,61 @@ out:
return res;
}
+
+/*
+ * Wrapper around ASN1_get_object() that preserves the current start
+ * state and returns a more meaningful value.
+ * Return zero on failure, non-zero on success.
+ */
+int
+ASN1_frame(const char *fn, size_t sz,
+ const unsigned char **cnt, long *cntsz, int *tag)
+{
+ int ret, pcls;
+
+ ret = ASN1_get_object(cnt, cntsz, tag, &pcls, sz);
+ if ((ret & 0x80)) {
+ cryptowarnx("%s: ASN1_get_object", fn);
+ return 0;
+ }
+ return ASN1_object_size((ret & 0x01) ? 2 : 0, *cntsz, *tag);
+}
+
+/*
+ * Check the version field in eContent.
+ * Returns -1 on failure, zero on success.
+ */
+int
+cms_econtent_version(const char *fn, const unsigned char **d, size_t dsz,
+ long *version)
+{
+ ASN1_INTEGER *aint = NULL;
+ long plen;
+ int ptag, rc = -1;
+
+ if (!ASN1_frame(fn, dsz, d, &plen, &ptag))
+ goto out;
+ if (ptag != 0) {
+ warnx("%s: eContent version: expected explicit tag [0]", fn);
+ goto out;
+ }
+
+ aint = d2i_ASN1_INTEGER(NULL, d, plen);
+ if (aint == NULL) {
+ cryptowarnx("%s: eContent version: failed d2i_ASN1_INTEGER",
+ fn);
+ goto out;
+ }
+
+ *version = ASN1_INTEGER_get(aint);
+ if (*version < 0) {
+ warnx("%s: eContent version: expected positive integer, got:"
+ " %ld", fn, *version);
+ goto out;
+ }
+
+ rc = 0;
+out:
+ ASN1_INTEGER_free(aint);
+ return rc;
+}