static int tlso_verify_cb( int ok, X509_STORE_CTX *ctx ) { X509 *cert; int errnum; int errdepth; X509_NAME *subject; X509_NAME *issuer; char *sname; char *iname; char *certerr = NULL; cert = X509_STORE_CTX_get_current_cert( ctx ); errnum = X509_STORE_CTX_get_error( ctx ); errdepth = X509_STORE_CTX_get_error_depth( ctx ); /* * X509_get_*_name return pointers to the internal copies of * those things requested. So do not free them. */ subject = X509_get_subject_name( cert ); issuer = X509_get_issuer_name( cert ); /* X509_NAME_oneline, if passed a NULL buf, allocate memomry */ sname = X509_NAME_oneline( subject, NULL, 0 ); iname = X509_NAME_oneline( issuer, NULL, 0 ); if ( !ok ) certerr = (char *)X509_verify_cert_error_string( errnum ); #ifdef HAVE_EBCDIC if ( sname ) __etoa( sname ); if ( iname ) __etoa( iname ); if ( certerr ) { certerr = LDAP_STRDUP( certerr ); __etoa( certerr ); } #endif Debug( LDAP_DEBUG_TRACE, "TLS certificate verification: depth: %d, err: %d, subject: %s,", errdepth, errnum, sname ? sname : "-unknown-" ); Debug( LDAP_DEBUG_TRACE, " issuer: %s\n", iname ? iname : "-unknown-", 0, 0 ); if ( !ok ) { Debug( LDAP_DEBUG_ANY, "TLS certificate verification: Error, %s\n", certerr, 0, 0 ); } if ( sname ) CRYPTO_free ( sname ); if ( iname ) CRYPTO_free ( iname ); #ifdef HAVE_EBCDIC if ( certerr ) LDAP_FREE( certerr ); #endif return ok; }
static int check_certificate_by_signer (X509 *peercert) { X509_STORE_CTX xsc; X509_STORE *ctx; int pass = 0, i; ctx = X509_STORE_new (); if (ctx == NULL) return 0; if (option (OPTSSLSYSTEMCERTS)) { if (X509_STORE_set_default_paths (ctx)) pass++; else dprint (2, (debugfile, "X509_STORE_set_default_paths failed\n")); } if (X509_STORE_load_locations (ctx, SslCertFile, NULL)) pass++; else dprint (2, (debugfile, "X509_STORE_load_locations failed\n")); for (i = 0; i < sk_X509_num (SslSessionCerts); i++) pass += (X509_STORE_add_cert (ctx, sk_X509_value (SslSessionCerts, i)) != 0); if (pass == 0) { /* nothing to do */ X509_STORE_free (ctx); return 0; } X509_STORE_CTX_init (&xsc, ctx, peercert, SslSessionCerts); pass = (X509_verify_cert (&xsc) > 0); #ifdef DEBUG if (! pass) { char buf[SHORT_STRING]; int err; err = X509_STORE_CTX_get_error (&xsc); snprintf (buf, sizeof (buf), "%s (%d)", X509_verify_cert_error_string(err), err); dprint (2, (debugfile, "X509_verify_cert: %s\n", buf)); dprint (2, (debugfile, " [%s]\n", peercert->name)); } #endif X509_STORE_CTX_cleanup (&xsc); X509_STORE_free (ctx); return pass; }
// VerifyChain verifies the certificate chain in chain // according to the verification options given as opts. bool X509PEMVerifier::VerifyChain(const std::vector<X509Certificate> &chain, const X509VerifierOptions &opts) { bool status = false; X509_STORE_CTX *ctx = X509_STORE_CTX_new(); STACK_OF(X509) *untrusted = sk_X509_new_null(); // Ensure that we have a chain to check on. if (chain.empty()) { goto out; } // If we've been passed a DNS name in opts, // we should check whether the leaf certificate // matches that before doing the more expensive // checks. if (!opts.dns_name.empty()) { if (!X509HostnameVerifier::VerifyHostname(chain.at(0), opts.dns_name)) { std::cerr << "X509PEMVerifier - hostname verification failed" << std::endl; goto out; } } // Extract our chain into the format that OpenSSL // expects for verification. for (const X509Certificate &cert : chain) { X509 *cur = cert.dptr_->AsOpenSSLX509(); sk_X509_push(untrusted, cur); } // Set up the X509_STORE_CTX to verify according to opts. X509_STORE_CTX_init(ctx, store_, sk_X509_value(untrusted, 0), untrusted); // If a time is not specified in opts, use the current system time. if (opts.time == 0) { X509_STORE_CTX_set_time(ctx, 0, std::time(nullptr)); } else { X509_STORE_CTX_set_time(ctx, 0, opts.time); } // If a dns_name is specified in opts, use the SSL server policy. if (!opts.dns_name.empty()) { X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SSL_SERVER); X509_STORE_CTX_set_trust(ctx, X509_TRUST_SSL_SERVER); } if (X509_verify_cert(ctx) == 1) { status = true; } else { std::cerr << "X509PEMVerifier - verification error: " << X509_verify_cert_error_string(ctx->error) << std::endl; } out: sk_X509_pop_free(untrusted, X509_free); X509_STORE_CTX_free(ctx); return status; }
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; }
/*********************************************************************** * doConnection - make a connection * Args: * scon = earlier ssl connection for session id, or NULL * Returns: * SSL * = the connection pointer. */ static SSL * doConnection(SSL * scon) { struct pollfd pfd[1]; SSL *serverCon; BIO *conn; long verify_error; int i; if ((conn = BIO_new(BIO_s_connect())) == NULL) return (NULL); /* BIO_set_conn_port(conn,port);*/ BIO_set_conn_hostname(conn, s_time_config.host); if (scon == NULL) serverCon = SSL_new(tm_ctx); else { serverCon = scon; SSL_set_connect_state(serverCon); } SSL_set_bio(serverCon, conn, conn); /* ok, lets connect */ for (;;) { i = SSL_connect(serverCon); if (BIO_sock_should_retry(i)) { BIO_printf(bio_err, "DELAY\n"); i = SSL_get_fd(serverCon); pfd[0].fd = i; pfd[0].events = POLLIN; poll(pfd, 1, -1); continue; } break; } if (i <= 0) { BIO_printf(bio_err, "ERROR\n"); verify_error = SSL_get_verify_result(serverCon); if (verify_error != X509_V_OK) BIO_printf(bio_err, "verify error:%s\n", X509_verify_cert_error_string(verify_error)); else ERR_print_errors(bio_err); if (scon == NULL) SSL_free(serverCon); return NULL; } return serverCon; }
static void ngx_stream_proxy_ssl_handshake(ngx_connection_t *pc) { long rc; ngx_stream_session_t *s; ngx_stream_upstream_t *u; ngx_stream_proxy_srv_conf_t *pscf; s = pc->data; pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module); if (pc->ssl->handshaked) { if (pscf->ssl_verify) { rc = SSL_get_verify_result(pc->ssl->connection); if (rc != X509_V_OK) { ngx_log_error(NGX_LOG_ERR, pc->log, 0, "upstream SSL certificate verify error: (%l:%s)", rc, X509_verify_cert_error_string(rc)); goto failed; } u = s->upstream; if (ngx_ssl_check_host(pc, &u->ssl_name) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, pc->log, 0, "upstream SSL certificate does not match \"%V\"", &u->ssl_name); goto failed; } } if (pscf->ssl_session_reuse) { u = s->upstream; u->peer.save_session(&u->peer, u->peer.data); } if (pc->write->timer_set) { ngx_del_timer(pc->write); } ngx_stream_proxy_init_upstream(s); return; } failed: ngx_stream_proxy_next_upstream(s); }
/* 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 gboolean irssi_ssl_verify(SSL *ssl, SSL_CTX *ctx, const char* hostname, int port, X509 *cert, SERVER_REC *server, TLS_REC *tls_rec) { long result; result = SSL_get_verify_result(ssl); if (result != X509_V_OK) { g_warning("Could not verify TLS servers certificate: %s", X509_verify_cert_error_string(result)); return FALSE; } else if (! irssi_ssl_verify_hostname(cert, hostname)){ return FALSE; } return TRUE; }
/*- * doConnection - make a connection */ static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx) { BIO *conn; SSL *serverCon; int i; if ((conn = BIO_new(BIO_s_connect())) == NULL) return NULL; BIO_set_conn_hostname(conn, host); BIO_set_conn_mode(conn, BIO_SOCK_NODELAY); if (scon == NULL) serverCon = SSL_new(ctx); else { serverCon = scon; SSL_set_connect_state(serverCon); } SSL_set_bio(serverCon, conn, conn); /* ok, lets connect */ i = SSL_connect(serverCon); if (i <= 0) { BIO_printf(bio_err, "ERROR\n"); if (verify_args.error != X509_V_OK) BIO_printf(bio_err, "verify error:%s\n", X509_verify_cert_error_string(verify_args.error)); else ERR_print_errors(bio_err); if (scon == NULL) SSL_free(serverCon); return NULL; } #if defined(SOL_SOCKET) && defined(SO_LINGER) { struct linger no_linger; int fd; no_linger.l_onoff = 1; no_linger.l_linger = 0; fd = SSL_get_fd(serverCon); if (fd >= 0) (void)setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&no_linger, sizeof(no_linger)); } #endif return serverCon; }
static int verify_cb(int ok, X509_STORE_CTX *ctx) { char *buf = NULL; 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); if (depth > MAX_CERT_DEPTH) { ok = 0; err = X509_V_ERR_CERT_CHAIN_TOO_LONG; X509_STORE_CTX_set_error(ctx, err); } if (!ok) { if (err_cert) buf = X509_NAME_oneline(X509_get_subject_name(err_cert), NULL, 0); debug(DBG_WARN, "verify error: num=%d:%s:depth=%d:%s", err, X509_verify_cert_error_string(err), depth, buf ? buf : ""); free(buf); buf = NULL; switch (err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: if (err_cert) { buf = X509_NAME_oneline(X509_get_issuer_name(err_cert), NULL, 0); if (buf) { debug(DBG_WARN, "\tIssuer=%s", buf); free(buf); buf = NULL; } } break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: debug(DBG_WARN, "\tCertificate not yet valid"); break; case X509_V_ERR_CERT_HAS_EXPIRED: debug(DBG_WARN, "Certificate has expired"); break; case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: debug(DBG_WARN, "Certificate no longer valid (after notAfter)"); break; case X509_V_ERR_NO_EXPLICIT_POLICY: debug(DBG_WARN, "No Explicit Certificate Policy"); break; } } return ok; }
int verify_callback (int ok, X509_STORE_CTX * store) { char data[256]; if (!ok) { 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); fprintf (stderr, "%s%i\n", "-Error with certificate at depth: ", depth); X509_NAME_oneline (X509_get_issuer_name (cert), data, 256); fprintf (stderr, "%s%s\n", " issuer = ", data); X509_NAME_oneline (X509_get_subject_name (cert), data, 256); fprintf (stderr, "%s%s\n", " subject = ", data); fprintf (stderr, "%s\n", X509_verify_cert_error_string (err)); fprintf (stderr, " err %i:%s\n", err, X509_verify_cert_error_string (err)); } return ok; }
static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) { char buf[256]; X509 *err_cert; int err, depth; SSL *ssl; struct tls_connection *conn; char *match; err_cert = X509_STORE_CTX_get_current_cert(x509_ctx); err = X509_STORE_CTX_get_error(x509_ctx); depth = X509_STORE_CTX_get_error_depth(x509_ctx); ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); conn = SSL_get_app_data(ssl); match = conn ? conn->subject_match : NULL; if (!preverify_ok) { wpa_printf(MSG_WARNING, "TLS: Certificate verification failed," " error %d (%s) depth %d for '%s'", err, X509_verify_cert_error_string(err), depth, buf); } else { wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - " "preverify_ok=%d err=%d (%s) depth=%d buf='%s'", preverify_ok, err, X509_verify_cert_error_string(err), depth, buf); if (depth == 0 && match && strstr(buf, match) == NULL) { wpa_printf(MSG_WARNING, "TLS: Subject '%s' did not " "match with '%s'", buf, match); preverify_ok = 0; } } return preverify_ok; }
/* Verify certificate callback. Gets invoked by crypto/x509/x509_vfy.c: * internal_verify() after it checks the signature and the time of * the certificate. Copied from apps/s_cb.c. Configured through * verify_depth and verify_error, initialized in main(). Doesn't * really do much other than print verify errors to the screen and * ignore errors down to verify_depth. Mainly an example of how * OpenSSL let's your app have a say in certificate validating. * At this point OpenSSL has checked the signature and dates are * good, so you don't need to do that. One thing you could do * here would be to verify the certificate status with an on-line * service, e.g. via OCSP. */ int verify_cb(int ok, X509_STORE_CTX *ctx) { char buf[256]; X509 *err_cert; int err,depth; BIO* bio_err; int verify_error = X509_V_OK, verify_depth = 0; if ((bio_err=BIO_new(BIO_s_file())) == NULL) return(0); BIO_set_fp(bio_err,stderr,BIO_NOCLOSE); err_cert=X509_STORE_CTX_get_current_cert(ctx); err=X509_STORE_CTX_get_error(ctx); depth=X509_STORE_CTX_get_error_depth(ctx); X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256); BIO_printf(bio_err,"depth=%d %s\n",depth,buf); if (!ok) { BIO_printf(bio_err,"verify error:num=%d:%s\n",err, X509_verify_cert_error_string(err)); if (depth > verify_depth) { verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; } else { ok=1; verify_error=X509_V_OK; } } switch (ctx->error) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256); BIO_printf(bio_err,"issuer= %s\n",buf); 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(ctx->current_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(ctx->current_cert)); BIO_printf(bio_err,"\n"); break; } BIO_printf(bio_err,"verify return:%d\n",ok); BIO_free(bio_err); return(ok); }
int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) { char buf[256]; 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); X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf); BIO_printf(bio_err,"depth=%d %s\n",depth,buf); if (!ok) { BIO_printf(bio_err,"verify error:num=%d:%s\n",err, X509_verify_cert_error_string(err)); if (verify_depth >= depth) { ok=1; verify_error=X509_V_OK; } else { ok=0; verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; } } switch (ctx->error) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof buf); BIO_printf(bio_err,"issuer= %s\n",buf); 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(ctx->current_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(ctx->current_cert)); BIO_printf(bio_err,"\n"); break; } BIO_printf(bio_err,"verify return:%d\n",ok); return(ok); }
void* conn_handler(void *arg) { long err; SSL *ssl; struct conn_ctx *ctx = (struct conn_ctx *)arg; struct freeq_ctx *freeqctx = ctx->srvctx->freeqctx; struct freeqd_state *fst = ctx->srvctx->fst; BIO *client = ctx->client; pthread_detach(pthread_self()); ssl = freeq_ssl_new(freeqctx); SSL_set_bio(ssl, client, client); if (SSL_accept(ssl) <= 0) { int_error("Error accepting SSL connection"); return NULL; } if ((err = post_connection_check(freeqctx, ssl, "localhost")) != X509_V_OK) { err(freeqctx, "error: peer certificate: %s\n", X509_verify_cert_error_string(err)); int_error("Error checking SSL object after connection"); } BIO *buf_io, *ssl_bio; buf_io = BIO_new(BIO_f_buffer()); ssl_bio = BIO_new(BIO_f_ssl()); BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE); BIO_push(buf_io, ssl_bio); dbg(freeqctx, "ssl client connection opened\n"); if (generation_table_merge(freeqctx, fst, buf_io)) { err(freeqctx, "table merge failed\n"); SSL_shutdown(ssl); } else { dbg(freeqctx, "table merged ok\n"); SSL_clear(ssl); } dbg(freeqctx, "ssl client connection closed\n"); SSL_free(ssl); ERR_remove_state(0); return 0; }
int verify_callback(int ok, X509_STORE_CTX *ctx) { static int v_verbose = 0; int cert_error = X509_STORE_CTX_get_error(ctx); if (!ok) { X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); if (current_cert) { char buf[256]; X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, sizeof(buf)); fprintf(stderr, "%s\n", buf); } { int error_depth = X509_STORE_CTX_get_error_depth(ctx); const char *error_msg = X509_verify_cert_error_string(cert_error); // FIXME(jweyrich): not thread-safe fprintf(stderr, "%sError %d at %d depth lookup: %s\n", #if OPENSSL_VERSION_NUMBER >= 0x1000000f X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path] " : "", #else "", #endif cert_error, error_depth, error_msg); } switch (cert_error) { case X509_V_ERR_NO_EXPLICIT_POLICY: policies_print(NULL, ctx); case X509_V_ERR_CERT_HAS_EXPIRED: // Since we are just checking the certificates, it is // ok if they are self signed. But we should still warn // the user. case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: // Continue after extension errors too case X509_V_ERR_INVALID_CA: case X509_V_ERR_INVALID_NON_CA: case X509_V_ERR_PATH_LENGTH_EXCEEDED: case X509_V_ERR_INVALID_PURPOSE: case X509_V_ERR_CRL_HAS_EXPIRED: case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: ok = 1; } return ok; } if (cert_error == X509_V_OK && ok == 2) policies_print(NULL, ctx); if (!v_verbose) ERR_clear_error(); return ok; }
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; }
static int vio_verify_callback(int ok, X509_STORE_CTX *ctx) { char buf[256]; X509* err_cert; int err,depth; DBUG_ENTER("vio_verify_callback"); DBUG_PRINT("enter", ("ok: %d, ctx: 0x%p", ok, ctx)); err_cert=X509_STORE_CTX_get_current_cert(ctx); err= X509_STORE_CTX_get_error(ctx); depth= X509_STORE_CTX_get_error_depth(ctx); X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf)); if (!ok) { DBUG_PRINT("error",("verify error: num: %d : '%s'\n",err, X509_verify_cert_error_string(err))); if (verify_depth >= depth) { ok=1; verify_error=X509_V_OK; } else { verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; } } switch (ctx->error) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256); DBUG_PRINT("info",("issuer= %s\n",buf)); break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: DBUG_PRINT("error", ("notBefore")); /*ASN1_TIME_print_fp(stderr,X509_get_notBefore(ctx->current_cert));*/ break; case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: DBUG_PRINT("error", ("notAfter error")); /*ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));*/ break; } DBUG_PRINT("exit", ("%d", ok)); DBUG_RETURN(ok); }
/** * Check if X509Cert is signed by trusted issuer * @param aStore X509_STORE of trusted issuers. If NULL, lib uses X509CertStore::getInstance()->getCertStore() * @return 0 or openssl error_code. Get human readable cause with X509_verify_cert_error_string(code) * @throw IOException if error */ int digidoc::X509Cert::verify(X509_STORE* aStore) const throw(IOException) { X509_STORE* store = aStore; X509_STORE** ppStore = NULL; if(store == NULL) { store = digidoc::X509CertStore::getInstance()->getCertStore(); ppStore = &store;//init ppStore to newly created store, so X509_STORE_scope can free it } X509_STORE_scope xst(ppStore); X509_STORE_CTX *csc = X509_STORE_CTX_new(); X509_STORE_CTX_scope csct(&csc); if (csc == NULL) { THROW_IOEXCEPTION("Failed to create X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error())); } X509* x = getX509(); X509_scope xt(&x); if(!X509_STORE_CTX_init(csc, store, x, NULL)) { THROW_IOEXCEPTION("Failed to init X509_STORE_CTX %s",ERR_reason_error_string(ERR_get_error())); } int ok = X509_verify_cert(csc); if(!ok) { int err = X509_STORE_CTX_get_error(csc); X509Cert cause(X509_STORE_CTX_get_current_cert (csc)); std::ostringstream s; s << "Unable to verify " << cause.getSubjectName(); s << ". Cause: " << X509_verify_cert_error_string(err); switch(err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: { IOException e(__FILE__, __LINE__, s.str()); e.setCode( Exception::CertificateIssuerMissing ); throw e; break; } default: THROW_IOEXCEPTION(s.str().c_str()); break; } } return ok; }
/* establish SSL connection between client and server SYNOPSIS my_ssl_connect ssl ssl object RETURN VALUES 0 success 1 error */ int my_ssl_connect(SSL *ssl) { my_bool blocking; MYSQL *mysql; long rc; DBUG_ENTER("my_ssl_connect"); DBUG_ASSERT(ssl != NULL); mysql= (MYSQL *)SSL_get_app_data(ssl); CLEAR_CLIENT_ERROR(mysql); /* Set socket to blocking if not already set */ if (!(blocking= vio_is_blocking(mysql->net.vio))) vio_blocking(mysql->net.vio, TRUE, 0); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql->net.vio->sd); if (SSL_connect(ssl) != 1) { my_SSL_error(mysql); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE, 0); DBUG_RETURN(1); } rc= SSL_get_verify_result(ssl); if (rc != X509_V_OK) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc)); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE, 0); DBUG_RETURN(1); } vio_reset(mysql->net.vio, VIO_TYPE_SSL, mysql->net.vio->sd, 0, 0); mysql->net.vio->ssl= ssl; DBUG_RETURN(0); }
static void do_ssl_accept(connections_head_t *head, connection_t *conn) { long err; int ret, ssl_err; if (conn->accept == 0) { /* first invoke do_ssl_accept */ conn->ssl = SSL_new(head->ctx); if (NULL == conn->ssl) { perror("SSL_new"); goto error; } if (SSL_set_fd(conn->ssl, conn->fd) != 1) { perror("SSL_set_fd"); goto error; } conn->accept = 1; } ret = SSL_accept(conn->ssl); if (ret != 1) { ssl_err = SSL_get_error(conn->ssl, ret); if (ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) { ERROR_MSG("ssl_err is: %d\n", ssl_err); ERROR_MSG("ssl_accept"); goto error; } /* called next epoll_wait loop */ return; } err = post_connection_check(conn->ssl, "192.168.1.10"); if (err != X509_V_OK) { ERROR_MSG("post_connection_check error\n"); ERROR_MSG("-Error: peer certificate: %s\n", X509_verify_cert_error_string(err)); } conn->handler = ssl_rdwr_handler; error: return; }
static int cert_check(CLI *c, X509_STORE_CTX *callback_ctx, int preverify_ok) { X509_OBJECT obj; #if OPENSSL_VERSION_NUMBER>=0x0090700fL ASN1_BIT_STRING *local_key, *peer_key; #endif X509 *cert; int depth; if(c->opt->verify_level<1) { s_log(LOG_INFO, "CERT: Verification not enabled"); return 1; /* accept connection */ } cert=X509_STORE_CTX_get_current_cert(callback_ctx); depth=X509_STORE_CTX_get_error_depth(callback_ctx); if(!preverify_ok) { /* remote site specified a certificate, but it's not correct */ if(c->opt->verify_level>=4 && depth>0) { s_log(LOG_INFO, "CERT: Invalid CA certificate ignored"); return 1; /* accept connection */ } else { s_log(LOG_WARNING, "CERT: Verification error: %s", X509_verify_cert_error_string( X509_STORE_CTX_get_error(callback_ctx))); return 0; /* reject connection */ } } if(c->opt->verify_level>=3 && depth==0) { if(X509_STORE_get_by_subject(callback_ctx, X509_LU_X509, X509_get_subject_name(cert), &obj)!=1) { s_log(LOG_WARNING, "CERT: Certificate not found in local repository"); return 0; /* reject connection */ } #if OPENSSL_VERSION_NUMBER>=0x0090700fL peer_key=X509_get0_pubkey_bitstr(cert); local_key=X509_get0_pubkey_bitstr(obj.data.x509); if(!peer_key || !local_key || peer_key->length!=local_key->length || memcmp(peer_key->data, local_key->data, local_key->length)) { s_log(LOG_WARNING, "CERT: Public keys do not match"); return 0; /* reject connection */ } #endif s_log(LOG_INFO, "CERT: Locally installed certificate matched"); } return 1; /* accept connection */ }
/*####################################################################### # STATIC FUNCTION IMPLEMENTATION # ########################################################################*/ static int verify_server_cb(int ok, X509_STORE_CTX *ctx) { qeo_log_d("Verifying server, pre-verify is %s", ok ? "ok" : "not ok"); if (!ok) { X509 *err_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); char subj[256], issuer[256]; X509_NAME_oneline(X509_get_subject_name(err_cert), subj, sizeof(subj)); X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), issuer, sizeof(issuer)); qeo_log_e("peer certificate verification failed: %s (@depth=%d, subject=%s, issuer=%s)", X509_verify_cert_error_string(err), depth, subj, issuer); } /* no extra verification needed */ return ok; }
my_bool ma_tls_connect(MARIADB_TLS *ctls) { SSL *ssl = (SSL *)ctls->ssl; my_bool blocking; MYSQL *mysql; MARIADB_PVIO *pvio; int rc; mysql= (MYSQL *)SSL_get_app_data(ssl); pvio= mysql->net.pvio; /* Set socket to blocking if not already set */ if (!(blocking= pvio->methods->is_blocking(pvio))) pvio->methods->blocking(pvio, TRUE, 0); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql_get_socket(mysql)); if (SSL_connect(ssl) != 1) { ma_tls_set_error(mysql); /* restore blocking mode */ if (!blocking) pvio->methods->blocking(pvio, FALSE, 0); return 1; } if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT)) { rc= SSL_get_verify_result(ssl); if (rc != X509_V_OK) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc)); /* restore blocking mode */ if (!blocking) pvio->methods->blocking(pvio, FALSE, 0); return 1; } } pvio->ctls->ssl= ctls->ssl= (void *)ssl; return 0; }
/* should be X509* but we can just have them as char*. (??? --Sampo) */ static int verify_callback(int ok, X509_STORE_CTX *ctx) { char buf[256]; 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); X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf)); fprintf(stderr,"depth=%d %s\n",depth,buf); if (!ok) { fprintf(stderr,"verify error:num=%d:%s\n",err, X509_verify_cert_error_string(err)); if (depth < 6) { ok=1; X509_STORE_CTX_set_error(ctx,X509_V_OK); } else { ok=0; X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG); } } switch (ctx->error) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof(buf)); fprintf(stderr,"issuer= %s\n",buf); break; #if 1 case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: fprintf(stderr,"notBefore="); /*ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert)); BIO_printf(bio_err,"\n");*/ break; case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: fprintf(stderr,"notAfter="); /*ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert)); BIO_printf(bio_err,"\n"); */ break; #endif } fprintf(stderr,"verify return:%d\n",ok); return(ok); }
int SSLSocket::checkSSL(int ret) { if(!ssl) { return -1; } if(ret <= 0) { /* inspired by boost.asio (asio/ssl/detail/impl/engine.ipp, function engine::perform) and the SSL_get_error doc at <https://www.openssl.org/docs/ssl/SSL_get_error.html>. */ auto err = SSL_get_error(ssl, ret); switch (err) { case SSL_ERROR_NONE: // Fallthrough - YaSSL doesn't for example return an openssl compatible error on recv fail case SSL_ERROR_WANT_READ: // Fallthrough case SSL_ERROR_WANT_WRITE: return -1; case SSL_ERROR_ZERO_RETURN: throw SocketException(STRING(CONNECTION_CLOSED)); case SSL_ERROR_SYSCALL: { auto sys_err = ERR_get_error(); if (sys_err == 0) { if (ret == 0) { dcdebug("TLS error: call ret = %d, SSL_get_error = %d, ERR_get_error = " U64_FMT "\n", ret, err, sys_err); throw SSLSocketException(STRING(CONNECTION_CLOSED)); } sys_err = getLastError(); } throw SSLSocketException(sys_err); } default: //display the cert errors as first choice, if the error is not the certs display the error from the ssl. auto sys_err = ERR_get_error(); string _error; int v_err = SSL_get_verify_result(ssl); if (v_err == X509_V_ERR_APPLICATION_VERIFICATION) { _error = "Keyprint mismatch"; } else if (v_err != X509_V_OK) { _error = X509_verify_cert_error_string(v_err); } else { _error = ERR_error_string(sys_err, NULL); } dcdebug("TLS error: call ret = %d, SSL_get_error = %d, ERR_get_error = " U64_FMT ",ERROR string: %s \n", ret, err, sys_err, ERR_error_string(sys_err, NULL)); throw SSLSocketException(STRING(TLS_ERROR) + (_error.empty() ? "" : + ": " + _error)); } } return ret; }
/* This function must be called before trying to sign any file. * It loads string for errors, and ciphers are auto-loaded by OpenSSL now. * If this function fails it may be because the certificate cannot * be validated. * * returns: true if can initialize and validate certificates, otherwise false */ bool initialize_signature(void) { int ret = -1; time_t mod_sec = 0; struct tm *alttime; struct stat statt; string_or_die(&CERTNAME, "%s/%s", cert_path, SWUPDCERT); ERR_load_crypto_strings(); ERR_load_PKCS7_strings(); EVP_add_digest(EVP_sha256()); if (!get_pubkey()) { goto fail; } ret = validate_certificate(); if (ret) { printf("Failed to verify certificate: %s\n", X509_verify_cert_error_string(ret)); if (ret == X509_V_ERR_CERT_NOT_YET_VALID) { /* If we can retrieve an approx. good system time, report out to user */ if (stat("/usr/lib/os-release", &statt) != -1) { mod_sec = statt.st_mtim.tv_sec; char timebuf[30]; alttime = localtime(&mod_sec); strftime(timebuf, sizeof(timebuf), "%F", alttime); printf("System clock should be at least %s\n", timebuf); } } goto fail; } /* Push our trust cert(s) to the stack, which is a set of certificates * in which to search for the signer's cert. */ x509_stack = sk_X509_new_null(); if (!x509_stack) { goto fail; } sk_X509_push(x509_stack, cert); return true; fail: return false; }
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { char buf[256]; X509 *cert; int err, depth; cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); /* * 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 (depth > 100) { preverify_ok = 0; err = X509_V_ERR_CERT_CHAIN_TOO_LONG; X509_STORE_CTX_set_error(ctx, err); } if (!preverify_ok) logit(LOG_ERR, "Certificate verification error:num=%d:%s:depth=%d:%s", err, X509_verify_cert_error_string(err), 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(cert), buf, sizeof(buf)); logit(LOG_ERR, "issuer= %s", buf); } if (secure_ssl) return preverify_ok; return 1; }
int verify_callback(int ok, X509_STORE_CTX* store) { char data[255]; if (!ok) { 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); printf("Error with certificate at depth: %d!\n", depth); X509_NAME_oneline(X509_get_issuer_name(cert), data, 255); printf("\tIssuer: %s\n", data); X509_NAME_oneline(X509_get_subject_name(cert), data, 255); printf("\tSubject: %s\n", data); printf("\tError %d: %s\n", err, X509_verify_cert_error_string(err)); } return ok; }
static int verify_callback(int ok, X509_STORE_CTX * ctx) { char buf[256]; X509 *err_cert; int err; int depth; syslog(LOG_ERR,"Doing a peer verify"); err_cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); if (ok==0) { syslog(LOG_ERR, "verify error:num=%d:%s", err, X509_verify_cert_error_string(err)); if (verify_depth >= depth) { ok = 0; verify_error = X509_V_OK; } else { ok = 0; verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG; } } switch (ctx->error) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, sizeof(buf)); syslog(LOG_NOTICE, "issuer= %s", buf); break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: syslog(LOG_NOTICE, "cert not yet valid"); break; case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: syslog(LOG_NOTICE, "cert has expired"); break; } return (ok); }