1.\" $OpenBSD: X509_STORE_CTX_set_verify_cb.3,v 1.12 2023/05/30 07:37:34 op Exp $
2.\" full merge up to: OpenSSL aebb9aac Jul 19 09:27:53 2016 -0400
3.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100
4.\"
5.\" This file is a derived work.
6.\" The changes are covered by the following Copyright and license:
7.\"
8.\" Copyright (c) 2021 Ingo Schwarze <schwarze@openbsd.org>
9.\"
10.\" Permission to use, copy, modify, and distribute this software for any
11.\" purpose with or without fee is hereby granted, provided that the above
12.\" copyright notice and this permission notice appear in all copies.
13.\"
14.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21.\"
22.\" The original file was written by Dr. Stephen Henson <steve@openssl.org>.
23.\" Copyright (c) 2009 The OpenSSL Project.  All rights reserved.
24.\"
25.\" Redistribution and use in source and binary forms, with or without
26.\" modification, are permitted provided that the following conditions
27.\" are met:
28.\"
29.\" 1. Redistributions of source code must retain the above copyright
30.\"    notice, this list of conditions and the following disclaimer.
31.\"
32.\" 2. Redistributions in binary form must reproduce the above copyright
33.\"    notice, this list of conditions and the following disclaimer in
34.\"    the documentation and/or other materials provided with the
35.\"    distribution.
36.\"
37.\" 3. All advertising materials mentioning features or use of this
38.\"    software must display the following acknowledgment:
39.\"    "This product includes software developed by the OpenSSL Project
40.\"    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
41.\"
42.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
43.\"    endorse or promote products derived from this software without
44.\"    prior written permission. For written permission, please contact
45.\"    openssl-core@openssl.org.
46.\"
47.\" 5. Products derived from this software may not be called "OpenSSL"
48.\"    nor may "OpenSSL" appear in their names without prior written
49.\"    permission of the OpenSSL Project.
50.\"
51.\" 6. Redistributions of any form whatsoever must retain the following
52.\"    acknowledgment:
53.\"    "This product includes software developed by the OpenSSL Project
54.\"    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
55.\"
56.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
57.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
59.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
60.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
61.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
62.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
65.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
66.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
67.\" OF THE POSSIBILITY OF SUCH DAMAGE.
68.\"
69.Dd $Mdocdate: May 30 2023 $
70.Dt X509_STORE_CTX_SET_VERIFY_CB 3
71.Os
72.Sh NAME
73.Nm X509_STORE_CTX_verify_cb ,
74.Nm X509_STORE_CTX_set_verify_cb ,
75.Nm X509_STORE_CTX_get_verify_cb
76.Nd set and retrieve verification callback
77.Sh SYNOPSIS
78.In openssl/x509_vfy.h
79.Ft typedef int
80.Fo (*X509_STORE_CTX_verify_cb)
81.Fa "int ok"
82.Fa "X509_STORE_CTX *ctx"
83.Fc
84.Ft void
85.Fo X509_STORE_CTX_set_verify_cb
86.Fa "X509_STORE_CTX *ctx"
87.Fa "X509_STORE_CTX_verify_cb verify_cb"
88.Fc
89.Ft X509_STORE_CTX_verify_cb
90.Fo X509_STORE_CTX_get_verify_cb
91.Fa "X509_STORE_CTX *ctx"
92.Fc
93.Sh DESCRIPTION
94.Fn X509_STORE_CTX_set_verify_cb
95sets the verification callback of
96.Fa ctx
97to
98.Fa verify_cb
99overwriting any existing callback.
100.Pp
101The verification callback can be used to modify the operation of
102certificate verification, either by overriding error conditions or
103logging errors for debugging purposes.
104The use of a verification callback is not essential, and should not
105be used in security sensitive programs.
106.Pp
107Do not use this function.
108It is extremely fragile and unpredictable.
109This callback exposes implementation details of certificate verification,
110which change as the library evolves.
111Attempting to use it for security checks can introduce vulnerabilities if
112making incorrect assumptions about when the callback is called.
113Additionally, overriding
114.Fa ok
115may leave
116.Fa ctx
117in an inconsistent state and break invariants.
118.Pp
119Instead, customize certificate verification by configuring options on the
120.Vt X509_STORE_CTX
121before verification, or applying additional checks after
122.Xr X509_verify_cert 3
123completes successfully.
124.Pp
125The
126.Fa ok
127parameter to the callback indicates the value the callback should return
128to retain the default behaviour.
129If it is zero then an error condition is indicated.
130If it is 1 then no error occurred.
131As the default behaviour is internal to the verifier, and possibly unknown
132to the caller, changing this parameter is inherently dangerous and should not
133normally be done except for debugging purposes, and should not be expected to
134be consistent if the verifier changes.
135If the flag
136.Dv X509_V_FLAG_NOTIFY_POLICY
137is set, then
138.Fa ok
139is set to 2 to indicate the policy checking is complete.
140.Pp
141The
142.Fa ctx
143parameter to the callback is the
144.Vt X509_STORE_CTX
145structure that is performing the verification operation.
146A callback can examine this structure and receive additional information
147about the error, for example by calling
148.Xr X509_STORE_CTX_get_current_cert 3 .
149Additional application data can be passed to the callback via the
150.Sy ex_data
151mechanism.
152.Pp
153The verification callback can be set and inherited from the parent
154structure performing the operation.
155In some cases (such as S/MIME verification) the
156.Vt X509_STORE_CTX
157structure is created and destroyed internally and the only way to set a
158custom verification callback is by inheriting it from the associated
159.Vt X509_STORE .
160.Sh RETURN VALUES
161.Fn X509_STORE_CTX_get_verify_cb
162returns a pointer to the current callback function
163used by the specified
164.Fa ctx .
165If no callback was set using
166.Fn X509_STORE_CTX_set_verify_cb ,
167that is a pointer to a built-in static function
168which does nothing except returning the
169.Fa ok
170argument passed to it.
171.Sh EXAMPLES
172Default callback operation:
173.Bd -literal
174int
175verify_callback(int ok, X509_STORE_CTX *ctx)
176{
177	return ok;
178}
179.Ed
180.Pp
181This is likely the only safe callback to use.
182.Pp
183Simple and terrible example that should not be used.
184Suppose a certificate in the chain is expired and we
185wish to continue after this error:
186.Bd -literal
187int
188verify_callback(int ok, X509_STORE_CTX *ctx)
189{
190	/* Tolerate certificate expiration */
191	if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED)
192		return 1;
193	/* Otherwise don't override */
194	return ok;
195}
196.Ed
197.Pp
198While this example is presented for historical purposes,
199this is not the correct way to accomplish this.
200The verification flag
201.Dv X509_V_FLAG_NO_CHECK_TIME
202should be set on the
203.Vt STORE_CTX
204using
205.Xr X509_VERIFY_PARAM_set_flags 3
206instead.
207.Pp
208Full featured debugging logging callback - note that the output and
209order that things happen from this can change over time and should not
210be parsed or expected to be consistent.
211In this case the
212.Fa bio_err
213is assumed to be a global logging
214.Vt BIO ,
215an alternative would to store a
216.Vt BIO
217in
218.Fa ctx
219using
220.Sy ex_data .
221.Bd -literal
222int
223verify_callback(int ok, X509_STORE_CTX *ctx)
224{
225	X509 *err_cert;
226	int err,depth;
227
228	err_cert = X509_STORE_CTX_get_current_cert(ctx);
229	err =	X509_STORE_CTX_get_error(ctx);
230	depth =	X509_STORE_CTX_get_error_depth(ctx);
231
232	BIO_printf(bio_err,"depth=%d ",depth);
233	if (err_cert) {
234		X509_NAME_print_ex(bio_err,
235		    X509_get_subject_name(err_cert), 0,
236		    XN_FLAG_ONELINE);
237		BIO_puts(bio_err, "\en");
238	} else
239		BIO_puts(bio_err, "<no cert>\en");
240	if (!ok)
241		BIO_printf(bio_err, "verify error:num=%d:%s\en",
242		    err, X509_verify_cert_error_string(err));
243	switch (err) {
244	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
245		BIO_puts(bio_err, "issuer= ");
246		X509_NAME_print_ex(bio_err,
247		    X509_get_issuer_name(err_cert), 0,
248		    XN_FLAG_ONELINE);
249		BIO_puts(bio_err, "\en");
250		break;
251	case X509_V_ERR_CERT_NOT_YET_VALID:
252	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
253		BIO_printf(bio_err, "notBefore=");
254		ASN1_TIME_print(bio_err,
255		    X509_get_notBefore(err_cert));
256		BIO_printf(bio_err, "\en");
257		break;
258	case X509_V_ERR_CERT_HAS_EXPIRED:
259	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
260		BIO_printf(bio_err, "notAfter=");
261		ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert));
262		BIO_printf(bio_err, "\en");
263		break;
264	case X509_V_ERR_NO_EXPLICIT_POLICY:
265		policies_print(bio_err, ctx);
266		break;
267	}
268	if (err == X509_V_OK && ok == 2)
269		/* print out policies */
270
271	BIO_printf(bio_err,"verify return:%d\en",ok);
272	return(ok);
273}
274.Ed
275.Sh SEE ALSO
276.Xr X509_STORE_CTX_get_error 3 ,
277.Xr X509_STORE_CTX_get_ex_new_index 3 ,
278.Xr X509_STORE_CTX_new 3 ,
279.Xr X509_STORE_CTX_set_error 3 ,
280.Xr X509_STORE_CTX_set_flags 3 ,
281.Xr X509_STORE_CTX_set_verify 3 ,
282.Xr X509_STORE_set_verify_cb 3 ,
283.Xr X509_verify_cert 3 ,
284.Xr X509_VERIFY_PARAM_set_flags 3
285.Sh HISTORY
286.Fn X509_STORE_CTX_set_verify_cb
287first appeared in OpenSSL 0.9.6c and has been available since
288.Ox 3.2 .
289.Pp
290.Fn X509_STORE_CTX_get_verify_cb
291first appeared in OpenSSL 1.1.0 and has been available since
292.Ox 7.1 .
293.Pp
294.Fn X509_STORE_CTX_verify_cb
295first appeared in OpenSSL 1.1.0 and has been available since
296.Ox 7.2 .
297.Sh CAVEATS
298In general a verification callback should
299.Sy NOT
300return a changed value of
301.Fa ok
302because this can allow the verification to appear to succeed
303in an unpredictable way.
304This can effectively remove all security from the application because
305untrusted or invalid certificates may be accepted.
306Doing this can possibly make
307.Xr X509_verify_cert 3
308return what appears to be a validated chain of certificates that has not
309been validated or even had the signatures checked.
310