---
name: "libressl-X509v3_asid_add_id_or_range"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-X509v3_asid_add_id_or_range"
---

# libressl-X509v3\_asid\_add\_id\_or\_range(3)

RFC 3779 autonomous system identifier delegation extension

## NAME

**X509v3\_asid\_add\_id\_or\_range**, **X509v3\_asid\_add\_inherit**, **X509v3\_asid\_canonize**, **X509v3\_asid\_is\_canonical** – RFC 3779 autonomous system identifier delegation extension

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#include \<openssl/x509v3.h\>**

*int*\

**X509v3\_asid\_add\_id\_or\_range**(*ASIdentifiers \*asid*, *int type*, *ASN1\_INTEGER \*min*, *ASN1\_INTEGER \*max*);

*int*\

**X509v3\_asid\_add\_inherit**(*ASIdentifiers \*asid*, *int type*);

*int*\

**X509v3\_asid\_canonize**(*ASIdentifiers \*asid*);

*int*\

**X509v3\_asid\_is\_canonical**(*ASIdentifiers \*asid*);

## DESCRIPTION

An *ASIdentifiers* object represents the content of the certificate extension defined in RFC 3779, section 3.2.3.1. It can be instantiated with ASIdentifiers\_new(3) and its internals are documented in ASRange\_new(3).

An autonomous system is identified by an unsigned 32-bit integer, called an AS identifier or AS number. An *ASIdentifiers* object can hold two lists: a list of *type* V3\_ASID\_ASNUM containing individual AS identifiers and ranges of AS identifiers, and an obsolete list of *type* V3\_ASID\_RDI containing routing domain identifiers (RDIs). Either of these lists may be absent, or it may contain nothing but a special “inherit” marker that indicates that the list is inherited from the issuer of the certificate.

**X509v3\_asid\_add\_id\_or\_range**() adds an individual identifier or a range of identifiers to the list of *type* (either V3\_ASID\_ASNUM or V3\_ASID\_RDI) in *asid*. If no such list exists, it is created first. If a list of *type* already exists and contains the “inherit” marker, the call fails. *min* must be a non-NULL *ASN1\_INTEGER*. If *max* is NULL, *min* is added as an individual identifier. Ownership of *min* and *max* is transferred to *asid* on success. It is the responsibility of the caller to ensure that the resulting *asid* does not contain lists with overlapping ranges and that *min* is strictly less than *max* if both are non-NULL. The caller should also ensure that the AS identifiers are 32-bit integers. Failure to do so may result in an *asid* that cannot be brought into canonical form by **X509v3\_asid\_canonize**().

**X509v3\_asid\_add\_inherit**() adds the list of *type* (either V3\_ASID\_ASNUM or V3\_ASID\_RDI) in *asid* if necessary and marks it “inherit”. This fails if *asid* already contains a list of *type* that is not marked “inherit”.

**X509v3\_asid\_canonize**() attempts to bring both lists in *asid* into canonical form. If *asid* is NULL the call succeeds and no action occurs. A list is in canonical form if it is either one of

- absent,

- marked “inherit”,

- non-empty and all identifiers and ranges are listed in increasing order. Ranges must not overlap, and adjacent ranges must be fully merged.

**X509v3\_asid\_canonize**() merges adjacent ranges but refuses to merge overlapping ranges or to discard duplicates. For example, the adjacent ranges \[a,b\] and \[b+1,c\] are merged into the single range \[a,c\], but if both \[a,b\] and \[b,c\] appear in a list, this results in an error since they are considered overlapping. Likewise, the identifier a is absorbed into the adjacent range \[a+1,b\] to yield \[a,b\]. **X509v3\_asid\_canonize**() errors if the minimum of any range is larger than the maximum. In contrast, minimum and maximum of a range may be equal.

**X509v3\_asid\_is\_canonical**() checks whether *asid* is in canonical form. Once **X509v3\_asid\_canonize**() is called successfully on *asid*, all subsequent calls to **X509v3\_asid\_is\_canonical**() succeed on an unmodified *asid* unless memory allocation fails.

## RETURN VALUES

All these functions return 1 on success and 0 on failure.

**X509v3\_asid\_add\_id\_or\_range**() and **X509v3\_asid\_add\_inherit**() fail if *asid* is NULL or if *type* is distinct from V3\_ASID\_ASNUM and V3\_ASID\_RDI, or on memory allocation failure. In addition, **X509v3\_asid\_add\_id\_or\_range**() fails if *asid* contains a list of *type* that is marked “inherit”, and **X509v3\_asid\_add\_inherit**() fails if *asid* contains a list of *type* that is not marked “inherit”.

**X509v3\_asid\_canonize**() fails if either list is empty and not marked “inherit”, or if it is malformed, or if memory allocation fails. Malformed lists include lists containing duplicate, overlapping, or malformed elements, for example AS ranges where the minimum is larger than the maximum. Some of these failure modes result in an error being pushed onto the error stack.

**X509v3\_asid\_is\_canonical**() returns 1 if *asid* is canonical and 0 if it is not canonical or on memory allocation failure.

## SEE ALSO

ASIdentifiers\_new(3), [crypto(3)](/crypto/3.md), s2i\_ASN1\_INTEGER(3), X509\_new(3), X509v3\_addr\_add\_inherit(3), X509v3\_addr\_validate\_path(3)

## STANDARDS

RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers,

- section 3: Autonomous System Delegation Extension

*Autonomous System (AS) Numbers*, https://www.iana.org/assignments/as-numbers.

## HISTORY

These functions first appeared in OpenSSL 0.9.8e and have been available since OpenBSD 7.1.

## BUGS

**X509v3\_asid\_add\_id\_or\_range**() does not check for inverted range bounds and overlaps on insertion. It is very easy to create an *asid* that fails to be canonized by **X509v3\_asid\_canonize**() and it is very hard to diagnose why.

Both **X509v3\_asid\_add\_id\_or\_range**() and **X509v3\_asid\_add\_inherit**() can leave *asid* in a corrupted state if memory allocation fails during their execution. In addition, **X509v3\_asid\_add\_id\_or\_range**() may already have freed the *min* and *max* arguments on failure.

RFC 3779 does not explicitly disallow ranges where the minimum is equal to the maximum. The isolated AS identifier *min* and the AS range \[*min*,*min*\] where the minimum and the maximum are equal to *min* have the same semantics. **X509v3\_asid\_is\_canonical**() accepts both representations as valid and **X509v3\_asid\_canonize**() does not prefer either representation over the other. The encodings of the two representations produced by i2d\_ASIdentifiers(3) are distinct.

**X509v3\_asid\_is\_canonical**() does not fully check inheriting lists to be well formed. It only checks the *type* to be ASIdentifierChoice\_inherit and ignores the presence or absence of the *inherit* element. **X509v3\_asid\_canonize**() does not fix that up. This can lead to incorrect or unexpected DER encoding of “canonical” *ASIdentifiers* objects. In particular, it is possible to construct an *ASIdentifiers* object for which both **X509v3\_asid\_is\_canonical**() and X509v3\_asid\_inherits(3) return 1, and after a round trip through DER the latter returns 0.
