LibreSSL 3.6 added ASN1_INTEGER_get_uint64() from OpenSSL. While this
still isn't great, at least it allows for unambiguous error checking.
In as_id_parse() we can replace some hand-rolled parsing which
simplifies things a bit.
The ASN1_INTEGER_get() API should not be used since it doesn't allow you
to distinguish errors from the (sometimes) legitimate return value -1.
Either you ignore that or you get to do some extra dances.
The conversion of the ASN1_INTEGER_get() uses is straightforward. The
price to pay is a cast for the printing, since that is the lesser evil
than the ugly PRIu64 macro.
Index: as.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/as.c,v
retrieving revision 1.11
diff -u -p -r1.11 as.c
--- as.c 30 Nov 2022 08:17:21 -0000 1.11
+++ as.c 9 May 2023 11:16:58 -0000
@@ -23,38 +23,16 @@
#include "extern.h"
-/*
- * Parse a uint32_t AS identifier from an ASN1_INTEGER.
- * This relies on the specification for ASN1_INTEGER itself, which is
- * essentially a series of big-endian bytes in the unsigned case.
- * All we do here is check if the number is negative then start copying
- * over bytes.
- * This is necessary because ASN1_INTEGER_get() on a 32-bit machine
- * (e.g., i386) will fail for AS numbers of UINT32_MAX.
- */
+/* Parse a uint32_t AS identifier from an ASN1_INTEGER. */
int
as_id_parse(const ASN1_INTEGER *v, uint32_t *out)
{
- int i;
- uint32_t res = 0;
+ uint64_t res = 0;
- /* If the negative bit is set, this is wrong. */
-
- if (v->type & V_ASN1_NEG)
+ if (!ASN1_INTEGER_get_uint64(&res, v))
return 0;
-
- /* Too many bytes for us to consider. */
-
- if ((size_t)v->length > sizeof(uint32_t))
+ if (res > UINT32_MAX)
return 0;
-
- /* Stored as big-endian bytes. */
-
- for (i = 0; i < v->length; i++) {
- res <<= 8;
- res |= v->data[i];
- }
-
*out = res;
return 1;
}
Index: roa.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/roa.c,v
retrieving revision 1.66
diff -u -p -r1.66 roa.c
--- roa.c 26 Apr 2023 16:32:41 -0000 1.66
+++ roa.c 9 May 2023 11:59:44 -0000
@@ -107,7 +107,7 @@ roa_parse_econtent(const unsigned char *
int addrsz;
enum afi afi;
const ROAIPAddress *addr;
- long maxlen;
+ uint64_t maxlen;
struct ip_addr ipaddr;
struct roa_ip *res;
int ipaddrblocksz;
@@ -168,21 +168,23 @@ roa_parse_econtent(const unsigned char *
maxlen = ipaddr.prefixlen;
if (addr->maxLength != NULL) {
- maxlen = ASN1_INTEGER_get(addr->maxLength);
- if (maxlen < 0) {
+ if (!ASN1_INTEGER_get_uint64(&maxlen,
+ addr->maxLength)) {
warnx("%s: RFC 6482 section 3.2: "
- "ASN1_INTEGER_get failed", p->fn);
+ "ASN1_INTEGER_get_uint64 failed",
+ p->fn);
goto out;
}
if (ipaddr.prefixlen > maxlen) {
warnx("%s: prefixlen (%d) larger than "
- "maxLength (%ld)", p->fn,
- ipaddr.prefixlen, maxlen);
+ "maxLength (%llu)", p->fn,
+ ipaddr.prefixlen,
+ (unsigned long long)maxlen);
goto out;
}
if (maxlen > ((afi == AFI_IPV4) ? 32 : 128)) {
- warnx("%s: maxLength (%ld) too large",
- p->fn, maxlen);
+ warnx("%s: maxLength (%llu) too large",
+ p->fn, (unsigned long long)maxlen);
goto out;
}
}
Index: validate.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
retrieving revision 1.61
diff -u -p -r1.61 validate.c
--- validate.c 11 May 2023 14:05:31 -0000 1.61
+++ validate.c 12 May 2023 05:37:43 -0000
@@ -516,13 +516,13 @@ valid_rsc(const char *fn, struct cert *c
int
valid_econtent_version(const char *fn, const ASN1_INTEGER *aint)
{
- long version;
+ uint64_t version;
if (aint == NULL)
return 1;
- if ((version = ASN1_INTEGER_get(aint)) < 0) {
- warnx("%s: ASN1_INTEGER_get failed", fn);
+ if (!ASN1_INTEGER_get_uint64(&version, aint)) {
+ warnx("%s: ASN1_INTEGER_get_uint64 failed", fn);
return 0;
}
@@ -531,7 +531,8 @@ valid_econtent_version(const char *fn, c
warnx("%s: incorrect encoding for version 0", fn);
return 0;
default:
- warnx("%s: version %ld not supported (yet)", fn, version);
+ warnx("%s: version %llu not supported (yet)", fn,
+ (unsigned long long)version);
return 0;
}
}