static int verify_callback(int ok, X509_STORE_CTX *store) { epdata_t *epd = SSL_get_ex_data(X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()), ssl_epd_idx); epd->ssl_verify = ok; return ok; }
static int certVerifyCallback(int ok, X509_STORE_CTX* ctx) { // whether the verification of the certificate in question was passed (preverify_ok=1) or not (preverify_ok=0) unsigned err = X509_STORE_CTX_get_error(ctx); if (!err) return 1; SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); SSL_CTX* sslctx = SSL_get_SSL_CTX(ssl); ResourceHandle* job = reinterpret_cast<ResourceHandle*>(SSL_CTX_get_app_data(sslctx)); String host = job->firstRequest().url().host(); ResourceHandleInternal* d = job->getInternal(); d->m_sslErrors = sslCertificateFlag(err); #if PLATFORM(WIN) HashMap<String, ListHashSet<String>>::iterator it = allowedHosts.find(host); ok = (it != allowedHosts.end()); #else ListHashSet<String> certificates; if (!pemData(ctx, certificates)) return 0; ok = sslIgnoreHTTPSCertificate(host.lower(), certificates); #endif if (ok) { // if the host and the certificate are stored for the current handle that means is enabled, // so don't need to curl verifies the authenticity of the peer's certificate curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, false); } return ok; }
static int my_verify_callback(int ok, X509_STORE_CTX *ctx) { X509 *check_cert; SSL *ssl; MYSQL *mysql; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); mysql= (MYSQL *)SSL_get_app_data(ssl); /* skip verification if no ca_file/path was specified */ if (!mysql->options.ssl_ca && !mysql->options.ssl_capath) { ok= 1; return 1; } if (!ok) { uint depth; if (!(check_cert= X509_STORE_CTX_get_current_cert(ctx))) return 0; depth= X509_STORE_CTX_get_error_depth(ctx); if (depth == 0) ok= 1; } return ok; }
NOEXPORT int cert_check(X509_STORE_CTX *callback_ctx, int preverify_ok) { SSL *ssl=X509_STORE_CTX_get_ex_data(callback_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); CLI *c=SSL_get_ex_data(ssl, cli_index); int depth=X509_STORE_CTX_get_error_depth(callback_ctx); if(preverify_ok) { s_log(LOG_DEBUG, "CERT: preverify ok"); } else { /* remote site sent an invalid certificate */ if(c->opt->verify_level>=4 && depth>0) { s_log(LOG_INFO, "CERT: Invalid CA certificate ignored"); return 1; /* accept */ } else { s_log(LOG_WARNING, "CERT: Verification error: %s", X509_verify_cert_error_string( X509_STORE_CTX_get_error(callback_ctx))); /* retain the STORE_CTX error produced by pre-verification */ return 0; /* reject */ } } if(c->opt->verify_level>=3 && depth==0) if(!cert_check_local(callback_ctx)) return 0; /* reject */ return 1; /* accept */ }
static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) { X509* err_cert; SSL* ssl; int bytes; unsigned char* buf = NULL; if(!preverify_ok) { err_cert = X509_STORE_CTX_get_current_cert(ctx); if(err_cert) { /* * Save the failed certificate for inspection/logging. */ bytes = i2d_X509(err_cert, &buf); if(bytes > 0) { ms_cert_buf* cert_buf = (ms_cert_buf*)malloc(sizeof(ms_cert_buf)); cert_buf->buf = buf; cert_buf->bytes = bytes; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); SSL_set_app_data(ssl, cert_buf); } } } return preverify_ok; }
int tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx) { char buf[CCERT_BUFSIZ]; X509 *cert; int err; int depth; int max_depth; SSL *con; TLS_SESS_STATE *TLScontext; /* May be NULL as of OpenSSL 1.0, thanks for the API change! */ cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); con = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); TLScontext = SSL_get_ex_data(con, TLScontext_index); depth = X509_STORE_CTX_get_error_depth(ctx); /* Don't log the internal root CA unless there's an unexpected error. */ if (ok && TLScontext->tadepth > 0 && depth > TLScontext->tadepth) return (1); /* * Certificate chain depth limit violations are mis-reported by the * OpenSSL library, from SSL_CTX_set_verify(3): * * The certificate verification depth set with SSL[_CTX]_verify_depth() * stops the verification at a certain depth. The error message produced * will be that of an incomplete certificate chain and not * X509_V_ERR_CERT_CHAIN_TOO_LONG as may be expected. * * We set a limit that is one higher than the user requested limit. If this * higher limit is reached, we raise an error even a trusted root CA is * present at this depth. This disambiguates trust chain truncation from * an incomplete trust chain. */ max_depth = SSL_get_verify_depth(con) - 1; /* * We never terminate the SSL handshake in the verification callback, * rather we allow the TLS handshake to continue, but mark the session as * unverified. The application is responsible for closing any sessions * with unverified credentials. */ if (max_depth >= 0 && depth > max_depth) { X509_STORE_CTX_set_error(ctx, err = X509_V_ERR_CERT_CHAIN_TOO_LONG); ok = 0; } if (ok == 0) update_error_state(TLScontext, depth, cert, err); if (TLScontext->log_mask & TLS_LOG_VERBOSE) { if (cert) X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); else strcpy(buf, "<unknown>"); msg_info("%s: depth=%d verify=%d subject=%s", TLScontext->namaddr, depth, ok, printable(buf, '?')); } return (1); }
/** * This callback implements the "continue on error" flag and log the errors. */ static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) { int err; int verify; SSL *ssl; SSL_CTX *ctx; p_context pctx; lua_State *L; /* Short-circuit optimization */ if (preverify_ok) return 1; ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); ctx = SSL_get_SSL_CTX(ssl); pctx = (p_context)SSL_CTX_get_app_data(ctx); L = pctx->L; /* Get verify flags */ luaL_getmetatable(L, "SSL:Verify:Registry"); lua_pushlightuserdata(L, (void*)ctx); lua_gettable(L, -2); verify = (int)lua_tonumber(L, -1); lua_pop(L, 2); /* Remove values from stack */ err = X509_STORE_CTX_get_error(x509_ctx); if (err != X509_V_OK) add_cert_error(L, ssl, err, X509_STORE_CTX_get_error_depth(x509_ctx)); return (verify & LSEC_VERIFY_CONTINUE ? 1 : preverify_ok); }
NOEXPORT int verify_callback(int preverify_ok, X509_STORE_CTX *callback_ctx) { /* our verify callback function */ SSL *ssl; CLI *c; /* retrieve application specific data */ ssl=X509_STORE_CTX_get_ex_data(callback_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); c=SSL_get_ex_data(ssl, cli_index); if(c->opt->verify_level<1) { s_log(LOG_INFO, "Certificate verification disabled"); return 1; /* accept */ } if(verify_checks(preverify_ok, callback_ctx)) return 1; /* accept */ if(c->opt->option.client || c->opt->protocol) return 0; /* reject */ if(c->opt->redirect_addr.num) { /* pre-resolved addresses */ addrlist_dup(&c->connect_addr, &c->opt->redirect_addr); s_log(LOG_INFO, "Redirecting connection"); return 1; /* accept */ } /* delayed lookup */ if(namelist2addrlist(&c->connect_addr, c->opt->redirect_list, DEFAULT_LOOPBACK)) { s_log(LOG_INFO, "Redirecting connection"); return 1; /* accept */ } return 0; /* reject */ }
static int OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { SSL *ssl; int n; struct lws *wsi; union lws_tls_cert_info_results ir; X509 *topcert = X509_STORE_CTX_get_current_cert(x509_ctx); ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); /* * !!! nasty openssl requires the index to come as a library-scope * static */ wsi = SSL_get_ex_data(ssl, openssl_websocket_private_data_index); n = lws_tls_openssl_cert_info(topcert, LWS_TLS_CERT_INFO_COMMON_NAME, &ir, sizeof(ir.ns.name)); if (!n) lwsl_info("%s: client cert CN '%s'\n", __func__, ir.ns.name); else lwsl_info("%s: couldn't get client cert CN\n", __func__); n = wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION, x509_ctx, ssl, preverify_ok); /* convert return code from 0 = OK to 1 = OK */ return !n; }
/*! This is called each time a certificate verification occurs. It allows us to catch failures and report them. */ /* static */ int BSecureSocket::Private::VerifyCallback(int ok, X509_STORE_CTX* ctx) { // OpenSSL already checked the certificate again the certificate store for // us, and tells the result of that in the ok parameter. // If the verification succeeded, no need for any further checks. Let's // proceed with the connection. if (ok) return ok; // The certificate verification failed. Signal this to the BSecureSocket. // First of all, get the affected BSecureSocket SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); BSecureSocket* socket = (BSecureSocket*)SSL_get_ex_data(ssl, sDataIndex); // Get the certificate that we could not validate (this may not be the one // we got from the server, but something higher up in the certificate // chain) X509* x509 = X509_STORE_CTX_get_current_cert(ctx); BCertificate::Private* certificate = new(std::nothrow) BCertificate::Private(x509); if (certificate == NULL) return 0; int error = X509_STORE_CTX_get_error(ctx); const char* message = X509_verify_cert_error_string(error); // Let the BSecureSocket (or subclass) decide if we should continue anyway. BCertificate failedCertificate(certificate); return socket->CertificateVerificationFailed(failedCertificate, message); }
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { int ret = preverify_ok; /* determine the status for the current cert */ X509_STORE_CTX_get_current_cert(ctx); int err = X509_STORE_CTX_get_error(ctx); int depth = X509_STORE_CTX_get_error_depth(ctx); /* conjure the stream & context to use */ SSL *ssl = (SSL*)X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); SSLSocket *stream = (SSLSocket*)SSL_get_ex_data(ssl, SSLSocket::GetSSLExDataIndex()); /* if allow_self_signed is set, make sure that verification succeeds */ if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && stream->getContext()["allow_self_signed"].toBoolean()) { ret = 1; } /* check the depth */ Variant vdepth = stream->getContext()["verify_depth"]; if (vdepth.toBoolean() && depth > vdepth.toInt64()) { ret = 0; X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG); } return ret; }
extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx) { // if the pre verification has failed, then don't bother validating via ruby if (preverify_ok != 1) { return preverify_ok; } unsigned long binding; X509 *cert; SSL *ssl; BUF_MEM *buf; BIO *out; int result; cert = X509_STORE_CTX_get_current_cert(ctx); ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); binding = (unsigned long) SSL_get_ex_data(ssl, 0); out = BIO_new(BIO_s_mem()); PEM_write_bio_X509(out, cert); BIO_write(out, "\0", 1); BIO_get_mem_ptr(out, &buf); ConnectionDescriptor *cd = dynamic_cast <ConnectionDescriptor*> (Bindable_t::GetObject(binding)); result = (cd->VerifySslPeer(buf->data) == true ? 1 : 0); BUF_MEM_free(buf); return result; }
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { printf("*** Verify callback function called\n"); char buf[256]; X509 *err_cert; int err, depth; SSL *ssl; err_cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); /* * Retrieve the pointer to the SSL of the connection currently treated * and the application specific data stored into the SSL object. */ ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); //mydata = SSL_get_ex_data(ssl, mydata_index); X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); /* * Catch a too long certificate chain. The depth limit set using * SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so * that whenever the "depth>verify_depth" condition is met, we * have violated the limit and want to log this error condition. * We must do it here, because the CHAIN_TOO_LONG error would not * be found explicitly; only errors introduced by cutting off the * additional certificates would be logged. */ #if 0 if (depth > mydata->verify_depth) { preverify_ok = 0; err = X509_V_ERR_CERT_CHAIN_TOO_LONG; X509_STORE_CTX_set_error(ctx, err); } #endif if (!preverify_ok) { printf("verify error:num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf); } printf("depth=%d:%s\n", depth, buf); /* * At this point, err contains the last verification error. We can use * it for something special */ if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) { X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); printf("issuer= %s\n", buf); } #if 0 if (mydata->always_continue) return 1; else #endif return preverify_ok; }
static int verify_callback(int ok, X509_STORE_CTX *store) { SSL *ssl; struct stream_fd *sfd; struct packet_stream *ps; struct call_media *media; ssl = X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()); sfd = SSL_get_app_data(ssl); if (sfd->dtls.ssl != ssl) return 0; ps = sfd->stream; if (!ps) return 0; if (PS_ISSET(ps, FINGERPRINT_VERIFIED)) return 1; media = ps->media; if (!media) return 0; if (ps->dtls_cert) X509_free(ps->dtls_cert); ps->dtls_cert = X509_dup(X509_STORE_CTX_get_current_cert(store)); if (!media->fingerprint.hash_func) return 1; /* delay verification */ if (dtls_verify_cert(ps)) return 0; return 1; }
int _mosquitto_server_certificate_verify(int preverify_ok, X509_STORE_CTX *ctx) { /* Preverify should have already checked expiry, revocation. * We need to verify the hostname. */ struct mosquitto *mosq; SSL *ssl; X509 *cert; /* Always reject if preverify_ok has failed. */ if(!preverify_ok) return 0; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); mosq = SSL_get_ex_data(ssl, tls_ex_index_mosq); if(!mosq) return 0; if(mosq->tls_insecure == false){ if(X509_STORE_CTX_get_error_depth(ctx) == 0){ /* FIXME - use X509_check_host() etc. for sufficiently new openssl (>=1.1.x) */ cert = X509_STORE_CTX_get_current_cert(ctx); /* This is the peer certificate, all others are upwards in the chain. */ #if defined(WITH_BROKER) return _mosquitto_verify_certificate_hostname(cert, mosq->bridge->addresses[mosq->bridge->cur_address].address); #else return _mosquitto_verify_certificate_hostname(cert, mosq->host); #endif }else{ return preverify_ok; } }else{ return preverify_ok; } }
static int swSSL_verify_callback(int ok, X509_STORE_CTX *x509_store) { #if 0 char *subject, *issuer; int err, depth; X509 *cert; X509_NAME *sname, *iname; X509_STORE_CTX_get_ex_data(x509_store, SSL_get_ex_data_X509_STORE_CTX_idx()); cert = X509_STORE_CTX_get_current_cert(x509_store); err = X509_STORE_CTX_get_error(x509_store); depth = X509_STORE_CTX_get_error_depth(x509_store); sname = X509_get_subject_name(cert); subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)"; iname = X509_get_issuer_name(cert); issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)"; swWarn("verify:%d, error:%d, depth:%d, subject:\"%s\", issuer:\"%s\"", ok, err, depth, subject, issuer); if (sname) { OPENSSL_free(subject); } if (iname) { OPENSSL_free(issuer); } #endif return 1; }
static int OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { SSL *ssl; int n; struct lws_context *context; struct lws wsi; ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); /* * !!! nasty openssl requires the index to come as a library-scope * static */ context = SSL_get_ex_data(ssl, openssl_websocket_private_data_index); /* * give him a fake wsi with context set, so he can use lws_get_context() * in the callback */ memset(&wsi, 0, sizeof(wsi)); wsi.context = context; n = context->protocols[0].callback(&wsi, LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION, x509_ctx, ssl, preverify_ok); /* convert return code from 0 = OK to 1 = OK */ return !n; }
int _qvd_verify_cert_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { SSL *ssl; SSL_CTX *sslctx; qvdclient *qvd ; ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); sslctx = SSL_get_SSL_CTX(ssl); qvd = SSL_CTX_get_ex_data(sslctx, _qvd_ssl_index); X509 *cert = X509_STORE_CTX_get_current_cert(x509_ctx); int depth = X509_STORE_CTX_get_error_depth(x509_ctx); int err = X509_STORE_CTX_get_error(x509_ctx); /* save the certificate by incrementing the reference count and * keeping a pointer */ if (depth < MAX_CERTS && !certificate[depth]) { certificate[depth] = cert; certificate_error[depth] = err; cert->references++; } /* See http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html# */ if (preverify_ok) { qvd_printf("_qvd_verify_cert_callback: Certificate was validated\n"); return preverify_ok; } if (qvd->ssl_verify_callback == NULL) { qvd_printf("_qvd_verify_cert_callback: No callback specified returning false (specify if you wissh callbacks for unknown certs with qvd_set_unknown_cert_callback)\n"); return 0; } BIO *bio_out = BIO_new(BIO_s_mem()); BUF_MEM *biomem; int result; PEM_write_bio_X509(bio_out, certificate[depth]); BIO_get_mem_ptr(bio_out, &biomem); char cert_info[1024]; char issuer[256], subject[256]; X509_NAME_oneline(X509_get_issuer_name(certificate[depth]), issuer, 256); X509_NAME_oneline(X509_get_subject_name(certificate[depth]), subject, 256); snprintf(cert_info, 1023, "Serial: %lu\n\nIssuer: %s\n\nValidity:\n\tNot before: %s\n\tNot after: %s\n\nSubject: %s\n", ASN1_INTEGER_get(X509_get_serialNumber(certificate[depth])), issuer, X509_get_notBefore(certificate[depth])->data, X509_get_notAfter(cert)->data, subject); cert_info[1023] = '\0'; result = qvd->ssl_verify_callback(qvd, cert_info, biomem->data); if (result) { _qvd_save_certificate(qvd, certificate[depth], depth, biomem); } BIO_free(bio_out); return result; }
static int ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { VALUE cb; SSL *ssl; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx); X509_STORE_CTX_set_ex_data(ctx, ossl_verify_cb_idx, (void*)cb); return ossl_verify_cb(preverify_ok, ctx); }
static int verify_callback(int preverify_ok, X509_STORE_CTX * ctx) { typedef struct { int verbose_mode; int verify_depth; int always_continue; } mydata_t; char buf[256]; X509 *err_cert; int err, depth, mydata_index=0; SSL *ssl; mydata_t *mydata; err_cert = X509_STORE_CTX_get_current_cert(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx ()); err = X509_STORE_CTX_get_error(ctx); fprintf(stderr, " err %i:%s\n", err, X509_verify_cert_error_string(err)); mydata = SSL_get_ex_data(ssl, mydata_index); /* X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); or */ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); printf("issuer= %s\n", buf); err = X509_STORE_CTX_get_error(ctx); fprintf(stderr, "X509_verify_cert_error_string=(%s)\n", X509_verify_cert_error_string(err)); /* Return 1 accept the connection. Return 0 reject the connection This isn't the only place this decision is made to continue. */ preverify_ok = 1; return preverify_ok; }
/* OpenSSL cert verification callback. This is invoked for *each* * error which is encoutered whilst verifying the cert chain; multiple * invocations for any particular cert in the chain are possible. */ static int verify_callback(int ok, X509_STORE_CTX *ctx) { /* OpenSSL, living in its own little happy world of global state, * where userdata was just a twinkle in the eye of an API designer * yet to be born. Or... "Seriously, wtf?" */ SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); ne_session *sess = SSL_get_app_data(ssl); int depth = X509_STORE_CTX_get_error_depth(ctx); int err = X509_STORE_CTX_get_error(ctx); int failures = 0; /* If there's no error, nothing to do here. */ if (ok) return ok; NE_DEBUG(NE_DBG_SSL, "ssl: Verify callback @ %d => %d\n", depth, err); /* Map the error code onto any of the exported cert validation * errors, if possible. */ switch (err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_CERT_UNTRUSTED: case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: failures |= NE_SSL_UNTRUSTED; break; case X509_V_ERR_CERT_NOT_YET_VALID: failures |= depth > 0 ? NE_SSL_BADCHAIN : NE_SSL_NOTYETVALID; break; case X509_V_ERR_CERT_HAS_EXPIRED: failures |= depth > 0 ? NE_SSL_BADCHAIN : NE_SSL_EXPIRED; break; case X509_V_OK: break; default: /* Clear the failures bitmask so check_certificate knows this * is a bailout. */ sess->ssl_context->failures |= NE_SSL_UNHANDLED; NE_DEBUG(NE_DBG_SSL, "ssl: Unhandled verification error %d -> %s\n", err, X509_verify_cert_error_string(err)); return 0; } sess->ssl_context->failures |= failures; NE_DEBUG(NE_DBG_SSL, "ssl: Verify failures |= %d => %d\n", failures, sess->ssl_context->failures); return 1; }
static int tls_verify_cb(int ok, X509_STORE_CTX *store) { if (!ok) { char data[256]; X509 *cert = X509_STORE_CTX_get_current_cert(store); int depth = X509_STORE_CTX_get_error_depth(store); int err = X509_STORE_CTX_get_error(store); int sslidx = SSL_get_ex_data_X509_STORE_CTX_idx(); SSL *ssl = X509_STORE_CTX_get_ex_data(store, sslidx); tls_t *tls = SSL_get_ex_data(ssl, tls_ex_data_idx); assert(tls); #define TLS_VERIFY_CB_CLEAR_ERROR(OK,ERR,STORE) \ do {\ OK = 1;\ ERR = X509_V_OK;\ X509_STORE_CTX_set_error(STORE,ERR);\ } while (0) if (tls->accept && !tls->verify_incoming) TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store); else if (!tls->accept && !tls->verify_outgoing) TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store); else switch (err) { case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_CRL_HAS_EXPIRED: if (!tls->verify_date) TLS_VERIFY_CB_CLEAR_ERROR(ok, err, store); default: break; } if (!ok) { SU_DEBUG_3(("-Error with certificate at depth: %i\n", depth)); X509_NAME_oneline(X509_get_issuer_name(cert), data, 256); SU_DEBUG_3((" issuer = %s\n", data)); X509_NAME_oneline(X509_get_subject_name(cert), data, 256); SU_DEBUG_3((" subject = %s\n", data)); SU_DEBUG_3((" err %i:%s\n", err, X509_verify_cert_error_string(err))); } } return ok; }
bool SSLSocket::verifyKeyprint(const string& expKP, bool allowUntrusted) noexcept { if (!ssl) return true; if (expKP.empty() || expKP.find("/") == string::npos) return allowUntrusted; verifyData.reset(new CryptoManager::SSLVerifyData(allowUntrusted, expKP)); SSL_set_ex_data(ssl, CryptoManager::idxVerifyData, verifyData.get()); SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl); X509_STORE* store = X509_STORE_new(); bool result = false; int err = SSL_get_verify_result(ssl); if (ssl_ctx && store) { X509_STORE_CTX* vrfy_ctx = X509_STORE_CTX_new(); X509* cert = SSL_get_peer_certificate(ssl); if (vrfy_ctx && cert && X509_STORE_CTX_init(vrfy_ctx, store, cert, SSL_get_peer_cert_chain(ssl))) { X509_STORE_CTX_set_ex_data(vrfy_ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), ssl); X509_STORE_CTX_set_verify_cb(vrfy_ctx, SSL_CTX_get_verify_callback(ssl_ctx)); int verify_result = 0; if ((verify_result = X509_verify_cert(vrfy_ctx)) >= 0) { err = X509_STORE_CTX_get_error(vrfy_ctx); // Watch out for weird library errors that might not set the context error code if (err == X509_V_OK && verify_result <= 0) err = X509_V_ERR_UNSPECIFIED; // This is for people who don't restart their clients and have low expiration time on their cert result = (err == X509_V_OK || err == X509_V_ERR_CERT_HAS_EXPIRED) || (allowUntrusted && err != X509_V_ERR_APPLICATION_VERIFICATION); } } if (cert) X509_free(cert); if (vrfy_ctx) X509_STORE_CTX_free(vrfy_ctx); if (store) X509_STORE_free(store); } // KeyPrint is a strong indicator of trust SSL_set_verify_result(ssl, err); return result; }
int verify_callback (int preverify_ok, X509_STORE_CTX * ctx) { int ret = 0; struct tls_session *session; SSL *ssl; struct gc_arena gc = gc_new(); /* get the tls_session pointer */ ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); ASSERT (ssl); session = (struct tls_session *) SSL_get_ex_data (ssl, mydata_index); ASSERT (session); cert_hash_remember (session, ctx->error_depth, x509_get_sha1_hash(ctx->current_cert, &gc)); /* did peer present cert which was signed by our root cert? */ if (!preverify_ok) { /* get the X509 name */ char *subject = x509_get_subject(ctx->current_cert, &gc); if (subject) { /* Remote site specified a certificate, but it's not correct */ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s", ctx->error_depth, X509_verify_cert_error_string (ctx->error), subject); } ERR_clear_error(); session->verified = false; goto cleanup; } if (SUCCESS != verify_cert(session, ctx->current_cert, ctx->error_depth)) goto cleanup; ret = 1; cleanup: gc_free(&gc); return ret; }
int FuzzerInitialize(int *argc, char ***argv) { STACK_OF(SSL_COMP) *comp_methods; OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ASYNC, NULL); OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); ERR_get_state(); CRYPTO_free_ex_index(0, -1); idx = SSL_get_ex_data_X509_STORE_CTX_idx(); FuzzerSetRand(); comp_methods = SSL_COMP_get_compression_methods(); if (comp_methods != NULL) sk_SSL_COMP_sort(comp_methods); return 1; }
getdns_upstream* _getdns_upstream_from_x509_store(X509_STORE_CTX *store) { int uidx = _get_ssl_getdns_upstream_idx(); int sslidx = SSL_get_ex_data_X509_STORE_CTX_idx(); const SSL *ssl; /* all *_get_ex_data() should return NULL on failure anyway */ ssl = X509_STORE_CTX_get_ex_data(store, sslidx); if (ssl) return (getdns_upstream*) SSL_get_ex_data(ssl, uidx); else return NULL; /* TODO: if we want more details about errors somehow, we * might call ERR_get_error (see CRYPTO_set_ex_data(3ssl))*/ }
static int verify_callback(int preverify_ok, X509_STORE_CTX *callback_ctx) { /* our verify callback function */ SSL *ssl; CLI *c; X509 *cert; int depth; char *subject_name; /* retrieve application specific data */ ssl=X509_STORE_CTX_get_ex_data(callback_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); c=SSL_get_ex_data(ssl, cli_index); cert=X509_STORE_CTX_get_current_cert(callback_ctx); depth=X509_STORE_CTX_get_error_depth(callback_ctx); /* certificate name for logging */ subject_name=X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); s_log(LOG_DEBUG, "Starting certificate verification: depth=%d, %s", depth, subject_name); if(!cert_check(c, callback_ctx, preverify_ok)) { s_log(LOG_WARNING, "Certificate check failed: depth=%d, %s", depth, subject_name); OPENSSL_free(subject_name); return 0; /* reject connection */ } if(!crl_check(c, callback_ctx)) { s_log(LOG_WARNING, "CRL check failed: depth=%d, %s", depth, subject_name); OPENSSL_free(subject_name); return 0; /* reject connection */ } #ifdef HAVE_OSSL_OCSP_H if(c->opt->option.ocsp && !ocsp_check(c, callback_ctx)) { s_log(LOG_WARNING, "OCSP check failed: depth=%d, %s", depth, subject_name); OPENSSL_free(subject_name); return 0; /* reject connection */ } #endif /* HAVE_OSSL_OCSP_H */ /* errnum=X509_STORE_CTX_get_error(ctx); */ s_log(LOG_NOTICE, "Certificate accepted: depth=%d, %s", depth, subject_name); OPENSSL_free(subject_name); return 1; /* accept connection */ }
static int openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx) { GstDtlsConnection *self; SSL *ssl; BIO *bio; gchar *pem = NULL; gboolean accepted = FALSE; ssl = X509_STORE_CTX_get_ex_data (x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx ()); self = SSL_get_ex_data (ssl, connection_ex_index); g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), FALSE); pem = _gst_dtls_x509_to_pem (X509_STORE_CTX_get0_cert (x509_ctx)); if (!pem) { GST_WARNING_OBJECT (self, "failed to convert received certificate to pem format"); } else { bio = BIO_new (BIO_s_mem ()); if (bio) { gchar buffer[2048]; gint len; len = X509_NAME_print_ex (bio, X509_get_subject_name (X509_STORE_CTX_get0_cert (x509_ctx)), 1, XN_FLAG_MULTILINE); BIO_read (bio, buffer, len); buffer[len] = '\0'; GST_DEBUG_OBJECT (self, "Peer certificate received:\n%s", buffer); BIO_free (bio); } else { GST_DEBUG_OBJECT (self, "failed to create certificate print membio"); } g_signal_emit (self, signals[SIGNAL_ON_PEER_CERTIFICATE], 0, pem, &accepted); g_free (pem); } return accepted; }
static int ssl_verify_callback(int goodcert, X509_STORE_CTX *x509) { SSL *ssl= X509_STORE_CTX_get_ex_data(x509, SSL_get_ex_data_X509_STORE_CTX_idx() ); struct tls_info *info=SSL_get_app_data(ssl); if (info->peer_verify_domain || get_peer_verify_level(info)) { if (!goodcert) return (0); info->certificate_verified=1; } return (1); }
static int Tls_openssl_certificate_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { DEBUG_LOG_PRINT_LEV2(("Tls_openssl_certificate_verify_callback preverify_ok: %d",preverify_ok)); if(preverify_ok) /* Check the common name only if certificate is verified by OpenSSL */ { SSL *ssl; X509 *cert; int depth; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); /* Return the SSL structure */ cert = X509_STORE_CTX_get_current_cert(ctx); /*returns the certificate in ctx*/ depth = X509_STORE_CTX_get_error_depth(ctx); /* non-negative integer representing where in the certificate chain*/ if ((depth == 0) && (cert != NULL) && (ssl != NULL)) /* Verify the common name only in end entity certificate (depth =0)*/ { t_TlsConnection *p_TlsConnection; char peer_CN[256]; char buf[256]; p_TlsConnection = TlsGetConnFromSSL(ssl); X509_NAME_oneline(X509_get_subject_name(cert), buf, 256); DEBUG_LOG_PRINT_LEV2(("Tls_openssl_certificate_verify_callback depth: %d subject name of certificate : %s ",depth,buf )); X509_NAME_get_text_by_NID (X509_get_subject_name(cert),NID_commonName, peer_CN, 256); /* get the common name from the certificate */ if(p_TlsConnection != NULL) { DEBUG_LOG_PRINT_LEV2(("Tls_openssl_certificate_verify_callback p_TlsConnection->server.a_Addr : %s peer_CN : %s ",p_TlsConnection->server.a_Addr,peer_CN)); if((p_TlsConnection->server.v_Type == K_TLS_FQDN_ADDRESS) && (strlen(peer_CN) >0)) { if(strncasecmp(peer_CN,p_TlsConnection->server.a_Addr,sizeof(peer_CN))) { DEBUG_LOG_PRINT_LEV2(("Tls_openssl_certificate_verify_callback MISMATCH between Common Name in server certificate and FQDN address which we connect ")); preverify_ok =0; /* Peer CN does not match with the server address which we are trying to connect. */ } } } } } return preverify_ok; }