diff options
author | job <job@cvs.openbsd.org> | 2021-07-13 18:39:40 +0000 |
---|---|---|
committer | job <job@cvs.openbsd.org> | 2021-07-13 18:39:40 +0000 |
commit | f814bd42c0cebb1797064eb24ab55724ec3da565 (patch) | |
tree | c61afe5a3fbc1b408dc768319bd0c9bb7b922b66 /usr.sbin/rpki-client/cms.c | |
parent | 7315605705b717306f71702925b6dc82fdfc1f4f (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.c | 60 |
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; +} |