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