Exemple #1
0
/*
 *	Load precomputed DH parameters.
 *
 *	To prevent "downgrade" attacks, we perform a number of checks
 *	to verify that the DBA-generated DH parameters file contains
 *	what we expect it to contain.
 */
static DH  *
load_dh_file(int keylength)
{
	FILE	   *fp;
	char		fnbuf[MAXPGPATH];
	DH		   *dh = NULL;
	int			codes;

	/* attempt to open file.  It's not an error if it doesn't exist. */
	snprintf(fnbuf, sizeof(fnbuf), "dh%d.pem", keylength);
	if ((fp = fopen(fnbuf, "r")) == NULL)
		return NULL;

/*	flock(fileno(fp), LOCK_SH); */
	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
/*	flock(fileno(fp), LOCK_UN); */
	fclose(fp);

	/* is the prime the correct size? */
	if (dh != NULL && 8 * DH_size(dh) < keylength)
	{
		elog(LOG, "DH errors (%s): %d bits expected, %d bits found",
			 fnbuf, keylength, 8 * DH_size(dh));
		dh = NULL;
	}

	/* make sure the DH parameters are usable */
	if (dh != NULL)
	{
		if (DH_check(dh, &codes) == 0)
		{
			elog(LOG, "DH_check error (%s): %s", fnbuf, SSLerrmessage());
			return NULL;
		}
		if (codes & DH_CHECK_P_NOT_PRIME)
		{
			elog(LOG, "DH error (%s): p is not prime", fnbuf);
			return NULL;
		}
		if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
			(codes & DH_CHECK_P_NOT_SAFE_PRIME))
		{
			elog(LOG,
				 "DH error (%s): neither suitable generator or safe prime",
				 fnbuf);
			return NULL;
		}
	}

	return dh;
}
Exemple #2
0
static ret_t
try_read_dh_param(cherokee_config_node_t  *conf,
		  DH                     **dh,
		  int                      bitsize)
{
	ret_t              ret;
	cherokee_buffer_t *buf;
	FILE              *paramfile = NULL;
	cherokee_buffer_t  confentry = CHEROKEE_BUF_INIT;

	cherokee_buffer_add_va (&confentry, "dh_param%d", bitsize);

	/* Read the configuration parameter
	 */
	ret = cherokee_config_node_read (conf, confentry.buf, &buf);
	if (ret != ret_ok) {
		ret = ret_ok;
		goto out;
	}

	/* Read the file
	 */
	paramfile = fopen (buf->buf, "r");
	if (paramfile == NULL) {
		TRACE(ENTRIES, "Cannot open file %s\n", buf->buf);
		ret = ret_file_not_found;
		goto out;
	}

	/* Process the content
	 */
	*dh = PEM_read_DHparams (paramfile, NULL, NULL, NULL);
	if (*dh == NULL) {
		TRACE(ENTRIES, "Failed to load PEM %s\n", buf->buf);
		ret = ret_error;
		goto out;
	}

	ret = ret_ok;

out:
	/* Clean up
	 */
	if (paramfile != NULL) {
		fclose (paramfile);
	}

	cherokee_buffer_mrproper (&confentry);
	return ret;
}
Exemple #3
0
/*
 * Load DH parameters from a PEM file.
 * Not thread-safe.
 */
DH *
ssl_dh_load(const char *filename)
{
	DH *dh;
	FILE *fh;

	if (ssl_init() == -1)
		return NULL;

	if (!(fh = fopen(filename, "r"))) {
		return NULL;
	}
	dh = PEM_read_DHparams(fh, NULL, NULL, NULL);
	fclose(fh);
	return dh;
}
Exemple #4
0
int Condor_Diffie_Hellman :: initialize()
{
    // First, check the config file to find out where is the file
    // with all the parameters
    config();
    char * dh_config = param(DH_CONFIG_FILE);

    FILE * fp = 0;
    if ( dh_config ) {
        if ( (fp = safe_fopen_wrapper_follow(dh_config, "r")) == NULL) {
            dprintf(D_ALWAYS, "Unable to open condor_dh_config file %s\n", dh_config);
            goto error;
        }

        dh_ = PEM_read_DHparams(fp, NULL, NULL, NULL);
        if (dh_ == NULL) {
            dprintf(D_ALWAYS, "Unable to read DH structure from the configuration file.\n");
            goto error;
        }

        // Now generate private key
        if (DH_generate_key(dh_) == 0) {
            dprintf(D_ALWAYS, "Unable to generate a private key \n");
            goto error;
        }
    }
    else {
        dprintf(D_ALWAYS, "The required configuration parameter CONDOR_DH_CONFIG is not specified in the condor configuration file!\n");
        goto error;
    }
    fclose(fp);
    free(dh_config);
    return 1;
 error:
    if (dh_) {
        DH_free(dh_);
        dh_ = 0;
    }
    if (dh_config) {
        free(dh_config);
    }
    if (fp) {
        fclose(fp);
    }
    return 0;
}
Exemple #5
0
/*
 *	Load precomputed DH parameters.
 *
 *	To prevent "downgrade" attacks, we perform a number of checks
 *	to verify that the DBA-generated DH parameters file contains
 *	what we expect it to contain.
 */
static DH  *
load_dh_file(int keylength)
{
	char		homedir[MAXPGPATH];
	char		fnbuf[MAXPGPATH];
	FILE	   *fp;
	DH		   *dh;
	int			codes;

	if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
		return NULL;

	/* attempt to open file.  It's not an error if it doesn't exist. */
	snprintf(fnbuf, sizeof(fnbuf), DHFILEPATTERN, homedir, keylength);

	if ((fp = fopen(fnbuf, "r")) == NULL)
		return NULL;

/*	flock(fileno(fp), LOCK_SH); */
	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
/*	flock(fileno(fp), LOCK_UN); */
	fclose(fp);

	/* is the prime the correct size? */
	if (dh != NULL && 8 * DH_size(dh) < keylength)
		dh = NULL;

	/* make sure the DH parameters are usable */
	if (dh != NULL)
	{
		if (DH_check(dh, &codes))
			return NULL;
		if (codes & DH_CHECK_P_NOT_PRIME)
			return NULL;
		if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
			(codes & DH_CHECK_P_NOT_SAFE_PRIME))
			return NULL;
	}

	return dh;
}
Exemple #6
0
void    tls_set_dh_from_file(const char *path, int bits)
{
    FILE   *paramfile;
    DH    **dhPtr;

    switch (bits) {
    case 512:
	dhPtr = &dh_512;
	break;
    case 1024:
	dhPtr = &dh_1024;
	break;
    default:
	msg_panic("Invalid DH parameters size %d, file %s", bits, path);
    }

    /*
     * This function is the first to set the DH parameters, but free any
     * prior value just in case the call sequence changes some day.
     */
    if (*dhPtr) {
	DH_free(*dhPtr);
	*dhPtr = 0;
    }
    if ((paramfile = fopen(path, "r")) != 0) {
	if ((*dhPtr = PEM_read_DHparams(paramfile, 0, 0, 0)) == 0) {
	    msg_warn("cannot load %d-bit DH parameters from file %s"
		     " -- using compiled-in defaults", bits, path);
	    tls_print_errors();
	}
	(void) fclose(paramfile);		/* 200411 */
    } else {
	msg_warn("cannot load %d-bit DH parameters from file %s: %m"
		 " -- using compiled-in defaults", bits, path);
    }
}
Exemple #7
0
static bool
Load_DH_params(void)
{
#ifdef HAVE_LIBSSL
	FILE *fp;
	bool ret = true;

	if (!Conf_SSLOptions.DHFile) {
		Log(LOG_NOTICE, "Configuration option \"DHFile\" not set!");
		return false;
	}
	fp = fopen(Conf_SSLOptions.DHFile, "r");
	if (!fp) {
		Log(LOG_ERR, "%s: %s", Conf_SSLOptions.DHFile, strerror(errno));
		return false;
	}
	dh_params = PEM_read_DHparams(fp, NULL, NULL, NULL);
	if (!dh_params) {
		Log(LOG_ERR, "%s: Failed to read SSL DH parameters!",
		    Conf_SSLOptions.DHFile);
		ret = false;
	}
	fclose(fp);
	return ret;
#endif
#ifdef HAVE_LIBGNUTLS
	bool need_dhgenerate = true;
	int err;
	gnutls_dh_params_t tmp_dh_params;

	err = gnutls_dh_params_init(&tmp_dh_params);
	if (err < 0) {
		Log(LOG_ERR, "Failed to initialize SSL DH parameters: %s",
		    gnutls_strerror(err));
		return false;
	}
	if (Conf_SSLOptions.DHFile) {
		gnutls_datum_t dhparms;
		size_t size;
		dhparms.data = (unsigned char *) openreadclose(Conf_SSLOptions.DHFile, &size);
		if (dhparms.data) {
			dhparms.size = size;
			err = gnutls_dh_params_import_pkcs3(tmp_dh_params, &dhparms, GNUTLS_X509_FMT_PEM);
			if (err == 0)
				need_dhgenerate = false;
			else
				Log(LOG_ERR,
				    "Failed to initialize SSL DH parameters: %s",
				    gnutls_strerror(err));

			memset(dhparms.data, 0, size);
			free(dhparms.data);
		}
	}
	if (need_dhgenerate) {
		Log(LOG_WARNING,
		    "DHFile not set, generating %u bit DH parameters. This may take a while ...",
		    DH_BITS);
		err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
		if (err < 0) {
			Log(LOG_ERR, "Failed to generate SSL DH parameters: %s",
			    gnutls_strerror(err));
			return false;
		}
        }
	dh_params = tmp_dh_params;
	return true;
#endif
}
Exemple #8
0
int
main(int arc, char** argv) {
	char* server_port = "5000";
	char* server_ip = "127.0.0.1";

	char* cert_file = "client.crt";
	char* key_file = "client.key";

	// Command Line generation of Diffie-Hellman parameters
	// openssl dhparam -out dh_param_2048.pem 2048
	char* dh_file = "dh_param_2048_client.pem";

	DH *dh_2048 = NULL;
	FILE *paramfile;

	int err;
        int sockfd;

	struct addrinfo hints;
	struct addrinfo *server;

	const SSL_METHOD *ssl_meth;
	SSL_CTX *ctx;

        /* Load encryption & hashing algorithms for the SSL program */
	SSL_library_init();
	/* Load the error strings for SSL & CRYPTO APIs */
	SSL_load_error_strings();

	/* Use SSLv3 for the connection */
	ssl_meth = SSLv23_client_method();
	/* Create a new context--stores configuration for SSL */
	ctx = SSL_CTX_new(ssl_meth);
	if (!ctx)
		error("Error creating SSL context.\n");

	printf("Setting the local certificates and keys...\n");
        /* Set the local certificates and keys */
	err = SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM);
	if (err <= 0) {
		ERR_print_errors_fp(stderr);
		fprintf(stderr, "Error setting the certificate file.\n");
		goto out;
	}

	err = SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM);
	if (err <= 0) {
		ERR_print_errors_fp(stderr);
		fprintf(stderr, "Error setting the private key file.\n");
		goto out;
	}

        /* Verify private key and public crt combination. */
	if (!SSL_CTX_check_private_key(ctx)) {		
		fprintf(stderr,
			"Error, private key does not match public key.\n");
		goto out;
	}

	/* Set up ephemeral DH parameters. */
	paramfile = fopen(dh_file, "r");

	if (!paramfile) {
		fprintf(stderr, "Error opening Diffie-Hellman parameters.\n");
		goto out;
	}
	dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL);

	err = fclose(paramfile);
	if (err) {
		fprintf(stderr, "Error closing file stream.\n");
		goto out;
	}

	if (!dh_2048) {
		fprintf(stderr, "Error reading Diffie-Hellman parameters.\n");
		goto out;
	}
	err = SSL_CTX_set_tmp_dh(ctx, dh_2048);
	if (err != 1) {
		fprintf(stderr,
			"Error setting Diffie-Hellman into SSL context\n");
		goto out;
	}


	/*--- Standard TCP server setup and connection ---*/

	printf("Creating TCP/IP socket...\n");
	{
		SSL *ssl;
		int bytes = 0;
		char *msg = "Hello!";
		char buf[256];

		memset(&buf, 0, sizeof(buf));
		/* The hints struct is used to specify what kind of server info
		 * we are looking for. */
		memset(&hints, 0, sizeof hints);
		hints.ai_family = AF_INET;
		hints.ai_socktype = SOCK_STREAM; /* or SOCK_DGRAM */
		
		/* getaddrinfo() gives us back a server address we can connect to.
		   It actually gives us a linked list of addresses, but we'll just
		   use the first. */
		err = getaddrinfo(server_ip, server_port, &hints, &server);
		if (err) {
			fprintf(stderr, "Error getting address information.\n");
			goto out;
		}
		/* Now we can create the socket and connect */
		sockfd = socket(server->ai_family, server->ai_socktype, server->ai_protocol);
		if (sockfd == -1) {		
			fprintf(stderr, "Error opening socket.\n");
			freeaddrinfo(server);
			goto out;
		}
		
		err = connect(sockfd, server->ai_addr, server->ai_addrlen);
		if (err == -1) {
			fprintf(stderr, "Error on connect.\n");
			close(sockfd);
			freeaddrinfo(server);
			goto out;
		}
		
		ssl = SSL_new(ctx);
		if (!ssl) {
			fprintf(stderr,
				"Error creating a new SSL structure.\n");
			ERR_print_errors_fp(stderr);
			close(sockfd);
			freeaddrinfo(server);
			goto out;
		}
		SSL_set_fd(ssl, sockfd); /* set connection to SSL state */
		
		err = SSL_connect(ssl);
		if (err < 1) {
			err = SSL_get_error(ssl,err);
			printf("SSL error #%d in accept.\n", err);
			ERR_print_errors_fp(stderr);

			SSL_free(ssl);
			close(sockfd);
			freeaddrinfo(server);
			goto out;
		}
		
		/* Print out connection details */
		printf("SSL connection on socket %x, Version: %s, Cipher: %s\
\n", sockfd, SSL_get_version(ssl), SSL_get_cipher(ssl));
		
		err = SSL_write(ssl, msg, strlen(msg) + 1);
		if (err < 0) {
			printf("sslerror:%d\n", SSL_get_error(ssl, err));
			ERR_print_errors_fp(stderr);
			
			SSL_free(ssl);
			close(sockfd);
			freeaddrinfo(server);
			goto out;
		}
		
		while(bytes <= 0)
			bytes = SSL_read(ssl, buf, sizeof(buf) - 1);
		
		printf("Received: %s\n", buf);
		
		err = SSL_shutdown(ssl);
		if (err < 0)
			printf("Error in SSL shutdown\n");
		else if (err == 1)
			printf("Client exited gracefully\n");
		
		/* close connection & clean up */
		SSL_free(ssl);
		close(sockfd);
		freeaddrinfo(server);
	}
out:
	SSL_CTX_free(ctx);
	return 0;
}
Exemple #9
0
//SSL_CTX* init_ssl_server_ctx(const SSL_METHOD* method, const char* server_cert, const char* server_priv_key, const char* dh_params, const char* ecdh_curve, const char* ecdsa_cert, const char* ecdsa_privkey, int check_client)
SSL_CTX* init_ssl_server_ctx(const SSL_METHOD* method, X509* server_cert, EVP_PKEY* server_priv_key, const char* dh_params, const char* ecdh_curve, X509* ecdsa_cert, EVP_PKEY* ecdsa_privkey, X509* root_cert)
{
    SSL_CTX* ssl_ctx = 0;
    DH* dh = 0;
    EC_KEY* ecdh = 0;
    FILE* param_file = 0;
    X509_STORE* x509_store;
    int nid;
    
    //make ssl context
    if (!(ssl_ctx = SSL_CTX_new(method)))
    {
        write_out(PRINT_ERROR, "Unable to initialize OpenSSL.");
        write_raise_level();
        print_ssl_error_stack(PRINT_ERROR);
        write_lower_level();
        
        goto error_die;
    }
    
    //disable renegotiation to ensure a fresh start
    SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_OFF);
    SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_TICKET);
    
    if (server_cert && server_priv_key)
    {
        //load rsa certs
        //if (SSL_CTX_use_certificate_file(ssl_ctx, server_cert, SSL_FILETYPE_PEM) != 1)
        if (SSL_CTX_use_certificate(ssl_ctx, server_cert) != 1)
        {
            write_out(PRINT_ERROR, "Unable to load RSA certificate.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        if (SSL_CTX_use_PrivateKey(ssl_ctx, server_priv_key) != 1)
        {
            write_out(PRINT_ERROR, "Unable to load RSA private key.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        if (!SSL_CTX_check_private_key(ssl_ctx))
        {
            write_out(PRINT_ERROR, "RSA Certificate and private key do not match!");
            
            goto error_die;
        }
    }
    
    if (dh_params)
    {    
        //load dh params
        param_file = fopen(dh_params, "rb");
        if (!param_file)
        {
            write_out(PRINT_ERROR, "DH Parameter file could not be read: %s", dh_params);
        }
        
        dh = PEM_read_DHparams(param_file, 0, 0, 0);
        if (!dh)
        {
            write_out(PRINT_ERROR, "DH Parameters could not be loaded!");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        fclose(param_file);
        param_file = 0;

        if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1)
        {
            write_out(PRINT_ERROR, "DH Parameters could not be set!");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        DH_free(dh);
        dh = 0;
    }
    
    if (ecdh_curve)
    {
        //load ecdh params
        if ((nid = OBJ_sn2nid(ecdh_curve)) == NID_undef)
        {
            write_out(PRINT_ERROR, "Unable to find elliptic curve %s.", ecdh_curve);
            goto error_die;
        }
        
        if ((ecdh = EC_KEY_new_by_curve_name(nid)) == 0)
        {
            write_out(PRINT_ERROR, "Unable to create elliptic curve %s.", ecdh_curve);
            goto error_die;
        }
        
        if (SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh) != 1)
        {
            write_out(PRINT_ERROR, "ECDH Parameters could not be set!");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        EC_KEY_free(ecdh);
        ecdh = 0;
    }
    
    if (ecdsa_cert && ecdsa_privkey)
    {
        //load ecdsa certs
        //if (SSL_CTX_use_certificate_file(ssl_ctx, ecdsa_cert, SSL_FILETYPE_PEM) != 1)
        if (SSL_CTX_use_certificate(ssl_ctx, ecdsa_cert) != 1)
        {
            write_out(PRINT_ERROR, "Unable to load ECDSA certificate.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        //if (SSL_CTX_use_PrivateKey_file(ssl_ctx, ecdsa_privkey, SSL_FILETYPE_PEM) != 1)
        if (SSL_CTX_use_PrivateKey(ssl_ctx, ecdsa_privkey) != 1)
        {
            write_out(PRINT_ERROR, "Unable to load ECDSA private key.");
            write_raise_level();
            print_ssl_error_stack(PRINT_ERROR);
            write_lower_level();
            
            goto error_die;
        }
        
        if (!SSL_CTX_check_private_key(ssl_ctx))
        {
            write_out(PRINT_ERROR, "ECDSA Certificate and private key do not match!");
            
            goto error_die;
        }
    }

    //setup the root_cert for verification
    if (root_cert)
    {
        x509_store = SSL_CTX_get_cert_store(ssl_ctx);
        
        X509_STORE_add_cert(x509_store, root_cert);
    }
    
    return ssl_ctx;
    
error_die:
    if (ssl_ctx)
        SSL_CTX_free(ssl_ctx);
    
    if (param_file)
        fclose(param_file);
    
    if (dh)
        DH_free(dh);
    
    if (ecdh)
        EC_KEY_free(ecdh);
    
    return 0;
}
Exemple #10
0
// .. c:function::
ch_error_t
ch_en_start(ch_encryption_t* enc)
//    :noindex:
//
//    see: :c:func:`ch_en_start`
//
// .. code-block:: cpp
//
{
    ch_chirp_t* chirp = enc->chirp;
    A(chirp->_init == CH_CHIRP_MAGIC, "Not a ch_chirp_t*");
    ch_chirp_int_t* ichirp = chirp->_;
    if(!_ch_en_manual_openssl) {
        int tmp_err;
        _ch_en_openssl_ref_count += 1;
        L(
            chirp,
            "Initializing the OpenSSL library. ch_chirp_t:%p",
            (void*) chirp
        );
        tmp_err = ch_en_openssl_init();
        if(tmp_err != CH_SUCCESS) {
            L(
                chirp,
                "Could not initialize the OpenSSL library. ch_chirp_t:%p",
                (void*) chirp
            );
            return tmp_err;
        }
    }
    const SSL_METHOD* method = TLSv1_2_method();
    if(method == NULL) {
        E(
            chirp,
            "Could not get the TLSv1_2_method. ch_chirp_t:%p",
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    enc->ssl_ctx = SSL_CTX_new(method);
    if(enc->ssl_ctx == NULL) {
        E(
            chirp,
            "Could create the SSL_CTX. ch_chirp_t:%p",
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    SSL_CTX_set_mode(
        enc->ssl_ctx,
        SSL_MODE_AUTO_RETRY |
        SSL_MODE_ENABLE_PARTIAL_WRITE
    );
    SSL_CTX_set_options(enc->ssl_ctx, SSL_OP_NO_COMPRESSION);
    SSL_CTX_set_verify(
            enc->ssl_ctx,
            SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
            NULL
    );
    SSL_CTX_set_verify_depth(enc->ssl_ctx, 5);
    if(SSL_CTX_load_verify_locations(
                enc->ssl_ctx,
                ichirp->config.CERT_CHAIN_PEM,
                NULL
    ) != 1) {
        E(
            chirp,
            "Could not set the verification certificate "
            "%s. ch_chirp_t:%p",
            ichirp->config.CERT_CHAIN_PEM,
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    if(SSL_CTX_use_certificate_chain_file(
                enc->ssl_ctx,
                ichirp->config.CERT_CHAIN_PEM
    ) != 1) {
        E(
            chirp,
            "Could not set the certificate %s. ch_chirp_t:%p",
            ichirp->config.CERT_CHAIN_PEM,
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    if(SSL_CTX_use_PrivateKey_file(
                enc->ssl_ctx,
                ichirp->config.CERT_CHAIN_PEM,
                SSL_FILETYPE_PEM
    ) != 1) {
        E(
            chirp,
            "Could not set the private key %s. ch_chirp_t:%p",
            ichirp->config.CERT_CHAIN_PEM,
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    if(SSL_CTX_check_private_key(enc->ssl_ctx) != 1) {
        E(
            chirp,
            "Private key is not valid %s. ch_chirp_t:%p",
            ichirp->config.CERT_CHAIN_PEM,
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    DH *dh = NULL;
    FILE *paramfile;
    paramfile = fopen(ichirp->config.DH_PARAMS_PEM, "r");
    if(paramfile == NULL) {
        E(
            chirp,
            "Could not open the dh-params %s. ch_chirp_t:%p",
            ichirp->config.DH_PARAMS_PEM,
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
    fclose(paramfile);
    if(dh == NULL) {
        E(
            chirp,
            "Could not load the dh-params %s. ch_chirp_t:%p",
            ichirp->config.DH_PARAMS_PEM,
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    if(SSL_CTX_set_tmp_dh(enc->ssl_ctx, dh) != 1) {
        E(
            chirp,
            "Could not set the dh-params %s. ch_chirp_t:%p",
            ichirp->config.DH_PARAMS_PEM,
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    if(SSL_CTX_set_cipher_list(
            enc->ssl_ctx,
            "-ALL:"
            "DHE-DSS-AES256-GCM-SHA384:"
            "DHE-RSA-AES256-GCM-SHA384:"
            "DHE-RSA-AES256-SHA256:"
            "DHE-DSS-AES256-SHA256:"
    ) != 1) {
        E(
            chirp,
            "Could not set the cipher list. ch_chirp_t:%p",
            (void*) chirp
        );
        return CH_TLS_ERROR;
    }
    L(
        chirp,
        "Created SSL context for chirp. ch_chirp_t:%p",
        (void*) chirp
    );
    return CH_SUCCESS;
}
Exemple #11
0
int
rb_setup_ssl_server(const char *certfile, const char *keyfile, const char *dhfile, const char *cipher_list)
{
	const char librb_ciphers[] = "kEECDH+HIGH:kEDH+HIGH:HIGH:!aNULL";

	#ifdef LRB_HAVE_TLS_SET_CURVES
	const char librb_curves[] = "P-521:P-384:P-256";
	#endif

	if(certfile == NULL)
	{
		rb_lib_log("rb_setup_ssl_server: No certificate file");
		return 0;
	}

	if(keyfile == NULL)
		keyfile = certfile;

	if(cipher_list == NULL)
		cipher_list = librb_ciphers;

	if (ssl_server_ctx)
		SSL_CTX_free(ssl_server_ctx);

	if (ssl_client_ctx)
		SSL_CTX_free(ssl_client_ctx);

	#ifdef LRB_HAVE_TLS_METHOD_API
	ssl_server_ctx = SSL_CTX_new(TLS_server_method());
	ssl_client_ctx = SSL_CTX_new(TLS_client_method());
	#else
	ssl_server_ctx = SSL_CTX_new(SSLv23_server_method());
	ssl_client_ctx = SSL_CTX_new(SSLv23_client_method());
	#endif

	if(ssl_server_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
			   get_ssl_error(ERR_get_error()));
		return 0;
	}

	if(ssl_client_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
			   get_ssl_error(ERR_get_error()));
		return 0;
	}

	#ifndef LRB_HAVE_TLS_METHOD_API
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
	SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
	#endif

	#ifdef SSL_OP_SINGLE_DH_USE
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_SINGLE_DH_USE);
	#endif

	#ifdef SSL_OP_SINGLE_ECDH_USE
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_SINGLE_ECDH_USE);
	#endif

	#ifdef SSL_OP_NO_TICKET
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_TICKET);
	SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_TICKET);
	#endif

	#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
	#endif

	SSL_CTX_set_verify(ssl_server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
	SSL_CTX_set_session_cache_mode(ssl_server_ctx, SSL_SESS_CACHE_OFF);

	#ifdef LRB_HAVE_TLS_SET_CURVES
	SSL_CTX_set1_curves_list(ssl_server_ctx, librb_curves);
	#endif

	#ifdef LRB_HAVE_TLS_ECDH_AUTO
	SSL_CTX_set_ecdh_auto(ssl_server_ctx, 1);
	#endif

	/*
	 * Set manual ECDHE curve on OpenSSL 1.0.0 & 1.0.1, but make sure it's actually available
	 */
	#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && (OPENSSL_VERSION_NUMBER < 0x10002000L) && !defined(OPENSSL_NO_ECDH)
	EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1);
	if (key) {
		SSL_CTX_set_tmp_ecdh(ssl_server_ctx, key);
		EC_KEY_free(key);
	}
	#endif

	SSL_CTX_set_cipher_list(ssl_server_ctx, cipher_list);
	SSL_CTX_set_cipher_list(ssl_client_ctx, cipher_list);

	if(!SSL_CTX_use_certificate_chain_file(ssl_server_ctx, certfile) || !SSL_CTX_use_certificate_chain_file(ssl_client_ctx, certfile))
	{
		rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", certfile,
			   get_ssl_error(ERR_get_error()));
		return 0;
	}

	if(!SSL_CTX_use_PrivateKey_file(ssl_server_ctx, keyfile, SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(ssl_client_ctx, keyfile, SSL_FILETYPE_PEM))
	{
		rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile,
			   get_ssl_error(ERR_get_error()));
		return 0;
	}

	if(dhfile != NULL)
	{
		/* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */
		FILE *fp = fopen(dhfile, "r");
		DH *dh = NULL;

		if(fp == NULL)
		{
			rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
			           dhfile, strerror(errno));
		}
		else if(PEM_read_DHparams(fp, &dh, NULL, NULL) == NULL)
		{
			rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
			           dhfile, get_ssl_error(ERR_get_error()));
			fclose(fp);
		}
		else
		{
			SSL_CTX_set_tmp_dh(ssl_server_ctx, dh);
			DH_free(dh);
			fclose(fp);
		}
	}

	return 1;
}
Exemple #12
0
	virtual void OnRehash(const std::string &param)
	{
		if(param != "ssl")
			return;
	
		Conf = new ConfigReader(ServerInstance);
			
		for(unsigned int i = 0; i < listenports.size(); i++)
		{
			ServerInstance->Config->DelIOHook(listenports[i]);
		}
		
		listenports.clear();
		
		for(int i = 0; i < Conf->Enumerate("bind"); i++)
		{
			// For each <bind> tag
			if(((Conf->ReadValue("bind", "type", i) == "") || (Conf->ReadValue("bind", "type", i) == "clients")) && (Conf->ReadValue("bind", "ssl", i) == "openssl"))
			{
				// Get the port we're meant to be listening on with SSL
				unsigned int port = Conf->ReadInteger("bind", "port", i, true);
				if (ServerInstance->Config->AddIOHook(port, this))
				{
					// We keep a record of which ports we're listening on with SSL
					listenports.push_back(port);
				
					ServerInstance->Log(DEFAULT, "m_ssl_openssl.so: Enabling SSL for port %d", port);
				}
				else
				{
					ServerInstance->Log(DEFAULT, "m_ssl_openssl.so: FAILED to enable SSL on port %d, maybe you have another ssl or similar module loaded?", port);
				}
			}
		}
		
		std::string confdir(CONFIG_FILE);
		// +1 so we the path ends with a /
		confdir = confdir.substr(0, confdir.find_last_of('/') + 1);
		
		cafile	= Conf->ReadValue("openssl", "cafile", 0);
		// crlfile	= Conf->ReadValue("openssl", "crlfile", 0);
		certfile	= Conf->ReadValue("openssl", "certfile", 0);
		keyfile	= Conf->ReadValue("openssl", "keyfile", 0);
		dhfile	= Conf->ReadValue("openssl", "dhfile", 0);
		
		// Set all the default values needed.
		if(cafile == "")
			cafile = "ca.pem";
			
		//if(crlfile == "")
		//	crlfile = "crl.pem";
			
		if(certfile == "")
			certfile = "cert.pem";
			
		if(keyfile == "")
			keyfile = "key.pem";
			
		if(dhfile == "")
			dhfile = "dhparams.pem";
			
		// Prepend relative paths with the path to the config directory.	
		if(cafile[0] != '/')
			cafile = confdir + cafile;
		
		//if(crlfile[0] != '/')
		//	crlfile = confdir + crlfile;
			
		if(certfile[0] != '/')
			certfile = confdir + certfile;
			
		if(keyfile[0] != '/')
			keyfile = confdir + keyfile;
			
		if(dhfile[0] != '/')
			dhfile = confdir + dhfile;

		/* Load our keys and certificates*/
		if(!SSL_CTX_use_certificate_chain_file(ctx, certfile.c_str()))
		{
			ServerInstance->Log(DEFAULT, "m_ssl_openssl.so: Can't read certificate file %s", certfile.c_str());
		}

		if(!SSL_CTX_use_PrivateKey_file(ctx, keyfile.c_str(), SSL_FILETYPE_PEM))
		{
			ServerInstance->Log(DEFAULT, "m_ssl_openssl.so: Can't read key file %s", keyfile.c_str());
		}

		/* Load the CAs we trust*/
		if(!SSL_CTX_load_verify_locations(ctx, cafile.c_str(), 0))
		{
			ServerInstance->Log(DEFAULT, "m_ssl_openssl.so: Can't read CA list from ", cafile.c_str());
		}

		FILE* dhpfile = fopen(dhfile.c_str(), "r");
		DH* ret;

		if(dhpfile == NULL)
		{
			ServerInstance->Log(DEFAULT, "m_ssl_openssl.so Couldn't open DH file %s: %s", dhfile.c_str(), strerror(errno));
			throw ModuleException();
		}
		else
		{
			ret = PEM_read_DHparams(dhpfile, NULL, NULL, NULL);
		
			if(SSL_CTX_set_tmp_dh(ctx, ret) < 0)
			{
				ServerInstance->Log(DEFAULT, "m_ssl_openssl.so: Couldn't set DH parameters");
			}
		}
		
		fclose(dhpfile);

		DELETE(Conf);
	}
Exemple #13
0
		inline dh_key dh_key::from_parameters(file _file, pem_passphrase_callback_type callback, void* callback_arg)
		{
			return take_ownership(PEM_read_DHparams(_file.raw(), NULL, callback, callback_arg));
		}