summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortb <>2023-09-25 01:14:34 +0000
committertb <>2023-09-25 01:14:34 +0000
commitde805f6a027c108e7292c0c5f4bd5be74fd6fde4 (patch)
tree0c90055b8753a2c2f45f1f0092fece234da5592c /src
parent3ea71d1778f511b776dc81cb998189a896bda759 (diff)
downloadopenbsd-de805f6a027c108e7292c0c5f4bd5be74fd6fde4.tar.gz
openbsd-de805f6a027c108e7292c0c5f4bd5be74fd6fde4.tar.bz2
openbsd-de805f6a027c108e7292c0c5f4bd5be74fd6fde4.zip
Add initial documentation for the RFC 3779 API
This documents the part of the API that allows building the two extensions. It is all very complicated and the bug density is quite high. Surely there's lots of room for improvement, but I've been sitting way too long on versions of these. I'll never finish. Let's fix and improve in tree.
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/man/ASIdentifiers_new.3129
-rw-r--r--src/lib/libcrypto/man/Makefile7
-rw-r--r--src/lib/libcrypto/man/X509_new.39
-rw-r--r--src/lib/libcrypto/man/X509v3_addr_add_inherit.3455
-rw-r--r--src/lib/libcrypto/man/X509v3_asid_add_id_or_range.3294
5 files changed, 889 insertions, 5 deletions
diff --git a/src/lib/libcrypto/man/ASIdentifiers_new.3 b/src/lib/libcrypto/man/ASIdentifiers_new.3
new file mode 100644
index 0000000000..828cda6ec6
--- /dev/null
+++ b/src/lib/libcrypto/man/ASIdentifiers_new.3
@@ -0,0 +1,129 @@
1.\" $OpenBSD: ASIdentifiers_new.3,v 1.1 2023/09/25 01:14:34 tb Exp $
2.\"
3.\" Copyright (c) 2021 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: September 25 2023 $
18.Dt ASIDENTIFIERS_NEW 3
19.Os
20.Sh NAME
21.Nm ASIdentifiers_new ,
22.Nm ASIdentifiers_free ,
23.Nm d2i_ASIdentifiers ,
24.Nm i2d_ASIdentifiers
25.Nd X509v3 certificate extension for autonomous system identifier delegation
26.Sh SYNOPSIS
27.In openssl/x509v3.h
28.Ft ASIdentifiers *
29.Fo ASIdentifiers_new
30.Fa "void"
31.Fc
32.Ft void
33.Fo ASIdentifiers_free
34.Fa "ASIdentifiers *asid"
35.Fc
36.Ft ASIdentifiers *
37.Fo d2i_ASIdentifiers
38.Fa "ASIdentifiers **asid"
39.Fa "const unsigned char **in"
40.Fa "long len"
41.Fc
42.Ft int
43.Fo i2d_ASIdentifiers
44.Fa "ASIdentifiers *asid"
45.Fa "unsigned char **out"
46.Fc
47.Sh DESCRIPTION
48RFC 3779 defines two X.509v3 certificate extensions that allow the
49delegation of
50IP address blocks and autonomous system (AS) identifiers
51from the issuer to the subject of the certificate.
52An
53.Vt ASIdentifiers
54object contains collections of individual AS numbers and
55ranges of AS numbers to be delegated.
56.Pp
57.Fn ASIdentifiers_new
58allocates and initializes a new, empty
59.Vt ASIdentifiers
60object that can be populated with
61.Xr X509v3_asid_add_id_or_range 3 .
62.Pp
63.Fn ASIdentifiers_free
64frees
65.Fa asid
66including any data contained in it.
67If
68.Fa asid
69is
70.Dv NULL ,
71no action occurs.
72.Pp
73.Fn d2i_ASIdentifiers
74and
75.Fn i2d_ASIdentifiers
76decode and encode ASN.1
77.Vt ASIdentifiers
78structures as defined in RFC 3779, section 3.2.3.1.
79For details about the semantics, examples, caveats, and bugs, see
80.Xr ASN1_item_d2i 3 .
81In order for the encoding produced by
82.Fn d2i_ASIdentifiers
83to conform to RFC 3779,
84.Fa asid
85must be in
86.Dq canonical form ,
87see
88.Xr X509v3_asid_canonize 3 .
89.Sh RETURN VALUES
90.Fn ASIdentifiers_new
91returns a new
92.Vt ASIdentifiers
93object or
94.Dv NULL
95on if an error occurs.
96.Pp
97.Fn d2i_ASIdentifiers
98returns an
99.Vt ASIdentifiers
100object or
101.Dv NULL
102on if a decoding or memory allocation error occurs.
103.Pp
104.Fn i2d_ASIdentifiers
105returns the number of bytes successfully encoded
106or a value <= 0 if an error occurs.
107.Sh SEE ALSO
108.Xr crypto 3 ,
109.Xr X509_new 3 ,
110.Xr X509v3_asid_add_id_or_range 3 ,
111.Xr X509v3_asid_is_canonical 3
112.Sh STANDARDS
113RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers:
114.Bl -dash -compact
115.It
116section 3: Autonomous System Identifier Delegation Extension
117.El
118.Pp
119RFC 7020: The Internet Numbers Registry System
120.Pp
121RFC 7249: Internet Numbers Registries
122.Sh HISTORY
123These functions first appeared in OpenSSL 0.9.8e
124and have been available since
125.Ox 7.1 .
126.Sh BUGS
127There are no corresponding functions for the RFC 3779
128IP address blocks delegation extension represented by
129.Vt IPAddrBlocks .
diff --git a/src/lib/libcrypto/man/Makefile b/src/lib/libcrypto/man/Makefile
index ec8d3fe191..ccf0be63fe 100644
--- a/src/lib/libcrypto/man/Makefile
+++ b/src/lib/libcrypto/man/Makefile
@@ -1,10 +1,11 @@
1# $OpenBSD: Makefile,v 1.268 2023/09/09 14:39:09 schwarze Exp $ 1# $OpenBSD: Makefile,v 1.269 2023/09/25 01:14:34 tb Exp $
2 2
3.include <bsd.own.mk> 3.include <bsd.own.mk>
4 4
5MAN= \ 5MAN= \
6 ACCESS_DESCRIPTION_new.3 \ 6 ACCESS_DESCRIPTION_new.3 \
7 AES_encrypt.3 \ 7 AES_encrypt.3 \
8 ASIdentifiers_new.3 \
8 ASN1_BIT_STRING_set.3 \ 9 ASN1_BIT_STRING_set.3 \
9 ASN1_INTEGER_get.3 \ 10 ASN1_INTEGER_get.3 \
10 ASN1_NULL_new.3 \ 11 ASN1_NULL_new.3 \
@@ -389,6 +390,8 @@ MAN= \
389 X509_verify_cert.3 \ 390 X509_verify_cert.3 \
390 X509at_add1_attr.3 \ 391 X509at_add1_attr.3 \
391 X509at_get_attr.3 \ 392 X509at_get_attr.3 \
393 X509v3_addr_add_inherit.3 \
394 X509v3_asid_add_id_or_range.3 \
392 X509v3_get_ext_by_NID.3 \ 395 X509v3_get_ext_by_NID.3 \
393 a2d_ASN1_OBJECT.3 \ 396 a2d_ASN1_OBJECT.3 \
394 crypto.3 \ 397 crypto.3 \
@@ -431,8 +434,8 @@ MAN= \
431 i2d_PKCS7_bio_stream.3 \ 434 i2d_PKCS7_bio_stream.3 \
432 lh_new.3 \ 435 lh_new.3 \
433 lh_stats.3 \ 436 lh_stats.3 \
434 s2i_ASN1_INTEGER.3 \
435 openssl.cnf.5 \ 437 openssl.cnf.5 \
438 s2i_ASN1_INTEGER.3 \
436 x509v3.cnf.5 439 x509v3.cnf.5
437 440
438all clean cleandir depend includes obj tags: 441all clean cleandir depend includes obj tags:
diff --git a/src/lib/libcrypto/man/X509_new.3 b/src/lib/libcrypto/man/X509_new.3
index c38dfc00b1..f2615cd5bd 100644
--- a/src/lib/libcrypto/man/X509_new.3
+++ b/src/lib/libcrypto/man/X509_new.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: X509_new.3,v 1.37 2023/04/30 14:49:47 tb Exp $ 1.\" $OpenBSD: X509_new.3,v 1.38 2023/09/25 01:14:34 tb Exp $
2.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 2.\" full merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
3.\" 3.\"
4.\" This file is a derived work. 4.\" This file is a derived work.
@@ -66,7 +66,7 @@
66.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 66.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
67.\" OF THE POSSIBILITY OF SUCH DAMAGE. 67.\" OF THE POSSIBILITY OF SUCH DAMAGE.
68.\" 68.\"
69.Dd $Mdocdate: April 30 2023 $ 69.Dd $Mdocdate: September 25 2023 $
70.Dt X509_NEW 3 70.Dt X509_NEW 3
71.Os 71.Os
72.Sh NAME 72.Sh NAME
@@ -193,6 +193,7 @@ or
193.Dv NULL 193.Dv NULL
194if an error occurs. 194if an error occurs.
195.Sh SEE ALSO 195.Sh SEE ALSO
196.Xr ASIdentifiers_new 3 ,
196.Xr AUTHORITY_KEYID_new 3 , 197.Xr AUTHORITY_KEYID_new 3 ,
197.Xr BASIC_CONSTRAINTS_new 3 , 198.Xr BASIC_CONSTRAINTS_new 3 ,
198.Xr crypto 3 , 199.Xr crypto 3 ,
@@ -238,7 +239,9 @@ if an error occurs.
238.Xr X509_STORE_CTX_new 3 , 239.Xr X509_STORE_CTX_new 3 ,
239.Xr X509_STORE_get_by_subject 3 , 240.Xr X509_STORE_get_by_subject 3 ,
240.Xr X509_STORE_new 3 , 241.Xr X509_STORE_new 3 ,
241.Xr X509_TRUST_set 3 242.Xr X509_TRUST_set 3 ,
243.Xr X509v3_addr_add_inherit 3 ,
244.Xr X509v3_asid_add_id_or_range 3
242.Sh STANDARDS 245.Sh STANDARDS
243RFC 5280: Internet X.509 Public Key Infrastructure Certificate and 246RFC 5280: Internet X.509 Public Key Infrastructure Certificate and
244Certificate Revocation List (CRL) Profile 247Certificate Revocation List (CRL) Profile
diff --git a/src/lib/libcrypto/man/X509v3_addr_add_inherit.3 b/src/lib/libcrypto/man/X509v3_addr_add_inherit.3
new file mode 100644
index 0000000000..e5730c881e
--- /dev/null
+++ b/src/lib/libcrypto/man/X509v3_addr_add_inherit.3
@@ -0,0 +1,455 @@
1.\" $OpenBSD: X509v3_addr_add_inherit.3,v 1.1 2023/09/25 01:14:34 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: September 25 2023 $
18.Dt X509V3_ADDR_ADD_INHERIT 3
19.Os
20.Sh NAME
21.Nm X509v3_addr_add_inherit ,
22.Nm X509v3_addr_add_prefix ,
23.Nm X509v3_addr_add_range ,
24.Nm X509v3_addr_canonize ,
25.Nm X509v3_addr_is_canonical
26.Nd construct X509v3 IP address blocks extensions and
27bring them into canonical form
28.Sh SYNOPSIS
29.In openssl/x509v3.h
30.Ft int
31.Fo X509v3_addr_add_inherit
32.Fa "IPAddrBlocks *addrblocks"
33.Fa "const unsigned afi"
34.Fa "const unsigned *safi"
35.Fc
36.Ft int
37.Fo X509v3_addr_add_prefix
38.Fa "IPAddrBlocks *addrblocks"
39.Fa "const unsigned afi"
40.Fa "const unsigned *safi"
41.Fa "unsigned char *prefix"
42.Fa "const int prefixlen"
43.Fc
44.Ft int
45.Fo X509v3_addr_add_range
46.Fa "IPAddrBlocks *addrblocks"
47.Fa "const unsigned afi"
48.Fa "const unsigned *safi"
49.Fa "unsigned char *min"
50.Fa "unsigned char *max"
51.Fc
52.Ft int
53.Fo X509v3_addr_canonize
54.Fa "IPAddrBlocks *addrblocks"
55.Fc
56.Ft int
57.Fo X509v3_addr_is_canonical
58.Fa "IPAddrBlocks *addrblocks"
59.Fc
60.Sh DESCRIPTION
61An
62.Vt IPAddrBlocks
63object represents the content of
64an X509v3 IP address blocks delegation extension
65as defined in RFC 3779, section 2.2.3.1.
66It can hold lists of delegated IP address prefixes and
67IP address ranges.
68Each list is uniquely identified by
69an address family identifier (AFI) and
70an optional subsequent address family identifier (SAFI).
71Each list can be absent or it can contain a single
72.Dq inherit
73marker to indicate that the resources are to be inherited
74from the corresponding list of the issuer certificate.
75.Pp
76Per specification, an AFI is an unsigned 16-bit integer and
77a SAFI is an unsigned 8-bit integer.
78For IPv4 and IPv6 there are the predefined constants
79.Dv IANA_AFI_IPV4
80and
81.Dv IANA_AFI_IPV6 ,
82which should be the only values used for
83.Fa afi
84in this API.
85In practice,
86.Fa safi
87is always NULL.
88.Fa afi
89is generally silently truncated to its lowest 16 bits and, if
90.Fa safi
91is non-NULL,
92only the lowest 8 bits of the value pointed at are used.
93.Pp
94.Fn X509v3_addr_add_inherit
95adds a list with an
96.Dq inherit
97marker to
98.Fa addrblocks .
99If a list corresponding to
100.Fa afi
101and
102.Fa safi
103already exists, no action occurs if it is marked
104.Dq inherit ,
105otherwise the call fails.
106.Pp
107.Fn X509v3_addr_add_prefix
108adds a newly allocated internal representation of the
109.Fa prefix
110of length
111.Fa prefixlen
112to the list corresponding to
113.Fa afi
114and the optional
115.Fa safi
116in
117.Fa addrblocks .
118If no such list exists, it is created first.
119If the list exists and is marked
120.Dq inherit ,
121the call fails.
122.Fa prefix
123is expected to be a byte array in network byte order.
124It should point at enough memory to accommodate
125.Fa prefixlen
126bits and it is recommended that all the bits not covered by
127the prefixlen be set to 0.
128It is the caller's responsibility to ensure that the prefix
129has no address in common with any of
130the prefixes or ranges already in the list.
131If
132.Fa afi
133is
134.Dv IANA_AFI_IPV4 ,
135.Fa prefixlen
136should be between 0 and 32 (inclusive) and if
137.Fa afi
138is
139.Dv IANA_AFI_IPV6 ,
140.Fa prefixlen
141should be between 0 and 128 (inclusive).
142.Pp
143.Fn X509v3_addr_add_range
144is similar to
145.Fn X509v3_addr_add_prefix
146for the closed interval of IP addresses between
147.Fa min
148and
149.Fa max
150in network presentation.
151If
152.Fa afi
153is
154.Dv IANA_AFI_IPV4 ,
155.Fa min
156and
157.Fa max
158should point at 4 bytes of memory
159and if
160.Fa afi
161is
162.Dv IANA_AFI_IPV6 ,
163.Fa min
164and
165.Fa max
166should point at 16 bytes of memory.
167In case the range of IP addresses between
168.Fa min
169and
170.Fa max
171is a prefix, a prefix will be added.
172It is the caller's responsibility to ensure that
173.Fa min
174is less than or equal to
175.Fa max
176and that it does not contain any address already present
177in the list.
178Failure to do so will result in a subsequent failure of
179.Fn X509v3_addr_canonize .
180.Pp
181.Fn X509v3_addr_canonize
182attempts to bring the
183.Pf non- Dv NULL
184.Fa addrblocks
185into canonical form.
186An
187.Vt IPAddrBlocks
188object is said to be in canonical form if it conforms
189to the ordering specified in RFC 3779:
190section 2.2.3.3 requires that the lists be sorted first by increasing
191.Fa afi
192and then by increasing
193.Fa safi ,
194where NULL is the minimal SAFI;
195section 2.2.3.6 requires that each list be in minimal form and sorted.
196The minimality requirement is that all adjacent prefixes
197and ranges must be merged into a single range and that each
198range must be expressed as a prefix, if possible.
199In particular, any given address can be in at most one list entry.
200The order is by increasing minimal IP address in network byte order.
201.Pp
202.Fn X509v3_addr_is_canonical
203indicates whether
204.Fa addrblocks
205is in canonical form.
206.Sh RETURN VALUES
207All these functions return 1 on success and 0 on failure.
208Memory allocation failure is one possible reason for all of them.
209Sometimes an error code can be obtained by
210.Xr ERR_get_error 3 .
211.Pp
212.Fn X509v3_addr_add_inherit
213fails if the list corresponding to
214.Fa afi
215and the optional
216.Fa safi
217already exists and is not marked
218.Dq inherit .
219.Pp
220.Fn X509v3_addr_add_prefix
221and
222.Fn X509v3_addr_add_range
223fail if a list corresponding to
224.Fa afi
225and the optional
226.Fa safi
227already exists and is marked
228.Dq inherit ,
229or if
230.Fa prefixlen
231is outside the interval [0,32] for IPv4 addresses
232or [0,128] for IPv6 addresses.
233.Pp
234.Fn X509v3_addr_canonize
235fails if one of the lists in
236.Fa addrblocks
237is malformed,
238in particular if it contains corrupt, overlapping,
239or duplicate entries.
240Corruption includes ranges where
241.Fa max
242is strictly smaller than
243.Fa min .
244The error conditions are generally indistinguishable.
245.Pp
246.Fn X509v3_addr_is_canonical
247returns 1 if
248.Fa addrblocks
249is in canonical form.
250A return value of 0 can indicate non-canonical form or corrupted list.
251.Sh EXAMPLES
252Construct the first extension from RFC 3779, Appendix B.
253.Bd -literal
254#include <sys/socket.h>
255#include <arpa/inet.h>
256
257#include <err.h>
258#include <stdio.h>
259#include <unistd.h>
260
261#include <openssl/asn1.h>
262#include <openssl/objects.h>
263#include <openssl/x509.h>
264#include <openssl/x509v3.h>
265
266const char *prefixes[6] = {
267 "10.0.32/20", "10.0.64/24", "10.1/16",
268 "10.2.48/20", "10.2.64/24", "10.3/16",
269};
270#define N_PREFIXES (sizeof(prefixes) / sizeof(prefixes[0]))
271
272static void
273hexdump(const unsigned char *buf, size_t len)
274{
275 size_t i;
276
277 for (i = 1; i <= len; i++)
278 printf(" 0x%02x,%s", buf[i - 1], i % 8 ? "" : "\en");
279 if (len % 8)
280 printf("\en");
281}
282
283int
284main(void)
285{
286 IPAddrBlocks *addrblocks;
287 X509_EXTENSION *ext;
288 unsigned char *der;
289 int der_len;
290 size_t i;
291
292 if (pledge("stdio", NULL) == -1)
293 err(1, "pledge");
294
295 /*
296 * Somebody forgot to implement IPAddrBlocks_new(). IPAddrBlocks
297 * is the same as STACK_OF(IPAddressFamily). As such, it should
298 * have IPAddressFamily_cmp() as its comparison function. It is
299 * not possible to call sk_new(3) because IPAddressFamily_cmp()
300 * is not part of the public API. The correct comparison function
301 * can be installed as a side-effect of X509v3_addr_canonize(3).
302 */
303 if ((addrblocks = sk_IPAddressFamily_new_null()) == NULL)
304 err(1, "sk_IPAddressFamily_new_null");
305 if (!X509v3_addr_canonize(addrblocks))
306 errx(1, "X509v3_addr_canonize");
307
308 /* Add the prefixes as IPv4 unicast. */
309 for (i = 0; i < N_PREFIXES; i++) {
310 unsigned char addr[16] = {0};
311 int len;
312 int unicast = 1; /* SAFI for unicast forwarding. */
313
314 len = inet_net_pton(AF_INET, prefixes[i], addr,
315 sizeof(addr));
316 if (len == -1)
317 errx(1, "inet_net_pton(%s)", prefixes[i]);
318 if (!X509v3_addr_add_prefix(addrblocks, IANA_AFI_IPV4,
319 &unicast, addr, len))
320 errx(1, "X509v3_addr_add_prefix(%s)", prefixes[i]);
321 }
322 if (!X509v3_addr_add_inherit(addrblocks, IANA_AFI_IPV6, NULL))
323 errx(1, "X509v3_addr_add_inherit");
324
325 /*
326 * Ensure the extension is in canonical form. Otherwise the two
327 * adjacent prefixes 10.2.48/20 and 10.2.64/24 are not merged into
328 * the range 10.2.48.0--10.2.64.255. This results in invalid DER
329 * encoding from X509V3_EXT_i2d(3) and i2d_X509_EXTENSION(3).
330 */
331 if (!X509v3_addr_canonize(addrblocks))
332 errx(1, "X509v3_addr_canonize");
333
334 /* Create the extension. The 1 indicates that it is critical. */
335 ext = X509V3_EXT_i2d(NID_sbgp_ipAddrBlock, 1, addrblocks);
336 if (ext == NULL)
337 errx(1, "X509V3_EXT_i2d");
338
339 der = NULL;
340 if ((der_len = i2d_X509_EXTENSION(ext, &der)) <= 0)
341 errx(1, "i2d_X509_EXTENSION");
342
343 hexdump(der, der_len);
344
345 /* One way of implementing IPAddrBlocks_free(). */
346 sk_IPAddressFamily_pop_free(addrblocks, IPAddressFamily_free);
347 X509_EXTENSION_free(ext);
348 free(der);
349
350 return 0;
351}
352.Ed
353.Pp
354Implement the missing public API
355.Fn d2i_IPAddrBlocks
356and
357.Fn i2d_IPAddrBlocks
358using
359.Xr ASN1_item_d2i 3 :
360.Bd -literal
361IPAddrBlocks *
362d2i_IPAddrBlocks(IPAddrBlocks **addrblocks, const unsigned char **in,
363 long len)
364{
365 const X509V3_EXT_METHOD *v3_addr;
366
367 if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL)
368 return NULL;
369 return (IPAddrBlocks *)ASN1_item_d2i((ASN1_VALUE **)addrblocks,
370 in, len, ASN1_ITEM_ptr(v3_addr->it));
371}
372
373int
374i2d_IPAddrBlocks(IPAddrBlocks *addrblocks, unsigned char **out)
375{
376 const X509V3_EXT_METHOD *v3_addr;
377
378 if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL)
379 return -1;
380 return ASN1_item_i2d((ASN1_VALUE *)addrblocks, out,
381 ASN1_ITEM_ptr(v3_addr->it));
382}
383.Ed
384.Pp
385the use of the undocumented macro
386.Dv ASN1_ITEM_ptr()
387is necessary if compatibility with modern versions of other implementations
388is desired.
389.Sh SEE ALSO
390.Xr ASIdentifiers_new 3 ,
391.Xr crypto 3 ,
392.Xr inet_net_ntop 3 ,
393.Xr inet_ntop 3 ,
394.Xr X509_new 3 ,
395.Xr X509v3_asid_add_id_or_range 3
396.Sh STANDARDS
397RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers:
398.Bl -dash -compact
399.It
400section 2: IP Address delegation extension
401.El
402.Pp
403RFC 7020: The Internet Numbers Registry System
404.Pp
405RFC 7249: Internet Number Registries
406.Pp
407.Rs
408.%T Address Family Numbers
409.%U https://www.iana.org/assignments/address-family-numbers
410.Re
411.Pp
412.Rs
413.%T Subsequent Address Family Identifiers (SAFI) Parameters
414.%U https://www.iana.org/assignments/safi-namespace
415.Re
416.Sh HISTORY
417These functions first appeared in OpenSSL 0.9.8e
418and have been available since
419.Ox 7.1 .
420.Sh BUGS
421.Fn IPAddrBlocks_new ,
422.Fn IPAddrBlocks_free ,
423.Fn d2i_IPAddrBlocks ,
424and
425.Fn i2d_IPAddrBlocks
426do not exist and
427.Fa IPAddrBlocks_it
428is not public.
429The above examples show how to implement the four missing functions
430with public API.
431.Pp
432.Fn X509v3_asid_add_range
433should check for inverted range bounds and overlaps
434on insertion and fail instead of creating a nonsensical
435.Fa asid
436that fails to be canonized by
437.Fn X509v3_asid_canonize .
438.Pp
439If
440.Dv NULL
441is passed to
442.Xr X509v3_asid_canonize 3 ,
443it succeeds.
444.Fn X509v3_addr_is_canonical
445considers
446.Dv NULL
447to be a canonical
448.Vt IPAddrBlocks .
449In contrast,
450.Fn X509v3_addr_canonize
451crashes with a
452.Dv NULL
453dereference.
454.Pp
455The only supported AFIs are IPv4 and IPv6, but this is not enforced.
diff --git a/src/lib/libcrypto/man/X509v3_asid_add_id_or_range.3 b/src/lib/libcrypto/man/X509v3_asid_add_id_or_range.3
new file mode 100644
index 0000000000..3373c2e435
--- /dev/null
+++ b/src/lib/libcrypto/man/X509v3_asid_add_id_or_range.3
@@ -0,0 +1,294 @@
1.\" $OpenBSD: X509v3_asid_add_id_or_range.3,v 1.1 2023/09/25 01:14:34 tb Exp $
2.\"
3.\" Copyright (c) 2021-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: September 25 2023 $
18.Dt X509V3_ASID_ADD_ID_OR_RANGE 3
19.Os
20.Sh NAME
21.Nm X509v3_asid_add_id_or_range ,
22.Nm X509v3_asid_add_inherit ,
23.Nm X509v3_asid_canonize ,
24.Nm X509v3_asid_is_canonical
25.Nd construct and validate individual X509v3 certificate extensions for
26autonomous system identifier delegation
27.Sh SYNOPSIS
28.In openssl/x509v3.h
29.Ft int
30.Fo X509v3_asid_add_id_or_range
31.Fa "ASIdentifiers *asid"
32.Fa "int type"
33.Fa "ASN1_INTEGER *min"
34.Fa "ASN1_INTEGER *max"
35.Fc
36.Ft int
37.Fo X509v3_asid_add_inherit
38.Fa "ASIdentifiers *asid"
39.Fa "int type"
40.Fc
41.Ft int
42.Fo X509v3_asid_canonize
43.Fa "ASIdentifiers *asid"
44.Fc
45.Ft int
46.Fo X509v3_asid_is_canonical
47.Fa "ASIdentifiers *asid"
48.Fc
49.Sh DESCRIPTION
50An
51.Vt ASIdentifiers
52object represents the content of the X509v3 certificate extension
53defined in RFC 3779, section 3.2.3.1.
54An autonomous system is identified by an unsigned 32-bit integer,
55called an AS number.
56An
57.Vt ASIdentifiers
58object can hold two lists:
59a list of
60.Fa type
61.Dv V3_ASID_ASNUM
62containing individual AS identifiers and ranges of AS identifiers,
63and an obsolete list of
64.Fa type
65.Dv V3_ASID_RDI
66containing routing domain identifiers (RDIs).
67Either of these lists may be absent, or it may contain nothing
68but a special
69.Dq inherit
70marker that indicates that the list is inherited from the issuer
71of the certificate.
72.Pp
73.Fn X509v3_asid_add_id_or_range
74adds an individual identifier or a range of identifiers to the list of
75.Fa type
76(either
77.Dv V3_ASID_ASNUM
78or
79.Dv V3_ASID_RDI )
80in
81.Fa asid .
82If no such list exists, it is created first.
83If a list of
84.Fa type
85already exists and contains the
86.Dq inherit
87marker, the call fails.
88.Fa min
89must be a
90.Pf non- Dv NULL
91.Vt ASN1_INTEGER .
92If
93.Fa max
94is
95.Dv NULL ,
96.Fa min
97is added as an individual identifier.
98Ownership of
99.Fa min
100and
101.Fa max
102is transferred to
103.Fa asid
104on success.
105It is the responsibility of the caller to ensure that
106the resulting
107.Fa asid
108does not contain lists with overlapping ranges and that
109.Fa min
110is strictly less than
111.Fa max
112if both are
113.Pf non- Dv NULL .
114The caller should also ensure that the AS identifiers are
11532-bit integers.
116Failure to do so may result in an
117.Fa asid
118that cannot be brought into canonical form by
119.Fn X509v3_asid_canonize .
120.Pp
121.Fn X509v3_asid_add_inherit
122adds the list of
123.Fa type
124(either
125.Dv V3_ASID_ASNUM
126or
127.Dv V3_ASID_RDI )
128in
129.Fa asid
130and marks it
131.Dq inherit .
132This fails if
133.Fa asid
134already contains a list of
135.Fa type
136that isn't marked
137.Dq inherit ,
138otherwise no action occurs.
139.Pp
140.Fn X509v3_asid_canonize
141attempts to bring both lists in
142.Fa asid
143into canonical form.
144If
145.Fa asid
146is
147.Dv NULL
148the call succeeds and no action occurs.
149A list is in canonical form if it is either one of
150.Bl -dash -compact
151.It
152absent,
153.It
154marked
155.Dq inherit ,
156.It
157non-empty and all identifiers and ranges are listed in increasing order.
158Ranges must not overlap,
159.\" the following is not currently specified and leads to ambiguity:
160.\" contain at least two elements,
161and adjacent ranges must be fully merged.
162.El
163.Fn X509v3_asid_canonize
164merges adjacent ranges
165but refuses to merge overlapping ranges or to discard duplicates.
166For example, the adjacent ranges [a,b] and [b+1,c] are merged
167into the single range [a,c], but if both [a,b] and [b,c] appear in a list,
168this results in an error since they are considered overlapping.
169Likewise, the identifier a is absorbed into the adjacent
170range [a+1,b] to yield [a,b].
171.Fn X509v3_asid_canonize
172errors if the minimum of any range is larger than the maximum.
173In contrast, minimum and maximum of a range may be equal.
174.Pp
175.Fn X509v3_asid_is_canonical
176checks whether
177.Fa asid
178is in canonical form.
179Once
180.Fn X509v3_asid_canonize
181is called successfully on
182.Fa asid ,
183all subsequent calls to
184.Fn X509v3_asid_is_canonical
185succeed on an unmodified
186.Fa asid
187unless memory allocation fails.
188.Sh RETURN VALUES
189All these functions return 1 on success and 0 on failure.
190.Pp
191.Fn X509v3_asid_add_id_or_range
192and
193.Fn X509v3_asid_add_inherit
194fail if
195.Fa asid
196is
197.Dv NULL
198or if
199.Fa type
200is distinct from
201.Dv V3_ASID_ASNUM
202and
203.Dv V3_ASID_RDI ,
204or on memory allocation failure.
205In addition,
206.Fn X509v3_asid_add_id_or_range
207fails if
208.Fa asid
209contains a list of
210.Fa type
211that is marked
212.Dq inherit ,
213and
214.Fn X509v3_asid_add_inherit
215fails if
216.Fa asid
217contains a list of
218.Fa type
219that is not marked
220.Dq inherit .
221.Pp
222.Fn X509v3_asid_canonize
223fails if either list is empty and not marked
224.Dq inherit ,
225or if it is malformed, or if memory allocation fails.
226Malformed lists include lists containing duplicate, overlapping,
227or malformed elements, for example AS ranges where the minimum is
228larger than the maximum.
229Some of these failure modes result in an error being pushed onto the
230error stack.
231.Pp
232.Fn X509v3_asid_is_canonical
233returns 1 if
234.Fa asid
235is canonical and 0 if it is not canonical or on memory allocation
236failure.
237.Sh SEE ALSO
238.Xr ASIdentifiers_new 3 ,
239.Xr crypto 3 ,
240.Xr s2i_ASN1_INTEGER 3 ,
241.Xr X509_new 3 ,
242.Xr X509v3_addr_add_range 3
243.Sh STANDARDS
244RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers,
245.Bl -dash -compact
246.It
247section 3: Autonomous System Delegation Extension
248.El
249.Pp
250.Rs
251.%T Autonomous System (AS) Numbers
252.%U https://www.iana.org/assignments/as-numbers
253.Re
254.Sh HISTORY
255These functions first appeared in OpenSSL 0.9.8e
256and have been available since
257.Ox 7.1 .
258.Sh BUGS
259.Fn X509v3_asid_add_id_or_range
260does not check for inverted range bounds and overlaps
261on insertion.
262It is very easy to create an
263.Fa asid
264that fails to be canonized by
265.Fn X509v3_asid_canonize
266and it is very hard to diagnose why.
267.Pp
268Both
269.Fn X509v3_asid_add_id_or_range
270and
271.Fn X509v3_asid_add_inherit
272can leave
273.Fa asid
274in a corrupted state if memory allocation fails during their execution.
275In addition,
276.Fn X509v3_asid_add_id_or_range
277may already have freed the
278.Fa min
279and
280.Fa max
281arguments on failure.
282.Pp
283RFC 3779 does not explicitly disallow ranges where the minimum
284is equal to the maximum.
285The isolated AS identifier a and
286the AS range [a,a] where the minimum and the maximum are equal to a
287have the same semantics.
288.Fn X509v3_asid_is_canonical
289accepts both representations as valid and
290.Fn X509v3_asid_canonize
291does not prefer either representation over the other.
292The encodings of the two representations produced by
293.Xr i2d_ASIdentifiers 3
294are distinct.