Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
Subject:
Re: rpki-client: convert most of ip.c to opaque ASN1_STRING
To:
Theo Buehler <tb@theobuehler.org>
Cc:
tech@openbsd.org
Date:
Wed, 3 Dec 2025 13:40:16 +0100

Download raw body.

Thread
On Wed, Dec 03, 2025 at 11:39:13AM +0100, Theo Buehler wrote:
> This removes all but two direct accesss into ASN1_STRING in ip.c.
> To handle the abs->flags reads, we will need new libcrypto API and a
> compat shim for portable.
> 
> This is in the works: https://github.com/openssl/openssl/issues/29184

Ah, the unused bits, one of the ASN1 things that just makes your day a lot
more exciting.

Diff below is OK claudio@
 
> Index: ip.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/ip.c,v
> diff -u -p -r1.35 ip.c
> --- ip.c	3 Dec 2025 10:26:52 -0000	1.35
> +++ ip.c	3 Dec 2025 10:29:36 -0000
> @@ -170,17 +170,19 @@ ip_addr_check_overlap(const struct cert_
>   * Return zero on failure, non-zero on success.
>   */
>  int
> -ip_addr_parse(const ASN1_BIT_STRING *p,
> +ip_addr_parse(const ASN1_BIT_STRING *abs,
>      enum afi afi, const char *fn, struct ip_addr *addr)
>  {
> -	long	 unused = 0;
> +	const unsigned char *data;
> +	int length, unused = 0;
>  
> -	/* Weird OpenSSL-ism to get unused bit count. */
> +	data = ASN1_STRING_get0_data(abs);
> +	length = ASN1_STRING_length(abs);
>  
> -	if ((p->flags & ASN1_STRING_FLAG_BITS_LEFT))
> -		unused = p->flags & 0x07;
> +	if ((abs->flags & ASN1_STRING_FLAG_BITS_LEFT))
> +		unused = abs->flags & 0x07;
>  
> -	if (p->length == 0 && unused != 0) {
> +	if (length == 0 && unused != 0) {
>  		warnx("%s: RFC 3779 section 2.2.3.8: "
>  		    "unused bit count must be zero if length is zero", fn);
>  		return 0;
> @@ -192,8 +194,7 @@ ip_addr_parse(const ASN1_BIT_STRING *p,
>  	 * of the [minimum] address ranges.
>  	 */
>  
> -	if (p->length != 0 &&
> -	    (p->data[p->length - 1] & ((1 << unused) - 1))) {
> +	if (length != 0 && (data[length - 1] & ((1 << unused) - 1))) {
>  		warnx("%s: RFC 3779 section 2.2.3.8: "
>  		    "unused bits must be set to zero", fn);
>  		return 0;
> @@ -201,16 +202,16 @@ ip_addr_parse(const ASN1_BIT_STRING *p,
>  
>  	/* Limit possible sizes of addresses. */
>  
> -	if ((afi == AFI_IPV4 && p->length > 4) ||
> -	    (afi == AFI_IPV6 && p->length > 16)) {
> +	if ((afi == AFI_IPV4 && length > 4) ||
> +	    (afi == AFI_IPV6 && length > 16)) {
>  		warnx("%s: RFC 3779 section 2.2.3.8: "
>  		    "IP address too long", fn);
>  		return 0;
>  	}
>  
>  	memset(addr, 0, sizeof(struct ip_addr));
> -	addr->prefixlen = p->length * 8 - unused;
> -	memcpy(addr->addr, p->data, p->length);
> +	addr->prefixlen = length * 8 - unused;
> +	memcpy(addr->addr, data, length);
>  	return 1;
>  }
>  
> 

-- 
:wq Claudio