Default callback operation:
int verify_callback(int ok, X509_STORE_CTX *ctx)
{
return ok;
}
Simple example, suppose a certificate in the chain is expired and we wish to continue after this error:
int verify_callback(int ok, X509_STORE_CTX *ctx)
{
/* Tolerate certificate expiration */
if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_CERT_HAS_EXPIRED)
return 1;
/* Otherwise don't override */
return ok;
}
More complex example, we don't wish to continue after any certificate has expired just one specific case:
int verify_callback(int ok, X509_STORE_CTX *ctx)
{
int err = X509_STORE_CTX_get_error(ctx);
X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx);
if (err == X509_V_ERR_CERT_HAS_EXPIRED)
{
if (check_is_acceptable_expired_cert(err_cert)
return 1;
}
return ok;
}
Full featured logging callback. In this case the bio_err is assumed to be a global logging BIO, an alternative would to store a BIO in ctx using ex_data.
int verify_callback(int ok, X509_STORE_CTX *ctx)
{
X509 *err_cert;
int err,depth;
err_cert = X509_STORE_CTX_get_current_cert(ctx);
err = X509_STORE_CTX_get_error(ctx);
depth = X509_STORE_CTX_get_error_depth(ctx);
BIO_printf(bio_err,"depth=%d ",depth);
if (err_cert)
{
X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
0, XN_FLAG_ONELINE);
BIO_puts(bio_err, "\n");
}
else
BIO_puts(bio_err, "<no cert>\n");
if (!ok)
BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
X509_verify_cert_error_string(err));
switch (err)
{
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
BIO_puts(bio_err,"issuer= ");
X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
0, XN_FLAG_ONELINE);
BIO_puts(bio_err, "\n");
break;
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
BIO_printf(bio_err,"notBefore=");
ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert));
BIO_printf(bio_err,"\n");
break;
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
BIO_printf(bio_err,"notAfter=");
ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert));
BIO_printf(bio_err,"\n");
break;
case X509_V_ERR_NO_EXPLICIT_POLICY:
policies_print(bio_err, ctx);
break;
}
if (err == X509_V_OK && ok == 2)
/* print out policies */
BIO_printf(bio_err,"verify return:%d\n",ok);
return(ok);
}