00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #include "libts.h"
00033 #include "I_Layout.h"
00034 
00035 #include <string.h>
00036 #include "P_Net.h"
00037 #include "P_SSLConfig.h"
00038 #include "P_SSLUtils.h"
00039 #include "P_SSLCertLookup.h"
00040 #include <records/I_RecHttp.h>
00041 
00042 int SSLConfig::configid = 0;
00043 int SSLCertificateConfig::configid = 0;
00044 int SSLConfigParams::ssl_maxrecord = 0;
00045 bool SSLConfigParams::ssl_allow_client_renegotiation = false;
00046 bool SSLConfigParams::ssl_ocsp_enabled = false;
00047 int SSLConfigParams::ssl_ocsp_cache_timeout = 3600;
00048 int SSLConfigParams::ssl_ocsp_request_timeout = 10;
00049 int SSLConfigParams::ssl_ocsp_update_period = 60;
00050 init_ssl_ctx_func SSLConfigParams::init_ssl_ctx_cb = NULL;
00051 
00052 static ConfigUpdateHandler<SSLCertificateConfig> * sslCertUpdate;
00053 
00054 SSLConfigParams::SSLConfigParams()
00055 {
00056   serverCertPathOnly =
00057     serverCertChainFilename =
00058     configFilePath =
00059     serverCACertFilename =
00060     serverCACertPath =
00061     clientCertPath =
00062     clientKeyPath =
00063     clientCACertFilename =
00064     clientCACertPath =
00065     cipherSuite =
00066     client_cipherSuite =
00067     serverKeyPathOnly = NULL;
00068 
00069   clientCertLevel = client_verify_depth = verify_depth = clientVerify = 0;
00070 
00071   ssl_ctx_options = 0;
00072   ssl_client_ctx_protocols = 0;
00073   ssl_session_cache = SSL_SESSION_CACHE_MODE_SERVER;
00074   ssl_session_cache_size = 1024*20;
00075   ssl_session_cache_timeout = 0;
00076 }
00077 
00078 SSLConfigParams::~SSLConfigParams()
00079 {
00080   cleanup();
00081 }
00082 
00083 void
00084 SSLConfigParams::cleanup()
00085 {
00086   ats_free_null(serverCertChainFilename);
00087   ats_free_null(serverCACertFilename);
00088   ats_free_null(serverCACertPath);
00089   ats_free_null(clientCertPath);
00090   ats_free_null(clientKeyPath);
00091   ats_free_null(clientCACertFilename);
00092   ats_free_null(clientCACertPath);
00093   ats_free_null(configFilePath);
00094   ats_free_null(serverCertPathOnly);
00095   ats_free_null(serverKeyPathOnly);
00096   ats_free_null(cipherSuite);
00097   ats_free_null(client_cipherSuite);
00098 
00099   clientCertLevel = client_verify_depth = verify_depth = clientVerify = 0;
00100 }
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 static void
00111 set_paths_helper(const char *path, const char *filename, char **final_path, char **final_filename)
00112 {
00113   if (final_path) {
00114     if (path && path[0] != '/') {
00115       *final_path = Layout::get()->relative_to(Layout::get()->prefix, path);
00116     } else if (!path || path[0] == '\0'){
00117       *final_path = ats_strdup(Layout::get()->sysconfdir);
00118     } else {
00119       *final_path = ats_strdup(path);
00120     }
00121   }
00122 
00123   if (final_filename) {
00124     *final_filename = filename ? Layout::get()->relative_to(path, filename) : NULL;
00125   }
00126 
00127 }
00128 
00129 void
00130 SSLConfigParams::initialize()
00131 {
00132   char *serverCertRelativePath = NULL;
00133   char *ssl_server_private_key_path = NULL;
00134   char *CACertRelativePath = NULL;
00135   char *ssl_client_cert_filename = NULL;
00136   char *ssl_client_cert_path = NULL;
00137   char *ssl_client_private_key_filename = NULL;
00138   char *ssl_client_private_key_path = NULL;
00139   char *clientCACertRelativePath = NULL;
00140   char *multicert_config_file = NULL;
00141   char *ssl_server_ca_cert_filename = NULL;
00142   char *ssl_client_ca_cert_filename = NULL;
00143 
00144   cleanup();
00145 
00146   
00147   verify_depth = 7;
00148 
00149   REC_ReadConfigInt32(clientCertLevel, "proxy.config.ssl.client.certification_level");
00150   REC_ReadConfigStringAlloc(cipherSuite, "proxy.config.ssl.server.cipher_suite");
00151   REC_ReadConfigStringAlloc(client_cipherSuite, "proxy.config.ssl.client.cipher_suite");
00152 
00153   int options;
00154   int client_ssl_options;
00155   REC_ReadConfigInteger(options, "proxy.config.ssl.SSLv2");
00156   if (!options)
00157     ssl_ctx_options |= SSL_OP_NO_SSLv2;
00158   REC_ReadConfigInteger(options, "proxy.config.ssl.SSLv3");
00159   if (!options)
00160     ssl_ctx_options |= SSL_OP_NO_SSLv3;
00161   REC_ReadConfigInteger(options, "proxy.config.ssl.TLSv1");
00162   if (!options)
00163     ssl_ctx_options |= SSL_OP_NO_TLSv1;
00164 
00165   REC_ReadConfigInteger(client_ssl_options, "proxy.config.ssl.client.SSLv2");
00166   if (!client_ssl_options)
00167     ssl_client_ctx_protocols |= SSL_OP_NO_SSLv2;
00168   REC_ReadConfigInteger(client_ssl_options, "proxy.config.ssl.client.SSLv3");
00169   if (!client_ssl_options)
00170     ssl_client_ctx_protocols |= SSL_OP_NO_SSLv3;
00171   REC_ReadConfigInteger(client_ssl_options, "proxy.config.ssl.client.TLSv1");
00172   if (!client_ssl_options)
00173     ssl_client_ctx_protocols |= SSL_OP_NO_TLSv1;
00174 
00175   
00176 #ifdef SSL_OP_NO_TLSv1_1
00177   REC_ReadConfigInteger(options, "proxy.config.ssl.TLSv1_1");
00178   if (!options)
00179     ssl_ctx_options |= SSL_OP_NO_TLSv1_1;
00180 
00181   REC_ReadConfigInteger(client_ssl_options, "proxy.config.ssl.client.TLSv1_1");
00182   if (!client_ssl_options)
00183     ssl_client_ctx_protocols |= SSL_OP_NO_TLSv1_1;
00184 #endif
00185 #ifdef SSL_OP_NO_TLSv1_2
00186   REC_ReadConfigInteger(options, "proxy.config.ssl.TLSv1_2");
00187   if (!options)
00188     ssl_ctx_options |= SSL_OP_NO_TLSv1_2;
00189 
00190   REC_ReadConfigInteger(client_ssl_options, "proxy.config.ssl.client.TLSv1_2");
00191   if (!client_ssl_options)
00192     ssl_client_ctx_protocols |= SSL_OP_NO_TLSv1_2;
00193 #endif
00194 
00195 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
00196   REC_ReadConfigInteger(options, "proxy.config.ssl.server.honor_cipher_order");
00197   if (options)
00198     ssl_ctx_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
00199 #endif
00200 
00201   REC_ReadConfigInteger(options, "proxy.config.ssl.compression");
00202   if (!options) {
00203 #ifdef SSL_OP_NO_COMPRESSION
00204     
00205     ssl_ctx_options |= SSL_OP_NO_COMPRESSION;
00206 #elif OPENSSL_VERSION_NUMBER >= 0x00908000L
00207     sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
00208 #endif
00209   }
00210 
00211   
00212 #ifdef SSL_OP_SINGLE_DH_USE
00213   ssl_ctx_options |= SSL_OP_SINGLE_DH_USE;
00214 #endif
00215 
00216 #ifdef SSL_OP_SINGLE_ECDH_USE
00217   ssl_ctx_options |= SSL_OP_SINGLE_ECDH_USE;
00218 #endif
00219 
00220   
00221   ssl_ctx_options |= SSL_OP_ALL;
00222 
00223   
00224   
00225 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
00226   ssl_ctx_options |= SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
00227 #endif
00228 
00229   REC_ReadConfigStringAlloc(serverCertChainFilename, "proxy.config.ssl.server.cert_chain.filename");
00230   REC_ReadConfigStringAlloc(serverCertRelativePath, "proxy.config.ssl.server.cert.path");
00231   set_paths_helper(serverCertRelativePath, NULL, &serverCertPathOnly, NULL);
00232   ats_free(serverCertRelativePath);
00233 
00234   REC_ReadConfigStringAlloc(multicert_config_file, "proxy.config.ssl.server.multicert.filename");
00235   set_paths_helper(Layout::get()->sysconfdir, multicert_config_file, NULL, &configFilePath);
00236   ats_free(multicert_config_file);
00237 
00238   REC_ReadConfigStringAlloc(ssl_server_private_key_path, "proxy.config.ssl.server.private_key.path");
00239   set_paths_helper(ssl_server_private_key_path, NULL, &serverKeyPathOnly, NULL);
00240   ats_free(ssl_server_private_key_path);
00241 
00242   REC_ReadConfigStringAlloc(ssl_server_ca_cert_filename, "proxy.config.ssl.CA.cert.filename");
00243   REC_ReadConfigStringAlloc(CACertRelativePath, "proxy.config.ssl.CA.cert.path");
00244   set_paths_helper(CACertRelativePath, ssl_server_ca_cert_filename, &serverCACertPath, &serverCACertFilename);
00245   ats_free(ssl_server_ca_cert_filename);
00246   ats_free(CACertRelativePath);
00247 
00248   
00249   REC_ReadConfigInteger(ssl_session_cache, "proxy.config.ssl.session_cache");
00250   REC_ReadConfigInteger(ssl_session_cache_size, "proxy.config.ssl.session_cache.size");
00251   REC_ReadConfigInteger(ssl_session_cache_timeout, "proxy.config.ssl.session_cache.timeout");
00252 
00253   
00254   REC_EstablishStaticConfigInt32(ssl_maxrecord, "proxy.config.ssl.max_record_size");
00255 
00256   
00257   REC_ReadConfigInt32(ssl_ocsp_enabled, "proxy.config.ssl.ocsp.enabled");
00258   REC_EstablishStaticConfigInt32(ssl_ocsp_cache_timeout, "proxy.config.ssl.ocsp.cache_timeout");
00259   REC_EstablishStaticConfigInt32(ssl_ocsp_request_timeout, "proxy.config.ssl.ocsp.request_timeout");
00260   REC_EstablishStaticConfigInt32(ssl_ocsp_update_period, "proxy.config.ssl.ocsp.update_period");
00261 
00262   
00263   client_verify_depth = 7;
00264   REC_ReadConfigInt32(clientVerify, "proxy.config.ssl.client.verify.server");
00265 
00266   ssl_client_cert_filename = NULL;
00267   ssl_client_cert_path = NULL;
00268   REC_ReadConfigStringAlloc(ssl_client_cert_filename, "proxy.config.ssl.client.cert.filename");
00269   REC_ReadConfigStringAlloc(ssl_client_cert_path, "proxy.config.ssl.client.cert.path");
00270   set_paths_helper(ssl_client_cert_path, ssl_client_cert_filename, NULL, &clientCertPath);
00271   ats_free_null(ssl_client_cert_filename);
00272   ats_free_null(ssl_client_cert_path);
00273 
00274   REC_ReadConfigStringAlloc(ssl_client_private_key_filename, "proxy.config.ssl.client.private_key.filename");
00275   REC_ReadConfigStringAlloc(ssl_client_private_key_path, "proxy.config.ssl.client.private_key.path");
00276   set_paths_helper(ssl_client_private_key_path, ssl_client_private_key_filename, NULL, &clientKeyPath);
00277   ats_free_null(ssl_client_private_key_filename);
00278   ats_free_null(ssl_client_private_key_path);
00279 
00280   REC_ReadConfigStringAlloc(ssl_client_ca_cert_filename, "proxy.config.ssl.client.CA.cert.filename");
00281   REC_ReadConfigStringAlloc(clientCACertRelativePath, "proxy.config.ssl.client.CA.cert.path");
00282   set_paths_helper(clientCACertRelativePath, ssl_client_ca_cert_filename, &clientCACertPath, &clientCACertFilename);
00283   ats_free(clientCACertRelativePath);
00284   ats_free(ssl_client_ca_cert_filename);
00285 
00286   REC_ReadConfigInt32(ssl_allow_client_renegotiation, "proxy.config.ssl.allow_client_renegotiation");
00287 }
00288 
00289 void
00290 SSLConfig::startup()
00291 {
00292   reconfigure();
00293 }
00294 
00295 void
00296 SSLConfig::reconfigure()
00297 {
00298   SSLConfigParams *params;
00299   params = new SSLConfigParams;
00300   params->initialize();         
00301   configid = configProcessor.set(configid, params);
00302 }
00303 
00304 SSLConfigParams *
00305 SSLConfig::acquire()
00306 {
00307   return ((SSLConfigParams *) configProcessor.get(configid));
00308 }
00309 
00310 void
00311 SSLConfig::release(SSLConfigParams * params)
00312 {
00313   configProcessor.release(configid, params);
00314 }
00315 
00316 void
00317 SSLCertificateConfig::startup()
00318 {
00319   sslCertUpdate = new ConfigUpdateHandler<SSLCertificateConfig>();
00320   sslCertUpdate->attach("proxy.config.ssl.server.multicert.filename");
00321   sslCertUpdate->attach("proxy.config.ssl.server.cert.path");
00322   sslCertUpdate->attach("proxy.config.ssl.server.private_key.path");
00323   sslCertUpdate->attach("proxy.config.ssl.server.cert_chain.filename");
00324 
00325   reconfigure();
00326 }
00327 
00328 void
00329 SSLCertificateConfig::reconfigure()
00330 {
00331   SSLConfig::scoped_config params;
00332   SSLCertLookup * lookup = new SSLCertLookup();
00333 
00334   
00335   
00336   if (is_action_tag_set("test.multicert.delay")) {
00337     const int secs = 60;
00338     Debug("ssl", "delaying certificate reload by %dsecs", secs);
00339     ink_hrtime_sleep(HRTIME_SECONDS(secs));
00340   }
00341 
00342   if (SSLParseCertificateConfiguration(params, lookup)) {
00343     configid = configProcessor.set(configid, lookup);
00344   } else {
00345     delete lookup;
00346   }
00347 }
00348 
00349 SSLCertLookup *
00350 SSLCertificateConfig::acquire()
00351 {
00352   return (SSLCertLookup *)configProcessor.get(configid);
00353 }
00354 
00355 void
00356 SSLCertificateConfig::release(SSLCertLookup * lookup)
00357 {
00358   configProcessor.release(configid, lookup);
00359 }
00360