コード例 #1
0
ファイル: servername_test.c プロジェクト: ciz/openssl
static int server_setup_sni(void)
{
    SSL_CTX *cctx = NULL, *sctx = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;

    if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
                                       TLS_client_method(),
                                       TLS1_VERSION, 0,
                                       &sctx, &cctx, cert, privkey))
            || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
                                             NULL, NULL)))
        goto end;

    /* set SNI at server side */
    SSL_set_tlsext_host_name(serverssl, host);

    if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
        goto end;

    if (!TEST_ptr_null(SSL_get_servername(serverssl,
                                          TLSEXT_NAMETYPE_host_name))) {
        /* SNI should have been cleared during handshake */
        goto end;
    }

    testresult = 1;
end:
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);

    return testresult;
}
コード例 #2
0
ファイル: handshake_helper.c プロジェクト: Beatzevo/openssl
/* Select the appropriate server CTX.
 * Returns SSL_TLSEXT_ERR_OK if a match was found.
 * If |ignore| is 1, returns SSL_TLSEXT_ERR_NOACK on mismatch.
 * Otherwise, returns SSL_TLSEXT_ERR_ALERT_FATAL on mismatch.
 * An empty SNI extension also returns SSL_TSLEXT_ERR_NOACK.
 */
static int select_server_ctx(SSL *s, void *arg, int ignore)
{
    const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
    HANDSHAKE_EX_DATA *ex_data =
        (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));

    if (servername == NULL) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_NOACK;
    }

    if (strcmp(servername, "server2") == 0) {
        SSL_CTX *new_ctx = (SSL_CTX*)arg;
        SSL_set_SSL_CTX(s, new_ctx);
        /*
         * Copy over all the SSL_CTX options - reasonable behavior
         * allows testing of cases where the options between two
         * contexts differ/conflict
         */
        SSL_clear_options(s, 0xFFFFFFFFL);
        SSL_set_options(s, SSL_CTX_get_options(new_ctx));

        ex_data->servername = SSL_TEST_SERVERNAME_SERVER2;
        return SSL_TLSEXT_ERR_OK;
    } else if (strcmp(servername, "server1") == 0) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_OK;
    } else if (ignore) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_NOACK;
    } else {
        /* Don't set an explicit alert, to test library defaults. */
        return SSL_TLSEXT_ERR_ALERT_FATAL;
    }
}
コード例 #3
0
ファイル: ossl_ssl.c プロジェクト: 2220142/ruby
static int
ssl_servername_cb(SSL *ssl, int *ad, void *arg)
{
    VALUE ary, ssl_obj, ret_obj;
    void *ptr;
    int state = 0;
    const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);

    if (!servername)
        return SSL_TLSEXT_ERR_OK;

    if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
    	return SSL_TLSEXT_ERR_ALERT_FATAL;
    ssl_obj = (VALUE)ptr;
    ary = rb_ary_new2(2);
    rb_ary_push(ary, ssl_obj);
    rb_ary_push(ary, rb_str_new2(servername));

    ret_obj = rb_protect((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state);
    if (state) {
        rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
        return SSL_TLSEXT_ERR_ALERT_FATAL;
    }

    return SSL_TLSEXT_ERR_OK;
}
コード例 #4
0
int ServerNameIndication::callback(void *s, int *ad, void *arg) {
  SSL *ssl = (SSL *)s;
  const char *sn_ptr = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
  if (!sn_ptr) {
    return SSL_TLSEXT_ERR_OK; // No server name; use the default.
  }

  // Calculate the names to search for: fqdn and wildcard.
  std::string fqdn = sn_ptr;
  size_t pos = fqdn.find('.');
  std::string wildcard;
  if (pos != string::npos) {
    wildcard = fqdn.substr(pos + 1);
  }

  // Search in memory for matching certificate.
  if (setCTXFromMemory(ssl, wildcard) || setCTXFromMemory(ssl, fqdn)) {
    return SSL_TLSEXT_ERR_OK;
  }

  if (setCTXFromFile(ssl, wildcard) || setCTXFromFile(ssl, fqdn)) {
    return SSL_TLSEXT_ERR_OK;
  }

  // Didn't find a match based on SNI, fallback to default.
  return SSL_TLSEXT_ERR_OK;
}
コード例 #5
0
int bud_config_select_sni_context(SSL* s, int* ad, void* arg) {
  bud_config_t* config;
  bud_context_t* ctx;
  const char* servername;

  config = arg;
  servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);

  /* No servername - no context selection */
  if (servername == NULL)
    return SSL_TLSEXT_ERR_OK;

  /* Async SNI */
  ctx = SSL_get_ex_data(s, kBudSSLSNIIndex);

  /* Normal SNI */
  if (ctx == NULL)
    ctx = bud_config_select_context(config, servername, strlen(servername));

  if (ctx != NULL) {
    SSL_set_SSL_CTX(s, ctx->ctx);
    if (!SSL_set_ex_data(s, kBudSSLSNIIndex, ctx))
      return SSL_TLSEXT_ERR_ALERT_FATAL;
  }

  return SSL_TLSEXT_ERR_OK;
}
コード例 #6
0
ファイル: SSLHelper.cpp プロジェクト: MarkYangUp/HP-Socket
int CALLBACK CSSLContext::InternalServerNameCallback(SSL* ssl, int* ad, void* arg)
{
	USES_CONVERSION;

	CSSLContext* pThis = (CSSLContext*)arg;
	ASSERT(pThis->m_fnServerNameCallback != nullptr);

	const char* lpszServerName = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);

	if(lpszServerName == nullptr)
		return SSL_TLSEXT_ERR_NOACK;

	int iIndex = pThis->m_fnServerNameCallback(A2CT(lpszServerName));

	if(iIndex == 0)
		return SSL_TLSEXT_ERR_OK;

	if(iIndex < 0)
	{
		::SetLastError(ERROR_INVALID_NAME);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	SSL_CTX* sslCtx = pThis->GetContext(iIndex);

	if(sslCtx == nullptr)
	{
		::SetLastError(ERROR_INVALID_INDEX);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	SSL_set_SSL_CTX(ssl, sslCtx);

	return SSL_TLSEXT_ERR_OK;
}
コード例 #7
0
ファイル: ssl.c プロジェクト: witchu/lua-openssl
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;
}
コード例 #8
0
ファイル: ssl.c プロジェクト: perry-clarke/luasec
static int meth_getsniname(lua_State *L)
{
  p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
  const char *name = SSL_get_servername(ssl->ssl, TLSEXT_NAMETYPE_host_name);
  if (name)
    lua_pushstring(L, name);
  else
    lua_pushnil(L);
  return 1;
}
コード例 #9
0
ファイル: s_client.c プロジェクト: 1310701102/sl4a
static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
	{
	tlsextctx * p = (tlsextctx *) arg;
	const char * hn= SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
	if (SSL_get_servername_type(s) != -1) 
 	        p->ack = !SSL_session_reused(s) && hn != NULL;
	else 
		BIO_printf(bio_err,"Can't use SSL_get_servername\n");
	
	return SSL_TLSEXT_ERR_OK;
	}
コード例 #10
0
SSLContext::ServerNameCallbackResult
SSLContextManager::serverNameCallback(SSL* ssl) {
  shared_ptr<SSLContext> ctx;

  const char* sn = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
  if (!sn) {
    VLOG(6) << "Server Name (tlsext_hostname) is missing";
    if (clientHelloTLSExtStats_) {
      clientHelloTLSExtStats_->recordAbsentHostname();
    }
    return SSLContext::SERVER_NAME_NOT_FOUND;
  }
  size_t snLen = strlen(sn);
  VLOG(6) << "Server Name (SNI TLS extension): '" << sn << "' ";

  // FIXME: This code breaks the abstraction. Suggestion?
  AsyncSSLSocket* sslSocket = AsyncSSLSocket::getFromSSL(ssl);
  CHECK(sslSocket);

  DNString dnstr(sn, snLen);

  uint32_t count = 0;
  do {
    // Try exact match first
    ctx = getSSLCtx(dnstr);
    if (ctx) {
      sslSocket->switchServerSSLContext(ctx);
      if (clientHelloTLSExtStats_) {
        clientHelloTLSExtStats_->recordMatch();
      }
      return SSLContext::SERVER_NAME_FOUND;
    }

    ctx = getSSLCtxBySuffix(dnstr);
    if (ctx) {
      sslSocket->switchServerSSLContext(ctx);
      if (clientHelloTLSExtStats_) {
        clientHelloTLSExtStats_->recordMatch();
      }
      return SSLContext::SERVER_NAME_FOUND;
    }

    // Give the noMatchFn one chance to add the correct cert
  }
  while (count++ == 0 && noMatchFn_ && noMatchFn_(sn));

  VLOG(6) << folly::stringPrintf("Cannot find a SSL_CTX for \"%s\"", sn);

  if (clientHelloTLSExtStats_) {
    clientHelloTLSExtStats_->recordNotMatch();
  }
  return SSLContext::SERVER_NAME_NOT_FOUND;
}
コード例 #11
0
static int uwsgi_sni_cb(SSL *ssl, int *ad, void *arg) {
        const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
        if (!servername) return SSL_TLSEXT_ERR_NOACK;
        size_t servername_len = strlen(servername);

        struct uwsgi_string_list *usl = uwsgi.sni;
        while(usl) {
                if (!uwsgi_strncmp(usl->value, usl->len, (char *)servername, servername_len)) {
                        SSL_set_SSL_CTX(ssl, usl->custom_ptr);
                        return SSL_TLSEXT_ERR_OK;
                }
                usl = usl->next;
        }

#ifdef UWSGI_PCRE
        struct uwsgi_regexp_list *url = uwsgi.sni_regexp;
        while(url) {
                if (uwsgi_regexp_match(url->pattern, url->pattern_extra, (char *)servername, servername_len) >= 0) {
                        SSL_set_SSL_CTX(ssl, url->custom_ptr);
                        return SSL_TLSEXT_ERR_OK;
                }
                url = url->next;
        }
#endif

	if (uwsgi.sni_dir) {
		size_t sni_dir_len = strlen(uwsgi.sni_dir);
		char *sni_dir_cert = uwsgi_concat4n(uwsgi.sni_dir, sni_dir_len, "/", 1, (char *) servername, servername_len, ".crt", 4);
		char *sni_dir_key = uwsgi_concat4n(uwsgi.sni_dir, sni_dir_len, "/", 1, (char *) servername, servername_len, ".key", 4);
		char *sni_dir_client_ca = uwsgi_concat4n(uwsgi.sni_dir, sni_dir_len, "/", 1, (char *) servername, servername_len, ".ca", 3);
		if (uwsgi_file_exists(sni_dir_cert) && uwsgi_file_exists(sni_dir_key)) {
			char *client_ca = NULL;
			if (uwsgi_file_exists(sni_dir_client_ca)) {
				client_ca = sni_dir_client_ca;
			}
			usl = uwsgi_ssl_add_sni_item(uwsgi_str((char *)servername), sni_dir_cert, sni_dir_key, uwsgi.sni_dir_ciphers, client_ca);
			if (!usl) goto done;
			free(sni_dir_cert);
			free(sni_dir_key);
			free(sni_dir_client_ca);
			SSL_set_SSL_CTX(ssl, usl->custom_ptr);
			uwsgi_log("[uwsgi-sni for pid %d] added context for %s\n", (int) getpid(), servername);
			return SSL_TLSEXT_ERR_OK;
		}
done:
		free(sni_dir_cert);
		free(sni_dir_key);
		free(sni_dir_client_ca);
	}

        return SSL_TLSEXT_ERR_NOACK;
}
コード例 #12
0
ファイル: sock.cpp プロジェクト: ksuarz/mongo
std::string Socket::getSNIServerName() const {
    if (!_sslConnection)
        return "";

    if (!_sslConnection->ssl)
        return "";

    const char* name = SSL_get_servername(_sslConnection->ssl, TLSEXT_NAMETYPE_host_name);
    if (!name)
        return "";

    return name;
}
コード例 #13
0
ファイル: openssl-server.c プロジェクト: PKRoma/libwebsockets
static int
lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
{
	struct lws_context *context = (struct lws_context *)arg;
	struct lws_vhost *vhost, *vh;
	const char *servername;

	if (!ssl)
		return SSL_TLSEXT_ERR_NOACK;

	/*
	 * We can only get ssl accepted connections by using a vhost's ssl_ctx
	 * find out which listening one took us and only match vhosts on the
	 * same port.
	 */
	vh = context->vhost_list;
	while (vh) {
		if (!vh->being_destroyed &&
		    vh->tls.ssl_ctx == SSL_get_SSL_CTX(ssl))
			break;
		vh = vh->vhost_next;
	}

	if (!vh) {
		assert(vh); /* can't match the incoming vh? */
		return SSL_TLSEXT_ERR_OK;
	}

	servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
	if (!servername) {
		/* the client doesn't know what hostname it wants */
		lwsl_info("SNI: Unknown ServerName: %s\n", servername);

		return SSL_TLSEXT_ERR_OK;
	}

	vhost = lws_select_vhost(context, vh->listen_port, servername);
	if (!vhost) {
		lwsl_info("SNI: none: %s:%d\n", servername, vh->listen_port);

		return SSL_TLSEXT_ERR_OK;
	}

	lwsl_info("SNI: Found: %s:%d\n", servername, vh->listen_port);

	/* select the ssl ctx from the selected vhost for this conn */
	SSL_set_SSL_CTX(ssl, vhost->tls.ssl_ctx);

	return SSL_TLSEXT_ERR_OK;
}
コード例 #14
0
ファイル: cryptor_libssl.c プロジェクト: Daniel15/webserver
static int
openssl_sni_servername_cb (SSL *ssl, int *ad, void *arg)
{
	ret_t                      ret;
	int                        re;
	const char                *servername;
	cherokee_connection_t     *conn;
	cherokee_buffer_t          tmp;
	cherokee_server_t         *srv       = SRV(arg);
	cherokee_virtual_server_t *vsrv      = NULL;

	UNUSED(ad);

	/* Get the pointer to the socket
	 */
	conn = SSL_get_app_data (ssl);
	if (unlikely (conn == NULL)) {
		LOG_ERROR (CHEROKEE_ERROR_SSL_SOCKET, ssl);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	cherokee_buffer_init(&tmp);
	cherokee_buffer_ensure_size(&tmp, 40);

	/* Read the SNI server name
	 */
	servername = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name);
	if (servername == NULL) {
		/* Set the server name to the IP address if we couldn't get the host name via SNI
		 */
		cherokee_socket_ntop (&conn->socket, tmp.buf, tmp.size);
		TRACE (ENTRIES, "No SNI: Did not provide a server name, using IP='%s' as servername.\n", tmp.buf);
	} else {
		cherokee_buffer_add (&tmp, servername, strlen(servername));
		TRACE (ENTRIES, "SNI: Switching to servername='%s'\n", servername);
	}

	/* Look up and change the vserver
	 */
	ret = cherokee_cryptor_libssl_find_vserver(ssl, srv, &tmp, conn);
	if (ret != ret_ok) {
		re = SSL_TLSEXT_ERR_NOACK;
	}
	else {
		re = SSL_TLSEXT_ERR_OK;
	}

	cherokee_buffer_mrproper (&tmp);
	return re;
}
コード例 #15
0
ファイル: tls_select.c プロジェクト: alezzandro/kamailio
static int get_tlsext_sn(str* res, sip_msg_t* msg)
{
	static char buf[1024];
	struct tcp_connection* c;
	str server_name;	
	SSL* ssl;

	c = get_cur_connection(msg);
	if (!c) {
		INFO("TLS connection not found in select_desc\n");
		goto error;
	}
	ssl = get_ssl(c);
	if (!ssl) goto error;

	buf[0] = '\0';

	server_name.s = (char*)SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
	if (server_name.s) {
		server_name.len = strlen(server_name.s);
		DBG("received server_name (TLS extension): '%.*s'\n", 
			STR_FMT(&server_name));
	} else {
		DBG("SSL_get_servername returned NULL\n");
		goto error;
	}
	
	/* copy server_name into the buffer. If the buffer is too small copy only
	 * the last bytes as these are the more important ones and prefix with
	 * '+' */
	if (server_name.len > sizeof(buf)) {
		ERR("server_name to big for buffer\n");
		buf[0] = '+';
		memcpy(buf + 1, server_name.s + 1 + server_name.len - sizeof(buf), 
			   sizeof(buf) - 1);
		res->len = sizeof(buf);
	} else {
		memcpy(buf, server_name.s, server_name.len);
		res->len = server_name.len;
	}
	res->s = buf;
	
	tcpconn_put(c);
	return 0;
	
error:
	if (c) tcpconn_put(c);
	return -1;
}
コード例 #16
0
ファイル: ssl-server.c プロジェクト: harron/libwebsockets
static int
lws_ssl_server_name_cb(SSL *ssl, int *ad, void *arg)
{
	struct lws_context *context;
	struct lws_vhost *vhost, *vh;
	const char *servername;
	int port;

	if (!ssl)
		return SSL_TLSEXT_ERR_NOACK;

	context = (struct lws_context *)SSL_CTX_get_ex_data(
					SSL_get_SSL_CTX(ssl),
					openssl_SSL_CTX_private_data_index);

	/*
	 * We can only get ssl accepted connections by using a vhost's ssl_ctx
	 * find out which listening one took us and only match vhosts on the
	 * same port.
	 */
	vh = context->vhost_list;
	while (vh) {
		if (!vh->being_destroyed && vh->ssl_ctx == SSL_get_SSL_CTX(ssl))
			break;
		vh = vh->vhost_next;
	}

	assert(vh); /* we cannot get an ssl without using a vhost ssl_ctx */
	port = vh->listen_port;

	servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);

	if (servername) {
		vhost = lws_select_vhost(context, port, servername);
		if (vhost) {
			lwsl_debug("SNI: Found: %s (port %d)\n",
				   servername, port);
			SSL_set_SSL_CTX(ssl, vhost->ssl_ctx);
			return SSL_TLSEXT_ERR_OK;
		}
		lwsl_err("SNI: Unknown ServerName: %s\n", servername);
	}

	return SSL_TLSEXT_ERR_OK;
}
コード例 #17
0
ファイル: network.c プロジェクト: h0tw1r3/asuswrt-merlin
static int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) {
	const char *servername;
	connection *con = (connection *) SSL_get_app_data(ssl);
	UNUSED(al);

	buffer_copy_string(con->uri.scheme, "https");

	if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
#if 0
		/* this "error" just means the client didn't support it */
		log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
				"failed to get TLS server name");
#endif
		return SSL_TLSEXT_ERR_NOACK;
	}
	buffer_copy_string(con->tlsext_server_name, servername);
	buffer_to_lower(con->tlsext_server_name);

	/* Sometimes this is still set, confusing COMP_HTTP_HOST */
	buffer_reset(con->uri.authority);

	config_cond_cache_reset(srv, con);
	config_setup_connection(srv, con);

	config_patch_connection(srv, con, COMP_SERVER_SOCKET);
	config_patch_connection(srv, con, COMP_HTTP_SCHEME);
	config_patch_connection(srv, con, COMP_HTTP_HOST);

	if (NULL == con->conf.ssl_ctx) {
		/* ssl_ctx <=> pemfile was set <=> ssl_ctx got patched: so this should never happen */
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
			"null SSL_CTX for TLS server name", con->tlsext_server_name);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	/* switch to new SSL_CTX in reaction to a client's server_name extension */
	if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) {
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
			"failed to set SSL_CTX for TLS server name", con->tlsext_server_name);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	return SSL_TLSEXT_ERR_OK;
}
コード例 #18
0
ファイル: ctx.c プロジェクト: NickolasLapp/stunnel
NOEXPORT int servername_cb(SSL *ssl, int *ad, void *arg) {
    SERVICE_OPTIONS *section=(SERVICE_OPTIONS *)arg;
    const char *servername=SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
    SERVERNAME_LIST *list;
    CLI *c;
#ifdef USE_LIBWRAP
    char *accepted_address;
#endif /* USE_LIBWRAP */

    /* leave the alert type at SSL_AD_UNRECOGNIZED_NAME */
    (void)ad; /* squash the unused parameter warning */
    if(!section->servername_list_head) {
        s_log(LOG_DEBUG, "SNI: no virtual services defined");
        return SSL_TLSEXT_ERR_OK;
    }
    if(!servername) {
        s_log(LOG_NOTICE, "SNI: no servername received");
        return SSL_TLSEXT_ERR_NOACK;
    }
    s_log(LOG_INFO, "SNI: requested servername: %s", servername);

    for(list=section->servername_list_head; list; list=list->next)
        if(matches_wildcard((char *)servername, list->servername)) {
            s_log(LOG_DEBUG, "SNI: matched pattern: %s", list->servername);
            c=SSL_get_ex_data(ssl, index_cli);
            c->opt=list->opt;
            SSL_set_SSL_CTX(ssl, c->opt->ctx);
            SSL_set_verify(ssl, SSL_CTX_get_verify_mode(c->opt->ctx),
                SSL_CTX_get_verify_callback(c->opt->ctx));
            s_log(LOG_NOTICE, "SNI: switched to service [%s]",
                c->opt->servname);
#ifdef USE_LIBWRAP
            accepted_address=s_ntop(&c->peer_addr, c->peer_addr_len);
            libwrap_auth(c, accepted_address); /* retry on a service switch */
            str_free(accepted_address);
#endif /* USE_LIBWRAP */
            return SSL_TLSEXT_ERR_OK;
        }
    s_log(LOG_ERR, "SNI: no pattern matched servername: %s", servername);
    return SSL_TLSEXT_ERR_ALERT_FATAL;
}
コード例 #19
0
ファイル: ssl.c プロジェクト: hfeeki/blastbeat
static int bb_ssl_servername(SSL *ssl,int *ad, void *arg) {
	const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
	if (!servername) return SSL_TLSEXT_ERR_NOACK;
	struct bb_connection *bbc = SSL_get_ex_data(ssl, blastbeat.ssl_index);
	struct bb_acceptor *bba = bbc->acceptor;
	size_t servername_len = strlen(servername);

	struct bb_virtualhost *vhost = NULL;
	struct bb_hostname *bbhn = NULL;

	if (bba->addr.in4.sin_port != htons(443) && !strchr(servername, ':')) {
		size_t port_len = strlen(bba->port_str);
		char *new_sn = bb_alloc(servername_len+port_len);
		if (!new_sn) return SSL_TLSEXT_ERR_NOACK;
		memcpy(new_sn, servername, servername_len);
		memcpy(new_sn + servername_len, bba->port_str, port_len);

		vhost = bb_vhost_get(new_sn, servername_len+port_len, &bbhn);
		bb_free(new_sn, servername_len+port_len);
	}
	else {
		vhost = bb_vhost_get((char *)servername, servername_len, &bbhn);
	}

	if (!vhost) return SSL_TLSEXT_ERR_NOACK;
	// per vhost-context is required to decrypt keys sent by dealers
	if (!vhost->ctx) return SSL_TLSEXT_ERR_NOACK;

	// prefer dealer-defined context
	if (bbhn->ctx) {
		SSL_set_SSL_CTX(ssl, bbhn->ctx);
		return SSL_TLSEXT_ERR_OK;
	}


	SSL_set_SSL_CTX(ssl, vhost->ctx);

	return SSL_TLSEXT_ERR_OK;
}
コード例 #20
0
ファイル: KSSLSocket.cpp プロジェクト: wirror800/kangle
//sni lookup server name
int httpSSLServerName(SSL *ssl,int *ad,void *arg)
{
	const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
	if (servername==NULL) {
		return SSL_TLSEXT_ERR_NOACK;
	}
	KConnectionSelectable *c = (KConnectionSelectable *)SSL_get_ex_data(ssl,kangle_ssl_conntion_index);
	if (c==NULL) {
		return SSL_TLSEXT_ERR_NOACK;
	}
	if (c->sni) {
		return SSL_TLSEXT_ERR_OK;
	}
	c->sni = new KSSLSniContext;
	if (query_vh_success != conf.gvm->queryVirtualHost(c->ls,&c->sni->svh,servername)) {
		return SSL_TLSEXT_ERR_OK;
	}
	if (c->sni->svh->vh && c->sni->svh->vh->ssl_ctx) {
		SSL_set_SSL_CTX(ssl,c->sni->svh->vh->ssl_ctx);
	}
	return SSL_TLSEXT_ERR_OK;
}
コード例 #21
0
ファイル: ssl.c プロジェクト: perry-clarke/luasec
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;
}
コード例 #22
0
ファイル: mpr-openssl.c プロジェクト: leemit/ejscript
static int sniHostname(SSL *handle, int *ad, void *arg)
{
    MprSocket       *sp;
    MprSsl          *ssl;
    OpenSocket      *osp;
    OpenConfig      *cfg;
    SSL_CTX         *ctx;
    cchar           *hostname;

    if (!handle) {
        return SSL_TLSEXT_ERR_NOACK;
    }
    osp = (OpenSocket*) SSL_get_app_data(handle);
    sp = osp->sock;

    hostname = SSL_get_servername(handle, TLSEXT_NAMETYPE_host_name);

    /*
        Select the appropriate SSL for this hostname
     */
    if ((ssl = (sp->ssl->matchSsl)(sp, hostname)) == 0) {
        return SSL_TLSEXT_ERR_ALERT_FATAL;
    }
    lock(ssl);
    if (configOss(ssl, sp->flags, &sp->errorMsg) < 0) {
        unlock(ssl);
        return SSL_TLSEXT_ERR_ALERT_FATAL;
    }
    unlock(ssl);

    sp->ssl = ssl;
    cfg = ssl->config;
    ctx = cfg->ctx;
    SSL_set_SSL_CTX(handle, ctx);

    return SSL_TLSEXT_ERR_OK;
}
コード例 #23
0
ファイル: https.c プロジェクト: wangmingfu/G7Platform
int hr_https_add_vars(struct http_session *hr, struct corerouter_peer *peer, struct uwsgi_buffer *out) {
// HTTPS (adapted from nginx)
        if (hr->session.ugs->mode == UWSGI_HTTP_SSL) {
                if (uwsgi_buffer_append_keyval(out, "HTTPS", 5, "on", 2)) return -1;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
			const char *servername = SSL_get_servername(hr->ssl, TLSEXT_NAMETYPE_host_name);
                        if (servername && strlen(servername) <= 0xff) {
				peer->key_len = strlen(servername);
                        	memcpy(peer->key, servername, peer->key_len) ;
                        }
#endif
                hr->ssl_client_cert = SSL_get_peer_certificate(hr->ssl);
                if (hr->ssl_client_cert) {
                        X509_NAME *name = X509_get_subject_name(hr->ssl_client_cert);
                        if (name) {
                                hr->ssl_client_dn = X509_NAME_oneline(name, NULL, 0);
                                if (uwsgi_buffer_append_keyval(out, "HTTPS_DN", 8, hr->ssl_client_dn, strlen(hr->ssl_client_dn))) return -1;
                        }
                        if (uhttp.https_export_cert) {
                        hr->ssl_bio = BIO_new(BIO_s_mem());
                        if (hr->ssl_bio) {
                                if (PEM_write_bio_X509(hr->ssl_bio, hr->ssl_client_cert) > 0) {
                                        size_t cc_len = BIO_pending(hr->ssl_bio);
                                        hr->ssl_cc = uwsgi_malloc(cc_len);
                                        BIO_read(hr->ssl_bio, hr->ssl_cc, cc_len);
                                        if (uwsgi_buffer_append_keyval(out, "HTTPS_CC", 8, hr->ssl_cc, cc_len)) return -1;
                                }
                        }
                        }
                }
        }
        else if (hr->session.ugs->mode == UWSGI_HTTP_FORCE_SSL) {
                hr->force_https = 1;
        }

	return 0;
}
コード例 #24
0
ファイル: ssl.c プロジェクト: witchu/lua-openssl
static int openssl_ssl_get(lua_State*L)
{
  SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl");
  int i;
  int top = lua_gettop(L);
  for (i = 2; i <= top; i++)
  {
    const char* what = luaL_checklstring(L, i, NULL);
    if (strcmp(what, "fd") == 0)
    {
      lua_pushinteger(L, SSL_get_fd(s));
    }
    else if (strcmp(what, "rfd") == 0)
    {
      lua_pushinteger(L, SSL_get_rfd(s));
    }
    else if (strcmp(what, "wfd") == 0)
    {
      lua_pushinteger(L, SSL_get_wfd(s));
    }
    else if (strcmp(what, "client_CA_list") == 0)
    {
      STACK_OF(X509_NAME)* sn = SSL_get_client_CA_list(s);
      PUSH_OBJECT(sn, "openssl.sk_x509_name");
    }
    else if (strcmp(what, "read_ahead") == 0)
    {
      lua_pushboolean(L, SSL_get_read_ahead(s));
    }
    else if (strcmp(what, "shared_ciphers") == 0)
    {
      char buf[LUAL_BUFFERSIZE] = {0};
      lua_pushstring(L, SSL_get_shared_ciphers(s, buf, sizeof(buf)));
    }
    else if (strcmp(what, "cipher_list") == 0)
    {
      //TODO FIX
      lua_pushstring(L, SSL_get_cipher_list(s, 0));
    }
    else if (strcmp(what, "verify_mode") == 0)
    {
      //FIX
      lua_pushinteger(L, SSL_get_verify_mode(s));
    }
    else if (strcmp(what, "verify_depth") == 0)
    {
      lua_pushinteger(L, SSL_get_verify_depth(s));
    }
    else if (strcmp(what, "state_string") == 0)
    {
      lua_pushstring(L, SSL_state_string(s));
    }
    else if (strcmp(what, "state_string_long") == 0)
    {
      lua_pushstring(L, SSL_state_string_long(s));
    }
    else if (strcmp(what, "rstate_string") == 0)
    {
      lua_pushstring(L, SSL_rstate_string(s));
    }
    else if (strcmp(what, "rstate_string_long") == 0)
    {
      lua_pushstring(L, SSL_rstate_string_long(s));
    }
    else if (strcmp(what, "version") == 0)
    {
      lua_pushstring(L, SSL_get_version(s));
    }
    else if (strcmp(what, "iversion") == 0)
    {
      lua_pushinteger(L, SSL_version(s));
    }
    else if (strcmp(what, "default_timeout") == 0)
    {
      lua_pushinteger(L, SSL_get_default_timeout(s));
    }
    else if (strcmp(what, "certificate") == 0)
    {
      X509* cert = SSL_get_certificate(s);
      PUSH_OBJECT(cert, "openssl.x509");
    }
    else if (strcmp(what, "verify_result") == 0)
    {
      long l = SSL_get_verify_result(s);
      lua_pushinteger(L, l);
    }
    else if (strcmp(what, "version") == 0)
    {
      lua_pushstring(L, SSL_get_version(s));
    }
    else if (strcmp(what, "state") == 0)
    {
      lua_pushinteger(L, SSL_state(s));
    }
    else if (strcmp(what, "hostname") == 0)
    {
      lua_pushstring(L, SSL_get_servername(s, TLSEXT_NAMETYPE_host_name));
    }
    else
      luaL_argerror(L, i, "can't understant");
  }
  return top - 1;
}
コード例 #25
0
ファイル: tls.c プロジェクト: jedisct1/pure-ftpd
static int ssl_servername_cb(SSL *cnx, int *al, void *arg)
{
    CertResult  result;
    const char *sni_name;

    (void) al;
    (void) arg;
    if ((sni_name = SSL_get_servername(cnx, TLSEXT_NAMETYPE_host_name))
        == NULL || *sni_name == 0 || validate_sni_name(sni_name) != 0) {
        return SSL_TLSEXT_ERR_NOACK;
    }
    logfile(LOG_INFO, "SNI: [%s]", sni_name);
    if (chrooted != 0 || loggedin != 0) {
        return SSL_TLSEXT_ERR_NOACK;
    }
    if (use_extcert == 0) {
        return SSL_TLSEXT_ERR_OK;
    }
    memset(&result, 0, sizeof result);
    tls_extcert_get(&result, sni_name);
    if (result.cert_ok != 1) {
        die(400, LOG_ERR, "Cert handler not ready");
    }
    if (result.action == CERT_ACTION_DENY) {
        die(400, LOG_INFO, MSG_LOGOUT);
    }
    if (result.action == CERT_ACTION_DEFAULT) {
        return SSL_TLSEXT_ERR_OK;
    }
    if (result.cert_file == NULL) {
        if (result.action == CERT_ACTION_STRICT) {
            die(400, LOG_ERR, "Missing certificate");
        } else {
            return SSL_TLSEXT_ERR_OK;
        }
    }
    if (result.key_file == NULL) {
        result.key_file = result.cert_file;
    }
    SSL_CTX_free(tls_ctx);
    tls_ctx = NULL;
    if (tls_create_new_context(result.cert_file, result.key_file) != 0) {
        if (result.action != CERT_ACTION_FALLBACK) {
            die(400, LOG_ERR, "Invalid certificate");
        }
        if (tls_create_new_context(cert_file, key_file) != 0) {
            die(400, LOG_ERR, "SSL error");
        }
    }
    if ((client_sni_name = strdup(sni_name)) == NULL) {
        die_mem();
    }
    if (tls_cnx != NULL) {
        const long ctx_options = SSL_CTX_get_options(tls_ctx);
        SSL_set_SSL_CTX(tls_cnx, tls_ctx);
# ifdef SSL_CTRL_CLEAR_OPTIONS
        SSL_clear_options(tls_cnx,
                          SSL_get_options(tls_cnx) & ~ctx_options);
# endif
        SSL_set_options(tls_cnx, ctx_options);
    }
    if (tls_data_cnx != NULL) {
        const long ctx_options = SSL_CTX_get_options(tls_ctx);
        SSL_set_SSL_CTX(tls_data_cnx, tls_ctx);
# ifdef SSL_CTRL_CLEAR_OPTIONS
        SSL_clear_options(tls_data_cnx,
                          SSL_get_options(tls_cnx) & ~ctx_options);
# endif
        SSL_set_options(tls_data_cnx, ctx_options);
    }
    return SSL_TLSEXT_ERR_OK;
}
コード例 #26
0
ファイル: network.c プロジェクト: Master-Lee/lighttpd1.4
static int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) {
	const char *servername;
	connection *con = (connection *) SSL_get_app_data(ssl);
	UNUSED(al);

	buffer_copy_string(con->uri.scheme, "https");

	if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
#if 0
		/* this "error" just means the client didn't support it */
		log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
				"failed to get TLS server name");
#endif
		return SSL_TLSEXT_ERR_NOACK;
	}
	buffer_copy_string(con->tlsext_server_name, servername);
	buffer_to_lower(con->tlsext_server_name);

	/* Sometimes this is still set, confusing COMP_HTTP_HOST */
	buffer_reset(con->uri.authority);

	config_cond_cache_reset(srv, con);
	config_setup_connection(srv, con);

	con->conditional_is_valid[COMP_SERVER_SOCKET] = 1;
	con->conditional_is_valid[COMP_HTTP_SCHEME] = 1;
	con->conditional_is_valid[COMP_HTTP_HOST] = 1;
	config_patch_connection(srv, con);

	if (NULL == con->conf.ssl_pemfile_x509 || NULL == con->conf.ssl_pemfile_pkey) {
		/* x509/pkey available <=> pemfile was set <=> pemfile got patched: so this should never happen, unless you nest $SERVER["socket"] */
		log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:",
			"no certificate/private key for TLS server name", con->tlsext_server_name);
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	/* first set certificate! setting private key checks whether certificate matches it */
	if (!SSL_use_certificate(ssl, con->conf.ssl_pemfile_x509)) {
		log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
			"failed to set certificate for TLS server name", con->tlsext_server_name,
			ERR_error_string(ERR_get_error(), NULL));
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	if (!SSL_use_PrivateKey(ssl, con->conf.ssl_pemfile_pkey)) {
		log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
			"failed to set private key for TLS server name", con->tlsext_server_name,
			ERR_error_string(ERR_get_error(), NULL));
		return SSL_TLSEXT_ERR_ALERT_FATAL;
	}

	if (con->conf.ssl_verifyclient) {
		if (NULL == con->conf.ssl_ca_file_cert_names) {
			log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:",
				"can't verify client without ssl.ca-file for TLS server name", con->tlsext_server_name,
				ERR_error_string(ERR_get_error(), NULL));
			return SSL_TLSEXT_ERR_ALERT_FATAL;
		}

		SSL_set_client_CA_list(ssl, SSL_dup_CA_list(con->conf.ssl_ca_file_cert_names));
		/* forcing verification here is really not that useful - a client could just connect without SNI */
		SSL_set_verify(
			ssl,
			SSL_VERIFY_PEER | (con->conf.ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0),
			NULL
		);
		SSL_set_verify_depth(ssl, con->conf.ssl_verifyclient_depth);
	} else {
		SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
	}

	return SSL_TLSEXT_ERR_OK;
}
コード例 #27
0
ファイル: vsslserver.cpp プロジェクト: AmesianX/vdream
// int VSslServer::ssl_servername_cb_debug(SSL *con, int *ad, void *arg, int* debug) // gilgil temp 2014.03.14
int VSslServer::ssl_servername_cb(SSL *con, int *ad, void *arg)
{
  Q_UNUSED(ad)

  const char* serverName = SSL_get_servername(con, TLSEXT_NAMETYPE_host_name);
  // *debug = 1000; // gilgil temp 2014.03.14

  if (serverName == NULL)
  {
    LOG_DEBUG("serverName is null");
    return SSL_TLSEXT_ERR_NOACK;
  }
  // *debug = 2500; // gilgil temp 2014.03.14
  // LOG_DEBUG("serverName=%p %s", serverName, serverName); // gilgil temp 2014.03.14
  // *debug = 3000; // gilgil temp 2014.03.14

  VSslServer* server  = (VSslServer*)(arg);
  LOG_ASSERT(server != NULL);

  VSslServerSession* session = (VSslServerSession*)SSL_get_ex_data(con, VSslSession::VSSL_SESSION_IDENTIFY_INDEX);
  LOG_ASSERT(session->con == con);

  // *debug = 500; // gilgil temp 2014.03.14
  // LOG_DEBUG("server=%p session=%p", server, session); // gilgil temp 2014.03.14

  QString path = server->certificatePath;
  QFileInfo fi(path);
  if (!fi.isAbsolute())
  {
    // path = VApp::_filePath() + path; // gilgil temp 2014.12.25
    path = QCoreApplication::applicationDirPath() + QDir::separator() + path;
  }
  if (!path.endsWith('/') && !path.endsWith('\\')) path += QDir::separator();

  QString fileName = path + serverName + ".pem";
  // *debug = 4000; // gilgil temp 2014.03.14
  {
    VLock lock(server->certificateCs); // protect file create critical section
    // *debug = 5000; // gilgil temp 2014.03.14
    if (!QFile::exists(fileName))
    {
      QProcess process;

      process.setWorkingDirectory(path);
      LOG_DEBUG("working directory=%s", qPrintable(process.workingDirectory())); // gilgil temp 2014.03.01

      QString command = QString("\"%1_make_site.bat\" %2 2>&1").arg(path).arg(serverName);
      LOG_INFO("command=%s", qPrintable(command));

      process.start(command);
      // LOG_DEBUG("pid=%llx", process.pid()); // gilgil temp 2015.01.02

      // *debug = 6000; // gilgil temp 2014.03.14
      if(!process.waitForStarted())
      {
        LOG_FATAL("process.waitForStarted(%s) return false", qPrintable(command));
      }
      // *debug = 700; // gilgil temp 2014.03.14
      while(process.waitForReadyRead())
      {
        QByteArray ba = process.readAll();
        LOG_DEBUG("ba.size=%d", ba.size())
        LOG_DEBUG("ba.datas=%s", ba.data());
      }
      // *debug = 8000; // gilgil temp 2014.03.14
    }
    // *debug = 9000; // gilgil temp 2014.03.14
    // LOG_DEBUG("con=%p", con); // gilgil temp 2014.03.14
    // *debug = 9100; // gilgil temp 2014.03.14
    if (!session->setup(fileName))
    {
      LOG_ERROR("session->setup(%s) return false", qPrintable(fileName));
    }
    // *debug = 9500; // gilgil temp 2014.03.14
  }

  return SSL_TLSEXT_ERR_NOACK;
}
コード例 #28
0
static int
ngx_http_multiple_ssl_cert_handler(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
{
    ngx_connection_t           *c;
    ngx_http_connection_t      *hc;
    const char                 *servername;
    ngx_str_t                   cert;
    ngx_str_t                   key;
    ngx_str_t                   host;

    ngx_http_multiple_ssl_srv_conf_t   *mscf;


    c = ngx_ssl_get_connection(ssl_conn);
    if (c == NULL) {
        return 0;
    }

    hc = c->data;
    if (NULL == hc) {
        ngx_log_error(NGX_LOG_ERR, c->log, 0,
                   "multiple ssl connection data hc NULL");
        return 0;
    }

    servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
    if (servername == NULL) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "multiple ssl SSL_get_servername NULL");

        return SSL_TLSEXT_ERR_NOACK;
    }

    host.len = ngx_strlen(servername);
    if (host.len == 0) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
            "multiple ssl servername len == 0");

        return SSL_TLSEXT_ERR_NOACK;
    }

    host.data = (u_char *) servername;
    ngx_log_error(NGX_LOG_INFO, c->log, 0, "multiple ssl servername \"%V\"", &host);

    mscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_multiple_ssl_module);
    if (NULL == mscf) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "multiple ssl mscf NULL");
        return SSL_TLSEXT_ERR_NOACK;
    }

    if (!mscf->multiple_ssl_enable) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
            "multiple ssl multiple_ssl_enable OFF");

        return SSL_TLSEXT_ERR_NOACK;
    }

    cert.len = mscf->multiple_ssl_cert_path.len + 2 + host.len + ngx_strlen(".cert.der");
    key.len = mscf->multiple_ssl_cert_path.len + 2 + host.len + ngx_strlen(".key.der");
    cert.data = ngx_pnalloc(c->pool, cert.len);
    if (NULL == cert.data) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "multiple ssl cert.data NULL");
        return SSL_TLSEXT_ERR_NOACK;
    }
    ngx_memzero(cert.data, cert.len);
    ngx_sprintf(cert.data, "%V/%V.cert.der", &mscf->multiple_ssl_cert_path, &host);
    *(cert.data+cert.len) = 0;
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "multiple ssl cert %V", &cert);

    key.data = ngx_pnalloc(c->pool, key.len+1);
    if (NULL == key.data) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "multiple ssl key.data NULL");
        return SSL_TLSEXT_ERR_NOACK;
    }
    ngx_memzero(key.data, key.len);
    ngx_sprintf(key.data, "%V/%V.key.der", &mscf->multiple_ssl_cert_path, &host);
    *(key.data+key.len) = 0;

    if (0 != access((const char *)cert.data, F_OK|R_OK)) {
        ngx_log_debug1(NGX_LOG_WARN, c->log, 0, "multiple ssl cert [%V] not exists or not read", &cert);
        return SSL_TLSEXT_ERR_NOACK;
    }

    ngx_http_multiple_ssl_set_der_certificate(ssl_conn, &cert, &key);

    return SSL_TLSEXT_ERR_OK;
}
コード例 #29
0
ファイル: sslrouter.c プロジェクト: chain710/uwsgi
static ssize_t sr_read(struct corerouter_peer *main_peer) {
        struct corerouter_session *cs = main_peer->session;
        struct sslrouter_session *sr = (struct sslrouter_session *) cs;

        int ret = SSL_read(sr->ssl, main_peer->in->buf + main_peer->in->pos, main_peer->in->len - main_peer->in->pos);
        if (ret > 0) {
                // fix the buffer
                main_peer->in->pos += ret;
                // check for pending data
                int ret2 = SSL_pending(sr->ssl);
                if (ret2 > 0) {
                        if (uwsgi_buffer_fix(main_peer->in, main_peer->in->len + ret2 )) {
                                uwsgi_cr_log(main_peer, "cannot fix the buffer to %d\n", main_peer->in->len + ret2);
                                return -1;
                        }
                        if (SSL_read(sr->ssl, main_peer->in->buf + main_peer->in->pos, ret2) != ret2) {
                                uwsgi_cr_log(main_peer, "SSL_read() on %d bytes of pending data failed\n", ret2);
                                return -1;
                        }
                        // fix the buffer
                        main_peer->in->pos += ret2;
                }
		if (!main_peer->session->peers) {
			// add a new peer
        		struct corerouter_peer *peer = uwsgi_cr_peer_add(cs);
        		// set default peer hook
        		peer->last_hook_read = sr_instance_read;
        		// use the address as hostname
        		peer->key = cs->ugs->name;
        		peer->key_len = cs->ugs->name_len;

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
			if (usr.sni) {
				const char *servername = SSL_get_servername(sr->ssl, TLSEXT_NAMETYPE_host_name);
				if (servername) {
        				peer->key = (char *) servername;
        				peer->key_len = strlen(servername);
				}
			}
#endif
        		// the mapper hook
        		if (cs->corerouter->mapper(cs->corerouter, peer)) {
                		return -1;
        		}

        		if (peer->instance_address_len == 0) {
                		return -1;
        		}

			peer->can_retry = 1;
        		cr_connect(peer, sr_instance_connected);
			return 1;
		}
		main_peer->session->peers->out = main_peer->in;
        	main_peer->session->peers->out_pos = 0;
		cr_write_to_backend(main_peer, sr_instance_write);
		return ret;
        }
        if (ret == 0) return 0;
        int err = SSL_get_error(sr->ssl, ret);

        if (err == SSL_ERROR_WANT_READ) {
                cr_reset_hooks_and_read(main_peer, sr_read);
                return 1;
        }

        else if (err == SSL_ERROR_WANT_WRITE) {
                cr_write_to_main(main_peer, sr_read);
                return 1;
        }

        else if (err == SSL_ERROR_SYSCALL) {
                uwsgi_cr_error(main_peer, "sr_ssl_read()");
        }

        else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
                ERR_print_errors_fp(stderr);
        }

        return -1;
}
コード例 #30
0
ファイル: ssl_engine_vars.c プロジェクト: pexip/os-apache2
static char *ssl_var_lookup_ssl(apr_pool_t *p, SSLConnRec *sslconn, 
                                request_rec *r, char *var)
{
    char *result;
    X509 *xs;
    STACK_OF(X509) *sk;
    SSL *ssl;

    result = NULL;

    ssl = sslconn->ssl;
    if (strlen(var) > 8 && strcEQn(var, "VERSION_", 8)) {
        result = ssl_var_lookup_ssl_version(p, var+8);
    }
    else if (ssl != NULL && strcEQ(var, "PROTOCOL")) {
        result = (char *)SSL_get_version(ssl);
    }
    else if (ssl != NULL && strcEQ(var, "SESSION_ID")) {
        char buf[MODSSL_SESSION_ID_STRING_LEN];
        SSL_SESSION *pSession = SSL_get_session(ssl);
        if (pSession) {
            IDCONST unsigned char *id;
            unsigned int idlen;

#ifdef OPENSSL_NO_SSL_INTERN
            id = (unsigned char *)SSL_SESSION_get_id(pSession, &idlen);
#else
            id = pSession->session_id;
            idlen = pSession->session_id_length;
#endif

            result = apr_pstrdup(p, modssl_SSL_SESSION_id2sz(id, idlen,
                                                             buf, sizeof(buf)));
        }
    }
    else if(ssl != NULL && strcEQ(var, "SESSION_RESUMED")) {
        if (SSL_session_reused(ssl) == 1)
            result = "Resumed";
        else
            result = "Initial";
    }
    else if (ssl != NULL && strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) {
        result = ssl_var_lookup_ssl_cipher(p, sslconn, var+6);
    }
    else if (ssl != NULL && strlen(var) > 18 && strcEQn(var, "CLIENT_CERT_CHAIN_", 18)) {
        sk = SSL_get_peer_cert_chain(ssl);
        result = ssl_var_lookup_ssl_cert_chain(p, sk, var+18);
    }
    else if (ssl != NULL && strcEQ(var, "CLIENT_CERT_RFC4523_CEA")) {
        result = ssl_var_lookup_ssl_cert_rfc4523_cea(p, ssl);
    }
    else if (ssl != NULL && strcEQ(var, "CLIENT_VERIFY")) {
        result = ssl_var_lookup_ssl_cert_verify(p, sslconn);
    }
    else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "CLIENT_", 7)) {
        if ((xs = SSL_get_peer_certificate(ssl)) != NULL) {
            result = ssl_var_lookup_ssl_cert(p, r, xs, var+7);
            X509_free(xs);
        }
    }
    else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "SERVER_", 7)) {
        if ((xs = SSL_get_certificate(ssl)) != NULL) {
            result = ssl_var_lookup_ssl_cert(p, r, xs, var+7);
            /* SSL_get_certificate is different from SSL_get_peer_certificate.
             * No need to X509_free(xs).
             */
        }
    }
    else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) {
        result = ssl_var_lookup_ssl_compress_meth(ssl);
    }
#ifdef HAVE_TLSEXT
    else if (ssl != NULL && strcEQ(var, "TLS_SNI")) {
        result = apr_pstrdup(p, SSL_get_servername(ssl,
                                                   TLSEXT_NAMETYPE_host_name));
    }
#endif
    else if (ssl != NULL && strcEQ(var, "SECURE_RENEG")) {
        int flag = 0;
#ifdef SSL_get_secure_renegotiation_support
        flag = SSL_get_secure_renegotiation_support(ssl);
#endif
        result = apr_pstrdup(p, flag ? "true" : "false");
    }
#ifdef HAVE_SRP
    else if (ssl != NULL && strcEQ(var, "SRP_USER")) {
        if ((result = SSL_get_srp_username(ssl)) != NULL) {
            result = apr_pstrdup(p, result);
        }
    }
    else if (ssl != NULL && strcEQ(var, "SRP_USERINFO")) {
        if ((result = SSL_get_srp_userinfo(ssl)) != NULL) {
            result = apr_pstrdup(p, result);
        }
    }
#endif

    return result;
}