コード例 #1
0
ファイル: socket.c プロジェクト: deweerdt/h2o
void h2o_socket_ssl_async_resumption_setup_ctx(SSL_CTX *ctx)
{
    SSL_CTX_sess_set_get_cb(ctx, on_async_resumption_get);
    SSL_CTX_sess_set_new_cb(ctx, on_async_resumption_new);
    SSL_CTX_sess_set_remove_cb(ctx, on_async_resumption_remove);
    /* if necessary, it is the responsibility of the caller to disable the internal cache */
}
コード例 #2
0
SSLSessionCacheManager::SSLSessionCacheManager(
  uint32_t maxCacheSize,
  uint32_t cacheCullSize,
  SSLContext* ctx,
  const folly::SocketAddress& sockaddr,
  const string& context,
  EventBase* eventBase,
  SSLStats* stats,
  const std::shared_ptr<SSLCacheProvider>& externalCache):
    ctx_(ctx),
    stats_(stats),
    externalCache_(externalCache) {

  SSL_CTX* sslCtx = ctx->getSSLCtx();

  SSLUtil::getSSLCtxExIndex(&sExDataIndex_);

  SSL_CTX_set_ex_data(sslCtx, sExDataIndex_, this);
  SSL_CTX_sess_set_new_cb(sslCtx, SSLSessionCacheManager::newSessionCallback);
  SSL_CTX_sess_set_get_cb(sslCtx, SSLSessionCacheManager::getSessionCallback);
  SSL_CTX_sess_set_remove_cb(sslCtx,
                             SSLSessionCacheManager::removeSessionCallback);
  if (!FLAGS_dcache_unit_test && !context.empty()) {
    // Use the passed in context
    ctx->setSessionCacheContext(context);
  }

  SSL_CTX_set_session_cache_mode(sslCtx, SSL_SESS_CACHE_NO_INTERNAL
                                 | SSL_SESS_CACHE_SERVER);

  localCache_ = SSLSessionCacheManager::getLocalCache(maxCacheSize,
                                                      cacheCullSize);

  VLOG(2) << "On VipID=" << sockaddr.describe() << " context=" << context;
}
コード例 #3
0
ファイル: openssl.c プロジェクト: piaoasd123/ServerTest
/*
  Initializes SSL and allocate global
  context SSL_context

  SYNOPSIS
    my_ssl_start
      mysql        connection handle

  RETURN VALUES
    0  success
    1  error
*/
int ma_tls_start(char *errmsg, size_t errmsg_len)
{
  int rc= 1;
  if (ma_tls_initialized)
    return 0;

  /* lock mutex to prevent multiple initialization */
  pthread_mutex_init(&LOCK_openssl_config,MY_MUTEX_INIT_FAST);
  pthread_mutex_lock(&LOCK_openssl_config);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
#else
  if (ssl_thread_init())
  {
    strncpy(errmsg, "Not enough memory", errmsg_len);
    goto end;
  }
  SSL_library_init();

#if SSLEAY_VERSION_NUMBER >= 0x00907000L
  OPENSSL_config(NULL);
#endif
#endif
  /* load errors */
  SSL_load_error_strings();
  /* digests and ciphers */
  OpenSSL_add_all_algorithms();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
  if (!(SSL_context= SSL_CTX_new(TLS_client_method())))
#else
  if (!(SSL_context= SSL_CTX_new(SSLv23_client_method())))
#endif
  {
    ma_tls_get_error(errmsg, errmsg_len);
    goto end;
  }
#ifdef HAVE_TLS_SESSION_CACHE
  SSL_CTX_set_session_cache_mode(SSL_context, SSL_SESS_CACHE_CLIENT);
  ma_tls_sessions= (MA_SSL_SESSION *)calloc(1, sizeof(struct st_ma_tls_session) * ma_tls_session_cache_size);
  SSL_CTX_sess_set_new_cb(SSL_context, ma_tls_session_cb);
  SSL_CTX_sess_set_remove_cb(SSL_context, ma_tls_remove_session_cb);
#endif
  disable_sigpipe();
#if OPENSSL_USE_BIOMETHOD
  memcpy(&ma_BIO_method, BIO_s_socket(), sizeof(BIO_METHOD));
  ma_BIO_method.bread= ma_bio_read;
  ma_BIO_method.bwrite= ma_bio_write;
#endif
  rc= 0;
  ma_tls_initialized= TRUE;
end:
  pthread_mutex_unlock(&LOCK_openssl_config);
  return rc;
}
コード例 #4
0
ファイル: ssl_engine_init.c プロジェクト: haggaie/httpd
static void ssl_init_ctx_session_cache(server_rec *s,
                                       apr_pool_t *p,
                                       apr_pool_t *ptemp,
                                       modssl_ctx_t *mctx)
{
    SSL_CTX *ctx = mctx->ssl_ctx;
    SSLModConfigRec *mc = myModConfig(s);
    long cache_mode = SSL_SESS_CACHE_OFF;
    if (mc->nSessionCacheMode != SSL_SCMODE_NONE) {
        /* SSL_SESS_CACHE_NO_INTERNAL will force OpenSSL
         * to ignore process local-caching and
         * to always get/set/delete sessions using mod_ssl's callbacks.
         */
        cache_mode = SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL;
    }

    SSL_CTX_set_session_cache_mode(ctx, cache_mode);

    SSL_CTX_sess_set_new_cb(ctx,    ssl_callback_NewSessionCacheEntry);
    SSL_CTX_sess_set_get_cb(ctx,    ssl_callback_GetSessionCacheEntry);
    SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
}
コード例 #5
0
ファイル: ctx.c プロジェクト: NickolasLapp/stunnel
int context_init(SERVICE_OPTIONS *section) { /* init SSL context */
    /* create SSL context */
    if(section->option.client)
        section->ctx=SSL_CTX_new(section->client_method);
    else /* server mode */
        section->ctx=SSL_CTX_new(section->server_method);
    if(!section->ctx) {
        sslerror("SSL_CTX_new");
        return 1; /* FAILED */
    }
    SSL_CTX_set_ex_data(section->ctx, index_opt, section); /* for callbacks */

    /* load certificate and private key to be verified by the peer server */
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_VERSION_NUMBER>=0x0090809fL
    /* SSL_CTX_set_client_cert_engine() was introduced in OpenSSL 0.9.8i */
    if(section->option.client && section->engine) {
        if(SSL_CTX_set_client_cert_engine(section->ctx, section->engine))
            s_log(LOG_INFO, "Client certificate engine (%s) enabled",
                ENGINE_get_id(section->engine));
        else /* no client certificate functionality in this engine */
            sslerror("SSL_CTX_set_client_cert_engine"); /* ignore error */
    }
#endif
    if(auth_init(section))
        return 1; /* FAILED */

    /* initialize verification of the peer server certificate */
    if(verify_init(section))
        return 1; /* FAILED */

    /* initialize DH/ECDH server mode */
    if(!section->option.client) {
#ifndef OPENSSL_NO_TLSEXT
        SSL_CTX_set_tlsext_servername_arg(section->ctx, section);
        SSL_CTX_set_tlsext_servername_callback(section->ctx, servername_cb);
#endif /* OPENSSL_NO_TLSEXT */
#ifndef OPENSSL_NO_DH
        dh_init(section); /* ignore the result (errors are not critical) */
#endif /* OPENSSL_NO_DH */
#ifndef OPENSSL_NO_ECDH
        ecdh_init(section); /* ignore the result (errors are not critical) */
#endif /* OPENSSL_NO_ECDH */
    }

    /* setup session cache */
    if(!section->option.client) {
        unsigned servname_len=(unsigned)strlen(section->servname);
        if(servname_len>SSL_MAX_SSL_SESSION_ID_LENGTH)
            servname_len=SSL_MAX_SSL_SESSION_ID_LENGTH;
        if(!SSL_CTX_set_session_id_context(section->ctx,
                (unsigned char *)section->servname, servname_len)) {
            sslerror("SSL_CTX_set_session_id_context");
            return 1; /* FAILED */
        }
    }
#ifdef SSL_SESS_CACHE_NO_INTERNAL_STORE
    /* the default cache mode is just SSL_SESS_CACHE_SERVER */
    SSL_CTX_set_session_cache_mode(section->ctx,
        SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE);
#endif
    SSL_CTX_sess_set_cache_size(section->ctx, section->session_size);
    SSL_CTX_set_timeout(section->ctx, section->session_timeout);
    SSL_CTX_sess_set_new_cb(section->ctx, sess_new_cb);
    SSL_CTX_sess_set_get_cb(section->ctx, sess_get_cb);
    SSL_CTX_sess_set_remove_cb(section->ctx, sess_remove_cb);

    /* set info callback */
    SSL_CTX_set_info_callback(section->ctx, info_callback);

    /* ciphers, options, mode */
    if(section->cipher_list)
        if(!SSL_CTX_set_cipher_list(section->ctx, section->cipher_list)) {
            sslerror("SSL_CTX_set_cipher_list");
            return 1; /* FAILED */
        }
    SSL_CTX_set_options(section->ctx,
        (SSL_OPTIONS_TYPE)(section->ssl_options_set));
#if OPENSSL_VERSION_NUMBER>=0x009080dfL
    SSL_CTX_clear_options(section->ctx,
        (SSL_OPTIONS_TYPE)(section->ssl_options_clear));
    s_log(LOG_DEBUG, "SSL options: 0x%08lX (+0x%08lX, -0x%08lX)",
        SSL_CTX_get_options(section->ctx),
        section->ssl_options_set, section->ssl_options_clear);
#else /* OpenSSL older than 0.9.8m */
    s_log(LOG_DEBUG, "SSL options: 0x%08lX (+0x%08lX)",
        SSL_CTX_get_options(section->ctx),
        section->ssl_options_set);
#endif /* OpenSSL 0.9.8m or later */

    /* initialize OpenSSL CONF options */
    if(conf_init(section))
        return 1; /* FAILED */

#ifdef SSL_MODE_RELEASE_BUFFERS
    SSL_CTX_set_mode(section->ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE |
        SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
        SSL_MODE_RELEASE_BUFFERS);
#else
    SSL_CTX_set_mode(section->ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE |
        SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
    return 0; /* OK */
}
コード例 #6
0
static int execute_test_session(SSL_SESSION_TEST_FIXTURE fix)
{
    SSL_CTX *sctx = NULL, *cctx = NULL;
    SSL *serverssl1 = NULL, *clientssl1 = NULL;
    SSL *serverssl2 = NULL, *clientssl2 = NULL;
#ifndef OPENSSL_NO_TLS1_1
    SSL *serverssl3 = NULL, *clientssl3 = NULL;
#endif
    SSL_SESSION *sess1 = NULL, *sess2 = NULL;
    int testresult = 0;

    if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx,
                             &cctx, cert, privkey)) {
        printf("Unable to create SSL_CTX pair\n");
        return 0;
    }

#ifndef OPENSSL_NO_TLS1_2
    /* Only allow TLS1.2 so we can force a connection failure later */
    SSL_CTX_set_min_proto_version(cctx, TLS1_2_VERSION);
#endif

    /* Set up session cache */
    if (fix.use_ext_cache) {
        SSL_CTX_sess_set_new_cb(cctx, new_session_cb);
        SSL_CTX_sess_set_remove_cb(cctx, remove_session_cb);
    }
    if (fix.use_int_cache) {
        /* Also covers instance where both are set */
        SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT);
    } else {
        SSL_CTX_set_session_cache_mode(cctx,
                                       SSL_SESS_CACHE_CLIENT
                                       | SSL_SESS_CACHE_NO_INTERNAL_STORE);
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL,
                               NULL)) {
        printf("Unable to create SSL objects\n");
        goto end;
    }

    if (!create_ssl_connection(serverssl1, clientssl1)) {
        printf("Unable to create SSL connection\n");
        goto end;
    }
    sess1 = SSL_get1_session(clientssl1);
    if (sess1 == NULL) {
        printf("Unexpected NULL session\n");
        goto end;
    }

    if (fix.use_int_cache && SSL_CTX_add_session(cctx, sess1)) {
        /* Should have failed because it should already be in the cache */
        printf("Unexpected success adding session to cache\n");
        goto end;
    }

    if (fix.use_ext_cache && (new_called != 1 || remove_called != 0)) {
        printf("Session not added to cache\n");
        goto end;
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl2, &clientssl2, NULL, NULL)) {
        printf("Unable to create second SSL objects\n");
        goto end;
    }

    if (!create_ssl_connection(serverssl2, clientssl2)) {
        printf("Unable to create second SSL connection\n");
        goto end;
    }

    sess2 = SSL_get1_session(clientssl2);
    if (sess2 == NULL) {
        printf("Unexpected NULL session from clientssl2\n");
        goto end;
    }

    if (fix.use_ext_cache && (new_called != 2 || remove_called != 0)) {
        printf("Remove session callback unexpectedly called\n");
        goto end;
    }

    /*
     * This should clear sess2 from the cache because it is a "bad" session. See
     * SSL_set_session() documentation.
     */
    if (!SSL_set_session(clientssl2, sess1)) {
        printf("Unexpected failure setting session\n");
        goto end;
    }

    if (fix.use_ext_cache && (new_called != 2 || remove_called != 1)) {
        printf("Failed to call callback to remove session\n");
        goto end;
    }


    if (SSL_get_session(clientssl2) != sess1) {
        printf("Unexpected session found\n");
        goto end;
    }

    if (fix.use_int_cache) {
        if (!SSL_CTX_add_session(cctx, sess2)) {
            /*
             * Should have succeeded because it should not already be in the cache
             */
            printf("Unexpected failure adding session to cache\n");
            goto end;
        }

        if (!SSL_CTX_remove_session(cctx, sess2)) {
            printf("Unexpected failure removing session from cache\n");
            goto end;
        }

        /* This is for the purposes of internal cache testing...ignore the
         * counter for external cache
         */
        if (fix.use_ext_cache)
            remove_called--;
    }

    /* This shouldn't be in the cache so should fail */
    if (SSL_CTX_remove_session(cctx, sess2)) {
        printf("Unexpected success removing session from cache\n");
        goto end;
    }

    if (fix.use_ext_cache && (new_called != 2 || remove_called != 2)) {
        printf("Failed to call callback to remove session #2\n");
        goto end;
    }

#if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_2)
    /* Force a connection failure */
    SSL_CTX_set_max_proto_version(sctx, TLS1_1_VERSION);

    if (!create_ssl_objects(sctx, cctx, &serverssl3, &clientssl3, NULL, NULL)) {
        printf("Unable to create third SSL objects\n");
        goto end;
    }

    if (!SSL_set_session(clientssl3, sess1)) {
        printf("Unable to set session for third connection\n");
        goto end;
    }

    /* This should fail because of the mismatched protocol versions */
    if (create_ssl_connection(serverssl3, clientssl3)) {
        printf("Unable to create third SSL connection\n");
        goto end;
    }


    /* We should have automatically removed the session from the cache */
    if (fix.use_ext_cache && (new_called != 2 || remove_called != 3)) {
        printf("Failed to call callback to remove session #2\n");
        goto end;
    }

    if (fix.use_int_cache && !SSL_CTX_add_session(cctx, sess2)) {
        /*
         * Should have succeeded because it should not already be in the cache
         */
        printf("Unexpected failure adding session to cache #2\n");
        goto end;
    }
#endif

    testresult = 1;

 end:
    SSL_free(serverssl1);
    SSL_free(clientssl1);
    SSL_free(serverssl2);
    SSL_free(clientssl2);
#ifndef OPENSSL_NO_TLS1_1
    SSL_free(serverssl3);
    SSL_free(clientssl3);
#endif
    SSL_SESSION_free(sess1);
    SSL_SESSION_free(sess2);
    /*
     * Check if we need to remove any sessions up-refed for the external cache
     */
    if (new_called >= 1)
        SSL_SESSION_free(sess1);
    if (new_called >= 2)
        SSL_SESSION_free(sess2);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);

    return testresult;
}
コード例 #7
0
/*
 *	Create Global context SSL and use it in every new session
 *
 *	- Load the trusted CAs
 *	- Load the Private key & the certificate
 *	- Set the Context options & Verify options
 */
static SSL_CTX *init_tls_ctx(EAP_TLS_CONF *conf)
{
	SSL_METHOD *meth;
	SSL_CTX *ctx;
	X509_STORE *certstore;
	int verify_mode = SSL_VERIFY_NONE;
	int ctx_options = 0;
	int type;

	/*
	 *	Add all the default ciphers and message digests
	 *	Create our context.
	 */
	SSL_library_init();
	SSL_load_error_strings();

	/*
	 *	SHA256 is in all versions of OpenSSL, but isn't
	 *	initialized by default.  It's needed for WiMAX
	 *	certificates.
	 */
#ifdef HAVE_OPENSSL_EVP_SHA256
	EVP_add_digest(EVP_sha256());
#endif

	meth = TLSv1_method();
	ctx = SSL_CTX_new(meth);

	/*
	 * Identify the type of certificates that needs to be loaded
	 */
	if (conf->file_type) {
		type = SSL_FILETYPE_PEM;
	} else {
		type = SSL_FILETYPE_ASN1;
	}

	/*
	 * Set the password to load private key
	 */
	if (conf->private_key_password) {
#ifdef __APPLE__
		/*
		 * We don't want to put the private key password in eap.conf, so  check
		 * for our special string which indicates we should get the password
		 * programmatically. 
		 */
		const char* special_string = "Apple:UseCertAdmin";
		if (strncmp(conf->private_key_password,
					special_string,
					strlen(special_string)) == 0)
		{
			char cmd[256];
			const long max_password_len = 128;
			snprintf(cmd, sizeof(cmd) - 1,
					 "/usr/sbin/certadmin --get-private-key-passphrase \"%s\"",
					 conf->private_key_file);

			DEBUG2("rlm_eap: Getting private key passphrase using command \"%s\"", cmd);

			FILE* cmd_pipe = popen(cmd, "r");
			if (!cmd_pipe) {
				radlog(L_ERR, "rlm_eap: %s command failed.	Unable to get private_key_password", cmd);
				radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file);
				return NULL;
			}

			free(conf->private_key_password);
			conf->private_key_password = malloc(max_password_len * sizeof(char));
			if (!conf->private_key_password) {
				radlog(L_ERR, "rlm_eap: Can't malloc space for private_key_password");
				radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file);
				pclose(cmd_pipe);
				return NULL;
			}

			fgets(conf->private_key_password, max_password_len, cmd_pipe);
			pclose(cmd_pipe);

			/* Get rid of newline at end of password. */
			conf->private_key_password[strlen(conf->private_key_password) - 1] = '\0';
			DEBUG2("rlm_eap:  Password from command = \"%s\"", conf->private_key_password);
		}
#endif
		SSL_CTX_set_default_passwd_cb_userdata(ctx, conf->private_key_password);
		SSL_CTX_set_default_passwd_cb(ctx, cbtls_password);
	}

	/*
	 *	Load our keys and certificates
	 *
	 *	If certificates are of type PEM then we can make use
	 *	of cert chain authentication using openssl api call
	 *	SSL_CTX_use_certificate_chain_file.  Please see how
	 *	the cert chain needs to be given in PEM from
	 *	openSSL.org
	 */
	if (type == SSL_FILETYPE_PEM) {
		if (!(SSL_CTX_use_certificate_chain_file(ctx, conf->certificate_file))) {
			radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
			radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
			return NULL;
		}

	} else if (!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, type))) {
		radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
		radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file);
		return NULL;
	}

	/* Load the CAs we trust */
	if (conf->ca_file || conf->ca_path) {
		if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) {
			radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
			radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file );
			return NULL;
		}
	}
	if (conf->ca_file && *conf->ca_file) SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file));
	if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) {
		radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
		radlog(L_ERR, "rlm_eap_tls: Error reading private key file %s", conf->private_key_file);
		return NULL;
	}

	/*
	 * Check if the loaded private key is the right one
	 */
	if (!SSL_CTX_check_private_key(ctx)) {
		radlog(L_ERR, "rlm_eap_tls: Private key does not match the certificate public key");
		return NULL;
	}

	/*
	 *	Set ctx_options
	 */
	ctx_options |= SSL_OP_NO_SSLv2;
   	ctx_options |= SSL_OP_NO_SSLv3;
#ifdef SSL_OP_NO_TICKET
	ctx_options |= SSL_OP_NO_TICKET ;
#endif

	/*
	 *	SSL_OP_SINGLE_DH_USE must be used in order to prevent
	 *	small subgroup attacks and forward secrecy. Always
	 *	using
	 *
	 *	SSL_OP_SINGLE_DH_USE has an impact on the computer
	 *	time needed during negotiation, but it is not very
	 *	large.
	 */
   	ctx_options |= SSL_OP_SINGLE_DH_USE;

	/*
	 *	SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS to work around issues
	 *	in Windows Vista client.
	 *	http://www.openssl.org/~bodo/tls-cbc.txt
	 *	http://www.nabble.com/(RADIATOR)-Radiator-Version-3.16-released-t2600070.html
	 */
   	ctx_options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;

	SSL_CTX_set_options(ctx, ctx_options);

	/*
	 *	TODO: Set the RSA & DH
	 *	SSL_CTX_set_tmp_rsa_callback(ctx, cbtls_rsa);
	 *	SSL_CTX_set_tmp_dh_callback(ctx, cbtls_dh);
	 */

	/*
	 *	set the message callback to identify the type of
	 *	message.  For every new session, there can be a
	 *	different callback argument.
	 *
	 *	SSL_CTX_set_msg_callback(ctx, cbtls_msg);
	 */

	/* Set Info callback */
	SSL_CTX_set_info_callback(ctx, cbtls_info);

	/*
	 *	Callbacks, etc. for session resumption.
	 */						      
	if (conf->session_cache_enable) {
		SSL_CTX_sess_set_new_cb(ctx, cbtls_new_session);
		SSL_CTX_sess_set_get_cb(ctx, cbtls_get_session);
		SSL_CTX_sess_set_remove_cb(ctx, cbtls_remove_session);

		SSL_CTX_set_quiet_shutdown(ctx, 1);
	}

	/*
	 *	Check the certificates for revocation.
	 */
#ifdef X509_V_FLAG_CRL_CHECK
	if (conf->check_crl) {
	  certstore = SSL_CTX_get_cert_store(ctx);
	  if (certstore == NULL) {
	    radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
	    radlog(L_ERR, "rlm_eap_tls: Error reading Certificate Store");
	    return NULL;
	  }
	  X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
	}
#endif

	/*
	 *	Set verify modes
	 *	Always verify the peer certificate
	 */
	verify_mode |= SSL_VERIFY_PEER;
	verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
	verify_mode |= SSL_VERIFY_CLIENT_ONCE;
	SSL_CTX_set_verify(ctx, verify_mode, cbtls_verify);

	if (conf->verify_depth) {
		SSL_CTX_set_verify_depth(ctx, conf->verify_depth);
	}

	/* Load randomness */
	if (!(RAND_load_file(conf->random_file, 1024*1024))) {
		radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL));
		radlog(L_ERR, "rlm_eap_tls: Error loading randomness");
		return NULL;
	}

	/*
	 * Set the cipher list if we were told to
	 */
	if (conf->cipher_list) {
		if (!SSL_CTX_set_cipher_list(ctx, conf->cipher_list)) {
			radlog(L_ERR, "rlm_eap_tls: Error setting cipher list");
			return NULL;
		}
	}

	/*
	 *	Setup session caching
	 */
	if (conf->session_cache_enable) {
		/*
		 *	Create a unique context Id per EAP-TLS configuration.
		 */
		if (conf->session_id_name) {
			snprintf(conf->session_context_id,
				 sizeof(conf->session_context_id),
				 "FreeRADIUS EAP-TLS %s",
				 conf->session_id_name);
		} else {
			snprintf(conf->session_context_id,
				 sizeof(conf->session_context_id),
				 "FreeRADIUS EAP-TLS %p", conf);
		}

		/*
		 *	Cache it, and DON'T auto-clear it.
		 */
		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR);
					       
		SSL_CTX_set_session_id_context(ctx,
					       (unsigned char *) conf->session_context_id,
					       (unsigned int) strlen(conf->session_context_id));

		/*
		 *	Our timeout is in hours, this is in seconds.
		 */
		SSL_CTX_set_timeout(ctx, conf->session_timeout * 3600);
		
		/*
		 *	Set the maximum number of entries in the
		 *	session cache.
		 */
		SSL_CTX_sess_set_cache_size(ctx, conf->session_cache_size);

	} else {
		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
	}

	/*
	 *	Register the application indices.  We can't use
	 *	hard-coded "0" and "1" as before, because we need to
	 *	set up a "free" handler for the cached session
	 *	information.
	 */
	if (eaptls_handle_idx < 0) {
		eaptls_handle_idx = SSL_get_ex_new_index(0, &eaptls_handle_idx,
							 NULL, NULL, NULL);
	}
	
	if (eaptls_conf_idx < 0) {
		eaptls_conf_idx = SSL_get_ex_new_index(0, &eaptls_conf_idx,
							  NULL, NULL, NULL);
	}

	if (eaptls_store_idx < 0) {
		eaptls_store_idx = SSL_get_ex_new_index(0, "eaptls_store_idx",
							  NULL, NULL, NULL);
	}

	if (eaptls_session_idx < 0) {
		eaptls_session_idx = SSL_get_ex_new_index(0, &eaptls_session_idx,
							  NULL, NULL,
							  eaptls_session_free);
	}

	return ctx;
}
コード例 #8
0
static
int tls_init_context(tls_t *tls, tls_issues_t const *ti)
{
  int verify;
  static int random_loaded;

  ONCE_INIT(tls_init_once);

  if (!random_loaded) {
    random_loaded = 1;

    if (ti->randFile &&
	!RAND_load_file(ti->randFile, 1024 * 1024)) {
      if (ti->configured > 1) {
	SU_DEBUG_3(("%s: cannot open randFile %s\n",
		   "tls_init_context", ti->randFile));
	tls_log_errors(3, "tls_init_context", 0);
      }
      /* errno = EIO; */
      /* return -1; */
    }
  }

#if HAVE_SIGPIPE
  /* Avoid possible SIGPIPE when sending close_notify */
  signal(SIGPIPE, SIG_IGN);
#endif

  if (tls->ctx == NULL)
    if (!(tls->ctx = SSL_CTX_new((SSL_METHOD*)SSLv23_method()))) {
      tls_log_errors(1, "SSL_CTX_new() failed", 0);
      errno = EIO;
      return -1;
    }
  if (!(ti->version & TPTLS_VERSION_SSLv2))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv2);
  if (!(ti->version & TPTLS_VERSION_SSLv3))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv3);
  if (!(ti->version & TPTLS_VERSION_TLSv1))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1);
  if (!(ti->version & TPTLS_VERSION_TLSv1_1))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1_1);
  if (!(ti->version & TPTLS_VERSION_TLSv1_2))
    SSL_CTX_set_options(tls->ctx, SSL_OP_NO_TLSv1_2);
  SSL_CTX_sess_set_remove_cb(tls->ctx, NULL);
  SSL_CTX_set_timeout(tls->ctx, ti->timeout);

  /* Set callback if we have a passphrase */
  if (ti->passphrase != NULL) {
    SSL_CTX_set_default_passwd_cb(tls->ctx, passwd_cb);
    SSL_CTX_set_default_passwd_cb_userdata(tls->ctx, (void *)ti);
  }

  if (!SSL_CTX_use_certificate_file(tls->ctx,
				    ti->cert,
				    SSL_FILETYPE_PEM)) {
    if (ti->configured > 0) {
      SU_DEBUG_1(("%s: invalid local certificate: %s\n",
		 "tls_init_context", ti->cert));
      tls_log_errors(3, "tls_init_context", 0);
#if require_client_certificate
      errno = EIO;
      return -1;
#endif
    }
  }

  if (!SSL_CTX_use_PrivateKey_file(tls->ctx,
                                   ti->key,
                                   SSL_FILETYPE_PEM)) {
    if (ti->configured > 0) {
      SU_DEBUG_1(("%s: invalid private key: %s\n",
		 "tls_init_context", ti->key));
      tls_log_errors(3, "tls_init_context(key)", 0);
#if require_client_certificate
      errno = EIO;
      return -1;
#endif
    }
  }

  if (!SSL_CTX_check_private_key(tls->ctx)) {
    if (ti->configured > 0) {
      SU_DEBUG_1(("%s: private key does not match the certificate public key\n",
		  "tls_init_context"));
    }
#if require_client_certificate
    errno = EIO;
    return -1;
#endif
  }

  if (!SSL_CTX_load_verify_locations(tls->ctx,
                                     ti->CAfile,
                                     ti->CApath)) {
    SU_DEBUG_1(("%s: error loading CA list: %s\n",
		 "tls_init_context", ti->CAfile));
    if (ti->configured > 0)
      tls_log_errors(3, "tls_init_context(CA)", 0);
    errno = EIO;
    return -1;
  }

  /* corresponds to (enum tport_tls_verify_policy) */
  tls->verify_incoming = (ti->policy & 0x1) ? 1 : 0;
  tls->verify_outgoing = (ti->policy & 0x2) ? 1 : 0;
  tls->verify_subj_in  = (ti->policy & 0x4) ? tls->verify_incoming : 0;
  tls->verify_subj_out = (ti->policy & 0x8) ? tls->verify_outgoing : 0;
  tls->verify_date     = (ti->verify_date)  ? 1 : 0;

  if (tls->verify_incoming)
    verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
  else
    verify = SSL_VERIFY_NONE;

  SSL_CTX_set_verify_depth(tls->ctx, ti->verify_depth);
  SSL_CTX_set_verify(tls->ctx, verify, tls_verify_cb);

  if (tls_init_ecdh_curve(tls) == 0) {
    SU_DEBUG_3(("%s\n", "tls: initialized ECDH"));
  } else {
    SU_DEBUG_3(("%s\n", "tls: failed to initialize ECDH"));
  }

  if (!SSL_CTX_set_cipher_list(tls->ctx, ti->ciphers)) {
    SU_DEBUG_1(("%s: error setting cipher list\n", "tls_init_context"));
    tls_log_errors(3, "tls_init_context", 0);
    errno = EIO;
    return -1;
  }

  return 0;
}
コード例 #9
0
static int tport_ws_init_primary_secure(tport_primary_t *pri,
				 tp_name_t tpn[1],
				 su_addrinfo_t *ai,
				 tagi_t const *tags,
				 char const **return_culprit)
{
  tport_ws_primary_t *wspri = (tport_ws_primary_t *)pri;
  const char *cert = "/ssl.pem";
  const char *key = "/ssl.pem";
  char *homedir;
  char *tbf = NULL;
  su_home_t autohome[SU_HOME_AUTO_SIZE(1024)];
  char const *path = NULL;
  int ret = -1;

  su_home_auto(autohome, sizeof autohome);

  tl_gets(tags,
	  TPTAG_CERTIFICATE_REF(path),
	  TAG_END());

  if (!path) {
    homedir = getenv("HOME");
    if (!homedir)
      homedir = "";
    path = tbf = su_sprintf(autohome, "%s/.sip/auth", homedir);
  }

  if (path) {
    key  = su_sprintf(autohome, "%s/%s", path, "wss.key");
	if (access(key, R_OK) != 0) key = NULL;
	cert = su_sprintf(autohome, "%s/%s", path, "wss.crt");
	if (access(cert, R_OK) != 0) cert = NULL;
	if ( !key )  key  = su_sprintf(autohome, "%s/%s", path, "wss.pem");
	if ( !cert ) cert = su_sprintf(autohome, "%s/%s", path, "wss.pem");
	if (access(key, R_OK) != 0) key = NULL;
	if (access(cert, R_OK) != 0) cert = NULL;
  }

  init_ssl();

  //  OpenSSL_add_all_algorithms();   /* load & register cryptos */                                                                                       
  //  SSL_load_error_strings();     /* load all error messages */                                                                                         
  wspri->ssl_method = SSLv23_server_method();   /* create server instance */
  wspri->ssl_ctx = SSL_CTX_new((SSL_METHOD *)wspri->ssl_method);         /* create context */
  SSL_CTX_sess_set_remove_cb(wspri->ssl_ctx, NULL);
  wspri->ws_secure = 1;

  if ( !wspri->ssl_ctx ) goto done;

  /* set the local certificate from CertFile */
  SSL_CTX_use_certificate_file(wspri->ssl_ctx, cert, SSL_FILETYPE_PEM);
  /* set the private key from KeyFile */
  SSL_CTX_use_PrivateKey_file(wspri->ssl_ctx, key, SSL_FILETYPE_PEM);
  /* verify private key */
  if ( !SSL_CTX_check_private_key(wspri->ssl_ctx) ) {
	  goto done;
  }

  SSL_CTX_set_cipher_list(wspri->ssl_ctx, "HIGH:!DSS:!aNULL@STRENGTH");

  ret = tport_ws_init_primary(pri, tpn, ai, tags, return_culprit);

 done:
  su_home_zap(autohome);
  return ret;
}
コード例 #10
0
ファイル: ossl_ssl.c プロジェクト: 2220142/ruby
/*
 * call-seq:
 *    ctx.setup => Qtrue # first time
 *    ctx.setup => nil # thereafter
 *
 * This method is called automatically when a new SSLSocket is created.
 * Normally you do not need to call this method (unless you are writing an extension in C).
 */
static VALUE
ossl_sslctx_setup(VALUE self)
{
    SSL_CTX *ctx;
    X509 *cert = NULL, *client_ca = NULL;
    X509_STORE *store;
    EVP_PKEY *key = NULL;
    char *ca_path = NULL, *ca_file = NULL;
    int i, verify_mode;
    VALUE val;

    if(OBJ_FROZEN(self)) return Qnil;
    Data_Get_Struct(self, SSL_CTX, ctx);

#if !defined(OPENSSL_NO_DH)
    if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){
	SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
    }
    else{
	SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback);
    }
#endif
    SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self);

    val = ossl_sslctx_get_cert_store(self);
    if(!NIL_P(val)){
	/*
         * WORKAROUND:
	 *   X509_STORE can count references, but
	 *   X509_STORE_free() doesn't care it.
	 *   So we won't increment it but mark it by ex_data.
	 */
        store = GetX509StorePtr(val); /* NO NEED TO DUP */
        SSL_CTX_set_cert_store(ctx, store);
        SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
    }

    val = ossl_sslctx_get_extra_cert(self);
    if(!NIL_P(val)){
	rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
    }

    /* private key may be bundled in certificate file. */
    val = ossl_sslctx_get_cert(self);
    cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
    val = ossl_sslctx_get_key(self);
    key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */
    if (cert && key) {
        if (!SSL_CTX_use_certificate(ctx, cert)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_certificate:");
        }
        if (!SSL_CTX_use_PrivateKey(ctx, key)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:");
        }
        if (!SSL_CTX_check_private_key(ctx)) {
            ossl_raise(eSSLError, "SSL_CTX_check_private_key:");
        }
    }

    val = ossl_sslctx_get_client_ca(self);
    if(!NIL_P(val)){
	if(TYPE(val) == T_ARRAY){
	    for(i = 0; i < RARRAY_LEN(val); i++){
		client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]);
        	if (!SSL_CTX_add_client_CA(ctx, client_ca)){
		    /* Copies X509_NAME => FREE it. */
        	    ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
        	}
	    }
        }
	else{
	    client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
            if (!SSL_CTX_add_client_CA(ctx, client_ca)){
		/* Copies X509_NAME => FREE it. */
        	ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
            }
	}
    }

    val = ossl_sslctx_get_ca_file(self);
    ca_file = NIL_P(val) ? NULL : StringValuePtr(val);
    val = ossl_sslctx_get_ca_path(self);
    ca_path = NIL_P(val) ? NULL : StringValuePtr(val);
    if(ca_file || ca_path){
	if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
	    rb_warning("can't set verify locations");
    }

    val = ossl_sslctx_get_verify_mode(self);
    verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
    SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
    if (RTEST(ossl_sslctx_get_client_cert_cb(self)))
	SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);

    val = ossl_sslctx_get_timeout(self);
    if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));

    val = ossl_sslctx_get_verify_dep(self);
    if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val));

    val = ossl_sslctx_get_options(self);
    if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val));
    rb_obj_freeze(self);

    val = ossl_sslctx_get_sess_id_ctx(self);
    if (!NIL_P(val)){
	StringValue(val);
	if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
					    RSTRING_LEN(val))){
	    ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:");
	}
    }

    if (RTEST(rb_iv_get(self, "@session_get_cb"))) {
	SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
	OSSL_Debug("SSL SESSION get callback added");
    }
    if (RTEST(rb_iv_get(self, "@session_new_cb"))) {
	SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
	OSSL_Debug("SSL SESSION new callback added");
    }
    if (RTEST(rb_iv_get(self, "@session_remove_cb"))) {
	SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
	OSSL_Debug("SSL SESSION remove callback added");
    }

#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
    val = rb_iv_get(self, "@servername_cb");
    if (!NIL_P(val)) {
        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
	OSSL_Debug("SSL TLSEXT servername callback added");
    }
#endif

    return Qtrue;
}
コード例 #11
0
ファイル: kTls.c プロジェクト: fractalspace/tahi
/* デフォルトの証明書は 自分:/usr/local/ct/cert/tn.pem 認証局:/usr/local/ct/cert/root.pem */
int kTLSInitialize(int sessionMode,int initialmode,int timeout,char *passwd,char *rootPEM,char *myPEM,
		   char *dhPEM,int version,int nagle,int clientveri,int tmprsa,char *enc)
{
    BIO         *bio;
    SSL_METHOD *meth;
    RSA *rsa;
    DH *dh=0;
    struct stat tmp;

    /* Nagleアルゴリズムの無効化フラグの保存 */
    NagleFlag=nagle;

    if(TLSctx){
      /* 強制初期化モードがある場合 */
      if(initialmode){
	TLSClose(NULL,0);
	kLogWrite(L_TLS, "%s: TLS ReInitialize", __FUNCTION__);
      }
      else
	return RETURN_OK;
    }

    /* パラメータの取得 */
    timeout = timeout<=0 ? SESSION_TIMEOUT : timeout;
    TLSSessionMode = sessionMode;
    kLogWrite(L_TLS,"%s: Session cache mode : %s   Session timeout : %d(s)",__FUNCTION__,sessionMode?"Enable":"Disable",timeout);

    rootPEM = (rootPEM && rootPEM[0]) ? rootPEM : ROOT_PEM;
    myPEM   = (myPEM && myPEM[0]) ?   myPEM   : MY_PEM;
    dhPEM   = (dhPEM && dhPEM[0]) ?   dhPEM   : DHFILE1024;
    strcpy(TLSPasswd,(passwd && passwd[0]) ?  passwd  : PASSWORD);

    if(lstat(rootPEM,&tmp)<0){
      kLogWrite(L_ERROR, "%s: TLS Initialize file[%s] not exist", __FUNCTION__,rootPEM);
      return(RETURN_NG);
    }
    if(lstat(myPEM,&tmp)<0){
      kLogWrite(L_ERROR, "%s: TLS Initialize file[%s] not exist", __FUNCTION__,myPEM);
      return(RETURN_NG);
    }
    if(lstat(dhPEM,&tmp)<0){
      kLogWrite(L_ERROR, "%s: TLS Initialize file[%s] not exist", __FUNCTION__,dhPEM);
      return(RETURN_NG);
    }

    /* SSLライブラリの初期化 */
    if(!SSL_library_init()){
      kLogWrite(L_ERROR, "%s: OpenSSL initialization failed!",__FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_library_init OK",__FUNCTION__);

    /* エラーメッセージの視覚化 */
    SSL_load_error_strings();

    RAND_load_file("/dev/urandom", 1024);
    kLogWrite(L_TLS,"%s: RAND_load_file OK",__FUNCTION__);

    /* SSL_METHODオブジェクトの取得 */
    if(version == 2)
      meth=SSLv2_method();
    else if(version == 3)
      meth=SSLv3_method();
    else if(version == 1)
      meth=TLSv1_method();
    else if(version == 23)
      meth=SSLv23_method();
    else
      meth=TLSv1_method();

    kLogWrite(L_TLS,"%s: SSL verion [%d] 2:SSLv2 23:SSLv23 3:SSLv3 1:TLSv1",__FUNCTION__,version);
    
    /* SSL_CTXオブジェクトの取得 */
    TLSctx=SSL_CTX_new(meth);
    kLogWrite(L_TLS,"%s: SSL_CTX_new OK",__FUNCTION__);

    /* SSL_CTXオブジェクトに証明書と秘密鍵を同時にロードする */
    if(!(SSL_CTX_use_certificate_file(TLSctx,myPEM,SSL_FILETYPE_PEM))){
      TLSClose(NULL,0);
      kLogWrite(L_ERROR, "%s: Couldn't read certificate file",__FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_CTX_use_certificate_file[%s] OK",__FUNCTION__,myPEM);

    /* パスフレーズのコールバック関数を登録する */
    SSL_CTX_set_default_passwd_cb(TLSctx,password_cb);

    if(!(SSL_CTX_use_PrivateKey_file(TLSctx,myPEM,SSL_FILETYPE_PEM))){
      TLSClose(NULL,0);
      kLogWrite(L_ERROR, "%s: Couldn't read key file",__FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_CTX_use_PrivateKey_file[%s] OK",__FUNCTION__,myPEM);
  
    /* SSL_CTXオブジェクトに信頼できるCA証明書をロードする */
    if(!(SSL_CTX_load_verify_locations(TLSctx,rootPEM,0))){
      TLSClose(NULL,0);
      kLogWrite(L_ERROR, "%s: Couldn't read CA list",__FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_CTX_load_verify_locations[%s] OK",__FUNCTION__,rootPEM);

    /* 認証コールバック関数の登録 */
    /* Server Key Exchange オプションを付与する (クライアント認証を行う) */
    kLogWrite(L_TLS,"%s: Server Key Exchange option : %s",__FUNCTION__,clientveri?"Enable":"Disable");
    SSL_CTX_set_verify(TLSctx, clientveri?SSL_VERIFY_PEER:SSL_VERIFY_NONE,VerifyCallback);
    kLogWrite(L_TLS,"%s:  SSL_CTX_set_verify[%s] OK",__FUNCTION__,clientveri?"PEER":"NONE");
    
    /* 信頼できる証明書に到達するまでのチェーンの回数を指定する */
    /* SSL_CTX_set_verify_depth(TLSctx,1); */

    /* SSLv2を選択不可にする */
    if(version != 2 && version != 23){
      SSL_CTX_set_options(TLSctx,SSL_OP_NO_SSLv2);
      kLogWrite(L_TLS,"%s: SSL_CTX_set_options NO_SSLv2",__FUNCTION__);
    }

    /* Certificate Request オプションを付与する (一時的RSAを使う ) */
    kLogWrite(L_TLS,"%s: Certificate Request option : %s",__FUNCTION__,tmprsa?"Enable":"Disable");
    if(tmprsa){

      /* BIOオブジェクトを使ってファイルをオープンする */
      if ((bio=BIO_new_file(dhPEM,"r")) == NULL){
	TLSClose(NULL,0);
	kLogWrite(L_ERROR, "%s: Couldn't open DH file",__FUNCTION__);
	return(RETURN_NG);
      }
      kLogWrite(L_TLS,"%s: BIO_new_file[%s] OK",__FUNCTION__,dhPEM);
    
      /* DHパラメータを読み込む */
      dh=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
      kLogWrite(L_TLS,"%s: PEM_read_bio_DHparams[%s] OK",__FUNCTION__,dhPEM);
      
      /* ファイルをクローズする */
      BIO_free(bio);
    
      /* DHパラメータをCTXオブジェクトにロードする */
      if(SSL_CTX_set_tmp_dh(TLSctx,dh)<0){
	TLSClose(NULL,0);
	kLogWrite(L_ERROR, "%s: Couldn't set DH parameters",__FUNCTION__);
	return(RETURN_NG);
      }
      kLogWrite(L_TLS,"%s: SSL_CTX_set_tmp_dh OK",__FUNCTION__);
    }

    /* 暗号スイートの選択 */
    if(enc && enc[0]){
      kLogWrite(L_TLS,"%s: Encrypt suit specified",__FUNCTION__);

      if(SSL_CTX_set_cipher_list(TLSctx,enc))
	kLogWrite(L_TLS,"%s:  SSL_CTX_set_cipher_list[%s] OK",__FUNCTION__,enc);
      else
	kLogWrite(L_TLS,"%s:  SSL_CTX_set_cipher_list[%s] invalid",__FUNCTION__,enc);
    }

    /* RSA鍵のペアを生成する */
    rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
    kLogWrite(L_TLS,"%s: RSA_generate_key OK",__FUNCTION__);
    
    /* RSA鍵をCTXオブジェクトにロードする */
    if (!SSL_CTX_set_tmp_rsa(TLSctx,rsa)){
      TLSClose(NULL,0);
      kLogWrite(L_ERROR, "%s: Couldn't set RSA key", __FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_CTX_set_tmp_rsa OK",__FUNCTION__);
    
    RSA_free(rsa);
  
    /* セッションキャッシュを有効モードに設定する */
    SSL_CTX_set_session_id_context(TLSctx,(void*)&TLSServerSessionIdContext, sizeof(TLSServerSessionIdContext));
    kLogWrite(L_TLS,"%s: SSL_CTX_set_session_id_context OK", __FUNCTION__);

    /* セッション削除時のコールバック設定 */
    SSL_CTX_sess_set_remove_cb(TLSctx,remove_session_cb);
    SSL_CTX_set_timeout(TLSctx,timeout);

    kLogWrite(L_TLS,"%s: Nagle algorithm : %s",__FUNCTION__,NagleFlag?"Enable":"Disable");

    return(RETURN_OK);
}
コード例 #12
0
ファイル: ctx.c プロジェクト: Jimdo/stunnel
int context_init(SERVICE_OPTIONS *section) { /* init SSL context */
    /* create SSL context */
    if(section->option.client)
        section->ctx=SSL_CTX_new(section->client_method);
    else /* server mode */
        section->ctx=SSL_CTX_new(section->server_method);
    if(!section->ctx) {
        sslerror("SSL_CTX_new");
        return 1; /* FAILED */
    }
    SSL_CTX_set_ex_data(section->ctx, opt_index, section); /* for callbacks */

    /* load certificate and private key to be verified by the peer server */
#ifdef HAVE_OSSL_ENGINE_H
    if(section->option.client && section->engine) {
        if(SSL_CTX_set_client_cert_engine(section->ctx, section->engine))
            s_log(LOG_INFO, "Client certificate engine (%s) enabled",
                ENGINE_get_id(section->engine));
        else /* no client certificate functionality in this engine */
            sslerror("SSL_CTX_set_client_cert_engine"); /* ignore error */
    }
#endif
    if(load_cert(section))
        return 1; /* FAILED */

    /* initialize verification of the peer server certificate */
    if(verify_init(section))
        return 1; /* FAILED */

    /* initialize DH/ECDH server mode */
    if(!section->option.client) {
#ifndef OPENSSL_NO_TLSEXT
        SSL_CTX_set_tlsext_servername_arg(section->ctx, section);
        SSL_CTX_set_tlsext_servername_callback(section->ctx, servername_cb);
#endif /* OPENSSL_NO_TLSEXT */
#ifndef OPENSSL_NO_DH
        init_dh(section); /* ignore the result (errors are not critical) */
#endif /* OPENSSL_NO_DH */
#ifndef OPENSSL_NO_ECDH
        init_ecdh(section); /* ignore the result (errors are not critical) */
#endif /* OPENSSL_NO_ECDH */
    }

    /* setup session cache */
    if(!section->option.client) {
        unsigned int servname_len=strlen(section->servname);
        if(servname_len>SSL_MAX_SSL_SESSION_ID_LENGTH)
            servname_len=SSL_MAX_SSL_SESSION_ID_LENGTH;
        if(!SSL_CTX_set_session_id_context(section->ctx,
                (unsigned char *)section->servname, servname_len)) {
            sslerror("SSL_CTX_set_session_id_context");
            return 1; /* FAILED */
        }
    }
    SSL_CTX_set_session_cache_mode(section->ctx, SSL_SESS_CACHE_BOTH);
    SSL_CTX_sess_set_cache_size(section->ctx, section->session_size);
    SSL_CTX_set_timeout(section->ctx, section->session_timeout);
    if(section->option.sessiond) {
        SSL_CTX_sess_set_new_cb(section->ctx, sess_new_cb);
        SSL_CTX_sess_set_get_cb(section->ctx, sess_get_cb);
        SSL_CTX_sess_set_remove_cb(section->ctx, sess_remove_cb);
    }

    /* set info callback */
    SSL_CTX_set_info_callback(section->ctx, info_callback);

    /* ciphers, options, mode */
    if(section->cipher_list)
        if(!SSL_CTX_set_cipher_list(section->ctx, section->cipher_list)) {
            sslerror("SSL_CTX_set_cipher_list");
            return 1; /* FAILED */
        }
    s_log(LOG_DEBUG, "SSL options set: 0x%08lX",
        SSL_CTX_set_options(section->ctx, section->ssl_options));
#ifdef SSL_MODE_RELEASE_BUFFERS
    SSL_CTX_set_mode(section->ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE |
        SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
        SSL_MODE_RELEASE_BUFFERS);
#else
    SSL_CTX_set_mode(section->ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE |
        SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
    return 0; /* OK */
}
コード例 #13
0
SSL_CTX *uwsgi_ssl_new_server_context(char *name, char *crt, char *key, char *ciphers, char *client_ca) {

        SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
        if (!ctx) {
                uwsgi_log("[uwsgi-ssl] unable to initialize context \"%s\"\n", name);
                return NULL;
        }

        // this part is taken from nginx and stud, removing unneeded functionality
        // stud (for me) has made the best choice on choosing DH approach

        long ssloptions = SSL_OP_NO_SSLv2 | SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
// disable compression (if possibile)
#ifdef SSL_OP_NO_COMPRESSION
        ssloptions |= SSL_OP_NO_COMPRESSION;
#endif

// release/reuse buffers as soon as possibile
#ifdef SSL_MODE_RELEASE_BUFFERS
        SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
#endif

        if (SSL_CTX_use_certificate_chain_file(ctx, crt) <= 0) {
                uwsgi_log("[uwsgi-ssl] unable to assign certificate %s for context \"%s\"\n", crt, name);
                SSL_CTX_free(ctx);
                return NULL;
        }

// this part is based from stud
        BIO *bio = BIO_new_file(crt, "r");
        if (bio) {
                DH *dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
                BIO_free(bio);
                if (dh) {
                        SSL_CTX_set_tmp_dh(ctx, dh);
                        DH_free(dh);
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
#ifdef NID_X9_62_prime256v1
                        EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
                        SSL_CTX_set_tmp_ecdh(ctx, ecdh);
                        EC_KEY_free(ecdh);
#endif
#endif
#endif
                }
        }

        if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) <= 0) {
                uwsgi_log("[uwsgi-ssl] unable to assign key %s for context \"%s\"\n", key, name);
                SSL_CTX_free(ctx);
                return NULL;
        }


	// if ciphers are specified, prefer server ciphers
        if (ciphers && strlen(ciphers) > 0) {
                if (SSL_CTX_set_cipher_list(ctx, ciphers) == 0) {
                        uwsgi_log("[uwsgi-ssl] unable to set requested ciphers (%s) for context \"%s\"\n", ciphers, name);
                        SSL_CTX_free(ctx);
                        return NULL;
                }

                ssloptions |= SSL_OP_CIPHER_SERVER_PREFERENCE;
        }

        // set session context (if possibile), this is required for client certificate authentication
        if (name) {
                SSL_CTX_set_session_id_context(ctx, (unsigned char *) name, strlen(name));
        }

        if (client_ca) {
                if (client_ca[0] == '!') {
                        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, uwsgi_ssl_verify_callback);
                        client_ca++;
                }
                else {
                        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, uwsgi_ssl_verify_callback);
                }
                // in the future we should allow to set the verify depth
                SSL_CTX_set_verify_depth(ctx, 1);
                if (SSL_CTX_load_verify_locations(ctx, client_ca, NULL) == 0) {
                        uwsgi_log("[uwsgi-ssl] unable to set ssl verify locations (%s) for context \"%s\"\n", client_ca, name);
                        SSL_CTX_free(ctx);
                        return NULL;
                }
                STACK_OF(X509_NAME) * list = SSL_load_client_CA_file(client_ca);
                if (!list) {
                        uwsgi_log("unable to load client CA certificate (%s) for context \"%s\"\n", client_ca, name);
                        SSL_CTX_free(ctx);
                        return NULL;
                }

                SSL_CTX_set_client_CA_list(ctx, list);
        }


        SSL_CTX_set_info_callback(ctx, uwsgi_ssl_info_cb);
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
        SSL_CTX_set_tlsext_servername_callback(ctx, uwsgi_sni_cb);
#endif

        // disable session caching by default
        SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

	if (uwsgi.ssl_sessions_use_cache) {

		// we need to early initialize locking and caching
		uwsgi_setup_locking();
		uwsgi_cache_create_all();

		uwsgi.ssl_sessions_cache = uwsgi_cache_by_name(uwsgi.ssl_sessions_use_cache);
		if (!uwsgi.ssl_sessions_cache) {
			// check for default cache
			if (!strcmp(uwsgi.ssl_sessions_use_cache, "true") && uwsgi.caches) {
				uwsgi.ssl_sessions_cache = uwsgi.caches;
			}
			else {
				uwsgi_log("unable to find cache \"%s\"\n", uwsgi.ssl_sessions_use_cache ? uwsgi.ssl_sessions_use_cache : "default");
				exit(1);
			}
		}

                if (!uwsgi.ssl_sessions_cache->max_items) {
                        uwsgi_log("you have to enable uWSGI cache to use it as SSL session store !!!\n");
                        exit(1);
                }

                if (uwsgi.ssl_sessions_cache->blocksize < 4096) {
                        uwsgi_log("cache blocksize for SSL session store must be at least 4096 bytes\n");
                        exit(1);
                }

                SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER|
                        SSL_SESS_CACHE_NO_INTERNAL|
                        SSL_SESS_CACHE_NO_AUTO_CLEAR);

#ifdef SSL_OP_NO_TICKET
                ssloptions |= SSL_OP_NO_TICKET;
#endif

                // just for fun
                SSL_CTX_sess_set_cache_size(ctx, 0);

                // set the callback for ssl sessions
                SSL_CTX_sess_set_new_cb(ctx, uwsgi_ssl_session_new_cb);
                SSL_CTX_sess_set_get_cb(ctx, uwsgi_ssl_session_get_cb);
                SSL_CTX_sess_set_remove_cb(ctx, uwsgi_ssl_session_remove_cb);
        }

        SSL_CTX_set_timeout(ctx, uwsgi.ssl_sessions_timeout);

        SSL_CTX_set_options(ctx, ssloptions);


        return ctx;
}
コード例 #14
0
ファイル: evhtp_ssl_cfg.cpp プロジェクト: austgl/libhttp
int
evhtp_ssl_init(evhtp * htp, evhtp_ssl_cfg * cfg) {
    long                  cache_mode;
    evhtp_ssl_scache_init init_cb = NULL;
    evhtp_ssl_scache_add  add_cb  = NULL;
    evhtp_ssl_scache_get  get_cb  = NULL;
    evhtp_ssl_scache_del  del_cb  = NULL;

    if (cfg == NULL || htp == NULL || cfg->pemfile == NULL) {
        return -1;
    }

    SSL_library_init();
    SSL_load_error_strings();
    RAND_poll();

    STACK_OF(SSL_COMP) * comp_methods = SSL_COMP_get_compression_methods();
    sk_SSL_COMP_zero(comp_methods);

    htp->ssl_cfg = cfg;
    htp->ssl_ctx = SSL_CTX_new(SSLv23_server_method());

#if OPENSSL_VERSION_NUMBER >= 0x10000000L
    SSL_CTX_set_options(htp->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
    SSL_CTX_set_timeout(htp->ssl_ctx, 60 * 60 * 48);
#endif

    SSL_CTX_set_options(htp->ssl_ctx, cfg->ssl_opts);

    if (cfg->ciphers != NULL) {
        SSL_CTX_set_cipher_list(htp->ssl_ctx, cfg->ciphers);
    }

    SSL_CTX_load_verify_locations(htp->ssl_ctx, cfg->cafile, cfg->capath);
    X509_STORE_set_flags(SSL_CTX_get_cert_store(htp->ssl_ctx), cfg->store_flags);
    SSL_CTX_set_verify(htp->ssl_ctx, cfg->verify_peer, cfg->x509_verify_cb);

    if (cfg->x509_chk_issued_cb != NULL) {
        htp->ssl_ctx->cert_store->check_issued = cfg->x509_chk_issued_cb;
    }

    if (cfg->verify_depth) {
        SSL_CTX_set_verify_depth(htp->ssl_ctx, cfg->verify_depth);
    }

    switch (cfg->scache_type) {
        case evhtp_ssl_scache_type_disabled:
            cache_mode = SSL_SESS_CACHE_OFF;
            break;
        case evhtp_ssl_scache_type_user:
            cache_mode = SSL_SESS_CACHE_SERVER |
                         SSL_SESS_CACHE_NO_INTERNAL |
                         SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;

            init_cb    = cfg->scache_init;
            add_cb     = cfg->scache_add;
            get_cb     = cfg->scache_get;
            del_cb     = cfg->scache_del;
            break;
        case evhtp_ssl_scache_type_builtin:
            cache_mode = SSL_SESS_CACHE_SERVER |
                         SSL_SESS_CACHE_NO_INTERNAL |
                         SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;

#if 0
            init_cb    = _evhtp_ssl_builtin_init;
            add_cb     = _evhtp_ssl_builtin_add;
            get_cb     = _evhtp_ssl_builtin_get;
            del_cb     = _evhtp_ssl_builtin_del;
#endif
            break;
        case evhtp_ssl_scache_type_internal:
        default:
            cache_mode = SSL_SESS_CACHE_SERVER;
            break;
    }     /* switch */

    SSL_CTX_use_certificate_file(htp->ssl_ctx, cfg->pemfile, SSL_FILETYPE_PEM);
    SSL_CTX_use_PrivateKey_file(htp->ssl_ctx, cfg->privfile ? cfg->privfile: cfg->pemfile, SSL_FILETYPE_PEM);

    SSL_CTX_set_session_id_context(htp->ssl_ctx,
                                   (const unsigned char*)&session_id_context,
                                   sizeof(session_id_context));

    SSL_CTX_set_app_data(htp->ssl_ctx, htp);
    SSL_CTX_set_session_cache_mode(htp->ssl_ctx, cache_mode);

    if (cache_mode != SSL_SESS_CACHE_OFF) {
        SSL_CTX_sess_set_cache_size(htp->ssl_ctx,
                                    cfg->scache_size ? cfg->scache_size : 1024);

        if (cfg->scache_type == evhtp_ssl_scache_type_builtin ||
            cfg->scache_type == evhtp_ssl_scache_type_user) {
            SSL_CTX_sess_set_new_cb(htp->ssl_ctx, _evhtp_ssl_add_scache_ent);
            SSL_CTX_sess_set_get_cb(htp->ssl_ctx, _evhtp_ssl_get_scache_ent);
            SSL_CTX_sess_set_remove_cb(htp->ssl_ctx, _evhtp_ssl_delete_scache_ent);

            if (cfg->scache_init) {
                cfg->args = (cfg->scache_init)(htp);
            }
        }
    }

    return 0;
}     /* evhtp_use_ssl */