diff options
Diffstat (limited to 'src/lib/libcrypto/man/X509v3_addr_add_inherit.3')
-rw-r--r-- | src/lib/libcrypto/man/X509v3_addr_add_inherit.3 | 455 |
1 files changed, 455 insertions, 0 deletions
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 | ||
27 | bring 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 | ||
61 | An | ||
62 | .Vt IPAddrBlocks | ||
63 | object represents the content of | ||
64 | an X509v3 IP address blocks delegation extension | ||
65 | as defined in RFC 3779, section 2.2.3.1. | ||
66 | It can hold lists of delegated IP address prefixes and | ||
67 | IP address ranges. | ||
68 | Each list is uniquely identified by | ||
69 | an address family identifier (AFI) and | ||
70 | an optional subsequent address family identifier (SAFI). | ||
71 | Each list can be absent or it can contain a single | ||
72 | .Dq inherit | ||
73 | marker to indicate that the resources are to be inherited | ||
74 | from the corresponding list of the issuer certificate. | ||
75 | .Pp | ||
76 | Per specification, an AFI is an unsigned 16-bit integer and | ||
77 | a SAFI is an unsigned 8-bit integer. | ||
78 | For IPv4 and IPv6 there are the predefined constants | ||
79 | .Dv IANA_AFI_IPV4 | ||
80 | and | ||
81 | .Dv IANA_AFI_IPV6 , | ||
82 | which should be the only values used for | ||
83 | .Fa afi | ||
84 | in this API. | ||
85 | In practice, | ||
86 | .Fa safi | ||
87 | is always NULL. | ||
88 | .Fa afi | ||
89 | is generally silently truncated to its lowest 16 bits and, if | ||
90 | .Fa safi | ||
91 | is non-NULL, | ||
92 | only the lowest 8 bits of the value pointed at are used. | ||
93 | .Pp | ||
94 | .Fn X509v3_addr_add_inherit | ||
95 | adds a list with an | ||
96 | .Dq inherit | ||
97 | marker to | ||
98 | .Fa addrblocks . | ||
99 | If a list corresponding to | ||
100 | .Fa afi | ||
101 | and | ||
102 | .Fa safi | ||
103 | already exists, no action occurs if it is marked | ||
104 | .Dq inherit , | ||
105 | otherwise the call fails. | ||
106 | .Pp | ||
107 | .Fn X509v3_addr_add_prefix | ||
108 | adds a newly allocated internal representation of the | ||
109 | .Fa prefix | ||
110 | of length | ||
111 | .Fa prefixlen | ||
112 | to the list corresponding to | ||
113 | .Fa afi | ||
114 | and the optional | ||
115 | .Fa safi | ||
116 | in | ||
117 | .Fa addrblocks . | ||
118 | If no such list exists, it is created first. | ||
119 | If the list exists and is marked | ||
120 | .Dq inherit , | ||
121 | the call fails. | ||
122 | .Fa prefix | ||
123 | is expected to be a byte array in network byte order. | ||
124 | It should point at enough memory to accommodate | ||
125 | .Fa prefixlen | ||
126 | bits and it is recommended that all the bits not covered by | ||
127 | the prefixlen be set to 0. | ||
128 | It is the caller's responsibility to ensure that the prefix | ||
129 | has no address in common with any of | ||
130 | the prefixes or ranges already in the list. | ||
131 | If | ||
132 | .Fa afi | ||
133 | is | ||
134 | .Dv IANA_AFI_IPV4 , | ||
135 | .Fa prefixlen | ||
136 | should be between 0 and 32 (inclusive) and if | ||
137 | .Fa afi | ||
138 | is | ||
139 | .Dv IANA_AFI_IPV6 , | ||
140 | .Fa prefixlen | ||
141 | should be between 0 and 128 (inclusive). | ||
142 | .Pp | ||
143 | .Fn X509v3_addr_add_range | ||
144 | is similar to | ||
145 | .Fn X509v3_addr_add_prefix | ||
146 | for the closed interval of IP addresses between | ||
147 | .Fa min | ||
148 | and | ||
149 | .Fa max | ||
150 | in network presentation. | ||
151 | If | ||
152 | .Fa afi | ||
153 | is | ||
154 | .Dv IANA_AFI_IPV4 , | ||
155 | .Fa min | ||
156 | and | ||
157 | .Fa max | ||
158 | should point at 4 bytes of memory | ||
159 | and if | ||
160 | .Fa afi | ||
161 | is | ||
162 | .Dv IANA_AFI_IPV6 , | ||
163 | .Fa min | ||
164 | and | ||
165 | .Fa max | ||
166 | should point at 16 bytes of memory. | ||
167 | In case the range of IP addresses between | ||
168 | .Fa min | ||
169 | and | ||
170 | .Fa max | ||
171 | is a prefix, a prefix will be added. | ||
172 | It is the caller's responsibility to ensure that | ||
173 | .Fa min | ||
174 | is less than or equal to | ||
175 | .Fa max | ||
176 | and that it does not contain any address already present | ||
177 | in the list. | ||
178 | Failure to do so will result in a subsequent failure of | ||
179 | .Fn X509v3_addr_canonize . | ||
180 | .Pp | ||
181 | .Fn X509v3_addr_canonize | ||
182 | attempts to bring the | ||
183 | .Pf non- Dv NULL | ||
184 | .Fa addrblocks | ||
185 | into canonical form. | ||
186 | An | ||
187 | .Vt IPAddrBlocks | ||
188 | object is said to be in canonical form if it conforms | ||
189 | to the ordering specified in RFC 3779: | ||
190 | section 2.2.3.3 requires that the lists be sorted first by increasing | ||
191 | .Fa afi | ||
192 | and then by increasing | ||
193 | .Fa safi , | ||
194 | where NULL is the minimal SAFI; | ||
195 | section 2.2.3.6 requires that each list be in minimal form and sorted. | ||
196 | The minimality requirement is that all adjacent prefixes | ||
197 | and ranges must be merged into a single range and that each | ||
198 | range must be expressed as a prefix, if possible. | ||
199 | In particular, any given address can be in at most one list entry. | ||
200 | The order is by increasing minimal IP address in network byte order. | ||
201 | .Pp | ||
202 | .Fn X509v3_addr_is_canonical | ||
203 | indicates whether | ||
204 | .Fa addrblocks | ||
205 | is in canonical form. | ||
206 | .Sh RETURN VALUES | ||
207 | All these functions return 1 on success and 0 on failure. | ||
208 | Memory allocation failure is one possible reason for all of them. | ||
209 | Sometimes an error code can be obtained by | ||
210 | .Xr ERR_get_error 3 . | ||
211 | .Pp | ||
212 | .Fn X509v3_addr_add_inherit | ||
213 | fails if the list corresponding to | ||
214 | .Fa afi | ||
215 | and the optional | ||
216 | .Fa safi | ||
217 | already exists and is not marked | ||
218 | .Dq inherit . | ||
219 | .Pp | ||
220 | .Fn X509v3_addr_add_prefix | ||
221 | and | ||
222 | .Fn X509v3_addr_add_range | ||
223 | fail if a list corresponding to | ||
224 | .Fa afi | ||
225 | and the optional | ||
226 | .Fa safi | ||
227 | already exists and is marked | ||
228 | .Dq inherit , | ||
229 | or if | ||
230 | .Fa prefixlen | ||
231 | is outside the interval [0,32] for IPv4 addresses | ||
232 | or [0,128] for IPv6 addresses. | ||
233 | .Pp | ||
234 | .Fn X509v3_addr_canonize | ||
235 | fails if one of the lists in | ||
236 | .Fa addrblocks | ||
237 | is malformed, | ||
238 | in particular if it contains corrupt, overlapping, | ||
239 | or duplicate entries. | ||
240 | Corruption includes ranges where | ||
241 | .Fa max | ||
242 | is strictly smaller than | ||
243 | .Fa min . | ||
244 | The error conditions are generally indistinguishable. | ||
245 | .Pp | ||
246 | .Fn X509v3_addr_is_canonical | ||
247 | returns 1 if | ||
248 | .Fa addrblocks | ||
249 | is in canonical form. | ||
250 | A return value of 0 can indicate non-canonical form or corrupted list. | ||
251 | .Sh EXAMPLES | ||
252 | Construct 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 | |||
266 | const 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 | |||
272 | static void | ||
273 | hexdump(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 | |||
283 | int | ||
284 | main(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 | ||
354 | Implement the missing public API | ||
355 | .Fn d2i_IPAddrBlocks | ||
356 | and | ||
357 | .Fn i2d_IPAddrBlocks | ||
358 | using | ||
359 | .Xr ASN1_item_d2i 3 : | ||
360 | .Bd -literal | ||
361 | IPAddrBlocks * | ||
362 | d2i_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 | |||
373 | int | ||
374 | i2d_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 | ||
385 | the use of the undocumented macro | ||
386 | .Dv ASN1_ITEM_ptr() | ||
387 | is necessary if compatibility with modern versions of other implementations | ||
388 | is 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 | ||
397 | RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: | ||
398 | .Bl -dash -compact | ||
399 | .It | ||
400 | section 2: IP Address delegation extension | ||
401 | .El | ||
402 | .Pp | ||
403 | RFC 7020: The Internet Numbers Registry System | ||
404 | .Pp | ||
405 | RFC 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 | ||
417 | These functions first appeared in OpenSSL 0.9.8e | ||
418 | and have been available since | ||
419 | .Ox 7.1 . | ||
420 | .Sh BUGS | ||
421 | .Fn IPAddrBlocks_new , | ||
422 | .Fn IPAddrBlocks_free , | ||
423 | .Fn d2i_IPAddrBlocks , | ||
424 | and | ||
425 | .Fn i2d_IPAddrBlocks | ||
426 | do not exist and | ||
427 | .Fa IPAddrBlocks_it | ||
428 | is not public. | ||
429 | The above examples show how to implement the four missing functions | ||
430 | with public API. | ||
431 | .Pp | ||
432 | .Fn X509v3_asid_add_range | ||
433 | should check for inverted range bounds and overlaps | ||
434 | on insertion and fail instead of creating a nonsensical | ||
435 | .Fa asid | ||
436 | that fails to be canonized by | ||
437 | .Fn X509v3_asid_canonize . | ||
438 | .Pp | ||
439 | If | ||
440 | .Dv NULL | ||
441 | is passed to | ||
442 | .Xr X509v3_asid_canonize 3 , | ||
443 | it succeeds. | ||
444 | .Fn X509v3_addr_is_canonical | ||
445 | considers | ||
446 | .Dv NULL | ||
447 | to be a canonical | ||
448 | .Vt IPAddrBlocks . | ||
449 | In contrast, | ||
450 | .Fn X509v3_addr_canonize | ||
451 | crashes with a | ||
452 | .Dv NULL | ||
453 | dereference. | ||
454 | .Pp | ||
455 | The only supported AFIs are IPv4 and IPv6, but this is not enforced. | ||