- struct wpabuf *cert;
- cert = get_x509_cert(err_cert);
- if (!cert) {
- wpa_printf(MSG_DEBUG, "tls_verify_cb: OpenSSL: Could not fetch "
- "server certificate data");
- preverify_ok = 0;
- } else {
- u8 hash[32];
- const u8 *addr[1];
- size_t len[1];
- addr[0] = wpabuf_head(cert);
- len[0] = wpabuf_len(cert);
- if (sha256_vector(1, addr, len, hash) < 0 ||
- os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
- err_str = "Server certificate mismatch";
- err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
- preverify_ok = 0;
- } else if (!preverify_ok) {
- /*
- * Certificate matches pinned certificate, allow
- * regardless of other problems.
- */
- wpa_printf(MSG_DEBUG,
- "tls_verify_cb: OpenSSL: Ignore validation issues for a pinned server certificate");
- preverify_ok = 1;
- }
- wpabuf_free(cert);
- }
- }
+ if (depth == 0 && conn->server_cert_cb) {
+ preverify_ok = conn->server_cert_cb(preverify_ok, err_cert, conn->server_cert_ctx);
+ wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb: server_cert_cb returned %d", preverify_ok);
+ }
+ else {
+ /*
+ * Do not require preverify_ok so we can explicity allow otherwise
+ * invalid pinned server certificates.
+ */
+ struct wpabuf *cert;
+ cert = get_x509_cert(err_cert);
+ if (!cert) {
+ wpa_printf(MSG_DEBUG, "tls_verify_cb: OpenSSL: Could not fetch "
+ "server certificate data");
+ preverify_ok = 0;
+ } else {
+ u8 hash[32];
+ const u8 *addr[1];
+ size_t len[1];
+ addr[0] = wpabuf_head(cert);
+ len[0] = wpabuf_len(cert);
+ if (sha256_vector(1, addr, len, hash) < 0 ||
+ os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
+ err_str = "Server certificate mismatch";
+ err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
+ preverify_ok = 0;
+ } else if (!preverify_ok) {
+ /*
+ * Certificate matches pinned certificate, allow
+ * regardless of other problems.
+ */
+ wpa_printf(MSG_DEBUG,
+ "tls_verify_cb: OpenSSL: Ignore validation issues for a pinned server certificate");
+ preverify_ok = 1;
+ }
+ wpabuf_free(cert);
+ }
+ }
+ }