示例#1
0
文件: tls.c 项目: JozLes77/FreeRDP
BOOL tls_accept(rdpTls* tls, BIO *underlying, const char* cert_file, const char* privatekey_file)
{
	long options = 0;

	/**
	 * SSL_OP_NO_SSLv2:
	 *
	 * We only want SSLv3 and TLSv1, so disable SSLv2.
	 * SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
	 */
	options |= SSL_OP_NO_SSLv2;

	/**
	 * SSL_OP_NO_COMPRESSION:
	 *
	 * The Microsoft RDP server does not advertise support
	 * for TLS compression, but alternative servers may support it.
	 * This was observed between early versions of the FreeRDP server
	 * and the FreeRDP client, and caused major performance issues,
	 * which is why we're disabling it.
	 */
#ifdef SSL_OP_NO_COMPRESSION
	options |= SSL_OP_NO_COMPRESSION;
#endif
	 
	/**
	 * SSL_OP_TLS_BLOCK_PADDING_BUG:
	 *
	 * The Microsoft RDP server does *not* support TLS padding.
	 * It absolutely needs to be disabled otherwise it won't work.
	 */
	options |= SSL_OP_TLS_BLOCK_PADDING_BUG;

	/**
	 * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
	 *
	 * Just like TLS padding, the Microsoft RDP server does not
	 * support empty fragments. This needs to be disabled.
	 */
	options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;

	if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE))
		return FALSE;

	if (SSL_use_RSAPrivateKey_file(tls->ssl, privatekey_file, SSL_FILETYPE_PEM) <= 0)
	{
		DEBUG_WARN( "%s: SSL_CTX_use_RSAPrivateKey_file failed\n", __FUNCTION__);
		DEBUG_WARN( "PrivateKeyFile: %s\n", privatekey_file);
		return FALSE;
	}

	if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0)
	{
		DEBUG_WARN( "%s: SSL_use_certificate_file failed\n", __FUNCTION__);
		return FALSE;
	}

	return tls_do_handshake(tls, FALSE) > 0;
}
示例#2
0
static void
tls_exec_server(const char *user, int startfd, const char *privkey,
    const char *cert, int debuglevel)
{
	SSL_CTX *sslctx;
	SSL *ssl;
	int sockfd, tcpfd, ret;

	pjdlog_debug_set(debuglevel);
	pjdlog_prefix_set("[TLS sandbox] (server) ");
#ifdef HAVE_SETPROCTITLE
	setproctitle("[TLS sandbox] (server) ");
#endif

	sockfd = startfd;
	tcpfd = startfd + 1;

	SSL_load_error_strings();
	SSL_library_init();

	sslctx = SSL_CTX_new(TLSv1_server_method());
	if (sslctx == NULL)
		pjdlog_exitx(EX_TEMPFAIL, "SSL_CTX_new() failed.");

	SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

	ssl = SSL_new(sslctx);
	if (ssl == NULL)
		pjdlog_exitx(EX_TEMPFAIL, "SSL_new() failed.");

	if (SSL_use_RSAPrivateKey_file(ssl, privkey, SSL_FILETYPE_PEM) != 1) {
		ssl_log_errors();
		pjdlog_exitx(EX_CONFIG,
		    "SSL_use_RSAPrivateKey_file(%s) failed.", privkey);
	}

	if (SSL_use_certificate_file(ssl, cert, SSL_FILETYPE_PEM) != 1) {
		ssl_log_errors();
		pjdlog_exitx(EX_CONFIG, "SSL_use_certificate_file(%s) failed.",
		    cert);
	}

	if (sandbox(user, true, "proto_tls server") != 0)
		pjdlog_exitx(EX_CONFIG, "Unable to sandbox TLS server.");
	pjdlog_debug(1, "Privileges successfully dropped.");

	nonblock(sockfd);
	nonblock(tcpfd);

	if (SSL_set_fd(ssl, tcpfd) != 1)
		pjdlog_exitx(EX_TEMPFAIL, "SSL_set_fd() failed.");

	ret = SSL_accept(ssl);
	ssl_check_error(ssl, ret);

	tls_loop(sockfd, ssl);
}
示例#3
0
文件: tls.c 项目: lordcrc/FreeRDP
boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file)
{
	int connection_status;

	tls->ctx = SSL_CTX_new(SSLv23_server_method());

	if (tls->ctx == NULL)
	{
		printf("SSL_CTX_new failed\n");
		return false;
	}

	/*
	 * We only want SSLv3 and TLSv1, so disable SSLv2.
	 * SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
	 */
	SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv2);

	if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0)
	{
		printf("SSL_CTX_use_RSAPrivateKey_file failed\n");
		return false;
	}

	tls->ssl = SSL_new(tls->ctx);

	if (tls->ssl == NULL)
	{
		printf("SSL_new failed\n");
		return false;
	}

	if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0)
	{
		printf("SSL_use_certificate_file failed\n");
		return false;
	}

	if (SSL_set_fd(tls->ssl, tls->sockfd) < 1)
	{
		printf("SSL_set_fd failed\n");
		return false;
	}

	connection_status = SSL_accept(tls->ssl);

	if (connection_status <= 0)
	{
		if (tls_print_error("SSL_accept", tls->ssl, connection_status))
			return false;
	}

	printf("TLS connection accepted\n");

	return true;
}
示例#4
0
int tls_connection_client_cert(void *ssl_ctx, struct tls_connection *conn,
			       const char *client_cert)
{
	if (client_cert == NULL)
		return 0;
	if (conn == NULL)
		return -1;

	if (SSL_use_certificate_file(conn->ssl, client_cert,
				     SSL_FILETYPE_ASN1) != 1 &&
	    SSL_use_certificate_file(conn->ssl, client_cert,
				     SSL_FILETYPE_PEM) != 1) {
		wpa_printf(MSG_INFO, "TLS: Failed to load client "
			   "certificate: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		return -1;
	}
	return 0;
}
示例#5
0
static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
	{
	int rv = 1;
	if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
		return -2;
	if (cctx->ctx)
		rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
	if (cctx->ssl)
		rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
	return rv > 0;
	}
示例#6
0
tbool tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file)
{
	int connection_status;

	tls->ctx = SSL_CTX_new(TLSv1_server_method());

	if (tls->ctx == NULL)
	{
		printf("SSL_CTX_new failed\n");
		return false;
	}

	if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0)
	{
		printf("SSL_CTX_use_RSAPrivateKey_file failed\n");
		return false;
	}

	tls->ssl = SSL_new(tls->ctx);

	if (tls->ssl == NULL)
	{
		printf("SSL_new failed\n");
		return false;
	}

	if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0)
	{
		printf("SSL_use_certificate_file failed\n");
		return false;
	}

	if (SSL_set_fd(tls->ssl, tls->sockfd) < 1)
	{
		printf("SSL_set_fd failed\n");
		return false;
	}

	connection_status = SSL_accept(tls->ssl);

	if (connection_status <= 0)
	{
		if (tls_print_error("SSL_accept", tls->ssl, connection_status))
			return false;
	}

	printf("TLS connection accepted\n");

	return true;
}
示例#7
0
文件: conn.c 项目: pwhelan/kannel
static int conn_init_client_ssl(Connection *ret, Octstr *certkeyfile)
{
    ret->ssl = SSL_new(global_ssl_context);

    /*
     * The current thread's error queue must be empty before
     * the TLS/SSL I/O operation is attempted, or SSL_get_error()
     * will not work reliably.
     */
    ERR_clear_error();

    if (certkeyfile != NULL) {
        SSL_use_certificate_file(ret->ssl, octstr_get_cstr(certkeyfile),
                                 SSL_FILETYPE_PEM);
        SSL_use_PrivateKey_file(ret->ssl, octstr_get_cstr(certkeyfile),
                                SSL_FILETYPE_PEM);
        if (SSL_check_private_key(ret->ssl) != 1) {
            error(0, "conn_open_ssl: private key isn't consistent with the "
                     "certificate from file %s (or failed reading the file)",
                  octstr_get_cstr(certkeyfile));
            return -1;
        }
    }

    /* SSL_set_fd can fail, so check it */
    if (SSL_set_fd(ret->ssl, ret->fd) == 0) {
        /* SSL_set_fd failed, log error */
        error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
        return -1;
    }

    /*
     * make sure the socket is non-blocking while we do SSL_connect
     */
    if (socket_set_blocking(ret->fd, 0) < 0) {
        return -1;
    }
    BIO_set_nbio(SSL_get_rbio(ret->ssl), 1);
    BIO_set_nbio(SSL_get_wbio(ret->ssl), 1);

    SSL_set_connect_state(ret->ssl);
    
    return 0;
}
示例#8
0
文件: ssl.c 项目: umegaya/pfm
DSCRPTR
nbr_ssl_accept(DSCRPTR fd, void *addr, int *alen, SKCONF *cfg)
{
	int r, ret;
	sslfd_t *sfd = nbr_array_alloc(g_ssl.socks), *afd = (sslfd_t *)fd;
	if (!sfd) {
		SSL_ERROUT(ERROR,EXPIRE,"sfd alloc fail");
		goto bad;
	}
	if ((sfd->fd = nbr_osdep_tcp_accept(afd->fd, addr, alen, cfg)) == INVALID_FD) {
		SSL_ERROUT(ERROR,ACCEPT,"ssl accept fail");
		goto bad;
	}
	if (!(sfd->ssl = SSL_new(g_ssl.server))) {
		SSL_ERROUT(ERROR,EXPIRE,"ssl new fail");
		goto bad;
	}
#if defined(_DEBUG)
	sfd->ssl->info_callback = (void (*)())ssl_info_callback;
#endif
	if (!g_ssl.pubkey || SSL_use_certificate_file(sfd->ssl, g_ssl.pubkey, SSL_FILETYPE_PEM) < 0) {
		SSL_ERROUT(ERROR,EXPIRE,"ssl SSL_use_certificate_file fail");
		goto bad;
	}
	if (!g_ssl.privkey || SSL_use_PrivateKey_file(sfd->ssl, g_ssl.privkey, SSL_FILETYPE_PEM) < 0) {
		SSL_ERROUT(ERROR,EXPIRE,"ssl SSL_use_PrivateKey_file fail");
		goto bad;
	}
	SSL_set_fd(sfd->ssl, sfd->fd);
	if ((r = SSL_accept(sfd->ssl)) <= 0) {
		ret = SSL_get_error(sfd->ssl, ret);
		if (ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_WANT_WRITE) {
			return 0;	/* connection pending */
		}
		ERR_print_errors_fp(stderr);
		SSL_ERROUT(ERROR,ACCEPT,"ssl_accept fail (%d/%d)", r, ret);
		goto bad;
	}
	return (DSCRPTR)sfd;
bad:
	ssl_free_fd(sfd);
	return INVALID_FD;
}
示例#9
0
/* Load certificate and private key */
static void tls_certkey(SSL *_tls)
{
	int ret, ret2;

	if(!_tls)
	{
		TLSERROR("Certificate cannot be loaded.");
		return;
	}

	if((!_key) || (!_cert) || (!_callback))
	{
		printf("WARNING: certificates are disabled!\n");
		return;
	}

	SSL_CTX_set_default_passwd_cb(_tlsctx, _callback);

	/*ret = SSL_CTX_load_verify_locations(_tlsctx, "/usr/lib/ssl/cacert.pem", NULL);
	if(ret != 1)
	{
		TLSERROR("Couldn't load root CA file!");
		ret2 = ERR_get_error();
		printf("EXT: %s\n%s\n%s\n%s\n%s\n", tls_exterror(_tls, ret), ERR_error_string(ret2, NULL),
		ERR_lib_error_string(ret2), ERR_func_error_string(ret2), ERR_reason_error_string(ret2));
	}*/

	ret = SSL_use_RSAPrivateKey_file(_tls, _key, SSL_FILETYPE_PEM);
	if(ret != 1)
	{
		TLSERROR("Error loading TLS PEM private key.");
		ret2 = ERR_get_error();
		printf("EXT: %s\n%s\n%s\n%s\n%s\n", tls_exterror(_tls, ret), ERR_error_string(ret2, NULL),
		ERR_lib_error_string(ret2), ERR_func_error_string(ret2), ERR_reason_error_string(ret2));
	}
	ret = SSL_use_certificate_file(_tls, _cert, SSL_FILETYPE_PEM);
	if(ret != 1) TLSERROR("Error loading TLS PEM certificate.");
	ret = SSL_check_private_key(_tls);
	if(!ret) TLSERROR("Private key doesn't match certificate public key.");
	printf("*** certificate loaded ***\n");
}
示例#10
0
/// loads one PEM file with one certificate, no chain, no CA
int Certificate::loadCertificateFromFile( void )
{
	const int certificateFileCheckResult = validateCertificateFilename(m_certfn);
	if(certificateFileCheckResult < 0) return certificateFileCheckResult;

	m_ssl = SSL_new( SSL_CTX_new( SSLv23_method() ) );
	SSL_use_certificate_file( m_ssl, m_certfn.c_str(), m_type);
	// or like this, including a CA
	// SSL_CTX_use_certificate_chain_file( _ssl_ctx, fname.c_str() );
	X509 *x509crt = SSL_get_certificate( m_ssl );

	// validity format is here:
	// https://github.com/openssl/openssl/commit/f48b83b4fb7d6689584cf25f61ca63a4891f5b11

	// in fact these are strings in UTC format, need to convert them into time_t to become useful
	m_time_end = _timeASN1toTIME_T(  x509crt->cert_info->validity->notAfter );

	remainingValidityTime();
	LOG(Log::INF) << " certificate remaining time= " << remainingDays() << "days "
			<< remainingHours() << ":"
			<< remainingMins() << ":"
			<< remainingSecs();
	return( 0 );
}
示例#11
0
文件: tls.c 项目: EdWatts/FreeRDP
boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file)
{
	CryptoCert cert;
	long options = 0;
	int connection_status;

	tls->ctx = SSL_CTX_new(SSLv23_server_method());

	if (tls->ctx == NULL)
	{
		printf("SSL_CTX_new failed\n");
		return false;
	}

	/*
	 * SSL_OP_NO_SSLv2:
	 *
	 * We only want SSLv3 and TLSv1, so disable SSLv2.
	 * SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
	 */
	options |= SSL_OP_NO_SSLv2;

	/**
	 * SSL_OP_NO_COMPRESSION:
	 *
	 * The Microsoft RDP server does not advertise support
	 * for TLS compression, but alternative servers may support it.
	 * This was observed between early versions of the FreeRDP server
	 * and the FreeRDP client, and caused major performance issues,
	 * which is why we're disabling it.
	 */
#ifdef SSL_OP_NO_COMPRESSION
	options |= SSL_OP_NO_COMPRESSION;
#endif
	 
	/**
	 * SSL_OP_TLS_BLOCK_PADDING_BUG:
	 *
	 * The Microsoft RDP server does *not* support TLS padding.
	 * It absolutely needs to be disabled otherwise it won't work.
	 */
	options |= SSL_OP_TLS_BLOCK_PADDING_BUG;

	/**
	 * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
	 *
	 * Just like TLS padding, the Microsoft RDP server does not
	 * support empty fragments. This needs to be disabled.
	 */
	options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;

	SSL_CTX_set_options(tls->ctx, options);

	if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0)
	{
		printf("SSL_CTX_use_RSAPrivateKey_file failed\n");
		return false;
	}

	tls->ssl = SSL_new(tls->ctx);

	if (tls->ssl == NULL)
	{
		printf("SSL_new failed\n");
		return false;
	}

	if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0)
	{
		printf("SSL_use_certificate_file failed\n");
		return false;
	}

	cert = tls_get_certificate(tls, false);

	if (cert == NULL)
	{
		printf("tls_connect: tls_get_certificate failed to return the server certificate.\n");
		return false;
	}

	if (!crypto_cert_get_public_key(cert, &tls->public_key))
	{
		printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n");
		tls_free_certificate(cert);
		return false;
	}

	xfree(cert);

	if (SSL_set_fd(tls->ssl, tls->sockfd) < 1)
	{
		printf("SSL_set_fd failed\n");
		return false;
	}

	while (1)
	{
		connection_status = SSL_accept(tls->ssl);

		if (connection_status <= 0)
		{
			switch (SSL_get_error(tls->ssl, connection_status))
			{
				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_WRITE:
					break;

				default:
					if (tls_print_error("SSL_accept", tls->ssl, connection_status))
						return false;
					break;

			}
		}
		else
		{
			break;
		}
	}

	printf("TLS connection accepted\n");

	return true;
}
示例#12
0
文件: ssls.c 项目: nsauzede/netsan2
int main( int argc, char *argv[])
{
	int port = 10001;
	int n;
	int s;

	if (argc > 1)
	{
		sscanf( argv[1], "%d", &port);
	}

	SSL_library_init();
	SSL_load_error_strings();

	s = socket( PF_INET, SOCK_STREAM, 0);
	if (s != -1)
	{
		int cs;
		char buf[1024];
		struct sockaddr_in sa;
		int on;

		on = 1;
		setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof( on));
		memset( &sa, 0, sizeof( sa));
		sa.sin_family = AF_INET;
		sa.sin_port = htons( port);
		sa.sin_addr.s_addr = INADDR_ANY;
		bind( s, (struct sockaddr *)&sa, sizeof( sa));
		listen( s, 1);
		while (1)
		{
			printf( "accepting on port %d..\n", port);
			cs = accept( s, NULL, NULL);
			if (cs != -1)
			{
				SSL *ssl = 0;
				SSL_CTX *ssl_ctx = 0;

				ssl_ctx = SSL_CTX_new( SSLv23_server_method());
				if (ssl_ctx)
				{
					ssl = SSL_new( ssl_ctx);
					if (ssl)
					{
						n = SSL_use_PrivateKey_file( ssl, key_file, 1);
						if (n != 1)
							printf( "failed to SSL use key (%d, %d)\n", n, SSL_get_error( ssl, n));
						n = SSL_use_certificate_file( ssl, certificate_file, 1);
						if (n != 1)
							printf( "failed to SSL use cert (%d, %d)\n", n, SSL_get_error( ssl, n));
						if (SSL_set_fd( ssl, cs))
						{
							printf( "SSL accepting..\n");
							n = SSL_accept( ssl);
							if (n == 1)
							{
								printf( "ssl initiated\n");
								if ((n = SSL_read( ssl, buf, sizeof( buf))) > 0)
								{
									if (n > (sizeof( buf) - 1))
										n = sizeof( buf) - 1;
									buf[n] = 0;
									printf( "SSL_read %d bytes [%s]\n", n, buf);
								}
								else
									printf( "failed to SSL read\n");
							}
							else
							{
#ifdef WIN32
								unsigned long err = ERR_get_error();
								printf( "failed to SSL accept (%d, %d) (%ld, %s)\n", n, SSL_get_error( ssl, n), err, ERR_error_string( err, NULL));
#else
								printf( "failed to SSL accept (%d)\n", n);
#endif
							}
						}
						else
							printf( "failed to SSL set fd\n");
						SSL_shutdown( ssl);
					}
					else
						printf( "couldn't create server ssl\n");
					SSL_CTX_free( ssl_ctx);
				}
				else
					printf( "couldn't create server ctx\n");
				close( cs);
			}
			else
				perror( "accept");
		}
	}
	else
		perror( "socket");

	return 0;
}
示例#13
0
int schannel_openssl_server_init(SCHANNEL_OPENSSL* context)
{
	int status;
	long options = 0;
	//context->ctx = SSL_CTX_new(SSLv23_server_method());
	context->ctx = SSL_CTX_new(TLSv1_server_method());

	if (!context->ctx)
	{
		WLog_ERR(TAG, "SSL_CTX_new failed");
		return -1;
	}

	/*
	 * SSL_OP_NO_SSLv2:
	 *
	 * We only want SSLv3 and TLSv1, so disable SSLv2.
	 * SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
	 */
	options |= SSL_OP_NO_SSLv2;
	/**
	 * SSL_OP_NO_COMPRESSION:
	 *
	 * The Microsoft RDP server does not advertise support
	 * for TLS compression, but alternative servers may support it.
	 * This was observed between early versions of the FreeRDP server
	 * and the FreeRDP client, and caused major performance issues,
	 * which is why we're disabling it.
	 */
#ifdef SSL_OP_NO_COMPRESSION
	options |= SSL_OP_NO_COMPRESSION;
#endif
	/**
	 * SSL_OP_TLS_BLOCK_PADDING_BUG:
	 *
	 * The Microsoft RDP server does *not* support TLS padding.
	 * It absolutely needs to be disabled otherwise it won't work.
	 */
	options |= SSL_OP_TLS_BLOCK_PADDING_BUG;
	/**
	 * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
	 *
	 * Just like TLS padding, the Microsoft RDP server does not
	 * support empty fragments. This needs to be disabled.
	 */
	options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
	SSL_CTX_set_options(context->ctx, options);

	if (SSL_CTX_use_RSAPrivateKey_file(context->ctx, "/tmp/localhost.key", SSL_FILETYPE_PEM) <= 0)
	{
		WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed");
		return -1;
	}

	context->ssl = SSL_new(context->ctx);

	if (!context->ssl)
	{
		WLog_ERR(TAG, "SSL_new failed");
		return -1;
	}

	if (SSL_use_certificate_file(context->ssl, "/tmp/localhost.crt", SSL_FILETYPE_PEM) <= 0)
	{
		WLog_ERR(TAG, "SSL_use_certificate_file failed");
		return -1;
	}

	context->bioRead = BIO_new(BIO_s_mem());

	if (!context->bioRead)
	{
		WLog_ERR(TAG, "BIO_new failed");
		return -1;
	}

	status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN);
	context->bioWrite = BIO_new(BIO_s_mem());

	if (!context->bioWrite)
	{
		WLog_ERR(TAG, "BIO_new failed");
		return -1;
	}

	status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN);
	status = BIO_make_bio_pair(context->bioRead, context->bioWrite);
	SSL_set_bio(context->ssl, context->bioRead, context->bioWrite);
	context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
	context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN);
	return 0;
}
示例#14
0
/** Create a new server TLS session
 *
 * Configures a new server TLS session, configuring options, setting callbacks etc...
 *
 * @param ctx		to alloc session data in. Should usually be NULL unless the lifetime of the
 *			session is tied to another talloc'd object.
 * @param conf		values for this TLS session.
 * @param request	The current #REQUEST.
 * @param client_cert	Whether to require a client_cert.
 * @return
 *	- A new session on success.
 *	- NULL on error.
 */
tls_session_t *tls_session_init_server(TALLOC_CTX *ctx, fr_tls_conf_t *conf, REQUEST *request, bool client_cert)
{
	tls_session_t	*session = NULL;
	SSL		*new_tls = NULL;
	int		verify_mode = 0;
	VALUE_PAIR	*vp;
	SSL_CTX		*ssl_ctx;

	rad_assert(request != NULL);
	rad_assert(conf->ctx_count > 0);

	RDEBUG2("Initiating new TLS session");

	ssl_ctx = conf->ctx[(conf->ctx_count == 1) ? 0 : conf->ctx_next++ % conf->ctx_count];	/* mutex not needed */
	rad_assert(ssl_ctx);

	new_tls = SSL_new(ssl_ctx);
	if (new_tls == NULL) {
		tls_log_error(request, "Error creating new TLS session");
		return NULL;
	}

	session = talloc_zero(ctx, tls_session_t);
	if (session == NULL) {
		RERROR("Error allocating memory for TLS session");
		SSL_free(new_tls);

		return NULL;
	}
	session_init(session);
	session->ctx = ssl_ctx;
	session->ssl = new_tls;

	talloc_set_destructor(session, _tls_session_free);

	/*
	 *	Initialize callbacks
	 */
	session->record_init = record_init;
	session->record_close = record_close;
	session->record_from_buff = record_from_buff;
	session->record_to_buff = record_to_buff;

	/*
	 *	Create & hook the BIOs to handle the dirty side of the
	 *	SSL.  This is *very important* as we want to handle
	 *	the transmission part.  Now the only IO interface
	 *	that SSL is aware of, is our defined BIO buffers.
	 *
	 *	This means that all SSL IO is done to/from memory,
	 *	and we can update those BIOs from the packets we've
	 *	received.
	 */
	session->into_ssl = BIO_new(BIO_s_mem());
	session->from_ssl = BIO_new(BIO_s_mem());
	SSL_set_bio(session->ssl, session->into_ssl, session->from_ssl);

	/*
	 *	Add the message callback to identify what type of
	 *	message/handshake is passed
	 */
	SSL_set_msg_callback(new_tls, tls_session_msg_cb);
	SSL_set_msg_callback_arg(new_tls, session);
	SSL_set_info_callback(new_tls, tls_session_info_cb);

	/*
	 *	This sets the context sessions can be resumed in.
	 *	This is to prevent sessions being created by one application
	 *	and used by another.  In our case it prevents sessions being
	 *	reused between modules, or TLS server components such as
	 *	RADSEC.
	 *
	 *	A context must always be set when doing session resumption
	 *	otherwise session resumption will fail.
	 *
	 *	As the context ID must be <= 32, we digest the context
	 *	data with sha256.
	 */
	rad_assert(conf->session_id_name);
	{
		char		*context_id;
		EVP_MD_CTX	*md_ctx;
		uint8_t		digest[SHA256_DIGEST_LENGTH];

		static_assert(sizeof(digest) <= SSL_MAX_SSL_SESSION_ID_LENGTH,
			      "SSL_MAX_SSL_SESSION_ID_LENGTH must be >= SHA256_DIGEST_LENGTH");

		if (tmpl_aexpand(session, &context_id, request, conf->session_id_name, NULL, NULL) < 0) {
			RPEDEBUG("Failed expanding session ID");
			talloc_free(session);
		}

		MEM(md_ctx = EVP_MD_CTX_create());
		EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL);
		EVP_DigestUpdate(md_ctx, context_id, talloc_array_length(context_id) - 1);
		EVP_DigestFinal_ex(md_ctx, digest, NULL);
		EVP_MD_CTX_destroy(md_ctx);
		talloc_free(context_id);

		if (!fr_cond_assert(SSL_set_session_id_context(session->ssl, digest, sizeof(digest)) == 1)) {
			talloc_free(session);
			return NULL;
		}
	}

	/*
	 *	Add the session certificate to the session.
	 */
	vp = fr_pair_find_by_da(request->control, attr_tls_session_cert_file, TAG_ANY);
	if (vp) {
		RDEBUG2("Loading TLS session certificate \"%s\"", vp->vp_strvalue);

		if (SSL_use_certificate_file(session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
			tls_log_error(request, "Failed loading TLS session certificate \"%s\"",
				      vp->vp_strvalue);
			talloc_free(session);
			return NULL;
		}

		if (SSL_use_PrivateKey_file(session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
			tls_log_error(request, "Failed loading TLS session certificate \"%s\"",
				      vp->vp_strvalue);
			talloc_free(session);
			return NULL;
		}

		if (SSL_check_private_key(session->ssl) != 1) {
			tls_log_error(request, "Failed validating TLS session certificate \"%s\"",
				      vp->vp_strvalue);
			talloc_free(session);
			return NULL;
		}
	/*
	 *	Better to perform explicit checks, than rely
	 *	on OpenSSL's opaque error messages.
	 */
	} else {
		if (!conf->chains || !conf->chains[0]->private_key_file) {
			ERROR("TLS Server requires a private key file");
			talloc_free(session);
			return NULL;
		}

		if (!conf->chains || !conf->chains[0]->certificate_file) {
			ERROR("TLS Server requires a certificate file");
			talloc_free(session);
			return NULL;
		}
	}

	/*
	 *	In Server mode we only accept.
	 *
	 *	This sets up the SSL session to work correctly with
	 *	tls_session_handhsake.
	 */
	SSL_set_accept_state(session->ssl);

	/*
	 *	Verify the peer certificate, if asked.
	 */
	if (client_cert) {
		RDEBUG2("Setting verify mode to require certificate from client");
		verify_mode = SSL_VERIFY_PEER;
		verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
		verify_mode |= SSL_VERIFY_CLIENT_ONCE;
	}
	SSL_set_verify(session->ssl, verify_mode, tls_validate_cert_cb);

	SSL_set_ex_data(session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
	SSL_set_ex_data(session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)session);

	/*
	 *	We use default fragment size, unless the Framed-MTU
	 *	tells us it's too big.  Note that we do NOT account
	 *	for the EAP-TLS headers if conf->fragment_size is
	 *	large, because that config item looks to be confusing.
	 *
	 *	i.e. it should REALLY be called MTU, and the code here
	 *	should figure out what that means for TLS fragment size.
	 *	asking the administrator to know the internal details
	 *	of EAP-TLS in order to calculate fragment sizes is
	 *	just too much.
	 */
	session->mtu = conf->fragment_size;
	vp = fr_pair_find_by_da(request->packet->vps, attr_framed_mtu, TAG_ANY);
	if (vp && (vp->vp_uint32 > 100) && (vp->vp_uint32 < session->mtu)) {
		RDEBUG2("Setting fragment_len to %u from &Framed-MTU", vp->vp_uint32);
		session->mtu = vp->vp_uint32;
	}

	if (conf->session_cache_server) session->allow_session_resumption = true; /* otherwise it's false */

	return session;
}
示例#15
0
文件: tls.c 项目: yunbox/FreeRDP
BOOL tls_accept(rdpTls* tls, BIO* underlying, const char* cert_file, const char* privatekey_file)
{
	long options = 0;

	/**
	 * SSL_OP_NO_SSLv2:
	 *
	 * We only want SSLv3 and TLSv1, so disable SSLv2.
	 * SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
	 */
	options |= SSL_OP_NO_SSLv2;

	/**
	 * SSL_OP_NO_COMPRESSION:
	 *
	 * The Microsoft RDP server does not advertise support
	 * for TLS compression, but alternative servers may support it.
	 * This was observed between early versions of the FreeRDP server
	 * and the FreeRDP client, and caused major performance issues,
	 * which is why we're disabling it.
	 */
#ifdef SSL_OP_NO_COMPRESSION
	options |= SSL_OP_NO_COMPRESSION;
#endif
	 
	/**
	 * SSL_OP_TLS_BLOCK_PADDING_BUG:
	 *
	 * The Microsoft RDP server does *not* support TLS padding.
	 * It absolutely needs to be disabled otherwise it won't work.
	 */
	options |= SSL_OP_TLS_BLOCK_PADDING_BUG;

	/**
	 * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
	 *
	 * Just like TLS padding, the Microsoft RDP server does not
	 * support empty fragments. This needs to be disabled.
	 */
	options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;

	if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE))
		return FALSE;

	if (SSL_use_RSAPrivateKey_file(tls->ssl, privatekey_file, SSL_FILETYPE_PEM) <= 0)
	{
		WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed");
		WLog_ERR(TAG, "PrivateKeyFile: %s", privatekey_file);
		return FALSE;
	}

	if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0)
	{
		WLog_ERR(TAG, "SSL_use_certificate_file failed");
		return FALSE;
	}

#ifndef OPENSSL_NO_TLSEXT
	/**
	 * The Microsoft iOS clients eventually send a null or even double null
	 * terminated hostname in the SNI TLS extension!
	 * If the length indicator does not equal the hostname strlen OpenSSL
	 * will abort (see openssl:ssl/t1_lib.c).
	 * Here is a tcpdump segment of Microsoft Remote Desktop Client Version
	 * 8.1.7 running on an iPhone 4 with iOS 7.1.2 showing the transmitted
	 * SNI hostname TLV blob when connection to server "abcd":
	 * 00                  name_type 0x00 (host_name)
	 * 00 06               length_in_bytes 0x0006
	 * 61 62 63 64 00 00   host_name "abcd\0\0"
	 *
	 * Currently the only (runtime) workaround is setting an openssl tls
	 * extension debug callback that sets the SSL context's servername_done
	 * to 1 which effectively disables the parsing of that extension type.
	 */

	SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback);
#endif

	return tls_do_handshake(tls, FALSE) > 0;
}
示例#16
0
文件: xrdp_tls.c 项目: Osirium/xrdp
int APP_CC
xrdp_tls_accept(struct xrdp_tls *self)
{
    int connection_status;
    long options = 0;

    /**
     * SSL_OP_NO_SSLv2:
     *
     * We only want SSLv3 and TLSv1, so disable SSLv2.
     * SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
     */
    options |= SSL_OP_NO_SSLv2;

#if defined(SSL_OP_NO_COMPRESSION)
    /**
     * SSL_OP_NO_COMPRESSION:
     *
     * The Microsoft RDP server does not advertise support
     * for TLS compression, but alternative servers may support it.
     * This was observed between early versions of the FreeRDP server
     * and the FreeRDP client, and caused major performance issues,
     * which is why we're disabling it.
     */
    options |= SSL_OP_NO_COMPRESSION;
#endif

    /**
     * SSL_OP_TLS_BLOCK_PADDING_BUG:
     *
     * The Microsoft RDP server does *not* support TLS padding.
     * It absolutely needs to be disabled otherwise it won't work.
     */
    options |= SSL_OP_TLS_BLOCK_PADDING_BUG;

    /**
     * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
     *
     * Just like TLS padding, the Microsoft RDP server does not
     * support empty fragments. This needs to be disabled.
     */
    options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;

    self->ctx = SSL_CTX_new(SSLv23_server_method());
    /* set context options */
    SSL_CTX_set_mode(self->ctx,
                     SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
                     SSL_MODE_ENABLE_PARTIAL_WRITE);
    SSL_CTX_set_options(self->ctx, options);
    SSL_CTX_set_read_ahead(self->ctx, 1);

    if (self->ctx == NULL)
    {
        g_writeln("xrdp_tls_accept: SSL_CTX_new failed");
        return 1;
    }

    if (SSL_CTX_use_RSAPrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM)
            <= 0)
    {
        g_writeln("xrdp_tls_accept: SSL_CTX_use_RSAPrivateKey_file failed");
        return 1;
    }

    self->ssl = SSL_new(self->ctx);

    if (self->ssl == NULL)
    {
        g_writeln("xrdp_tls_accept: SSL_new failed");
        return 1;
    }

    if (SSL_use_certificate_file(self->ssl, self->cert, SSL_FILETYPE_PEM) <= 0)
    {
        g_writeln("xrdp_tls_accept: SSL_use_certificate_file failed");
        return 1;
    }

    if (SSL_set_fd(self->ssl, self->trans->sck) < 1)
    {
        g_writeln("xrdp_tls_accept: SSL_set_fd failed");
        return 1;
    }

    connection_status = SSL_accept(self->ssl);

    if (connection_status <= 0)
    {
        if (xrdp_tls_print_error("SSL_accept", self->ssl, connection_status))
        {
            return 1;
        }
    }

    g_writeln("xrdp_tls_accept: TLS connection accepted");

    return 0;
}