/* Provenance: openssl/openssl selfsigned_verify_cb (fixed). * repo: openssl/openssl * commit: c2765d53c2649b56bc1ca1bb799e42002953056a * parent: d5030cdf32d6cd27bd964a0cb7aed2b7cb713369 * commit_url: https://github.com/openssl/openssl/commit/c2765d53c2649b56bc1ca1bb799e42002953056a * cve: CVE-2026-42769 * license: Apache-2.0 * function: selfsigned_verify_cb * relpath: crypto/cmp/cmp_genm.c */ static int selfsigned_verify_cb(int ok, X509_STORE_CTX *store_ctx) { if (ok == 0 && X509_STORE_CTX_get_error_depth(store_ctx) == 0 && X509_STORE_CTX_get_error(store_ctx) == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) { /* in this case, custom chain building */ int i; STACK_OF(X509) *trust; STACK_OF(X509) *chain = X509_STORE_CTX_get0_chain(store_ctx); STACK_OF(X509) *untrusted = X509_STORE_CTX_get0_untrusted(store_ctx); X509_STORE_CTX_check_issued_fn check_issued = X509_STORE_CTX_get_check_issued(store_ctx); X509 *cert = sk_X509_value(chain, 0); /* target cert */ X509 *issuer; for (i = 0; i < sk_X509_num(untrusted); i++) { cert = sk_X509_value(untrusted, i); if (!X509_add_cert(chain, cert, X509_ADD_FLAG_UP_REF)) return 0; } trust = X509_STORE_get1_all_certs(X509_STORE_CTX_get0_store(store_ctx)); for (i = 0; i < sk_X509_num(trust); i++) { issuer = sk_X509_value(trust, i); if ((*check_issued)(store_ctx, cert, issuer)) { if (X509_add_cert(chain, issuer, X509_ADD_FLAG_UP_REF)) ok = 1; break; } } sk_X509_pop_free(trust, X509_free); return ok; } else { X509_STORE *ts = X509_STORE_CTX_get0_store(store_ctx); X509_STORE_CTX_verify_cb verify_cb; if (ts == NULL || (verify_cb = X509_STORE_get_verify_cb(ts)) == NULL) return ok; return (*verify_cb)(ok, store_ctx); } }