src/ssl_sock.c
int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
{
	int cfgerr = 0;
	int options =
		SSL_OP_ALL | /* all known workarounds for bugs */
		SSL_OP_NO_SSLv2 |
		SSL_OP_NO_COMPRESSION;
	int mode =
		SSL_MODE_ENABLE_PARTIAL_WRITE |
		SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
		SSL_MODE_RELEASE_BUFFERS;

	/* Make sure openssl opens /dev/urandom before the chroot */
	if (!ssl_initialize_random()) {
		Alert("OpenSSL random data generator initialization failed.\n");
		cfgerr++;
	}

	 /* Initiate SSL context for current server */
	srv->ssl_ctx.reused_sess = NULL;
	if (srv->use_ssl)
		srv->xprt = &ssl_sock;
	if (srv->check.use_ssl)
		srv->check.xprt = &ssl_sock;

	srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
	if (!srv->ssl_ctx.ctx) {
		Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
		      proxy_type_str(curproxy), curproxy->id,
		      srv->id);
		cfgerr++;
		return cfgerr;
	}
	if (srv->ssl_ctx.client_crt) {
		if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
			Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
			      proxy_type_str(curproxy), curproxy->id,
			      srv->id, srv->ssl_ctx.client_crt);
			cfgerr++;
		}
		else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
			Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
			      proxy_type_str(curproxy), curproxy->id,
			      srv->id, srv->ssl_ctx.client_crt);
			cfgerr++;
		}
		else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
			Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
			      proxy_type_str(curproxy), curproxy->id,
			      srv->id, srv->ssl_ctx.client_crt);
			cfgerr++;
		}
	}

	if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
		options |= SSL_OP_NO_SSLv3;
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
		options |= SSL_OP_NO_TLSv1;
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
		options |= SSL_OP_NO_TLSv1_1;
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
		options |= SSL_OP_NO_TLSv1_2;
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
		options |= SSL_OP_NO_TICKET;
	if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
		SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
	if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
		SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
#if SSL_OP_NO_TLSv1_1
	if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
		SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
#endif
#if SSL_OP_NO_TLSv1_2
	if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
		SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
#endif

	SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
	SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
	SSL_CTX_set_verify(srv->ssl_ctx.ctx, srv->ssl_ctx.verify ? srv->ssl_ctx.verify : SSL_VERIFY_NONE, NULL);
	if (srv->ssl_ctx.verify & SSL_VERIFY_PEER) {
		if (srv->ssl_ctx.ca_file) {
			/* load CAfile to verify */
			if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
				Alert("Proxy '%s', server '%s' |%s:%d] unable to load CA file '%s'.\n",
				      curproxy->id, srv->id,
				      srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
				cfgerr++;
			}
		}
#ifdef X509_V_FLAG_CRL_CHECK
		if (srv->ssl_ctx.crl_file) {
			X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);

			if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
				Alert("Proxy '%s', server '%s' |%s:%d] unable to configure CRL file '%s'.\n",
				      curproxy->id, srv->id,
				      srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
				cfgerr++;
			}
			else {
				X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
			}
		}
#endif
	}

	if (global.tune.ssllifetime)
		SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);

	SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
	if (srv->ssl_ctx.ciphers &&
		!SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
		Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
		      curproxy->id, srv->id,
		      srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
		cfgerr++;
	}

	return cfgerr;
}
/* prepare ssl context from servers options. Returns an error count */
prepare ssl context from servers options. Returns an error count
prepare ssl context from servers options . Returns an error count
int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
{
	int cfgerr = 0;
	int options =
		SSL_OP_ALL | 
		SSL_OP_NO_SSLv2 |
		SSL_OP_NO_COMPRESSION;
	int mode =
		SSL_MODE_ENABLE_PARTIAL_WRITE |
		SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
		SSL_MODE_RELEASE_BUFFERS;
	if (!ssl_initialize_random()) {
		Alert("OpenSSL random data generator initialization failed.\n");
		cfgerr++;
	}
	srv->ssl_ctx.reused_sess = NULL;
	if (srv->use_ssl)
		srv->xprt = &ssl_sock;
	if (srv->check.use_ssl)
		srv->check.xprt = &ssl_sock;
	srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
	if (!srv->ssl_ctx.ctx) {
		Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
		      proxy_type_str(curproxy), curproxy->id,
		      srv->id);
		cfgerr++;
		return cfgerr;
	}
	if (srv->ssl_ctx.client_crt) {
		if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
			Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
			      proxy_type_str(curproxy), curproxy->id,
			      srv->id, srv->ssl_ctx.client_crt);
			cfgerr++;
		}
		else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
			Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
			      proxy_type_str(curproxy), curproxy->id,
			      srv->id, srv->ssl_ctx.client_crt);
			cfgerr++;
		}
		else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
			Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
			      proxy_type_str(curproxy), curproxy->id,
			      srv->id, srv->ssl_ctx.client_crt);
			cfgerr++;
		}
	}
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
		options |= SSL_OP_NO_SSLv3;
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
		options |= SSL_OP_NO_TLSv1;
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
		options |= SSL_OP_NO_TLSv1_1;
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
		options |= SSL_OP_NO_TLSv1_2;
	if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
		options |= SSL_OP_NO_TICKET;
	if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
		SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
	if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
		SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
#if SSL_OP_NO_TLSv1_1
	if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
		SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
#endif
#if SSL_OP_NO_TLSv1_2
	if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
		SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
#endif
	SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
	SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
	SSL_CTX_set_verify(srv->ssl_ctx.ctx, srv->ssl_ctx.verify ? srv->ssl_ctx.verify : SSL_VERIFY_NONE, NULL);
	if (srv->ssl_ctx.verify & SSL_VERIFY_PEER) {
		if (srv->ssl_ctx.ca_file) {
			if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
				Alert("Proxy '%s', server '%s' |%s:%d] unable to load CA file '%s'.\n",
				      curproxy->id, srv->id,
				      srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
				cfgerr++;
			}
		}
#ifdef X509_V_FLAG_CRL_CHECK
		if (srv->ssl_ctx.crl_file) {
			X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
			if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
				Alert("Proxy '%s', server '%s' |%s:%d] unable to configure CRL file '%s'.\n",
				      curproxy->id, srv->id,
				      srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
				cfgerr++;
			}
			else {
				X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
			}
		}
#endif
	}
	if (global.tune.ssllifetime)
		SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
	SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
	if (srv->ssl_ctx.ciphers &&
		!SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
		Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
		      curproxy->id, srv->id,
		      srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
		cfgerr++;
	}
	return cfgerr;
}
int ssl_sock_prepare_srv_ctx ( struct server * srv , struct proxy * curproxy ) { int cfgerr = 0 ; int options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION ; int mode = SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_RELEASE_BUFFERS ; if ( ! ssl_initialize_random ( ) ) { Alert ( " \n " ) ; cfgerr ++ ; } srv -> ssl_ctx . reused_sess = NULL ; if ( srv -> use_ssl ) srv -> xprt = & ssl_sock ; if ( srv -> check . use_ssl ) srv -> check . xprt = & ssl_sock ; srv -> ssl_ctx . ctx = SSL_CTX_new ( SSLv23_client_method ( ) ) ; if ( ! srv -> ssl_ctx . ctx ) { Alert ( " \n " , proxy_type_str ( curproxy ) , curproxy -> id , srv -> id ) ; cfgerr ++ ; return cfgerr ; } if ( srv -> ssl_ctx . client_crt ) { if ( SSL_CTX_use_PrivateKey_file ( srv -> ssl_ctx . ctx , srv -> ssl_ctx . client_crt , SSL_FILETYPE_PEM ) <= 0 ) { Alert ( " \n " , proxy_type_str ( curproxy ) , curproxy -> id , srv -> id , srv -> ssl_ctx . client_crt ) ; cfgerr ++ ; } else if ( SSL_CTX_use_certificate_chain_file ( srv -> ssl_ctx . ctx , srv -> ssl_ctx . client_crt ) <= 0 ) { Alert ( " \n " , proxy_type_str ( curproxy ) , curproxy -> id , srv -> id , srv -> ssl_ctx . client_crt ) ; cfgerr ++ ; } else if ( SSL_CTX_check_private_key ( srv -> ssl_ctx . ctx ) <= 0 ) { Alert ( " \n " , proxy_type_str ( curproxy ) , curproxy -> id , srv -> id , srv -> ssl_ctx . client_crt ) ; cfgerr ++ ; } } if ( srv -> ssl_ctx . options & SRV_SSL_O_NO_SSLV3 ) options |= SSL_OP_NO_SSLv3 ; if ( srv -> ssl_ctx . options & SRV_SSL_O_NO_TLSV10 ) options |= SSL_OP_NO_TLSv1 ; if ( srv -> ssl_ctx . options & SRV_SSL_O_NO_TLSV11 ) options |= SSL_OP_NO_TLSv1_1 ; if ( srv -> ssl_ctx . options & SRV_SSL_O_NO_TLSV12 ) options |= SSL_OP_NO_TLSv1_2 ; if ( srv -> ssl_ctx . options & SRV_SSL_O_NO_TLS_TICKETS ) options |= SSL_OP_NO_TICKET ; if ( srv -> ssl_ctx . options & SRV_SSL_O_USE_SSLV3 ) SSL_CTX_set_ssl_version ( srv -> ssl_ctx . ctx , SSLv3_client_method ( ) ) ; if ( srv -> ssl_ctx . options & SRV_SSL_O_USE_TLSV10 ) SSL_CTX_set_ssl_version ( srv -> ssl_ctx . ctx , TLSv1_client_method ( ) ) ; #if SSL_OP_NO_TLSv1_1 if ( srv -> ssl_ctx . options & SRV_SSL_O_USE_TLSV11 ) SSL_CTX_set_ssl_version ( srv -> ssl_ctx . ctx , TLSv1_1_client_method ( ) ) ; #endif #if SSL_OP_NO_TLSv1_2 if ( srv -> ssl_ctx . options & SRV_SSL_O_USE_TLSV12 ) SSL_CTX_set_ssl_version ( srv -> ssl_ctx . ctx , TLSv1_2_client_method ( ) ) ; #endif SSL_CTX_set_options ( srv -> ssl_ctx . ctx , options ) ; SSL_CTX_set_mode ( srv -> ssl_ctx . ctx , mode ) ; SSL_CTX_set_verify ( srv -> ssl_ctx . ctx , srv -> ssl_ctx . verify ? srv -> ssl_ctx . verify : SSL_VERIFY_NONE , NULL ) ; if ( srv -> ssl_ctx . verify & SSL_VERIFY_PEER ) { if ( srv -> ssl_ctx . ca_file ) { if ( ! SSL_CTX_load_verify_locations ( srv -> ssl_ctx . ctx , srv -> ssl_ctx . ca_file , NULL ) ) { Alert ( " \n " , curproxy -> id , srv -> id , srv -> conf . file , srv -> conf . line , srv -> ssl_ctx . ca_file ) ; cfgerr ++ ; } } #ifdef X509_V_FLAG_CRL_CHECK if ( srv -> ssl_ctx . crl_file ) { X509_STORE * store = SSL_CTX_get_cert_store ( srv -> ssl_ctx . ctx ) ; if ( ! store || ! X509_STORE_load_locations ( store , srv -> ssl_ctx . crl_file , NULL ) ) { Alert ( " \n " , curproxy -> id , srv -> id , srv -> conf . file , srv -> conf . line , srv -> ssl_ctx . crl_file ) ; cfgerr ++ ; } else { X509_STORE_set_flags ( store , X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL ) ; } } #endif } if ( global . tune . ssllifetime ) SSL_CTX_set_timeout ( srv -> ssl_ctx . ctx , global . tune . ssllifetime ) ; SSL_CTX_set_session_cache_mode ( srv -> ssl_ctx . ctx , SSL_SESS_CACHE_OFF ) ; if ( srv -> ssl_ctx . ciphers && ! SSL_CTX_set_cipher_list ( srv -> ssl_ctx . ctx , srv -> ssl_ctx . ciphers ) ) { Alert ( " \n " , curproxy -> id , srv -> id , srv -> conf . file , srv -> conf . line , srv -> ssl_ctx . ciphers ) ; cfgerr ++ ; } return cfgerr ; }
prepare ssl context from servers options.
prepare ssl context from servers options .
/* all known workarounds for bugs */ /* Make sure openssl opens /dev/urandom before the chroot */ /* Initiate SSL context for current server */ /* load CAfile to verify */