/** * Initializes a ssl connection for server use. * @param pemfilename Filename for the key/cert file * @return An ssl connection, or NULL if an error occured. */ ssl_server_connection *init_ssl_server(char *pemfile, char *clientpemfile) { ASSERT(pemfile); if (!ssl_initialized) start_ssl(); ssl_server_connection *ssl_server = new_ssl_server_connection(pemfile, clientpemfile); if (!(ssl_server->method = SSLv23_server_method())) { LogError("Cannot initialize the SSL method -- %s\n", SSLERROR); goto sslerror; } if (!(ssl_server->ctx = SSL_CTX_new(ssl_server->method))) { LogError("Cannot initialize SSL server certificate handler -- %s\n", SSLERROR); goto sslerror; } if (SSL_CTX_use_certificate_chain_file(ssl_server->ctx, pemfile) != 1) { LogError("Cannot initialize SSL server certificate -- %s\n", SSLERROR); goto sslerror; } if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) != 1) { LogError("Cannot initialize SSL server private key -- %s\n", SSLERROR); goto sslerror; } if (SSL_CTX_check_private_key(ssl_server->ctx) != 1) { LogError("The private key doesn't match the certificate public key -- %s\n", SSLERROR); goto sslerror; } if (SSL_CTX_set_cipher_list(ssl_server->ctx, CIPHER_LIST) != 1) { LogError("Error setting cipher list '%s' (no valid ciphers)\n", CIPHER_LIST); goto sslerror; } SSL_CTX_set_options(ssl_server->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); // Disable SSLv2 and SSLv3 for security reasons SSL_CTX_set_session_cache_mode(ssl_server->ctx, SSL_SESS_CACHE_OFF); // Disable session cache /* * We need this to force transmission of client certs */ if (!verify_init(ssl_server)) { LogError("Verification engine was not properly initialized -- %s\n", SSLERROR); goto sslerror; } if (ssl_server->clientpemfile) { STACK_OF(X509_NAME) *stack = SSL_CTX_get_client_CA_list(ssl_server->ctx); LogInfo("Found %d client certificates\n", sk_X509_NAME_num(stack)); } return ssl_server; sslerror: delete_ssl_server_socket(ssl_server); return NULL; }
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 */ }
/** * Initializes a ssl connection for server use. * @param pemfilename Filename for the key/cert file * @return An ssl connection, or NULL if an error occured. */ ssl_server_connection *init_ssl_server(char *pemfile, char *clientpemfile) { SSL_METHOD *server_method = NULL; ssl_server_connection *ssl_server; ASSERT(pemfile); if (!ssl_initialized) start_ssl(); ssl_server = new_ssl_server_connection(pemfile, clientpemfile); #ifdef OPENSSL_FIPS if (FIPS_mode()) server_method = TLSv1_server_method(); else #endif server_method = SSLv23_server_method(); if (!(ssl_server->method = server_method)) { LogError("%s: Cannot initialize the SSL method -- %s\n", prog, SSLERROR); goto sslerror; } if (!(ssl_server->ctx = SSL_CTX_new(ssl_server->method))) { LogError("%s: Cannot initialize SSL server certificate handler -- %s\n", prog, SSLERROR); goto sslerror; } if (SSL_CTX_use_certificate_chain_file(ssl_server->ctx, pemfile) != 1) { LogError("%s: Cannot initialize SSL server certificate -- %s\n", prog, SSLERROR); goto sslerror; } if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) != 1) { LogError("%s: Cannot initialize SSL server private key -- %s\n", prog, SSLERROR); goto sslerror; } if (SSL_CTX_check_private_key(ssl_server->ctx) != 1) { LogError("%s: The private key doesn't match the certificate public key -- %s\n", prog, SSLERROR); goto sslerror; } /* Disable session cache */ SSL_CTX_set_session_cache_mode(ssl_server->ctx, SSL_SESS_CACHE_OFF); /* * We need this to force transmission of client certs */ if (!verify_init(ssl_server)) { LogError("%s: Verification engine was not properly initialized -- %s\n", prog, SSLERROR); goto sslerror; } if (ssl_server->clientpemfile) { STACK_OF(X509_NAME) *stack = SSL_CTX_get_client_CA_list(ssl_server->ctx); LogInfo("%s: Found %d client certificates\n", prog, sk_X509_NAME_num(stack)); } return ssl_server; sslerror: delete_ssl_server_socket(ssl_server); return NULL; }
void context_init(void) { /* init SSL */ int i; #if SSLEAY_VERSION_NUMBER >= 0x00907000L /* Load all bundled ENGINEs into memory and make them visible */ ENGINE_load_builtin_engines(); /* Register all of them for every algorithm they collectively implement */ ENGINE_register_all_complete(); #endif if(!init_prng()) log(LOG_INFO, "PRNG seeded successfully"); SSLeay_add_ssl_algorithms(); SSL_load_error_strings(); if(options.option.client) { ctx=SSL_CTX_new(SSLv3_client_method()); } else { /* Server mode */ ctx=SSL_CTX_new(SSLv23_server_method()); #ifndef NO_RSA SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb); #endif /* NO_RSA */ if(init_dh()) log(LOG_WARNING, "Diffie-Hellman initialization failed"); } if(options.ssl_options) { log(LOG_DEBUG, "Configuration SSL options: 0x%08lX", options.ssl_options); log(LOG_DEBUG, "SSL options set: 0x%08lX", SSL_CTX_set_options(ctx, options.ssl_options)); } #if SSLEAY_VERSION_NUMBER >= 0x00906000L SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); #endif /* OpenSSL-0.9.6 */ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH); SSL_CTX_set_timeout(ctx, options.session_timeout); if(options.option.cert) { if(!SSL_CTX_use_certificate_chain_file(ctx, options.cert)) { log(LOG_ERR, "Error reading certificate file: %s", options.cert); sslerror("SSL_CTX_use_certificate_chain_file"); exit(1); } log(LOG_DEBUG, "Certificate: %s", options.cert); log(LOG_DEBUG, "Key file: %s", options.key); #ifdef USE_WIN32 SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb); #endif for(i=0; i<3; i++) { #ifdef NO_RSA if(SSL_CTX_use_PrivateKey_file(ctx, options.key, SSL_FILETYPE_PEM)) #else /* NO_RSA */ if(SSL_CTX_use_RSAPrivateKey_file(ctx, options.key, SSL_FILETYPE_PEM)) #endif /* NO_RSA */ break; if(i<2 && ERR_GET_REASON(ERR_peek_error())==EVP_R_BAD_DECRYPT) { sslerror_stack(); /* dump the error stack */ log(LOG_ERR, "Wrong pass phrase: retrying"); continue; } #ifdef NO_RSA sslerror("SSL_CTX_use_PrivateKey_file"); #else /* NO_RSA */ sslerror("SSL_CTX_use_RSAPrivateKey_file"); #endif /* NO_RSA */ exit(1); } if(!SSL_CTX_check_private_key(ctx)) { sslerror("Private key does not match the certificate"); exit(1); } } verify_init(); /* Initialize certificate verification */ SSL_CTX_set_info_callback(ctx, info_callback); if(options.cipher_list) { if (!SSL_CTX_set_cipher_list(ctx, options.cipher_list)) { sslerror("SSL_CTX_set_cipher_list"); exit(1); } } }
/** * Initializes a ssl connection for server use. * @param pemfilename Filename for the key/cert file * @return An ssl connection, or NULL if an error occured. */ ssl_server_connection *init_ssl_server (char *pemfile, char *clientpemfile) { #ifdef HAVE_OPENSSL ssl_server_connection *ssl_server = new_ssl_server_connection(pemfile, clientpemfile); ASSERT(pemfile); if (!ssl_initilized) { start_ssl(); } if ((ssl_server->method= SSLv23_server_method()) == NULL ) { handle_ssl_error("init_ssl_server()"); log("%s: init_ssl_server (): Cannot initialize the SSL method!\n", prog); goto sslerror; } if ((ssl_server->ctx= SSL_CTX_new(ssl_server->method)) == NULL ) { handle_ssl_error("init_ssl_server()"); log("%s: init_ssl_server (): Cannot initialize SSL server" " certificate handler!\n" , prog); goto sslerror; } if (SSL_CTX_use_certificate_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) <= 0) { handle_ssl_error("init_ssl_server()"); log("%s: init_ssl_server(): Cannot initialize SSL server" " certificate!\n", prog); goto sslerror; } if (SSL_CTX_use_PrivateKey_file(ssl_server->ctx, pemfile, SSL_FILETYPE_PEM) <= 0) { handle_ssl_error("init_ssl_server()"); log("%s: init_ssl_server(): Cannot initialize SSL server" " private key!\n", prog); goto sslerror; } if (!SSL_CTX_check_private_key(ssl_server->ctx)) { handle_ssl_error("init_ssl_server()"); log("%s: init_ssl_server(): The private key does not match the" " certificate public key!\n", prog); goto sslerror; } /* * We need this to force transmission of client certs */ if (!verify_init(ssl_server)) { handle_ssl_error("init_ssl_server()"); log("%s: init_ssl_server(): Verification engine was not" " properly initilized!\n", prog); goto sslerror; } if (ssl_server->clientpemfile != NULL) { verify_info(ssl_server); } return ssl_server; sslerror: cleanup_ssl_server_socket(ssl_server); return NULL; #else return NULL; #endif }
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 */ }