Download raw body.
rpki-client: fix ip_addr_afi_parse
Per RFC 3779, the AFI is 2 or 3 octets on the wire:
IPAddressFamily ::= SEQUENCE { -- AFI & optional SAFI --
addressFamily OCTET STRING (SIZE (2..3)),
In other IP address variants this was either copied or fixed to allow
only 2 since the SAFI is not used in the RPKI.
Therefore the current length checks don't make much sense as they are.
There is a one-byte OOB read in the subsequent memcpy if p has length 1
(possible in a malformed product that libcrypto will still deserialize).
This has been this way since r1.12 in 2020.
Rework this by pulling the SAFI check up, then checking that the length
is actually 2 and adjust the warning.
Also use the oh so convenient accessors because OpenSSL 4 will require
this. It is fine to stuff an ASN1_OCTET_STRING into ASN1_STRING API:
like most ASN.1 types both are typedefs for struct asn1_string_st. It is
also necessary since no such accessors for ASN1_OCTET_STRING exist.
Index: ip.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/ip.c,v
diff -u -p -r1.34 ip.c
--- ip.c 12 Nov 2024 09:23:07 -0000 1.34
+++ ip.c 28 Nov 2025 10:35:58 -0000
@@ -35,17 +35,25 @@
* Return zero on failure, non-zero on success.
*/
int
-ip_addr_afi_parse(const char *fn, const ASN1_OCTET_STRING *p, enum afi *afi)
+ip_addr_afi_parse(const char *fn, const ASN1_OCTET_STRING *astr, enum afi *afi)
{
+ const unsigned char *buf;
+ int len;
uint16_t v;
- if (p->length == 0 || p->length > 3) {
- warnx("%s: invalid field length, want 1--3, have %d",
- fn, p->length);
+ buf = ASN1_STRING_get0_data(astr);
+ len = ASN1_STRING_length(astr);
+
+ if (len == 3) {
+ warnx("%s: SAFI not allowed", fn);
+ return 0;
+ }
+ if (len != sizeof(v)) {
+ warnx("%s: invalid AFI length, want 2, have %d", fn, len);
return 0;
}
- memcpy(&v, p->data, sizeof(v));
+ memcpy(&v, buf, sizeof(v));
v = ntohs(v);
/* Only accept IPv4 and IPv6 AFIs. */
@@ -56,12 +64,6 @@ ip_addr_afi_parse(const char *fn, const
return 0;
}
- /* Disallow the optional SAFI. */
-
- if (p->length == 3) {
- warnx("%s: SAFI not allowed", fn);
- return 0;
- }
*afi = v;
return 1;
rpki-client: fix ip_addr_afi_parse