diff options
author | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
---|---|---|
committer | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
commit | eb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch) | |
tree | edb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libcrypto/man/X509v3_addr_add_inherit.3 | |
parent | 247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff) | |
download | openbsd-tb_20250414.tar.gz openbsd-tb_20250414.tar.bz2 openbsd-tb_20250414.zip |
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libcrypto/man/X509v3_addr_add_inherit.3')
-rw-r--r-- | src/lib/libcrypto/man/X509v3_addr_add_inherit.3 | 475 |
1 files changed, 0 insertions, 475 deletions
diff --git a/src/lib/libcrypto/man/X509v3_addr_add_inherit.3 b/src/lib/libcrypto/man/X509v3_addr_add_inherit.3 deleted file mode 100644 index 4b2d150c86..0000000000 --- a/src/lib/libcrypto/man/X509v3_addr_add_inherit.3 +++ /dev/null | |||
@@ -1,475 +0,0 @@ | |||
1 | .\" $OpenBSD: X509v3_addr_add_inherit.3,v 1.11 2023/10/01 22:46:21 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 1 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 RFC 3779 IP address delegation extensions | ||
27 | .Sh SYNOPSIS | ||
28 | .In openssl/x509v3.h | ||
29 | .Ft int | ||
30 | .Fo X509v3_addr_add_inherit | ||
31 | .Fa "IPAddrBlocks *addrblocks" | ||
32 | .Fa "const unsigned afi" | ||
33 | .Fa "const unsigned *safi" | ||
34 | .Fc | ||
35 | .Ft int | ||
36 | .Fo X509v3_addr_add_prefix | ||
37 | .Fa "IPAddrBlocks *addrblocks" | ||
38 | .Fa "const unsigned afi" | ||
39 | .Fa "const unsigned *safi" | ||
40 | .Fa "unsigned char *prefix" | ||
41 | .Fa "const int prefixlen" | ||
42 | .Fc | ||
43 | .Ft int | ||
44 | .Fo X509v3_addr_add_range | ||
45 | .Fa "IPAddrBlocks *addrblocks" | ||
46 | .Fa "const unsigned afi" | ||
47 | .Fa "const unsigned *safi" | ||
48 | .Fa "unsigned char *min" | ||
49 | .Fa "unsigned char *max" | ||
50 | .Fc | ||
51 | .Ft int | ||
52 | .Fo X509v3_addr_canonize | ||
53 | .Fa "IPAddrBlocks *addrblocks" | ||
54 | .Fc | ||
55 | .Ft int | ||
56 | .Fo X509v3_addr_is_canonical | ||
57 | .Fa "IPAddrBlocks *addrblocks" | ||
58 | .Fc | ||
59 | .Sh DESCRIPTION | ||
60 | An | ||
61 | .Vt IPAddrBlocks | ||
62 | object represents the content of | ||
63 | an IP address delegation extension | ||
64 | as defined in RFC 3779, section 2.2.3.1. | ||
65 | It holds lists of IP address prefixes and IP address ranges | ||
66 | delegated from the issuer to the subject of the certificate. | ||
67 | It can be instantiated as explained in the EXAMPLES section | ||
68 | and its internals are documented in | ||
69 | .Xr IPAddressRange_new 3 . | ||
70 | .Pp | ||
71 | Each list in a well-formed | ||
72 | .Vt IPAddrBlocks | ||
73 | object is uniquely identified by | ||
74 | an address family identifier (AFI) and | ||
75 | an optional subsequent address family identifier (SAFI). | ||
76 | Lists can be absent or can contain an | ||
77 | .Dq inherit | ||
78 | marker to indicate that the resources are to be inherited | ||
79 | from the corresponding list of the issuer certificate. | ||
80 | .Pp | ||
81 | Per specification, an AFI is an unsigned 16-bit integer and | ||
82 | a SAFI is an unsigned 8-bit integer. | ||
83 | For IPv4 and IPv6 there are the predefined constants | ||
84 | .Dv IANA_AFI_IPV4 | ||
85 | and | ||
86 | .Dv IANA_AFI_IPV6 , | ||
87 | which should be the only values used for | ||
88 | .Fa afi | ||
89 | in this API. | ||
90 | In practice, | ||
91 | .Fa safi | ||
92 | is always NULL. | ||
93 | .Fa afi | ||
94 | is generally silently truncated to its lowest 16 bits and, if | ||
95 | .Fa safi | ||
96 | is non-NULL, | ||
97 | only the lowest 8 bits of the value pointed at are used. | ||
98 | .Pp | ||
99 | .Fn X509v3_addr_add_inherit | ||
100 | adds a list with an | ||
101 | .Dq inherit | ||
102 | marker to | ||
103 | .Fa addrblocks . | ||
104 | If a list corresponding to | ||
105 | .Fa afi | ||
106 | and | ||
107 | .Fa safi | ||
108 | already exists, no action occurs if it is marked | ||
109 | .Dq inherit , | ||
110 | otherwise the call fails. | ||
111 | .Pp | ||
112 | .Fn X509v3_addr_add_prefix | ||
113 | adds a newly allocated internal representation of the | ||
114 | .Fa prefix | ||
115 | of length | ||
116 | .Fa prefixlen | ||
117 | to the list corresponding to | ||
118 | .Fa afi | ||
119 | and the optional | ||
120 | .Fa safi | ||
121 | in | ||
122 | .Fa addrblocks . | ||
123 | If no such list exists, it is created first. | ||
124 | If the list exists and is marked | ||
125 | .Dq inherit , | ||
126 | the call fails. | ||
127 | .Fa prefix | ||
128 | is expected to be a byte array in network byte order. | ||
129 | It should point at enough memory to accommodate | ||
130 | .Fa prefixlen | ||
131 | bits and it is recommended that all the bits not covered by the | ||
132 | .Fa prefixlen | ||
133 | be set to 0. | ||
134 | It is the caller's responsibility to ensure that the | ||
135 | .Fa prefix | ||
136 | has no address in common with any of | ||
137 | the prefixes or ranges already in the list. | ||
138 | If | ||
139 | .Fa afi | ||
140 | is | ||
141 | .Dv IANA_AFI_IPV4 , | ||
142 | .Fa prefixlen | ||
143 | should be between 0 and 32 (inclusive) and if | ||
144 | .Fa afi | ||
145 | is | ||
146 | .Dv IANA_AFI_IPV6 , | ||
147 | .Fa prefixlen | ||
148 | should be between 0 and 128 (inclusive). | ||
149 | .Pp | ||
150 | .Fn X509v3_addr_add_range | ||
151 | is similar to | ||
152 | .Fn X509v3_addr_add_prefix | ||
153 | for the closed interval of IP addresses between | ||
154 | .Fa min | ||
155 | and | ||
156 | .Fa max | ||
157 | in network presentation. | ||
158 | If | ||
159 | .Fa afi | ||
160 | is | ||
161 | .Dv IANA_AFI_IPV4 , | ||
162 | .Fa min | ||
163 | and | ||
164 | .Fa max | ||
165 | should point at 4 bytes of memory | ||
166 | and if | ||
167 | .Fa afi | ||
168 | is | ||
169 | .Dv IANA_AFI_IPV6 , | ||
170 | .Fa min | ||
171 | and | ||
172 | .Fa max | ||
173 | should point at 16 bytes of memory. | ||
174 | In case the range of IP addresses between | ||
175 | .Fa min | ||
176 | and | ||
177 | .Fa max | ||
178 | is a prefix, a prefix will be added instead of a range. | ||
179 | It is the caller's responsibility to ensure that | ||
180 | .Fa min | ||
181 | is less than or equal to | ||
182 | .Fa max | ||
183 | and that it does not contain any address already present | ||
184 | in the list. | ||
185 | Failure to do so will result in a subsequent failure of | ||
186 | .Fn X509v3_addr_canonize . | ||
187 | .Pp | ||
188 | .Fn X509v3_addr_canonize | ||
189 | attempts to bring the | ||
190 | .Pf non- Dv NULL | ||
191 | .Fa addrblocks | ||
192 | into canonical form. | ||
193 | An | ||
194 | .Vt IPAddrBlocks | ||
195 | object is said to be in canonical form if it conforms | ||
196 | to the ordering specified in RFC 3779: | ||
197 | section 2.2.3.3 requires that | ||
198 | the list of lists be sorted first by increasing | ||
199 | .Fa afi | ||
200 | and then by increasing | ||
201 | .Fa safi , | ||
202 | where NULL is the minimal SAFI; | ||
203 | section 2.2.3.6 requires that each list be in minimal form and sorted. | ||
204 | The minimality requirement is that all adjacent prefixes | ||
205 | and ranges must be merged into a single range and that each | ||
206 | range must be expressed as a prefix, if possible. | ||
207 | In particular, any given address can be in at most one list entry. | ||
208 | The order is by increasing minimal IP address in network byte order. | ||
209 | .Pp | ||
210 | .Fn X509v3_addr_is_canonical | ||
211 | indicates whether | ||
212 | .Fa addrblocks | ||
213 | is in canonical form. | ||
214 | .Sh RETURN VALUES | ||
215 | All these functions return 1 on success and 0 on failure. | ||
216 | Memory allocation failure is one possible reason for all of them. | ||
217 | Sometimes an error code can be obtained by | ||
218 | .Xr ERR_get_error 3 . | ||
219 | .Pp | ||
220 | .Fn X509v3_addr_add_inherit | ||
221 | fails if the list corresponding to | ||
222 | .Fa afi | ||
223 | and the optional | ||
224 | .Fa safi | ||
225 | already exists and is not marked | ||
226 | .Dq inherit . | ||
227 | .Pp | ||
228 | .Fn X509v3_addr_add_prefix | ||
229 | and | ||
230 | .Fn X509v3_addr_add_range | ||
231 | fail if a list corresponding to | ||
232 | .Fa afi | ||
233 | and the optional | ||
234 | .Fa safi | ||
235 | already exists and is marked | ||
236 | .Dq inherit , | ||
237 | or if | ||
238 | .Fa prefixlen | ||
239 | is outside the interval [0,32] for IPv4 addresses | ||
240 | or [0,128] for IPv6 addresses. | ||
241 | .Pp | ||
242 | .Fn X509v3_addr_canonize | ||
243 | fails if one of the lists in | ||
244 | .Fa addrblocks | ||
245 | is malformed, | ||
246 | in particular if it contains corrupt, overlapping, | ||
247 | or duplicate entries. | ||
248 | Corruption includes ranges where | ||
249 | .Fa max | ||
250 | is strictly smaller than | ||
251 | .Fa min . | ||
252 | The error conditions are generally indistinguishable. | ||
253 | .Pp | ||
254 | .Fn X509v3_addr_is_canonical | ||
255 | returns 1 if | ||
256 | .Fa addrblocks | ||
257 | is in canonical form. | ||
258 | A return value of 0 can indicate non-canonical form or a corrupted list. | ||
259 | .Sh EXAMPLES | ||
260 | Construct the first extension from RFC 3779, Appendix B. | ||
261 | .Bd -literal | ||
262 | #include <sys/socket.h> | ||
263 | #include <arpa/inet.h> | ||
264 | |||
265 | #include <err.h> | ||
266 | #include <stdio.h> | ||
267 | #include <unistd.h> | ||
268 | |||
269 | #include <openssl/asn1.h> | ||
270 | #include <openssl/objects.h> | ||
271 | #include <openssl/x509.h> | ||
272 | #include <openssl/x509v3.h> | ||
273 | |||
274 | const char *prefixes[] = { | ||
275 | "10.0.32/20", "10.0.64/24", "10.1/16", | ||
276 | "10.2.48/20", "10.2.64/24", "10.3/16", | ||
277 | }; | ||
278 | #define N_PREFIXES (sizeof(prefixes) / sizeof(prefixes[0])) | ||
279 | |||
280 | static void | ||
281 | hexdump(const unsigned char *buf, size_t len) | ||
282 | { | ||
283 | size_t i; | ||
284 | |||
285 | for (i = 1; i <= len; i++) | ||
286 | printf(" 0x%02x,%s", buf[i \- 1], i % 8 ? "" : "\en"); | ||
287 | if (len % 8) | ||
288 | printf("\en"); | ||
289 | } | ||
290 | |||
291 | int | ||
292 | main(void) | ||
293 | { | ||
294 | IPAddrBlocks *addrblocks; | ||
295 | X509_EXTENSION *ext; | ||
296 | unsigned char *der; | ||
297 | int der_len; | ||
298 | size_t i; | ||
299 | |||
300 | if (pledge("stdio", NULL) == \-1) | ||
301 | err(1, "pledge"); | ||
302 | |||
303 | /* | ||
304 | * Somebody forgot to implement IPAddrBlocks_new(). IPAddrBlocks | ||
305 | * is the same as STACK_OF(IPAddressFamily). As such, it should | ||
306 | * have IPAddressFamily_cmp() as its comparison function. It is | ||
307 | * not possible to call sk_new(3) because IPAddressFamily_cmp() | ||
308 | * is not part of the public API. The correct comparison function | ||
309 | * can be installed as a side-effect of X509v3_addr_canonize(3). | ||
310 | */ | ||
311 | if ((addrblocks = sk_IPAddressFamily_new_null()) == NULL) | ||
312 | err(1, "sk_IPAddressFamily_new_null"); | ||
313 | if (!X509v3_addr_canonize(addrblocks)) | ||
314 | errx(1, "X509v3_addr_canonize"); | ||
315 | |||
316 | /* Add the prefixes as IPv4 unicast. */ | ||
317 | for (i = 0; i < N_PREFIXES; i++) { | ||
318 | unsigned char addr[16] = {0}; | ||
319 | int len; | ||
320 | int unicast = 1; /* SAFI for unicast forwarding. */ | ||
321 | |||
322 | len = inet_net_pton(AF_INET, prefixes[i], addr, | ||
323 | sizeof(addr)); | ||
324 | if (len == \-1) | ||
325 | errx(1, "inet_net_pton(%s)", prefixes[i]); | ||
326 | if (!X509v3_addr_add_prefix(addrblocks, IANA_AFI_IPV4, | ||
327 | &unicast, addr, len)) | ||
328 | errx(1, "X509v3_addr_add_prefix(%s)", prefixes[i]); | ||
329 | } | ||
330 | if (!X509v3_addr_add_inherit(addrblocks, IANA_AFI_IPV6, NULL)) | ||
331 | errx(1, "X509v3_addr_add_inherit"); | ||
332 | |||
333 | /* | ||
334 | * Ensure the extension is in canonical form. Otherwise the two | ||
335 | * adjacent prefixes 10.2.48/20 and 10.2.64/24 are not merged into | ||
336 | * the range 10.2.48.0--10.2.64.255. This results in invalid DER | ||
337 | * encoding from X509V3_EXT_i2d(3) and i2d_X509_EXTENSION(3). | ||
338 | */ | ||
339 | if (!X509v3_addr_canonize(addrblocks)) | ||
340 | errx(1, "X509v3_addr_canonize"); | ||
341 | |||
342 | /* Create the extension with the correct OID; mark it critical. */ | ||
343 | ext = X509V3_EXT_i2d(NID_sbgp_ipAddrBlock, 1, addrblocks); | ||
344 | if (ext == NULL) | ||
345 | errx(1, "X509V3_EXT_i2d"); | ||
346 | |||
347 | der = NULL; | ||
348 | if ((der_len = i2d_X509_EXTENSION(ext, &der)) <= 0) | ||
349 | errx(1, "i2d_X509_EXTENSION"); | ||
350 | |||
351 | hexdump(der, der_len); | ||
352 | |||
353 | /* One way of implementing IPAddrBlocks_free(). */ | ||
354 | sk_IPAddressFamily_pop_free(addrblocks, IPAddressFamily_free); | ||
355 | X509_EXTENSION_free(ext); | ||
356 | free(der); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | .Ed | ||
361 | .Pp | ||
362 | Implement the missing public API | ||
363 | .Fn d2i_IPAddrBlocks | ||
364 | and | ||
365 | .Fn i2d_IPAddrBlocks | ||
366 | using | ||
367 | .Xr ASN1_item_d2i 3 : | ||
368 | .Bd -literal | ||
369 | IPAddrBlocks * | ||
370 | d2i_IPAddrBlocks(IPAddrBlocks **addrblocks, const unsigned char **in, | ||
371 | long len) | ||
372 | { | ||
373 | const X509V3_EXT_METHOD *v3_addr; | ||
374 | |||
375 | if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL) | ||
376 | return NULL; | ||
377 | return (IPAddrBlocks *)ASN1_item_d2i((ASN1_VALUE **)addrblocks, | ||
378 | in, len, ASN1_ITEM_ptr(v3_addr\->it)); | ||
379 | } | ||
380 | |||
381 | int | ||
382 | i2d_IPAddrBlocks(IPAddrBlocks *addrblocks, unsigned char **out) | ||
383 | { | ||
384 | const X509V3_EXT_METHOD *v3_addr; | ||
385 | |||
386 | if ((v3_addr = X509V3_EXT_get_nid(NID_sbgp_ipAddrBlock)) == NULL) | ||
387 | return \-1; | ||
388 | return ASN1_item_i2d((ASN1_VALUE *)addrblocks, out, | ||
389 | ASN1_ITEM_ptr(v3_addr\->it)); | ||
390 | } | ||
391 | .Ed | ||
392 | .Pp | ||
393 | The use of the undocumented macro | ||
394 | .Dv ASN1_ITEM_ptr() | ||
395 | is necessary if compatibility with modern versions of other implementations | ||
396 | is desired. | ||
397 | .Sh SEE ALSO | ||
398 | .Xr ASIdentifiers_new 3 , | ||
399 | .Xr crypto 3 , | ||
400 | .Xr inet_net_ntop 3 , | ||
401 | .Xr inet_ntop 3 , | ||
402 | .Xr IPAddressRange_new 3 , | ||
403 | .Xr X509_new 3 , | ||
404 | .Xr X509v3_addr_get_range 3 , | ||
405 | .Xr X509v3_addr_validate_path 3 , | ||
406 | .Xr X509v3_asid_add_id_or_range 3 | ||
407 | .Sh STANDARDS | ||
408 | RFC 3779: X.509 Extensions for IP Addresses and AS Identifiers: | ||
409 | .Bl -dash -compact | ||
410 | .It | ||
411 | section 2: IP Address delegation extension | ||
412 | .El | ||
413 | .Pp | ||
414 | RFC 7020: The Internet Numbers Registry System | ||
415 | .Pp | ||
416 | RFC 7249: Internet Number Registries | ||
417 | .Pp | ||
418 | .Rs | ||
419 | .%T Address Family Numbers | ||
420 | .%U https://www.iana.org/assignments/address\-family\-numbers | ||
421 | .Re | ||
422 | .Pp | ||
423 | .Rs | ||
424 | .%T Subsequent Address Family Identifiers (SAFI) Parameters | ||
425 | .%U https://www.iana.org/assignments/safi\-namespace | ||
426 | .Re | ||
427 | .Sh HISTORY | ||
428 | These functions first appeared in OpenSSL 0.9.8e | ||
429 | and have been available since | ||
430 | .Ox 7.1 . | ||
431 | .Sh BUGS | ||
432 | .Fn IPAddrBlocks_new , | ||
433 | .Fn IPAddrBlocks_free , | ||
434 | .Fn d2i_IPAddrBlocks , | ||
435 | and | ||
436 | .Fn i2d_IPAddrBlocks | ||
437 | do not exist and | ||
438 | .Fa IPAddrBlocks_it | ||
439 | is not public. | ||
440 | The above examples show how to implement the four missing functions | ||
441 | with public API. | ||
442 | .Pp | ||
443 | .Fn X509v3_addr_add_range | ||
444 | should check for inverted range bounds and overlaps | ||
445 | on insertion and fail instead of creating a nonsensical | ||
446 | .Fa addrblocks | ||
447 | that fails to be canonized by | ||
448 | .Fn X509v3_addr_canonize . | ||
449 | .Pp | ||
450 | If | ||
451 | .Dv NULL | ||
452 | is passed to | ||
453 | .Xr X509v3_asid_canonize 3 , | ||
454 | it succeeds. | ||
455 | .Fn X509v3_addr_is_canonical | ||
456 | considers | ||
457 | .Dv NULL | ||
458 | to be a canonical | ||
459 | .Vt IPAddrBlocks . | ||
460 | In contrast, | ||
461 | .Fn X509v3_addr_canonize | ||
462 | crashes with a | ||
463 | .Dv NULL | ||
464 | dereference. | ||
465 | .Pp | ||
466 | The code only supports the IPv4 and IPv6 AFIs. | ||
467 | This is not consistently enforced across implementations. | ||
468 | .Pp | ||
469 | .Fn X509v3_addr_add_range | ||
470 | fails to clear the unused bits set to 1 in the last octet of | ||
471 | the | ||
472 | .Vt ASN1_BIT_STRING | ||
473 | representation of | ||
474 | .Fa max . | ||
475 | This confuses some software. | ||