ASRANGE_NEW(3) Library Functions Manual ASRANGE_NEW(3)

ASRange_new, ASRange_free, d2i_ASRange, i2d_ASRange, ASIdOrRange_new, ASIdOrRange_free, d2i_ASIdOrRange, i2d_ASIdOrRange, ASIdentifierChoice_new, ASIdentifierChoice_free, d2i_ASIdentifierChoice, i2d_ASIdentifierChoiceRFC 3779 autonomous system identifiers and ranges

#include <openssl/x509v3.h>

ASRange *
ASRange_new(void);

void
ASRange_free(ASRange *asrange);

ASRange *
d2i_ASRange(ASRange **asrange, const unsigned char **der_in, long length);

int
i2d_ASRange(ASRange *asrange, unsigned char **der_out);

ASIdOrRange *
ASIdOrRange_new(void);

void
ASIdOrRange_free(ASIdOrRange *aor);

ASIdOrRange *
d2i_ASIdOrRange(ASIdOrRange **aor, const unsigned char **der_in, long length);

int
i2d_ASIdOrRange(ASIdOrRange *aor, unsigned char **der_out);

ASIdentifierChoice *
ASIdentifierChoice_new(void);

void
ASIdentifierChoice_free(ASIdentifierChoice *aic);

ASIdentifierChoice *
d2i_ASIdentifierChoice(ASIdentifierChoice **aic, const unsigned char **der_in, long length);

int
i2d_ASIdentifierChoice(ASIdentifierChoice *aic, unsigned char **der_out);

ASRange, ASIdOrRange, and ASIdentifierChoice are building blocks of the ASIdentifiers type representing the RFC 3779 autonomous system identifier delegation extension.

All ASN1_INTEGERs in this manual must be representable as unsigned 32-bit integers. The API performs no corresponding checks. An ASN1_INTEGER can be set using ASN1_INTEGER_set_uint64(3).

The ASRange type defined in RFC 3779 section 3.2.3.8 is implemented as

typedef struct ASRange_st {
	ASN1_INTEGER *min;
	ASN1_INTEGER *max;
} ASRange;

It represents the closed range [min,max] of AS identifiers between min and max, where min should be strictly smaller than max.

() allocates a new ASRange object with allocated, empty min and max, thus representing the invalid range [0,0].

() frees asrange including any data contained in it. If asrange is NULL, no action occurs.

The ASIdOrRange type defined in RFC 3779 section 3.2.3.5 is implemented as

typedef struct ASIdOrRange_st {
	int type;
	union {
		ASN1_INTEGER *id;
		ASRange *range;
	} u;
} ASIdOrRange;

representing an individual AS identifier or a range. When populating an ASIdOrRange object by hand, its type should be set to ASIdOrRange_id or ASIdOrRange_range to indicate which member of the union u is valid.

() returns a new ASIdOrRange object with invalid type and NULL members of the union u.

() frees aor including any data contained in it, provided type is set correctly. If asrange is NULL, no action occurs.

In order to express a list of AS identifiers and ranges, RFC 3779 section 3.2.3.4 uses an ASN.1 SEQUENCE, which is implemented via a STACK_OF(3) construction over ASIdOrRange:

typedef STACK_OF(ASIdOrRange) ASIdOrRanges;

Since an ASIdOrRanges object should be sorted in a specific way (see X509v3_asid_canonize(3)), a comparison function is needed for a correct instantiation with sk_new(3). The () function is not directly exposed and not easily accessible from outside the library, and it is non-trivial to implement. It is therefore discouraged to use ASIdOrRanges objects that are not part of an ASIdentifiers object.

The “inherit” marker from RFC 3779 section 3.2.3.3 is implemented as ASN1_NULL. It has no dedicated type or API and can be instantiated with ASN1_NULL_new(3).

The ASIdentifierChoice type defined in RFC 3779 section 3.2.3.2 is implemented as

typedef struct ASIdentifierChoice_st {
	int type;
	union {
		ASN1_NULL *inherit;
		ASIdOrRanges *asIdsOrRanges;
	} u;
} ASIdentifierChoice;

where the type member should be set to ASIdentifierChoice_inherit or ASIdentifierChoice_asIdsOrRanges to indicate whether a given ASIdentifierChoice object represents an inherited list or an explicit list.

() returns a new ASIdentifierChoice object with invalid type and NULL members of the union u.

() frees aic including any data contained in it, provided type is set correctly.

The ASIdentifiers type defined in RFC 3779 section 3.2.3.1 is implemented as

typedef struct ASIdentifiers_st {
	ASIdentifierChoice *asnum;
	ASIdentifierChoice *rdi;
} ASIdentifiers;

It should be instantiated with ASIdentifiers_new(3) and populated with X509v3_asid_add_id_or_range(3).

(), (), (), (), (), and () decode and encode ASN.1 ASRange, ASIdOrRange, and ASIdentifierChoice objects. For details about the semantics, examples, caveats, and bugs, see ASN1_item_d2i(3). In order for the encoding produced by i2d_ASRange() to be correct, min must be strictly less than max. Similarly for i2d_ASIdOrRange() and an ASIdOrRange object of type ASIdOrRange_range.

ASRange_new() returns a new ASRange object with allocated, empty members, or NULL if an error occurs.

ASIdOrRange_new() returns a new, empty ASIdOrRange object or NULL if an error occurs.

ASIdentifierChoice_new() returns a new, empty ASIdentifierChoice object or NULL if an error occurs.

The decoding functions d2i_ASRange(), d2i_ASIdOrRange(), and d2i_ASIdentifierChoice() return an ASRange, an ASIdOrRange, or an ASIdentifierChoice, object, respectively, or NULL if an error occurs.

The encoding functions i2d_ASRange(), i2d_ASIdOrRange(), and i2d_ASIdentifierChoice() return the number of bytes successfully encoded or a value <= 0 if an error occurs.

ASIdentifiers_new(3), ASN1_INTEGER_set_uint64(3), crypto(3), IPAddressRange_new(3), s2i_ASN1_INTEGER(3), STACK_OF(3), X509_new(3), X509v3_asid_add_id_or_range(3)

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

  • section 3.2.3: Syntax
  • section 3.2.3.1: Type ASIdentifiers
  • section 3.2.3.2: Elements asnum, rdi, and Type ASIdentifierChoice
  • section 3.2.3.3: Element inherit
  • section 3.2.3.4: Element asIdsOrRanges
  • section 3.2.3.5: Type ASIdOrRange
  • section 3.2.3.6: Element id
  • section 3.2.3.7: Element range
  • section 3.2.3.8: Type ASRange
  • section 3.2.3.9: Elements min and max

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

An ASIdOrRanges_new() function that installs the correct comparison function on the stack of ASIdOrRange should have been part of the API to make it usable.

ASIdentifierChoice_new() is of very limited use because ASIdOrRanges_new() is missing.

There is no way of ensuring that an ASIdOrRanges object is in canonical form unless it is part of an ASIdentifiers object. It is therefore difficult to guarantee that the output of i2d_ASIdentifierChoice() is conformant.

RFC 3779 3.2.3.4 has “asIdsOrRanges” while its type in this implementation is ASIdOrRanges.

October 11, 2023 Linux 6.8.2-arch2-1