xref: /openbsd-src/lib/libcrypto/man/ASN1_item_d2i.3 (revision de401f90b0cb4204d067ec72a696e6e107c48965)
1*de401f90Stb.\" $OpenBSD: ASN1_item_d2i.3,v 1.18 2023/05/01 07:37:45 tb Exp $
25f8f3622Sschwarze.\" selective merge up to:
35f8f3622Sschwarze.\" OpenSSL doc/man3/d2i_X509.pod 256989ce Jun 19 15:00:32 2020 +0200
4268393fdSschwarze.\"
5268393fdSschwarze.\" This file is a derived work.
6268393fdSschwarze.\" The changes are covered by the following Copyright and license:
7268393fdSschwarze.\"
85f9d48b0Sschwarze.\" Copyright (c) 2016, 2021 Ingo Schwarze <schwarze@openbsd.org>
9268393fdSschwarze.\"
10268393fdSschwarze.\" Permission to use, copy, modify, and distribute this software for any
11268393fdSschwarze.\" purpose with or without fee is hereby granted, provided that the above
12268393fdSschwarze.\" copyright notice and this permission notice appear in all copies.
13268393fdSschwarze.\"
14268393fdSschwarze.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15268393fdSschwarze.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16268393fdSschwarze.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17268393fdSschwarze.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18268393fdSschwarze.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19268393fdSschwarze.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20268393fdSschwarze.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21268393fdSschwarze.\"
22268393fdSschwarze.\" The original file was written by Dr. Stephen Henson <steve@openssl.org>.
23268393fdSschwarze.\" Copyright (c) 2002, 2003, 2015 The OpenSSL Project.  All rights reserved.
24268393fdSschwarze.\"
25268393fdSschwarze.\" Redistribution and use in source and binary forms, with or without
26268393fdSschwarze.\" modification, are permitted provided that the following conditions
27268393fdSschwarze.\" are met:
28268393fdSschwarze.\"
29268393fdSschwarze.\" 1. Redistributions of source code must retain the above copyright
30268393fdSschwarze.\"    notice, this list of conditions and the following disclaimer.
31268393fdSschwarze.\"
32268393fdSschwarze.\" 2. Redistributions in binary form must reproduce the above copyright
33268393fdSschwarze.\"    notice, this list of conditions and the following disclaimer in
34268393fdSschwarze.\"    the documentation and/or other materials provided with the
35268393fdSschwarze.\"    distribution.
36268393fdSschwarze.\"
37268393fdSschwarze.\" 3. All advertising materials mentioning features or use of this
38268393fdSschwarze.\"    software must display the following acknowledgment:
39268393fdSschwarze.\"    "This product includes software developed by the OpenSSL Project
40268393fdSschwarze.\"    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
41268393fdSschwarze.\"
42268393fdSschwarze.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
43268393fdSschwarze.\"    endorse or promote products derived from this software without
44268393fdSschwarze.\"    prior written permission. For written permission, please contact
45268393fdSschwarze.\"    openssl-core@openssl.org.
46268393fdSschwarze.\"
47268393fdSschwarze.\" 5. Products derived from this software may not be called "OpenSSL"
48268393fdSschwarze.\"    nor may "OpenSSL" appear in their names without prior written
49268393fdSschwarze.\"    permission of the OpenSSL Project.
50268393fdSschwarze.\"
51268393fdSschwarze.\" 6. Redistributions of any form whatsoever must retain the following
52268393fdSschwarze.\"    acknowledgment:
53268393fdSschwarze.\"    "This product includes software developed by the OpenSSL Project
54268393fdSschwarze.\"    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
55268393fdSschwarze.\"
56268393fdSschwarze.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
57268393fdSschwarze.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58268393fdSschwarze.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
59268393fdSschwarze.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
60268393fdSschwarze.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
61268393fdSschwarze.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
62268393fdSschwarze.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63268393fdSschwarze.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64268393fdSschwarze.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
65268393fdSschwarze.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
66268393fdSschwarze.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
67268393fdSschwarze.\" OF THE POSSIBILITY OF SUCH DAMAGE.
68268393fdSschwarze.\"
69*de401f90Stb.Dd $Mdocdate: May 1 2023 $
70268393fdSschwarze.Dt ASN1_ITEM_D2I 3
71268393fdSschwarze.Os
72268393fdSschwarze.Sh NAME
73268393fdSschwarze.Nm ASN1_item_d2i ,
74268393fdSschwarze.Nm ASN1_item_d2i_bio ,
75268393fdSschwarze.Nm ASN1_item_d2i_fp ,
7687ac4493Sschwarze.Nm d2i_ASN1_TYPE ,
77268393fdSschwarze.Nm ASN1_item_i2d ,
78268393fdSschwarze.Nm ASN1_item_i2d_bio ,
79268393fdSschwarze.Nm ASN1_item_i2d_fp ,
8087ac4493Sschwarze.Nm i2d_ASN1_TYPE ,
81268393fdSschwarze.Nm ASN1_item_dup ,
82268393fdSschwarze.Nm ASN1_item_print
83268393fdSschwarze.Nd decode and encode ASN.1 objects
84268393fdSschwarze.Sh SYNOPSIS
85268393fdSschwarze.In openssl/asn1.h
86268393fdSschwarze.Ft ASN1_VALUE *
87268393fdSschwarze.Fo ASN1_item_d2i
88268393fdSschwarze.Fa "ASN1_VALUE **val_out"
89268393fdSschwarze.Fa "const unsigned char **der_in"
90268393fdSschwarze.Fa "long length"
91268393fdSschwarze.Fa "const ASN1_ITEM *it"
92268393fdSschwarze.Fc
93268393fdSschwarze.Ft void *
94268393fdSschwarze.Fo ASN1_item_d2i_bio
95268393fdSschwarze.Fa "const ASN1_ITEM *it"
96268393fdSschwarze.Fa "BIO *in_bio"
97268393fdSschwarze.Fa "void *val_out"
98268393fdSschwarze.Fc
99268393fdSschwarze.Ft void *
100268393fdSschwarze.Fo ASN1_item_d2i_fp
101268393fdSschwarze.Fa "const ASN1_ITEM *it"
102268393fdSschwarze.Fa "FILE *in_fp"
103268393fdSschwarze.Fa "void *val_out"
104268393fdSschwarze.Fc
10587ac4493Sschwarze.Ft ASN1_TYPE *
10687ac4493Sschwarze.Fo d2i_ASN1_TYPE
10787ac4493Sschwarze.Fa "ASN1_TYPE **val_out"
10887ac4493Sschwarze.Fa "const unsigned char **der_in"
10987ac4493Sschwarze.Fa "long length"
11087ac4493Sschwarze.Fc
111268393fdSschwarze.Ft int
112268393fdSschwarze.Fo ASN1_item_i2d
113268393fdSschwarze.Fa "ASN1_VALUE *val_in"
114268393fdSschwarze.Fa "unsigned char **der_out"
115268393fdSschwarze.Fa "const ASN1_ITEM *it"
116268393fdSschwarze.Fc
117268393fdSschwarze.Ft int
118268393fdSschwarze.Fo ASN1_item_i2d_bio
119268393fdSschwarze.Fa "const ASN1_ITEM *it"
120268393fdSschwarze.Fa "BIO *out_bio"
121268393fdSschwarze.Fa "void *val_in"
122268393fdSschwarze.Fc
123268393fdSschwarze.Ft int
124268393fdSschwarze.Fo ASN1_item_i2d_fp
125268393fdSschwarze.Fa "const ASN1_ITEM *it"
126268393fdSschwarze.Fa "FILE *out_fp"
127268393fdSschwarze.Fa "void *val_in"
128268393fdSschwarze.Fc
12987ac4493Sschwarze.Ft int
13087ac4493Sschwarze.Fo i2d_ASN1_TYPE
13187ac4493Sschwarze.Fa "ASN1_TYPE *val_in"
13287ac4493Sschwarze.Fa "unsigned char **der_out"
13387ac4493Sschwarze.Fc
134268393fdSschwarze.Ft void *
135268393fdSschwarze.Fo ASN1_item_dup
136268393fdSschwarze.Fa "const ASN1_ITEM *it"
137268393fdSschwarze.Fa "void *val_in"
138268393fdSschwarze.Fc
139268393fdSschwarze.Ft int
140268393fdSschwarze.Fo ASN1_item_print
141268393fdSschwarze.Fa "BIO *out_bio"
142268393fdSschwarze.Fa "ASN1_VALUE *val_in"
143268393fdSschwarze.Fa "int indent"
144268393fdSschwarze.Fa "const ASN1_ITEM *it"
145268393fdSschwarze.Fa "const ASN1_PCTX *pctx"
146268393fdSschwarze.Fc
147268393fdSschwarze.Sh DESCRIPTION
14887ac4493SschwarzeThese functions convert ASN.1 values from their BER encoding to
149268393fdSschwarzeinternal C structures
150268393fdSschwarze.Pq Dq d2i
151268393fdSschwarzeand vice versa
152268393fdSschwarze.Pq Dq i2d .
15387ac4493SschwarzeUnlike the C structures which contain pointers to sub-objects, BER
154268393fdSschwarzeis a serialized encoding, suitable for transfer over the network
155268393fdSschwarzeand for storage in a file.
156268393fdSschwarze.Pp
157268393fdSschwarze.Fn ASN1_item_d2i
158c5d247d8Sjsginterprets
159268393fdSschwarze.Pf * Fa der_in
16087ac4493Sschwarzeas a DER- or BER-encoded byte array and decodes one value of type
16187ac4493Sschwarze.Fa it
16287ac4493Sschwarzerepresented by up to
163268393fdSschwarze.Fa length
164268393fdSschwarzebytes.
165268393fdSschwarzeIf successful,
166268393fdSschwarze.Pf * Fa der_in
167268393fdSschwarzeis advanced to the byte following the parsed data.
168268393fdSschwarze.Pp
169268393fdSschwarzeIf decoding succeeds and
170efcd3f34Sschwarze.Fa val_out
171efcd3f34Sschwarzeor
172268393fdSschwarze.Pf * Fa val_out
173268393fdSschwarzeis
174268393fdSschwarze.Dv NULL ,
175268393fdSschwarzea new object is allocated.
176268393fdSschwarze.Pp
177268393fdSschwarzeIf decoding succeeds and
178268393fdSschwarze.Pf * Fa val_out
179268393fdSschwarzeis not
180268393fdSschwarze.Dv NULL ,
181268393fdSschwarzeit is assumed to point to a valid populated object and an attempt
182268393fdSschwarzeis made to reuse it.
183268393fdSschwarzeIt must not be an empty structure such as one returned by
184268393fdSschwarze.Xr ASN1_item_new 3
185268393fdSschwarzeor by one of the various type-specific
186268393fdSschwarze.Fn *_new
187268393fdSschwarzefunctions.
188268393fdSschwarzeThis
189268393fdSschwarze.Dq reuse
190268393fdSschwarzecapability is present for backward compatibility, but its use is
191268393fdSschwarzestrongly discouraged; see the
192268393fdSschwarze.Sx BUGS
193268393fdSschwarzesection below.
194268393fdSschwarze.Pp
195268393fdSschwarze.Fn ASN1_item_d2i_bio
196268393fdSschwarzeand
197268393fdSschwarze.Fn ASN1_item_d2i_fp
198268393fdSschwarzeare similar to
199268393fdSschwarze.Fn ASN1_item_d2i
200268393fdSschwarzeexcept that they read from a
201268393fdSschwarze.Vt BIO
202268393fdSschwarzeor
203268393fdSschwarze.Vt FILE ,
204268393fdSschwarzerespectively.
205268393fdSschwarze.Pp
20687ac4493Sschwarze.Fn d2i_ASN1_TYPE
20787ac4493Sschwarzeis similar to
20887ac4493Sschwarze.Fn ASN1_item_d2i
20987ac4493Sschwarzeexcept that it does not require a desired type to be specified by
21087ac4493Sschwarzethe user, but instead returns an
21187ac4493Sschwarze.Vt ASN1_TYPE
21287ac4493Sschwarzewrapper object containing both the type and the value found in the input.
21387ac4493Sschwarze.Pp
214268393fdSschwarze.Fn ASN1_item_i2d
215268393fdSschwarzeencodes the object pointed to by
216268393fdSschwarze.Fa val_in
217268393fdSschwarzeinto DER format.
218efcd3f34Sschwarze.Pp
219268393fdSschwarzeIf
220efcd3f34Sschwarze.Pf * Fa der_out
221268393fdSschwarzeis not
222268393fdSschwarze.Dv NULL ,
223268393fdSschwarzeit writes the DER-encoded data to the buffer at
224268393fdSschwarze.Pf * Fa der_out
225268393fdSschwarzeand increments it to point after the data just written.
226efcd3f34SschwarzeIn this case, it is the responsibility of the user to make sure
227efcd3f34Sschwarzethat the buffer pointed to by
228efcd3f34Sschwarze.Pf * Fa der_out
229c5d247d8Sjsgis long enough, such that no buffer overflow can occur.
230268393fdSschwarze.Pp
231268393fdSschwarzeIf
232268393fdSschwarze.Pf * Fa der_out
233268393fdSschwarzeis
234268393fdSschwarze.Dv NULL ,
235268393fdSschwarzememory is allocated for a buffer, and
236268393fdSschwarze.Pf * Fa der_out
237268393fdSschwarzeis not incremented, but points to the start of the data just written.
238268393fdSschwarze.Pp
239efcd3f34SschwarzeIf
240efcd3f34Sschwarze.Fa der_out
241efcd3f34Sschwarzeis
242efcd3f34Sschwarze.Dv NULL ,
243efcd3f34Sschwarzethe encoded bytes are not written anywhere but discarded.
244efcd3f34SschwarzeFor
245efcd3f34Sschwarze.Fa val_in
246efcd3f34Sschwarzeobjects of variable encoding size, this is sometimes used to first
247efcd3f34Sschwarzefind the number of bytes that will be written.
248efcd3f34SschwarzeThen, a sufficient amount of memory is allocated before calling
249efcd3f34Sschwarze.Fn ASN1_item_i2d
250efcd3f34Sschwarzeagain.
251efcd3f34SschwarzeThis explicit double-call technique is often not needed because the
252efcd3f34Sschwarzeauto-allocation technique described in the previous paragraph can
253efcd3f34Sschwarzebe used.
254efcd3f34Sschwarze.Pp
255268393fdSschwarze.Fn ASN1_item_i2d_bio
256268393fdSschwarzeand
257268393fdSschwarze.Fn ASN1_item_i2d_fp
258268393fdSschwarzeare similar to
259268393fdSschwarze.Fn ASN1_item_i2d
260268393fdSschwarzeexcept that they write to a
261268393fdSschwarze.Vt BIO
262268393fdSschwarzeor
263268393fdSschwarze.Vt FILE ,
264268393fdSschwarzerespectively.
265268393fdSschwarze.Pp
26687ac4493Sschwarze.Fn i2d_ASN1_TYPE
26787ac4493Sschwarzeis similar to
26887ac4493Sschwarze.Fn ASN1_item_i2d
26987ac4493Sschwarzeexcept that the type and the value are not provided separately,
27087ac4493Sschwarzebut in the form of a single
27187ac4493Sschwarze.Vt ASN1_TYPE
27287ac4493Sschwarzeobject.
27387ac4493Sschwarze.Pp
274268393fdSschwarze.Fn ASN1_item_dup
275268393fdSschwarzecreates a deep copy of
276268393fdSschwarze.Fa val_in
277268393fdSschwarzeby calling
278268393fdSschwarze.Fn ASN1_item_i2d
279268393fdSschwarzeand
280268393fdSschwarze.Fn ASN1_item_d2i .
281268393fdSschwarze.Sh RETURN VALUES
282c9f95782SjmcIf successful,
283268393fdSschwarze.Fn ASN1_item_d2i ,
284268393fdSschwarze.Fn ASN1_item_d2i_bio ,
28587ac4493Sschwarze.Fn ASN1_item_d2i_fp ,
286268393fdSschwarzeand
28787ac4493Sschwarze.Fn d2i_ASN1_TYPE
288268393fdSschwarzereturn a pointer to the decoded ASN.1 value.
289268393fdSschwarzeIn addition, if
290268393fdSschwarze.Fa val_out
291268393fdSschwarzeis not
292268393fdSschwarze.Dv NULL ,
293268393fdSschwarzethe pointer is also written to
294268393fdSschwarze.Pf * Fa val_out .
295268393fdSschwarzeIf an error occurs,
296268393fdSschwarze.Dv NULL
297268393fdSschwarzeis returned.
298268393fdSschwarze.Pp
299*de401f90Stb.Fn ASN1_item_i2d
30087ac4493Sschwarzeand
30187ac4493Sschwarze.Fn i2d_ASN1_TYPE
30287ac4493Sschwarzereturn the number of bytes written
303268393fdSschwarzeor a negative value if an error occurs.
304268393fdSschwarze.Pp
305268393fdSschwarze.Fn ASN1_item_i2d_bio
306268393fdSschwarzeand
307268393fdSschwarze.Fn ASN1_item_i2d_fp
308268393fdSschwarzereturn 1 for success or 0 for failure.
309268393fdSschwarze.Pp
310268393fdSschwarze.Fn ASN1_item_dup
311268393fdSschwarzereturns the new
312268393fdSschwarze.Vt ASN1_VALUE
313268393fdSschwarzeobject or
314268393fdSschwarze.Dv NULL
315268393fdSschwarzeif an error occurs.
316268393fdSschwarze.Sh EXAMPLES
317268393fdSschwarzeMany type-specific wrapper functions exist.
318268393fdSschwarzeUsing those wrappers is recommended in application code
319268393fdSschwarzebecause it restores part of the type safety that the low-level
32087ac4493Sschwarzeinterfaces using
32187ac4493Sschwarze.Vt ASN1_VALUE
32287ac4493Sschwarzelack.
323268393fdSschwarze.Pp
324268393fdSschwarzeFor example, to allocate a buffer and write the DER encoding of an
325268393fdSschwarze.Vt X509
326268393fdSschwarzeobject into it:
327268393fdSschwarze.Bd -literal -offset indent
328268393fdSschwarzeX509		*x;
329268393fdSschwarzeunsigned char	*buf;
330268393fdSschwarzeint		 len;
331268393fdSschwarze
332268393fdSschwarzebuf = NULL;
333268393fdSschwarzelen = i2d_X509(x, &buf);
334268393fdSschwarzeif (len < 0)
335268393fdSschwarze	/* error */
336268393fdSschwarze.Ed
337268393fdSschwarze.Pp
338268393fdSschwarzeAttempt to decode a buffer:
339268393fdSschwarze.Bd -literal -offset indent
340268393fdSschwarzeX509			*x;
3415f8f3622Sschwarzeunsigned char		*buf;
3425f8f3622Sschwarzeconst unsigned char	*p;
343268393fdSschwarzeint			 len;
344268393fdSschwarze
345268393fdSschwarze/* Set up buf and len to point to the input buffer. */
346268393fdSschwarzep = buf;
347268393fdSschwarzex = d2i_X509(NULL, &p, len);
348268393fdSschwarzeif (x == NULL)
349268393fdSschwarze	/* error */
350268393fdSschwarze.Ed
351268393fdSschwarze.Pp
352268393fdSschwarzeEquivalent technique:
353268393fdSschwarze.Bd -literal -offset indent
354268393fdSschwarzeX509			*x;
3555f8f3622Sschwarzeunsigned char		*buf;
3565f8f3622Sschwarzeconst unsigned char	*p;
357268393fdSschwarzeint			 len;
358268393fdSschwarze
359268393fdSschwarze/* Set up buf and len to point to the input buffer. */
360268393fdSschwarzep = buf;
361268393fdSschwarzex = NULL;
362268393fdSschwarze
363268393fdSschwarzeif (d2i_X509(&x, &p, len) == NULL)
364268393fdSschwarze	/* error */
365268393fdSschwarze.Ed
366268393fdSschwarze.Sh SEE ALSO
3674a15bab7Sschwarze.Xr ASN1_get_object 3 ,
368a974b571Sschwarze.Xr ASN1_item_digest 3 ,
36987ac4493Sschwarze.Xr ASN1_item_new 3 ,
3707ad55bc0Sschwarze.Xr ASN1_item_pack 3 ,
371a974b571Sschwarze.Xr ASN1_item_sign 3 ,
372a974b571Sschwarze.Xr ASN1_item_verify 3 ,
37387ac4493Sschwarze.Xr ASN1_TYPE_new 3
374483db640Sschwarze.Sh HISTORY
375483db640Sschwarze.Fn d2i_ASN1_TYPE
376483db640Sschwarzeand
377483db640Sschwarze.Fn i2d_ASN1_TYPE
37810e00d17Sschwarzefirst appeared in SSLeay 0.5.1 and have been available since
379483db640Sschwarze.Ox 2.4 .
38080d1afcdSschwarze.Pp
38180d1afcdSschwarze.Fn ASN1_item_d2i ,
38280d1afcdSschwarze.Fn ASN1_item_d2i_bio ,
38380d1afcdSschwarze.Fn ASN1_item_d2i_fp ,
38480d1afcdSschwarze.Fn ASN1_item_i2d ,
38580d1afcdSschwarze.Fn ASN1_item_i2d_bio ,
38680d1afcdSschwarze.Fn ASN1_item_i2d_fp ,
38780d1afcdSschwarzeand
38880d1afcdSschwarze.Fn ASN1_item_dup
38980d1afcdSschwarzefirst appeared in OpenSSL 0.9.7 and have been available since
39080d1afcdSschwarze.Ox 3.2 .
39156929f71Sschwarze.Pp
39256929f71Sschwarze.Fn ASN1_item_print
39356929f71Sschwarzefirst appeared in OpenSSL 1.0.0 and has been available since
39456929f71Sschwarze.Ox 4.9 .
395268393fdSschwarze.Sh CAVEATS
396268393fdSschwarzeIf the type described by
397268393fdSschwarze.Fa it
398268393fdSschwarzefails to match the true type of
399268393fdSschwarze.Fa val_in
400268393fdSschwarzeor
401268393fdSschwarze.Pf * Fa val_out ,
402268393fdSschwarzebuffer overflows and segmentation faults are likely to occur.
403268393fdSschwarzeFor more details about why the type
404268393fdSschwarze.Vt ASN1_VALUE
405268393fdSschwarzeconstitutes dangerous user interface design, see
406268393fdSschwarze.Xr ASN1_item_new 3 .
407268393fdSschwarze.Pp
408268393fdSschwarzeThe encoded data is in binary form and may contain embedded NUL bytes.
409268393fdSschwarzeFunctions such as
410268393fdSschwarze.Xr strlen 3
411268393fdSschwarzewill not return the correct length of the encoded data.
412268393fdSschwarze.Pp
413268393fdSschwarzeWhile the way that
414268393fdSschwarze.Pf * Fa der_in
415268393fdSschwarzeand
416268393fdSschwarze.Pf * Fa der_out
417268393fdSschwarzeare incremented after the operation supports the typical usage
418268393fdSschwarzepatterns of reading or writing one object after another, this
419268393fdSschwarzebehaviour can trap the unwary.
420268393fdSschwarze.Pp
421268393fdSschwarzeUsing a temporary pointer into the buffer is mandatory.
422268393fdSschwarzeA common mistake is to attempt to use a buffer directly as follows:
423268393fdSschwarze.Bd -literal -offset indent
424268393fdSschwarzeX509		*x;
425268393fdSschwarzeunsigned char	*buf;
426268393fdSschwarzeint		 len;
427268393fdSschwarze
428268393fdSschwarzelen = i2d_X509(x, NULL);
429268393fdSschwarzebuf = malloc(len);
430268393fdSschwarzei2d_X509(x, &buf);
431268393fdSschwarze/* do something with buf[] */
432268393fdSschwarzefree(buf);
433268393fdSschwarze.Ed
434268393fdSschwarze.Pp
435268393fdSschwarzeThis code will result in
436268393fdSschwarze.Va buf
437268393fdSschwarzeapparently containing garbage because it was incremented during
438268393fdSschwarze.Fn i2d_X509
439268393fdSschwarzeto point after the data just written.
440268393fdSschwarzeAlso
441268393fdSschwarze.Va buf
442268393fdSschwarzewill no longer contain the pointer allocated by
443268393fdSschwarze.Xr malloc 3
444268393fdSschwarzeand the subsequent call to
445268393fdSschwarze.Xr free 3
446268393fdSschwarzeis likely to crash.
447268393fdSschwarze.Pp
448268393fdSschwarzeAnother trap to avoid is misuse of the
449268393fdSschwarze.Fa val_out
450268393fdSschwarzeargument:
451268393fdSschwarze.Bd -literal -offset indent
452268393fdSschwarzeX509		*x;
453268393fdSschwarze
454268393fdSschwarzeif (d2i_X509(&x, &p, len) == NULL)
455268393fdSschwarze	/* error */
456268393fdSschwarze.Ed
457268393fdSschwarze.Pp
458268393fdSschwarzeThis will probably crash somewhere in
459268393fdSschwarze.Fn d2i_X509
460268393fdSschwarzebecause
461268393fdSschwarze.Va x
462268393fdSschwarzeis uninitialized and an attempt will be made to interpret its invalid
463268393fdSschwarzecontent as an
464268393fdSschwarze.Vt X509
465268393fdSschwarzeobject, typically causing a segmentation violation.
466268393fdSschwarzeIf
467268393fdSschwarze.Va x
468268393fdSschwarzeis set to
469268393fdSschwarze.Dv NULL
470268393fdSschwarzefirst, then this will not happen.
471268393fdSschwarze.Sh BUGS
472268393fdSschwarzeIf the
473268393fdSschwarze.Dq reuse
474268393fdSschwarzecapability is used, a valid object is passed in via
475268393fdSschwarze.Pf * Fa val_out ,
476268393fdSschwarzeand an error occurs, then the object is not freed and may be left
477268393fdSschwarzein an invalid or inconsistent state.
478268393fdSschwarze.Pp
479268393fdSschwarzeIn some versions of OpenSSL, the
480268393fdSschwarze.Dq reuse
481268393fdSschwarzebehaviour is broken such that some parts of the reused object may
482268393fdSschwarzepersist if they are not present in the new one.
483268393fdSschwarze.Pp
484268393fdSschwarzeIn many versions of OpenSSL,
485268393fdSschwarze.Fn ASN1_item_i2d
486268393fdSschwarzewill not return an error if mandatory fields are not initialized
487268393fdSschwarzedue to a programming error.
488268393fdSschwarzeIn that case, the encoded structure may contain invalid data and
489268393fdSschwarzesome fields may be missing entirely, such that trying to parse it
490268393fdSschwarzewith
491268393fdSschwarze.Fn ASN1_item_d2i
492268393fdSschwarzemay fail.
493