c->cert_cb_arg = arg;
}
+/*
+ * Verify a certificate chain
+ * Return codes:
+ * 1: Verify success
+ * 0: Verify failure or error
+ * -1: Retry required
+ */
int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
{
X509 *x;
if (s->verify_callback)
X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback);
- if (s->ctx->app_verify_callback != NULL)
+ if (s->ctx->app_verify_callback != NULL) {
i = s->ctx->app_verify_callback(ctx, s->ctx->app_verify_arg);
- else
+ } else {
i = X509_verify_cert(ctx);
+ /* We treat an error in the same way as a failure to verify */
+ if (i < 0)
+ i = 0;
+ }
s->verify_result = X509_STORE_CTX_get_error(ctx);
sk_X509_pop_free(s->verified_chain, X509_free);
* (less clean) historic behaviour of performing validation if any flag is
* set. The *documented* interface remains the same.
*/
- if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) {
+ if (s->verify_mode != SSL_VERIFY_NONE && i == 0) {
SSLfatal(s, ssl_x509err2alert(s->verify_result),
SSL_R_CERTIFICATE_VERIFY_FAILED);
return WORK_ERROR;