From: tb Date: Tue, 26 Sep 2023 15:34:23 +0000 (+0000) Subject: Document the guts of RFC 3779 IPAddrBlocks X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=64eca56b6f0f34e9ed190a3bdc06191643e2797f;p=openbsd Document the guts of RFC 3779 IPAddrBlocks Let's just say there's room for improvement... --- diff --git a/lib/libcrypto/man/ASIdentifiers_new.3 b/lib/libcrypto/man/ASIdentifiers_new.3 index f95b258cae8..a67c54434c8 100644 --- a/lib/libcrypto/man/ASIdentifiers_new.3 +++ b/lib/libcrypto/man/ASIdentifiers_new.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ASIdentifiers_new.3,v 1.4 2023/09/26 08:56:18 tb Exp $ +.\" $OpenBSD: ASIdentifiers_new.3,v 1.5 2023/09/26 15:34:23 tb Exp $ .\" .\" Copyright (c) 2021 Theo Buehler .\" @@ -110,9 +110,9 @@ or a value <= 0 if an error occurs. .Sh SEE ALSO .Xr ASRange_new 3 , .Xr crypto 3 , +.Xr IPAddressRange_new 3 , .Xr X509_new 3 , -.Xr X509v3_asid_add_id_or_range 3 , -.Xr X509v3_asid_is_canonical 3 +.Xr X509v3_asid_add_id_or_range 3 .Sh STANDARDS RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: .Bl -dash -compact diff --git a/lib/libcrypto/man/ASRange_new.3 b/lib/libcrypto/man/ASRange_new.3 index e7aafbcc3f1..75b911c5888 100644 --- a/lib/libcrypto/man/ASRange_new.3 +++ b/lib/libcrypto/man/ASRange_new.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ASRange_new.3,v 1.3 2023/09/26 13:02:47 tb Exp $ +.\" $OpenBSD: ASRange_new.3,v 1.4 2023/09/26 15:34:23 tb Exp $ .\" .\" Copyright (c) 2023 Theo Buehler .\" @@ -83,9 +83,10 @@ .Vt ASIdOrRange , and .Vt ASIdentifierChoice -are building blocks of the RFC 3779 +are building blocks of the .Vt ASIdentifiers -type representing the autonomous system identifier delegation extension. +type representing the RFC 3779 +autonomous system identifier delegation extension. See .Xr ASIdentifiers_new 3 and @@ -355,10 +356,10 @@ or a value <= 0 if an error occurs. .Xr BN_set_word 3 , .Xr BN_to_ASN1_INTEGER 3 , .Xr crypto 3 , +.Xr IPAddressRange_new 3 , .Xr s2i_ASN1_INTEGER 3 , .Xr X509_new 3 , -.Xr X509v3_asid_add_id_or_range 3 , -.Xr X509v3_asid_is_canonical 3 +.Xr X509v3_asid_add_id_or_range 3 .Sh STANDARDS RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: .Bl -dash -compact diff --git a/lib/libcrypto/man/IPAddressRange_new.3 b/lib/libcrypto/man/IPAddressRange_new.3 new file mode 100644 index 00000000000..7a71ac7ffa8 --- /dev/null +++ b/lib/libcrypto/man/IPAddressRange_new.3 @@ -0,0 +1,514 @@ +.\" $OpenBSD: IPAddressRange_new.3,v 1.1 2023/09/26 15:34:23 tb Exp $ +.\" +.\" Copyright (c) 2023 Theo Buehler +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 26 2023 $ +.Dt IPADDRESSRANGE_NEW 3 +.Os +.Sh NAME +.Nm IPAddressRange_new , +.Nm IPAddressRange_free , +.Nm d2i_IPAddressRange , +.Nm i2d_IPAddressRange , +.Nm IPAddressOrRange_new , +.Nm IPAddressOrRange_free , +.Nm d2i_IPAddressOrRange , +.Nm i2d_IPAddressOrRange , +.Nm IPAddressChoice_new , +.Nm IPAddressChoice_free , +.Nm d2i_IPAddressChoice , +.Nm i2d_IPAddressChoice , +.Nm IPAddressFamily_new , +.Nm IPAddressFamily_free , +.Nm d2i_IPAddressFamily , +.Nm i2d_IPAddressFamily +.Nd IP address prefixes and ranges +.Sh SYNOPSIS +.In openssl/x509v3.h +.Ft "IPAddressRange *" +.Fn IPAddressRange_new void +.Ft void +.Fn IPAddressRange_free "IPAddressRange *range" +.Ft IPAddressRange * +.Fo d2i_IPAddressRange +.Fa "IPAddressRange **range" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_IPAddressRange +.Fa "IPAddressRange *range" +.Fa "unsigned char **der_out" +.Fc +.Ft "IPAddressOrRange *" +.Fn IPAddressOrRange_new void +.Ft void +.Fn IPAddressOrRange_free "IPAddressOrRange *aor" +.Ft IPAddressOrRange * +.Fo d2i_IPAddressOrRange +.Fa "IPAddressOrRange **aor" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_IPAddressOrRange +.Fa "IPAddressOrRange *aor" +.Fa "unsigned char **der_out" +.Fc +.Ft "IPAddressChoice *" +.Fn IPAddressChoice_new void +.Ft void +.Fn IPAddressChoice_free "IPAddressChoice *ac" +.Ft IPAddressChoice * +.Fo d2i_IPAddressChoice +.Fa "IPAddressChoice **ac" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_IPAddressChoice +.Fa "IPAddressChoice *ac" +.Fa "unsigned char **der_out" +.Fc +.Ft "IPAddressFamily *" +.Fn IPAddressFamily_new void +.Ft void +.Fn IPAddressFamily_free "IPAddressFamily *af" +.Ft IPAddressFamily * +.Fo d2i_IPAddressFamily +.Fa "IPAddressFamily **af" +.Fa "const unsigned char **der_in" +.Fa "long length" +.Fc +.Ft int +.Fo i2d_IPAddressFamily +.Fa "IPAddressFamily *af" +.Fa "unsigned char **der_out" +.Fc +.Sh DESCRIPTION +.Vt IPAddressRange , +.Vt IPAddressOrRange , +.Vt IPAddressChoice , +and +.Vt IPAddressFamily +are building blocks of the RFC 3779 +.Vt IPAddrBlocks +type representing the IP address delegation extension. +See +.Xr X509v3_addr_add_inherit 3 +for more details. +.Pp +Per RFC 3779, section 2.1.1, +an IPv4 or an IPv6 address is encoded in network byte order in an +ASN.1 BIT STRING of bit size 32 or 128 bits, respectively. +The bit size of a prefix is its prefix length, +in other words, all insignificant zero bits are omitted. +An address range is expressed as a pair of BIT STRINGs +where all least significant zero bits of the lower bound +and the all least significant one bits of the upper bound are omitted. +Whether a prefix or a range represents a range of IPv4 address or +an IPv6 address must be derived from the context. +.Pp +The library provides no API for directly converting an IP address or +prefix (in any form) to and from an +.Vt ASN1_BIT_STRING +and it also provides no API for directly handling ranges. +The +.Vt ASN1_BIT_STRING +internals are subtle and directly manipulating them in the +context of the RFC 3779 API is discouraged. +The bit size of an +.Vt ASN1_BIT_STRING +representing an IP address prefix or range is eight times its length +member minus the lowest three bits of its flags, provided the +.Dv ASN1_STRING_FLAG_BITS_LEFT +flag is set. +.Pp +The +.Vt IPAddressRange +type defined in RFC 3779 section 2.2.3.9 is implemented as +.Bd -literal -offset indent +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min; + ASN1_BIT_STRING *max; +} IPAddressRange; +.Ed +.Pp +It represents the closed range [min,max] of IP addresses between +.Fa min +and +.Fa max , +where +.Fa min +should be strictly smaller than +.Fa max +and the range should not be expressible as a prefix. +.Pp +.Fn IPAddressRange_new +allocates a new +.Vt IPAddressRange +object with allocated, empty +.Fa min +and +.Fa max , +thus representing the entire address space. +.Pp +.Fn IPAddressRange_free +frees +.Fa range +including any data contained in it. +If +.Fa range +is +.Dv NULL , +no action occurs. +.Pp +There is no dedicated type to represent the +.Vt IPAddress +type defined in RFC 3779 section 2.2.3.8. +The API uses +.Vt ASN1_BIT_STRING +for this. +.Pp +The +.Vt IpAddressOrRange +type defined in RFC 3779 section 2.2.3.7 is implemented as +.Bd -literal -offset indent +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; +.Ed +.Pp +representing an individual address prefix or an address range. +The +.Fa type +member should be set to +.Dv IPAddressOrRange_addressPrefix +or +.Dv IPAddressOrRange_addressRange +to indicate which member of the union +.Fa u +is valid. +.Pp +.Fn IPAddressOrRange_new +returns a new +.Vt IPAddressOrRange +object with invalid type and +.Dv NULL +members of the union +.Fa u . +.Pp +.Fn IPAddressOrRange_free +frees +.Fa aor +including any data contained in it, +provided +.Fa type +is set correctly. +If +.Fa aor +is +.Dv NULL , +no action occurs. +.Pp +In order to express a list of address prefixes and address ranges, +RFC 3779 section 2.2.3.6 +uses an ASN.1 SEQUENCE, +which is implemented via a +.Xr STACK_OF 3 +construction over +.Vt IPAddressOrRange : +.Bd -literal -offset indent +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +.Ed +.Pp +Since an +.Vt IPAddressOrRanges +object should be sorted in a specific way (see +.Xr X509v3_addr_canonize 3 Ns ), +a comparison function is needed for a correct instantiation +with +.Xr sk_new 3 . +The +.Fn v4IPAddressOrRange_cmp +and +.Fn v6IPAddressOrRange_cmp +functions are not directly exposed and not easily accessible +from outside the library, +and they are non-trivial to implement. +It is therefore discouraged to use +.Vt IPAddressOrRanges +objects that are not part of an +.Vt IPAddrBlocks +object. +.Pp +The +.Dq inherit +marker from RFC 3779 section 2.2.3.5 is implemented as +.Vt ASN1_NULL . +It has no dedicated type or API and can be instantiated with +.Xr ASN1_NULL_new 3 . +.Pp +The +.Vt IPAddressChoice +type defined in RFC 3779 section 2.2.3.4 is implemented as +.Bd -literal -offset indent +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; +.Ed +.Pp +where the +.Fa type +member should be set to +.Dv IPAddressChoice_inherit +or +.Dv IPAddressChoice_addressesOrRanges +to indicate whether a given +.Vt IPAddressChoice +object represents an inherited list or an explicit list. +.Pp +.Fn IPAddressChoice_new +returns a new +.Vt IPAddressChoice +object with invalid type and +.Dv NULL +members of the union +.Fa u . +.Pp +.Fn IPAddressChoice_free +frees +.Fa ac +including any data contained in it, +provided +.Fa type +is set correctly. +.Pp +The +.Fa addressFamily +element defined in RFC 3779 section 2.2.3.3 is implemented as an +.Vt ASN1_OCTET_STRING +and it contains two or three octets. +The first two octets are always present and represent the +address family identifier (AFI) +in network byte order. +The optional subsequent address family identifier (SAFI) +occupies the third octet. +For IPv4 and IPv6, +.Dv IANA_AFI_IPV4 +and +.Dv IANA_AFI_IPV6 +are predefined. +Other AFIs are not supported by this implementation. +.Pp +The +.Vt IPAddressFamily +type defined in RFC 3779 section 2.2.3.2 is implemented as +.Bd -literal -offset indent +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; +.Ed +.Pp +The +.Fa addressFamily +member indicates the address family the +.Fa ipAddressChoice +represents. +.Pp +.Fn IPAddressFamily_new +returns a new +.Vt IPAddressFamily +object with empty +.Fa addressFamily +and invalid +.Fa ipAddressChoice +members. +.Pp +.Fn IPAddressFamily_free +frees +.Fa af +including any data contained in it. +If +.Fa af +is +.Dv NULL , +no action occurs. +.Pp +The +.Vt IPAddrBlocks +type defined in RFC 3779 section 2.2.3.1 +uses an ASN.1 SEQUENCE, +which is implemented via a +.Xr STACK_OF 3 +construction over +.Vt IPAddressFamily : +.Bd -literal -offset indent +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +.Ed +.Pp +It can be instantiated with +.Fn sk_IPAddressFamily_new_null +and the correct sorting function can be installed with +.Xr X509v3_addr_canonize 3 . +To populate it, use +.Xr X509v3_addr_add_prefix 3 +and related functions. +.Pp +.Fn d2i_IPAddressRange , +.Fn i2d_IPAddressRange , +.Fn d2i_IPAddressOrRange , +.Fn i2d_IPAddressOrRange , +.Fn d2i_IPAddressChoice , +.Fn i2d_IPAddressChoice , +.Fn d2i_IPAddressFamily , +and +.Fn i2d_IPAddressFamily , +decode and encode ASN.1 +.Vt IPAddressRange , +.Vt IPAddressOrRange , +.Vt IPAddressChoice , +and +.Vt IPAddressFamily +objects. +For details about the semantics, examples, caveats, and bugs, see +.Xr ASN1_item_d2i 3 . +There is no easy way of ensuring that the encodings generated by +these functions are correct, unless they are applied to objects +that are part of a canonical +.Vt IPAddrBlocks +structure, see +.Xr X509v3_addr_is_canonical 3 . +.Sh RETURN VALUES +.Fn IPAddressRange_new +returns a new +.Vt IPAddressRange +object or +.Dv NULL +if an error occurs. +.Pp +.Fn IPAddressRange_new +returns a new, empty +.Vt IPAddressOrRange +object or +.Dv NULL +if an error occurs. +.Pp +.Fn IPAddressChoice_new +returns a new, empty +.Vt IPAddressChoice +object or +.Dv NULL +if an error occurs. +.Pp +.Fn IPAddressFamily_new +returns a new, +.Vt IPAddressChoice +object with allocated, empty members, or +.Dv NULL +if an error occurs. +.Pp +The encoding functions +.Fn d2i_IPAddressRange , +.Fn d2i_IPAddressOrRange , +.Fn d2i_IPAddressChoice , +and +.Fn d2i_IPAddressFamily , +return an +.Vt IPAddressRange , +an +.Vt IPAddressOrRange , +an +.Vt IPAddressChoice , +or an +.Vt IPAddressFamily +object, respectively, +or +.Dv NULL +if an error occurs. +.Pp +The encoding functions +.Fn i2d_IPAddressRange , +.Fn i2d_IPAddressOrRange , +.Fn i2d_IPAddressChoice , +and +.Fn i2d_IPAddressFamily , +return the number of bytes successfully encoded +or a value <= 0 if an error occurs. +.Sh SEE ALSO +.Xr ASIdentifiers_new 3 , +.Xr ASN1_BIT_STRING_new 3 , +.Xr ASN1_OCTET_STRING_new 3 , +.Xr ASN1_OCTET_STRING_set 3 , +.Xr crypto 3 , +.Xr X509_new 3 , +.Xr X509v3_addr_add_inherit 3 +.Sh STANDARDS +RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: +.Bl -dash -compact +.It +section 2.2.3: Syntax +.It +section 2.2.3.1: Type IPAddrBlocks +.It +section 2.2.3.2: Type IPAddressFamily +.It +section 2.2.3.3: Element addressFamily +.It +section 2.2.3.4: Element ipAddressChoice and Type IPAddressChoice +.It +section 2.2.3.5: Element inherit +.It +section 2.2.3.6: Element addressesOrRanges +.It +section 2.2.3.7: Type IPAddressOrRange +.It +section 2.2.3.8: Element addressPrefix and Type IPAddress +.It +section 2.2.3.9: Elements addressRange and Type IPAddressRange +.El +.Pp +ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: +Information technology - ASN.1 encoding rules: +Specification of Basic Encoding Rules (BER), Canonical Encoding +Rules (CER) and Distinguished Encoding Rules (DER), +section 8.6: Encoding of a bitstring value +.Sh HISTORY +These functions first appeared in OpenSSL 0.9.8e +and have been available since +.Ox 7.1 . +.Sh BUGS +.\" The internals do not seem to consistently apply and check +.\" .Dv ASN1_STRING_FLAG_BITS_LEFT +.\" which may lead to incorrect encoding and misinterpretation +As it stands, the API is barely usable +due to missing convenience accessors, constructors and destructors +and due to the complete absence of API that checks that the +individual building blocks are correct. +Extracting information from a given object can be done relatively +safely. +However, constructing objects is very error prone, be it +by hand or using the bug-ridden +.Xr X509v3_addr_add_inherit 3 +API. diff --git a/lib/libcrypto/man/Makefile b/lib/libcrypto/man/Makefile index 957e8a4cefe..0f501ceb833 100644 --- a/lib/libcrypto/man/Makefile +++ b/lib/libcrypto/man/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.271 2023/09/25 12:00:49 tb Exp $ +# $OpenBSD: Makefile,v 1.272 2023/09/26 15:34:23 tb Exp $ .include @@ -222,6 +222,7 @@ MAN= \ EXTENDED_KEY_USAGE_new.3 \ GENERAL_NAME_new.3 \ HMAC.3 \ + IPAddressRange_new.3 \ MD5.3 \ NAME_CONSTRAINTS_new.3 \ OBJ_NAME_add.3 \ diff --git a/lib/libcrypto/man/X509_new.3 b/lib/libcrypto/man/X509_new.3 index 42a29a0183b..ebffc7e69ba 100644 --- a/lib/libcrypto/man/X509_new.3 +++ b/lib/libcrypto/man/X509_new.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: X509_new.3,v 1.39 2023/09/25 11:59:10 tb Exp $ +.\" $OpenBSD: X509_new.3,v 1.40 2023/09/26 15:34:23 tb Exp $ .\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 .\" .\" This file is a derived work. @@ -66,7 +66,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: September 25 2023 $ +.Dd $Mdocdate: September 26 2023 $ .Dt X509_NEW 3 .Os .Sh NAME @@ -199,6 +199,7 @@ if an error occurs. .Xr BASIC_CONSTRAINTS_new 3 , .Xr crypto 3 , .Xr d2i_X509 3 , +.Xr IPAddressRange_new 3 , .Xr PKCS8_PRIV_KEY_INFO_new 3 , .Xr X509_ALGOR_new 3 , .Xr X509_ATTRIBUTE_new 3 , diff --git a/lib/libcrypto/man/X509v3_addr_add_inherit.3 b/lib/libcrypto/man/X509v3_addr_add_inherit.3 index 98de5a01f0d..8d304751817 100644 --- a/lib/libcrypto/man/X509v3_addr_add_inherit.3 +++ b/lib/libcrypto/man/X509v3_addr_add_inherit.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: X509v3_addr_add_inherit.3,v 1.2 2023/09/25 10:34:44 tb Exp $ +.\" $OpenBSD: X509v3_addr_add_inherit.3,v 1.3 2023/09/26 15:34:23 tb Exp $ .\" .\" Copyright (c) 2023 Theo Buehler .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 25 2023 $ +.Dd $Mdocdate: September 26 2023 $ .Dt X509V3_ADDR_ADD_INHERIT 3 .Os .Sh NAME @@ -65,6 +65,9 @@ an X509v3 IP address blocks delegation extension as defined in RFC 3779, section 2.2.3.1. It can hold lists of delegated IP address prefixes and IP address ranges. +It can be instantiated as explained in the EXAMPLES section +and its internals are documented in +.Xr IPAddressRange_new 3 . Each list is uniquely identified by an address family identifier (AFI) and an optional subsequent address family identifier (SAFI). @@ -391,6 +394,7 @@ is desired. .Xr crypto 3 , .Xr inet_net_ntop 3 , .Xr inet_ntop 3 , +.Xr IPAddressRange_new 3 , .Xr X509_new 3 , .Xr X509v3_asid_add_id_or_range 3 .Sh STANDARDS