static int tlsext_servername_callback(SSL *ssl, int *ad, void *arg) { SSL_CTX *newctx = NULL; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); lua_State *L = SSL_CTX_get_app_data(ctx); const char *name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); /* No name, use default context */ if (!name) return SSL_TLSEXT_ERR_NOACK; /* Search for the name in the map */ openssl_getvalue(L, ctx, "tlsext_servername"); if (lua_istable(L, -1)) { lua_getfield(L, -1, name); if (auxiliar_isclass(L, "openssl.ssl_ctx", -1)) { newctx = CHECK_OBJECT(-1, SSL_CTX, "openssl.ssl_ctx"); SSL_set_SSL_CTX(ssl, newctx); lua_pop(L, 2); return SSL_TLSEXT_ERR_OK; } } else if (lua_isfunction(L, -1)) { } else { } lua_pop(L, 1); return SSL_TLSEXT_ERR_ALERT_FATAL; }
/** * 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); }
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; }
/** * Set the "ignore purpose" before to start verifing the certificate chain. */ static int cert_verify_cb(X509_STORE_CTX *x509_ctx, void *ptr) { int verify; lua_State *L; SSL_CTX *ctx = (SSL_CTX*)ptr; p_context 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 */ if (verify & LSEC_VERIFY_IGNORE_PURPOSE) { /* Set parameters to ignore the server purpose */ X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(x509_ctx); if (param) { X509_VERIFY_PARAM_set_purpose(param, X509_PURPOSE_SSL_SERVER); X509_VERIFY_PARAM_set_trust(param, X509_TRUST_SSL_SERVER); } } /* Call OpenSSL standard verification function */ return X509_verify_cert(x509_ctx); }
/** * Call Lua user function to get the DH key. */ static DH *dhparam_cb(SSL *ssl, int is_export, int keylength) { BIO *bio; lua_State *L; DH *dh_tmp = NULL; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); L = (lua_State*)SSL_CTX_get_app_data(ctx); /* Get the callback */ luaL_getmetatable(L, "SSL:DH:Registry"); lua_pushlightuserdata(L, (void*)ctx); lua_gettable(L, -2); /* Invoke the callback */ lua_pushnumber(L, is_export); lua_pushnumber(L, keylength); lua_call(L, 2, 1); /* Load parameters from returned value */ if (lua_type(L, -1) != LUA_TSTRING) { lua_pop(L, 2); /* Remove values from stack */ return NULL; } bio = BIO_new_mem_buf((void*)lua_tostring(L, -1), lua_rawlen(L, -1)); if (bio) { dh_tmp = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); BIO_free(bio); } lua_pop(L, 2); /* Remove values from stack */ return dh_tmp; }
static void _evhtp_ssl_delete_scache_ent(SSL_CTX * ctx, SSL_SESSION * sess) { evhtp * htp; evhtp_ssl_cfg * cfg; unsigned char * sid; unsigned int slen; htp = (evhtp *)SSL_CTX_get_app_data(ctx); cfg = htp->ssl_cfg; sid = sess->session_id; slen = sess->session_id_length; if (cfg->scache_del) { (cfg->scache_del)(htp, sid, slen); } }
/** * Call Lua user function to get the DH key. */ static DH *dhparam_cb(SSL *ssl, int is_export, int keylength) { BIO *bio; lua_State *L; DH *dh_tmp = NULL; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); p_context pctx = (p_context)SSL_CTX_get_app_data(ctx); L = pctx->L; /* Get the callback */ luaL_getmetatable(L, "SSL:DH:Registry"); lua_pushlightuserdata(L, (void*)ctx); lua_gettable(L, -2); /* Invoke the callback */ lua_pushboolean(L, is_export); lua_pushnumber(L, keylength); lua_call(L, 2, 1); /* Load parameters from returned value */ if (lua_type(L, -1) != LUA_TSTRING) { lua_pop(L, 2); /* Remove values from stack */ return NULL; } bio = BIO_new_mem_buf((void*)lua_tostring(L, -1), lua_rawlen(L, -1)); if (bio) { dh_tmp = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); BIO_free(bio); } /* * OpenSSL exepcts the callback to maintain a reference to the DH*. So, * cache it here, and clean up the previous set of parameters. Any remaining * set is cleaned up when destroying the LuaSec context. */ if (pctx->dh_param) DH_free(pctx->dh_param); pctx->dh_param = dh_tmp; lua_pop(L, 2); /* Remove values from stack */ return dh_tmp; }
static int mailstream_openssl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) { struct mailstream_ssl_context * ssl_context = (struct mailstream_ssl_context *)SSL_CTX_get_app_data(ssl->ctx); if (x509 == NULL || pkey == NULL) { return 0; } if (ssl_context == NULL) return 0; *x509 = ssl_context->client_x509; *pkey = ssl_context->client_pkey; if (*x509 && *pkey) return 1; else return 0; }
static int ssl_verify (int ok, X509_STORE_CTX *ctx) { unsigned char md5sum[16], fingerprint[40], *f; rfbClient *client; char *prompt, *cert_str; int err, i; unsigned int md5len; //char buf[257]; X509 *cert; SSL *ssl; if (ok) return TRUE; ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx ()); client = SSL_CTX_get_app_data (ssl->ctx); cert = X509_STORE_CTX_get_current_cert (ctx); err = X509_STORE_CTX_get_error (ctx); /* calculate the MD5 hash of the raw certificate */ md5len = sizeof (md5sum); X509_digest (cert, EVP_md5 (), md5sum, &md5len); for (i = 0, f = fingerprint; i < 16; i++, f += 3) sprintf ((char *) f, "%.2x%c", md5sum[i], i != 15 ? ':' : '\0'); #define GET_STRING(name) X509_NAME_oneline (name, buf, 256) /* TODO: Don't just ignore certificate checks fingerprint = key to check in db GET_STRING (X509_get_issuer_name (cert)); GET_STRING (X509_get_subject_name (cert)); cert->valid (bool: GOOD or BAD) */ ok = TRUE; return ok; }
static int meth_sni(lua_State *L) { int strict; SSL_CTX *aux; const char *name; p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); SSL_CTX *ctx = SSL_get_SSL_CTX(ssl->ssl); p_context pctx = (p_context)SSL_CTX_get_app_data(ctx); if (pctx->mode == LSEC_MODE_CLIENT) { name = luaL_checkstring(L, 2); SSL_set_tlsext_host_name(ssl->ssl, name); return 0; } else if (pctx->mode == LSEC_MODE_SERVER) { luaL_checktype(L, 2, LUA_TTABLE); strict = lua_toboolean(L, 3); /* Check if the table contains only (string -> context) */ lua_pushnil(L); while (lua_next(L, 2)) { luaL_checkstring(L, -2); aux = lsec_checkcontext(L, -1); /* Set callback in every context */ SSL_CTX_set_tlsext_servername_callback(aux, sni_cb); /* leave the next key on the stack */ lua_pop(L, 1); } /* Save table in the register */ luaL_getmetatable(L, "SSL:SNI:Registry"); lua_pushlightuserdata(L, (void*)ssl->ssl); lua_newtable(L); lua_pushstring(L, "map"); lua_pushvalue(L, 2); lua_settable(L, -3); lua_pushstring(L, "strict"); lua_pushboolean(L, strict); lua_settable(L, -3); lua_settable(L, -3); /* Set callback in the default context */ SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb); } return 0; }
static int BSslCertVerifyCB(int iOK, X509_STORE_CTX *pXsCtx) { int iError, iDepth; SSL *pSSL; SSL_CTX *pSCtx; SslServerBind const *pSSLB; X509 *pCert; iError = X509_STORE_CTX_get_error(pXsCtx); iDepth = X509_STORE_CTX_get_error_depth(pXsCtx); if ((pSSL = (SSL *) X509_STORE_CTX_get_ex_data(pXsCtx, SSL_get_ex_data_X509_STORE_CTX_idx())) == NULL) return iOK; pSCtx = SSL_get_SSL_CTX(pSSL); pSSLB = (SslServerBind const *) SSL_CTX_get_app_data(pSCtx); pCert = X509_STORE_CTX_get_current_cert(pXsCtx); #ifdef DEBUG_OSSL char *pszVal; pszVal = X509_NAME_oneline(X509_get_issuer_name(pCert), 0, 0); SysLogMessage(LOG_LEV_MESSAGE, "CERT Issuer: %s\n", pszVal); OPENSSL_free(pszVal); pszVal = X509_NAME_oneline(X509_get_subject_name(pCert), 0, 0); SysLogMessage(LOG_LEV_MESSAGE, "CERT Subject: %s\n", pszVal); OPENSSL_free(pszVal); #endif if (!iOK) { SysLogMessage(LOG_LEV_MESSAGE, "CERT verify error: depth = %d error = '%s'\n", iDepth, X509_verify_cert_error_string(iError)); if (iError == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && pSSLB->ulFlags & BSSLF_ALLOW_SEFLSIGNED) { SysLogMessage(LOG_LEV_MESSAGE, "Self signed CERT allowed (override)\n"); iOK = 1; } } return iOK; }
static EC_KEY *tmp_ecdh_callback(SSL *ssl, int is_export, int keylength) { BIO *bio; EC_KEY *ec_tmp = NULL; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); lua_State *L = SSL_CTX_get_app_data(ctx); int ret = 0; /* get callback function */ openssl_getvalue(L, ctx, "tmp_ecdh_callback"); /* Invoke the callback */ lua_pushboolean(L, is_export); lua_pushnumber(L, keylength); ret = lua_pcall(L, 2, 1, 0); if (ret == 0) { /* Load parameters from returned value */ if (lua_type(L, -1) != LUA_TSTRING) { lua_pop(L, 2); /* Remove values from stack */ return NULL; } bio = BIO_new_mem_buf((void*)lua_tostring(L, -1), lua_rawlen(L, -1)); if (bio) { ec_tmp = PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); } } else { lua_error(L); } lua_pop(L, 2); /* Remove values from stack */ return ec_tmp; }
static int sni_cb(SSL *ssl, int *ad, void *arg) { int strict; SSL_CTX *newctx = NULL; SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); lua_State *L = ((p_context)SSL_CTX_get_app_data(ctx))->L; const char *name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); /* No name, use default context */ if (!name) return SSL_TLSEXT_ERR_NOACK; /* Retrieve struct from registry */ luaL_getmetatable(L, "SSL:SNI:Registry"); lua_pushlightuserdata(L, (void*)ssl); lua_gettable(L, -2); /* Strict search? */ lua_pushstring(L, "strict"); lua_gettable(L, -2); strict = lua_toboolean(L, -1); lua_pop(L, 1); /* Search for the name in the map */ lua_pushstring(L, "map"); lua_gettable(L, -2); lua_pushstring(L, name); lua_gettable(L, -2); if (lua_isuserdata(L, -1)) newctx = lsec_checkcontext(L, -1); lua_pop(L, 4); /* Found, use this context */ if (newctx) { SSL_set_SSL_CTX(ssl, newctx); return SSL_TLSEXT_ERR_OK; } /* Not found, but use initial context */ if (!strict) return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_ALERT_FATAL; }