1.\" $OpenBSD: IPAddressRange_new.3,v 1.9 2023/10/03 09:58:06 tb Exp $ 2.\" 3.\" Copyright (c) 2023 Theo Buehler <tb@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: October 3 2023 $ 18.Dt IPADDRESSRANGE_NEW 3 19.Os 20.Sh NAME 21.Nm IPAddressRange_new , 22.Nm IPAddressRange_free , 23.Nm d2i_IPAddressRange , 24.Nm i2d_IPAddressRange , 25.Nm IPAddressOrRange_new , 26.Nm IPAddressOrRange_free , 27.Nm d2i_IPAddressOrRange , 28.Nm i2d_IPAddressOrRange , 29.Nm IPAddressChoice_new , 30.Nm IPAddressChoice_free , 31.Nm d2i_IPAddressChoice , 32.Nm i2d_IPAddressChoice , 33.Nm IPAddressFamily_new , 34.Nm IPAddressFamily_free , 35.Nm d2i_IPAddressFamily , 36.Nm i2d_IPAddressFamily 37.Nd RFC 3779 IP address prefixes and ranges 38.Sh SYNOPSIS 39.In openssl/x509v3.h 40.Ft "IPAddressRange *" 41.Fn IPAddressRange_new void 42.Ft void 43.Fn IPAddressRange_free "IPAddressRange *range" 44.Ft IPAddressRange * 45.Fo d2i_IPAddressRange 46.Fa "IPAddressRange **range" 47.Fa "const unsigned char **der_in" 48.Fa "long length" 49.Fc 50.Ft int 51.Fo i2d_IPAddressRange 52.Fa "IPAddressRange *range" 53.Fa "unsigned char **der_out" 54.Fc 55.Ft "IPAddressOrRange *" 56.Fn IPAddressOrRange_new void 57.Ft void 58.Fn IPAddressOrRange_free "IPAddressOrRange *aor" 59.Ft IPAddressOrRange * 60.Fo d2i_IPAddressOrRange 61.Fa "IPAddressOrRange **aor" 62.Fa "const unsigned char **der_in" 63.Fa "long length" 64.Fc 65.Ft int 66.Fo i2d_IPAddressOrRange 67.Fa "IPAddressOrRange *aor" 68.Fa "unsigned char **der_out" 69.Fc 70.Ft "IPAddressChoice *" 71.Fn IPAddressChoice_new void 72.Ft void 73.Fn IPAddressChoice_free "IPAddressChoice *ac" 74.Ft IPAddressChoice * 75.Fo d2i_IPAddressChoice 76.Fa "IPAddressChoice **ac" 77.Fa "const unsigned char **der_in" 78.Fa "long length" 79.Fc 80.Ft int 81.Fo i2d_IPAddressChoice 82.Fa "IPAddressChoice *ac" 83.Fa "unsigned char **der_out" 84.Fc 85.Ft "IPAddressFamily *" 86.Fn IPAddressFamily_new void 87.Ft void 88.Fn IPAddressFamily_free "IPAddressFamily *af" 89.Ft IPAddressFamily * 90.Fo d2i_IPAddressFamily 91.Fa "IPAddressFamily **af" 92.Fa "const unsigned char **der_in" 93.Fa "long length" 94.Fc 95.Ft int 96.Fo i2d_IPAddressFamily 97.Fa "IPAddressFamily *af" 98.Fa "unsigned char **der_out" 99.Fc 100.Sh DESCRIPTION 101.Vt IPAddressRange , 102.Vt IPAddressOrRange , 103.Vt IPAddressChoice , 104and 105.Vt IPAddressFamily 106are building blocks of the 107.Vt IPAddrBlocks 108type representing the RFC 3779 IP address delegation extension. 109.Pp 110Per RFC 3779, section 2.1.1, 111an IPv4 or an IPv6 address is encoded in network byte order in an 112ASN.1 BIT STRING of bit size 32 or 128 bits, respectively. 113The bit size of a prefix is its prefix length; 114all insignificant zero bits are omitted 115from the encoding. 116Per section 2.1.2, 117an address range is expressed as a pair of BIT STRINGs 118where all the least significant zero bits of the lower bound 119and all the least significant one bits of the upper bound are omitted. 120.Pp 121The library provides no API for directly converting an IP address or 122prefix (in any form) to and from an 123.Vt ASN1_BIT_STRING . 124It also provides no API for directly handling ranges. 125The 126.Vt ASN1_BIT_STRING 127internals are subtle and directly manipulating them in the 128context of the RFC 3779 API is discouraged. 129The bit size of an 130.Vt ASN1_BIT_STRING 131representing an IP address prefix or range is eight times its 132.Fa length 133member minus the lowest three bits of its 134.Fa flags , 135provided the 136.Dv ASN1_STRING_FLAG_BITS_LEFT 137flag is set. 138.Pp 139The 140.Vt IPAddressRange 141type defined in RFC 3779 section 2.2.3.9 is implemented as 142.Bd -literal -offset indent 143typedef struct IPAddressRange_st { 144 ASN1_BIT_STRING *min; 145 ASN1_BIT_STRING *max; 146} IPAddressRange; 147.Ed 148.Pp 149It represents the closed range [min,max] of IP addresses between 150.Fa min 151and 152.Fa max , 153where 154.Fa min 155should be strictly smaller than 156.Fa max 157and the range should not be expressible as a prefix. 158.Pp 159.Fn IPAddressRange_new 160allocates a new 161.Vt IPAddressRange 162object with allocated, empty 163.Fa min 164and 165.Fa max , 166thus representing the entire address space invalidly as a non-prefix. 167.Pp 168.Fn IPAddressRange_free 169frees 170.Fa range 171including any data contained in it. 172If 173.Fa range 174is 175.Dv NULL , 176no action occurs. 177.Pp 178There is no dedicated type representing the 179.Vt IPAddress 180type defined in RFC 3779 section 2.2.3.8. 181The API uses 182.Vt ASN1_BIT_STRING 183for this. 184.Pp 185The 186.Vt IPAddressOrRange 187type defined in RFC 3779 section 2.2.3.7 is implemented as 188.Bd -literal -offset indent 189typedef struct IPAddressOrRange_st { 190 int type; 191 union { 192 ASN1_BIT_STRING *addressPrefix; 193 IPAddressRange *addressRange; 194 } u; 195} IPAddressOrRange; 196.Ed 197.Pp 198representing an individual address prefix or an address range. 199The 200.Fa type 201member should be set to 202.Dv IPAddressOrRange_addressPrefix 203or 204.Dv IPAddressOrRange_addressRange 205to indicate which member of the union 206.Fa u 207is valid. 208.Pp 209.Fn IPAddressOrRange_new 210returns a new 211.Vt IPAddressOrRange 212object with invalid type and 213.Dv NULL 214members of the union 215.Fa u . 216.Pp 217.Fn IPAddressOrRange_free 218frees 219.Fa aor 220including any data contained in it, 221provided 222.Fa type 223is set correctly. 224If 225.Fa aor 226is 227.Dv NULL , 228no action occurs. 229.Pp 230In order to express a list of address prefixes and address ranges, 231RFC 3779 section 2.2.3.6 232uses an ASN.1 SEQUENCE, 233which is implemented via a 234.Xr STACK_OF 3 235construction over 236.Vt IPAddressOrRange : 237.Bd -literal -offset indent 238typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; 239.Ed 240.Pp 241Since an 242.Vt IPAddressOrRanges 243object should be sorted in a specific way (see 244.Xr X509v3_addr_canonize 3 ) , 245a comparison function is needed for a correct instantiation 246with 247.Xr sk_new 3 . 248The 249.Fn v4IPAddressOrRange_cmp 250and 251.Fn v6IPAddressOrRange_cmp 252functions are not directly exposed and not easily accessible 253from outside the library, 254and they are non-trivial to implement. 255It is therefore discouraged to use 256.Vt IPAddressOrRanges 257objects that are not part of an 258.Vt IPAddrBlocks 259object. 260.Pp 261The 262.Dq inherit 263marker from RFC 3779 section 2.2.3.5 is implemented as 264.Vt ASN1_NULL . 265It has no dedicated type or API and can be instantiated with 266.Xr ASN1_NULL_new 3 . 267.Pp 268The 269.Vt IPAddressChoice 270type defined in RFC 3779 section 2.2.3.4 is implemented as 271.Bd -literal -offset indent 272typedef struct IPAddressChoice_st { 273 int type; 274 union { 275 ASN1_NULL *inherit; 276 IPAddressOrRanges *addressesOrRanges; 277 } u; 278} IPAddressChoice; 279.Ed 280.Pp 281where the 282.Fa type 283member should be set to 284.Dv IPAddressChoice_inherit 285or 286.Dv IPAddressChoice_addressesOrRanges 287to indicate whether a given 288.Vt IPAddressChoice 289object represents an inherited list or an explicit list. 290.Pp 291.Fn IPAddressChoice_new 292returns a new 293.Vt IPAddressChoice 294object with invalid type and 295.Dv NULL 296members of the union 297.Fa u . 298.Pp 299.Fn IPAddressChoice_free 300frees 301.Fa ac 302including any data contained in it, 303provided 304.Fa type 305is set correctly. 306.Pp 307The 308.Fa addressFamily 309element defined in RFC 3779 section 2.2.3.3 is implemented as an 310.Vt ASN1_OCTET_STRING 311and it contains two or three octets. 312The first two octets are always present and represent the 313address family identifier (AFI) 314in network byte order. 315The optional subsequent address family identifier (SAFI) 316occupies the third octet. 317For IPv4 and IPv6, 318.Dv IANA_AFI_IPV4 319and 320.Dv IANA_AFI_IPV6 321are predefined. 322Other AFIs are not supported by this implementation. 323.Pp 324The 325.Vt IPAddressFamily 326type defined in RFC 3779 section 2.2.3.2 is implemented as 327.Bd -literal -offset indent 328typedef struct IPAddressFamily_st { 329 ASN1_OCTET_STRING *addressFamily; 330 IPAddressChoice *ipAddressChoice; 331} IPAddressFamily; 332.Ed 333.Pp 334The 335.Fa addressFamily 336member indicates the address family the 337.Fa ipAddressChoice 338represents. 339.Pp 340.Fn IPAddressFamily_new 341returns a new 342.Vt IPAddressFamily 343object with empty 344.Fa addressFamily 345and invalid 346.Fa ipAddressChoice 347members. 348.Pp 349.Fn IPAddressFamily_free 350frees 351.Fa af 352including any data contained in it. 353If 354.Fa af 355is 356.Dv NULL , 357no action occurs. 358.Pp 359The 360.Vt IPAddrBlocks 361type defined in RFC 3779 section 2.2.3.1 362uses an ASN.1 SEQUENCE, 363which is implemented via a 364.Xr STACK_OF 3 365construction over 366.Vt IPAddressFamily : 367.Bd -literal -offset indent 368typedef STACK_OF(IPAddressFamily) IPAddrBlocks; 369.Ed 370.Pp 371It can be instantiated with 372.Fn sk_IPAddressFamily_new_null 373and the correct sorting function can be installed with 374.Xr X509v3_addr_canonize 3 . 375To populate it, use 376.Xr X509v3_addr_add_prefix 3 377and related functions. 378.Pp 379.Fn d2i_IPAddressRange , 380.Fn i2d_IPAddressRange , 381.Fn d2i_IPAddressOrRange , 382.Fn i2d_IPAddressOrRange , 383.Fn d2i_IPAddressChoice , 384.Fn i2d_IPAddressChoice , 385.Fn d2i_IPAddressFamily , 386and 387.Fn i2d_IPAddressFamily 388decode and encode ASN.1 389.Vt IPAddressRange , 390.Vt IPAddressOrRange , 391.Vt IPAddressChoice , 392and 393.Vt IPAddressFamily 394objects. 395For details about the semantics, examples, caveats, and bugs, see 396.Xr ASN1_item_d2i 3 . 397There is no easy way of ensuring that the encodings generated by 398these functions are correct, unless they are applied to objects 399that are part of a canonical 400.Vt IPAddrBlocks 401structure, see 402.Xr X509v3_addr_is_canonical 3 . 403.Sh RETURN VALUES 404.Fn IPAddressRange_new 405returns a new 406.Vt IPAddressRange 407object with allocated, empty members, or 408.Dv NULL 409if an error occurs. 410.Pp 411.Fn IPAddressOrRange_new 412returns a new, empty 413.Vt IPAddressOrRange 414object or 415.Dv NULL 416if an error occurs. 417.Pp 418.Fn IPAddressChoice_new 419returns a new, empty 420.Vt IPAddressChoice 421object or 422.Dv NULL 423if an error occurs. 424.Pp 425.Fn IPAddressFamily_new 426returns a new 427.Vt IPAddressFamily 428object with allocated, empty members, or 429.Dv NULL 430if an error occurs. 431.Pp 432The decoding functions 433.Fn d2i_IPAddressRange , 434.Fn d2i_IPAddressOrRange , 435.Fn d2i_IPAddressChoice , 436and 437.Fn d2i_IPAddressFamily 438return an 439.Vt IPAddressRange , 440an 441.Vt IPAddressOrRange , 442an 443.Vt IPAddressChoice , 444or an 445.Vt IPAddressFamily 446object, respectively, 447or 448.Dv NULL 449if an error occurs. 450.Pp 451The encoding functions 452.Fn i2d_IPAddressRange , 453.Fn i2d_IPAddressOrRange , 454.Fn i2d_IPAddressChoice , 455and 456.Fn i2d_IPAddressFamily 457return the number of bytes successfully encoded 458or a value <= 0 if an error occurs. 459.Sh SEE ALSO 460.Xr ASIdentifiers_new 3 , 461.Xr ASN1_BIT_STRING_new 3 , 462.Xr ASN1_OCTET_STRING_new 3 , 463.Xr ASN1_OCTET_STRING_set 3 , 464.Xr crypto 3 , 465.Xr X509_new 3 , 466.Xr X509v3_addr_add_inherit 3 , 467.Xr X509v3_addr_inherits 3 , 468.Xr X509v3_addr_subset 3 469.Sh STANDARDS 470RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: 471.Bl -dash -compact 472.It 473section 2.1.1: Encoding of an IP Address or Prefix 474.It 475section 2.1.2: Encoding of a Range of IP Addresses 476.It 477section 2.2.3: Syntax 478.It 479section 2.2.3.1: Type IPAddrBlocks 480.It 481section 2.2.3.2: Type IPAddressFamily 482.It 483section 2.2.3.3: Element addressFamily 484.It 485section 2.2.3.4: Element ipAddressChoice and Type IPAddressChoice 486.It 487section 2.2.3.5: Element inherit 488.It 489section 2.2.3.6: Element addressesOrRanges 490.It 491section 2.2.3.7: Type IPAddressOrRange 492.It 493section 2.2.3.8: Element addressPrefix and Type IPAddress 494.It 495section 2.2.3.9: Element addressRange and Type IPAddressRange 496.El 497.Pp 498ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: 499Information technology - ASN.1 encoding rules: 500Specification of Basic Encoding Rules (BER), Canonical Encoding 501Rules (CER) and Distinguished Encoding Rules (DER), 502section 8.6: Encoding of a bitstring value 503.Sh HISTORY 504These functions first appeared in OpenSSL 0.9.8e 505and have been available since 506.Ox 7.1 . 507.Sh BUGS 508.\" The internals do not seem to consistently apply and check 509.\" .Dv ASN1_STRING_FLAG_BITS_LEFT 510.\" which may lead to incorrect encoding and misinterpretation 511As it stands, the API is barely usable 512due to missing convenience accessors, constructors and destructors 513and due to the complete absence of API that checks that the 514individual building blocks are correct. 515Extracting information from a given object can be done relatively 516safely. 517However, constructing objects is very error prone, be it 518by hand or using the bug-ridden 519.Xr X509v3_addr_add_inherit 3 520API. 521.Pp 522RFC 3779 has element 523.Dq addressesOrRanges . 524Its type in this API is 525.Vt IPAddressOrRanges . 526