00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include "ink_config.h"
00023 #include "libts.h"
00024 #include "I_Layout.h"
00025 #include "P_Net.h"
00026 #include "ink_cap.h"
00027 #include "P_OCSPStapling.h"
00028 
00029 #include <string>
00030 #include <openssl/err.h>
00031 #include <openssl/bio.h>
00032 #include <openssl/pem.h>
00033 #include <openssl/x509.h>
00034 #include <openssl/asn1.h>
00035 #include <openssl/rand.h>
00036 #include <unistd.h>
00037 #include <termios.h>
00038 
00039 #if HAVE_OPENSSL_EVP_H
00040 #include <openssl/evp.h>
00041 #endif
00042 
00043 #if HAVE_OPENSSL_HMAC_H
00044 #include <openssl/hmac.h>
00045 #endif
00046 
00047 #if HAVE_OPENSSL_TS_H
00048 #include <openssl/ts.h>
00049 #endif
00050 
00051 #if HAVE_OPENSSL_EC_H
00052 #include <openssl/ec.h>
00053 #endif
00054 
00055 
00056 #define SSL_IP_TAG            "dest_ip"
00057 #define SSL_CERT_TAG          "ssl_cert_name"
00058 #define SSL_PRIVATE_KEY_TAG   "ssl_key_name"
00059 #define SSL_CA_TAG            "ssl_ca_name"
00060 #define SSL_SESSION_TICKET_ENABLED "ssl_ticket_enabled"
00061 #define SSL_SESSION_TICKET_KEY_FILE_TAG "ticket_key_name"
00062 #define SSL_KEY_DIALOG        "ssl_key_dialog"
00063 #define SSL_CERT_SEPARATE_DELIM ','
00064 
00065 
00066 #if (OPENSSL_VERSION_NUMBER < 0x00090400L)
00067 # error Traffic Server requires an OpenSSL library version 0.9.4 or greater
00068 #endif
00069 
00070 #ifndef evp_md_func
00071 #ifdef OPENSSL_NO_SHA256
00072 #define evp_md_func EVP_sha1()
00073 #else
00074 #define evp_md_func EVP_sha256()
00075 #endif
00076 #endif
00077 
00078 #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) // openssl returns a const SSL_METHOD
00079 typedef const SSL_METHOD * ink_ssl_method_t;
00080 #else
00081 typedef SSL_METHOD * ink_ssl_method_t;
00082 #endif
00083 
00084 
00085 struct ssl_user_config
00086 {
00087   ssl_user_config () : session_ticket_enabled(1) {
00088   }
00089 
00090   int session_ticket_enabled;  
00091   ats_scoped_str addr;   
00092   ats_scoped_str cert;   
00093   ats_scoped_str first_cert; 
00094   ats_scoped_str ca;     
00095   ats_scoped_str key;    
00096   ats_scoped_str ticket_key_filename; 
00097   ats_scoped_str dialog; 
00098 };
00099 
00100 
00101 #ifdef SSL_CTX_set_tlsext_ticket_key_cb
00102 
00103 #define HAVE_OPENSSL_SESSION_TICKETS 1
00104 
00105 static void session_ticket_free(void *, void *, CRYPTO_EX_DATA *, int, long, void *);
00106 static int ssl_callback_session_ticket(SSL *, unsigned char *, unsigned char *, EVP_CIPHER_CTX *, HMAC_CTX *, int);
00107 #endif 
00108 
00109 struct ssl_ticket_key_t
00110 {
00111   unsigned char key_name[16];
00112   unsigned char hmac_secret[16];
00113   unsigned char aes_key[16];
00114 };
00115 
00116 static int ssl_session_ticket_index = -1;
00117 static pthread_mutex_t *mutex_buf = NULL;
00118 static bool open_ssl_initialized = false;
00119 
00120 RecRawStatBlock *ssl_rsb = NULL;
00121 static InkHashTable *ssl_cipher_name_table = NULL;
00122 
00123 struct ats_file_bio
00124 {
00125   ats_file_bio(const char * path, const char * mode)
00126     : bio(BIO_new_file(path, mode)) {
00127   }
00128 
00129   ~ats_file_bio() {
00130     (void)BIO_set_close(bio, BIO_CLOSE);
00131     BIO_free(bio);
00132   }
00133 
00134   operator bool() const {
00135     return bio != NULL;
00136   }
00137 
00138   BIO * bio;
00139 
00140 private:
00141   ats_file_bio(const ats_file_bio&);
00142   ats_file_bio& operator=(const ats_file_bio&);
00143 };
00144 
00145 
00146 
00147 
00148 
00149 
00150 static unsigned long
00151 SSL_pthreads_thread_id()
00152 {
00153   return (unsigned long)pthread_self();
00154 }
00155 
00156 static void
00157 SSL_locking_callback(int mode, int type, const char * , int )
00158 {
00159   ink_assert(type < CRYPTO_num_locks());
00160 
00161   if (mode & CRYPTO_LOCK) {
00162     pthread_mutex_lock(&mutex_buf[type]);
00163   } else if (mode & CRYPTO_UNLOCK) {
00164     pthread_mutex_unlock(&mutex_buf[type]);
00165   } else {
00166     Debug("ssl", "invalid SSL locking mode 0x%x", mode);
00167     ink_assert(0);
00168   }
00169 }
00170 
00171 static bool
00172 SSL_CTX_add_extra_chain_cert_file(SSL_CTX * ctx, const char * chainfile)
00173 {
00174   X509 *cert;
00175   ats_file_bio bio(chainfile, "r");
00176 
00177   if (!bio) {
00178     return false;
00179   }
00180 
00181   for (;;) {
00182     cert = PEM_read_bio_X509_AUX(bio.bio, NULL, NULL, NULL);
00183 
00184     if (!cert) {
00185       
00186       break;
00187     }
00188 
00189     
00190     if (!SSL_CTX_add_extra_chain_cert(ctx, cert)) {
00191       X509_free(cert);
00192       return false;
00193     }
00194   }
00195 
00196   return true;
00197 }
00198 
00199 #if TS_USE_TLS_SNI
00200 
00201 static int
00202 ssl_servername_callback(SSL * ssl, int * ad, void * arg)
00203 {
00204   SSL_CTX *           ctx = NULL;
00205   SSLCertLookup *     lookup = (SSLCertLookup *) arg;
00206   const char *        servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
00207   SSLNetVConnection * netvc = (SSLNetVConnection *)SSL_get_app_data(ssl);
00208 
00209   Debug("ssl", "ssl_servername_callback ssl=%p ad=%d lookup=%p server=%s handshake_complete=%d", ssl, *ad, lookup, servername,
00210     netvc->getSSLHandShakeComplete());
00211 
00212   
00213   if (SSLConfigParams::ssl_allow_client_renegotiation == false && netvc->getSSLHandShakeComplete()) {
00214     Debug("ssl", "ssl_servername_callback trying to renegotiate from the client");
00215     return SSL_TLSEXT_ERR_ALERT_FATAL;
00216   }
00217 
00218   
00219   
00220   
00221   if (likely(servername)) {
00222     ctx = lookup->findInfoInHash((char *)servername);
00223   }
00224 
00225   
00226   if (ctx == NULL) {
00227     IpEndpoint ip;
00228     int namelen = sizeof(ip);
00229 
00230     safe_getsockname(netvc->get_socket(), &ip.sa, &namelen);
00231     ctx = lookup->findInfoInHash(ip);
00232   }
00233 
00234   if (ctx != NULL) {
00235     SSL_set_SSL_CTX(ssl, ctx);
00236   }
00237 
00238   ctx = SSL_get_SSL_CTX(ssl);
00239   Debug("ssl", "ssl_servername_callback found SSL context %p for requested name '%s'", ctx, servername);
00240 
00241   if (ctx == NULL) {
00242     return SSL_TLSEXT_ERR_NOACK;
00243   }
00244 
00245   
00246   
00247   
00248   return SSL_TLSEXT_ERR_OK;
00249 }
00250 
00251 #endif 
00252 
00253 static SSL_CTX *
00254 ssl_context_enable_sni(SSL_CTX * ctx, SSLCertLookup * lookup)
00255 {
00256 #if TS_USE_TLS_SNI
00257   if (ctx) {
00258     Debug("ssl", "setting SNI callbacks with for ctx %p", ctx);
00259     SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_callback);
00260     SSL_CTX_set_tlsext_servername_arg(ctx, lookup);
00261   }
00262 #else
00263   (void)lookup;
00264 #endif 
00265 
00266   return ctx;
00267 }
00268 
00269 static SSL_CTX *
00270 ssl_context_enable_ecdh(SSL_CTX * ctx)
00271 {
00272 #if TS_USE_TLS_ECKEY
00273 
00274 #if defined(SSL_CTRL_SET_ECDH_AUTO)
00275   SSL_CTX_set_ecdh_auto(ctx, 1);
00276 #elif defined(HAVE_EC_KEY_NEW_BY_CURVE_NAME) && defined(NID_X9_62_prime256v1)
00277   EC_KEY * ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
00278 
00279   if (ecdh) {
00280     SSL_CTX_set_tmp_ecdh(ctx, ecdh);
00281     EC_KEY_free(ecdh);
00282   }
00283 #endif
00284 #endif
00285 
00286   return ctx;
00287 }
00288 
00289 static SSL_CTX *
00290 ssl_context_enable_tickets(SSL_CTX * ctx, const char * ticket_key_path)
00291 {
00292 #if HAVE_OPENSSL_SESSION_TICKETS
00293   ats_scoped_str          ticket_key_data;
00294   int                 ticket_key_len;
00295   ssl_ticket_key_t *  ticket_key = NULL;
00296 
00297   ticket_key_data = readIntoBuffer(ticket_key_path, __func__, &ticket_key_len);
00298   if (!ticket_key_data) {
00299     Error("failed to read SSL session ticket key from %s", (const char *)ticket_key_path);
00300     goto fail;
00301   }
00302 
00303   if (ticket_key_len < 48) {
00304     Error("SSL session ticket key from %s is too short (48 bytes are required)", (const char *)ticket_key_path);
00305     goto fail;
00306   }
00307 
00308   ticket_key = new ssl_ticket_key_t();
00309   memcpy(ticket_key->key_name, (const char *)ticket_key_data, 16);
00310   memcpy(ticket_key->hmac_secret, (const char *)ticket_key_data + 16, 16);
00311   memcpy(ticket_key->aes_key, (const char *)ticket_key_data + 32, 16);
00312 
00313   
00314   
00315   
00316   if (SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_callback_session_ticket) == 0) {
00317     Error("failed to set session ticket callback");
00318     goto fail;
00319   }
00320 
00321   if (SSL_CTX_set_ex_data(ctx, ssl_session_ticket_index, ticket_key) == 0) {
00322     Error ("failed to set session ticket data to ctx");
00323     goto fail;
00324   }
00325 
00326   SSL_CTX_clear_options(ctx, SSL_OP_NO_TICKET);
00327   return ctx;
00328 
00329 fail:
00330   delete ticket_key;
00331   return ctx;
00332 
00333 #else 
00334   (void)ticket_key_path;
00335   return ctx;
00336 #endif 
00337 }
00338 
00339 struct passphrase_cb_userdata
00340 {
00341     const SSLConfigParams * _configParams;
00342     const char * _serverDialog;
00343     const char * _serverCert;
00344     const char * _serverKey;
00345 
00346     passphrase_cb_userdata(const SSLConfigParams *params,const char *dialog, const char *cert, const char *key) :
00347             _configParams(params), _serverDialog(dialog), _serverCert(cert), _serverKey(key) {}
00348 };
00349 
00350 
00351 struct ssl_termios : public  termios
00352 {
00353   ssl_termios(int fd) {
00354     _fd = -1;
00355     
00356     if (tcgetattr(fd, this) == 0) { 
00357        _fd = fd;
00358     }
00359     
00360     _initialAttr = *this;
00361   }
00362 
00363   ~ssl_termios() {
00364     if (_fd != -1) {
00365       tcsetattr(_fd, 0, &_initialAttr);
00366     }
00367   }
00368 
00369   bool ok() {
00370     return (_fd != -1);
00371   }
00372 
00373 private:
00374   int _fd;
00375   struct termios _initialAttr;
00376 };
00377 
00378 static int
00379 ssl_getpassword(const char* prompt, char* buffer, int size)
00380 {
00381   fprintf(stdout, "%s", prompt);
00382 
00383   
00384   ssl_termios tty_attr(STDIN_FILENO);
00385 
00386   if (!tty_attr.ok()) {
00387     return -1;
00388   }
00389 
00390   tty_attr.c_lflag &= ~ICANON; 
00391   tty_attr.c_lflag &= ~ECHO; 
00392   tty_attr.c_lflag &= ~ISIG; 
00393 
00394   if (tcsetattr(STDIN_FILENO, 0, &tty_attr) < 0) {
00395     return -1;
00396   }
00397 
00398   int i = 0;
00399   int ch = 0;
00400   *buffer = 0;
00401   while ((ch = getchar()) != '\n' && ch != EOF) {
00402     
00403     if (i >= size - 1) {
00404       return -1;
00405     }
00406 
00407     buffer[i] = ch;
00408     buffer[++i] = 0;
00409   }
00410 
00411   return i;
00412 }
00413 
00414 static int
00415 ssl_private_key_passphrase_callback_exec(char *buf, int size, int rwflag, void *userdata)
00416 {
00417   if (0 == size) {
00418     return 0;
00419   }
00420 
00421   *buf = 0;
00422   passphrase_cb_userdata *ud = static_cast<passphrase_cb_userdata *> (userdata);
00423 
00424   Debug("ssl", "ssl_private_key_passphrase_callback_exec rwflag=%d serverDialog=%s", rwflag, ud->_serverDialog);
00425 
00426   
00427   if (0 == rwflag) {
00428     
00429     FILE *f = popen(ud->_serverDialog, "r");
00430     if (f) {
00431       if (fgets(buf, size, f)) {
00432         
00433         for (char *pass = buf; *pass; pass++) {
00434           if (*pass == '\n' || *pass == '\r') {
00435             *pass = 0;
00436             break;
00437           }
00438         }
00439       }
00440       pclose(f);
00441     } else {
00442       Error("could not open dialog '%s' - %s", ud->_serverDialog, strerror(errno));
00443     }
00444   }
00445   return strlen(buf);
00446 }
00447 
00448 static int
00449 ssl_private_key_passphrase_callback_builtin(char *buf, int size, int rwflag, void *userdata)
00450 {
00451   if (0 == size) {
00452     return 0;
00453   }
00454 
00455   *buf = 0;
00456   passphrase_cb_userdata *ud = static_cast<passphrase_cb_userdata *> (userdata);
00457 
00458   Debug("ssl", "ssl_private_key_passphrase_callback rwflag=%d serverDialog=%s", rwflag, ud->_serverDialog);
00459 
00460   
00461   if (0 == rwflag) {
00462     
00463     fprintf(stdout, "Some of your private key files are encrypted for security reasons.\n");
00464     fprintf(stdout, "In order to read them you have to provide the pass phrases.\n");
00465     fprintf(stdout, "ssl_cert_name=%s", ud->_serverCert);
00466     if (ud->_serverKey) { 
00467       fprintf(stdout, " ssl_key_name=%s", ud->_serverKey);
00468     }
00469     fprintf(stdout, "\n");
00470     
00471     
00472     if (ssl_getpassword("Enter passphrase:", buf, size) <= 0) {
00473       *buf = 0;
00474     }
00475     fprintf(stdout, "\n");
00476   }
00477   return strlen(buf);
00478 }
00479 
00480 static bool
00481 ssl_private_key_validate_exec(const char *cmdLine)
00482 {
00483   if (NULL == cmdLine) {
00484     errno = EINVAL;
00485     return false;
00486   }
00487 
00488   bool bReturn = false;
00489   char *cmdLineCopy = ats_strdup(cmdLine);
00490   char *ptr = cmdLineCopy;
00491 
00492   while(*ptr && !isspace(*ptr)) ++ptr;
00493   *ptr = 0;
00494   if (access(cmdLineCopy, X_OK) != -1) {
00495     bReturn = true;
00496   }
00497   ats_free(cmdLineCopy);
00498   return bReturn;
00499 }
00500 
00501 static int
00502 SSLRecRawStatSyncCount(const char *name, RecDataT data_type, RecData *data, RecRawStatBlock *rsb, int id)
00503 {
00504   
00505   
00506   SSLCertificateConfig::scoped_config certLookup;
00507 
00508   int64_t sessions = 0;
00509   int64_t hits = 0;
00510   int64_t misses = 0;
00511   int64_t timeouts = 0;
00512 
00513   if (certLookup) {
00514     const unsigned ctxCount = certLookup->count();
00515     for (size_t i = 0; i < ctxCount; i++) {
00516       SSL_CTX * ctx = certLookup->get(i);
00517 
00518       sessions += SSL_CTX_sess_accept_good(ctx);
00519       hits += SSL_CTX_sess_hits(ctx);
00520       misses += SSL_CTX_sess_misses(ctx);
00521       timeouts += SSL_CTX_sess_timeouts(ctx);
00522     }
00523   }
00524 
00525   SSL_SET_COUNT_DYN_STAT(ssl_user_agent_sessions_stat, sessions);
00526   SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_hit_stat, hits);
00527   SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_miss_stat, misses);
00528   SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_timeout_stat, timeouts);
00529   return RecRawStatSyncCount(name, data_type, data, rsb, id);
00530 }
00531 
00532 void
00533 SSLInitializeLibrary()
00534 {
00535   if (!open_ssl_initialized) {
00536     CRYPTO_set_mem_functions(ats_malloc, ats_realloc, ats_free);
00537 
00538     SSL_load_error_strings();
00539     SSL_library_init();
00540 
00541     mutex_buf = (pthread_mutex_t *) OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
00542 
00543     for (int i = 0; i < CRYPTO_num_locks(); i++) {
00544       pthread_mutex_init(&mutex_buf[i], NULL);
00545     }
00546 
00547     CRYPTO_set_locking_callback(SSL_locking_callback);
00548     CRYPTO_set_id_callback(SSL_pthreads_thread_id);
00549   }
00550 
00551 #ifdef SSL_CTX_set_tlsext_ticket_key_cb
00552   ssl_session_ticket_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, session_ticket_free);
00553   if (ssl_session_ticket_index == -1) {
00554     SSLError("failed to create session ticket index");
00555   }
00556 #endif
00557 
00558 #ifdef HAVE_OPENSSL_OCSP_STAPLING
00559   ssl_stapling_ex_init();
00560 #endif 
00561 
00562   open_ssl_initialized = true;
00563 }
00564 
00565 void
00566 SSLInitializeStatistics()
00567 {
00568   SSL_CTX *               ctx;
00569   SSL *                   ssl;
00570   STACK_OF(SSL_CIPHER) *  ciphers;
00571 
00572   
00573   ssl_rsb = RecAllocateRawStatBlock((int) Ssl_Stat_Count);
00574   ink_assert(ssl_rsb != NULL);
00575 
00576   
00577   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_other_errors",
00578                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_other_errors_stat,
00579                      RecRawStatSyncSum);
00580   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_expired_cert",
00581                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_expired_cert_stat,
00582                      RecRawStatSyncSum);
00583   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_revoked_cert",
00584                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_revoked_cert_stat,
00585                      RecRawStatSyncSum);
00586   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_unknown_cert",
00587                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_unknown_cert_stat,
00588                      RecRawStatSyncSum);
00589   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_cert_verify_failed",
00590                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_cert_verify_failed_stat,
00591                      RecRawStatSyncSum);
00592   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_bad_cert",
00593                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_bad_cert_stat,
00594                      RecRawStatSyncSum);
00595   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_decryption_failed",
00596                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_decryption_failed_stat,
00597                      RecRawStatSyncSum);
00598   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_wrong_version",
00599                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_wrong_version_stat,
00600                      RecRawStatSyncSum);
00601   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_unknown_ca",
00602                      RECD_INT, RECP_PERSISTENT, (int) ssl_user_agent_unknown_ca_stat,
00603                      RecRawStatSyncSum);
00604 
00605   
00606   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_sessions",
00607                      RECD_INT, RECP_NON_PERSISTENT, (int) ssl_user_agent_sessions_stat,
00608                      SSLRecRawStatSyncCount); 
00609   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_session_hit",
00610                      RECD_INT, RECP_NON_PERSISTENT, (int) ssl_user_agent_session_hit_stat,
00611                      RecRawStatSyncCount);
00612   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_session_miss",
00613                      RECD_INT, RECP_NON_PERSISTENT, (int) ssl_user_agent_session_miss_stat,
00614                      RecRawStatSyncCount);
00615   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.user_agent_session_timeout",
00616                      RECD_INT, RECP_NON_PERSISTENT, (int) ssl_user_agent_session_timeout_stat,
00617                      RecRawStatSyncCount);
00618 
00619   
00620   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_other_errors",
00621                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_other_errors_stat,
00622                      RecRawStatSyncSum);
00623   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_expired_cert",
00624                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_expired_cert_stat,
00625                      RecRawStatSyncSum);
00626   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_revoked_cert",
00627                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_revoked_cert_stat,
00628                      RecRawStatSyncSum);
00629   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_unknown_cert",
00630                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_unknown_cert_stat,
00631                      RecRawStatSyncSum);
00632   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_cert_verify_failed",
00633                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_cert_verify_failed_stat,
00634                      RecRawStatSyncSum);
00635   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_bad_cert",
00636                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_bad_cert_stat,
00637                      RecRawStatSyncSum);
00638   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_decryption_failed",
00639                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_decryption_failed_stat,
00640                      RecRawStatSyncSum);
00641   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_wrong_version",
00642                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_wrong_version_stat,
00643                      RecRawStatSyncSum);
00644   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.origin_server_unknown_ca",
00645                      RECD_INT, RECP_PERSISTENT, (int) ssl_origin_server_unknown_ca_stat,
00646                      RecRawStatSyncSum);
00647 
00648   
00649   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.total_handshake_time",
00650                      RECD_INT, RECP_PERSISTENT, (int) ssl_total_handshake_time_stat,
00651                      RecRawStatSyncSum);
00652   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.total_success_handshake_count",
00653                      RECD_INT, RECP_PERSISTENT, (int) ssl_total_success_handshake_count_stat,
00654                      RecRawStatSyncCount);
00655 
00656   
00657   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.total_tickets_created",
00658                      RECD_INT, RECP_PERSISTENT, (int) ssl_total_tickets_created_stat,
00659                      RecRawStatSyncCount);
00660   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.total_tickets_verified",
00661                      RECD_INT, RECP_PERSISTENT, (int) ssl_total_tickets_verified_stat,
00662                      RecRawStatSyncCount);
00663   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.total_tickets_not_found",
00664                      RECD_INT, RECP_PERSISTENT, (int) ssl_total_tickets_not_found_stat,
00665                      RecRawStatSyncCount);
00666   
00667   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.total_tickets_renewed",
00668                      RECD_INT, RECP_PERSISTENT, (int) ssl_total_tickets_renewed_stat,
00669                      RecRawStatSyncCount);
00670 
00671 
00672   
00673   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_want_write",
00674                      RECD_INT, RECP_PERSISTENT, (int) ssl_error_want_write,
00675                      RecRawStatSyncCount);
00676   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_want_read",
00677                      RECD_INT, RECP_PERSISTENT, (int) ssl_error_want_read,
00678                      RecRawStatSyncCount);
00679   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_want_x509_lookup",
00680                      RECD_INT, RECP_PERSISTENT, (int) ssl_error_want_x509_lookup,
00681                      RecRawStatSyncCount);
00682   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_syscall",
00683                      RECD_INT, RECP_PERSISTENT, (int) ssl_error_syscall,
00684                      RecRawStatSyncCount);
00685   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_read_eos",
00686                      RECD_INT, RECP_PERSISTENT, (int) ssl_error_read_eos,
00687                      RecRawStatSyncCount);
00688   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_zero_return",
00689                      RECD_INT, RECP_PERSISTENT, (int) ssl_error_zero_return,
00690                      RecRawStatSyncCount);
00691   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_ssl",
00692                      RECD_INT, RECP_PERSISTENT, (int) ssl_error_ssl,
00693                      RecRawStatSyncCount);
00694   RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_sni_name_set_failure",
00695                        RECD_INT, RECP_PERSISTENT, (int) ssl_sni_name_set_failure,
00696                        RecRawStatSyncCount);
00697 
00698 
00699   
00700   
00701   
00702   
00703 
00704   
00705   ssl_cipher_name_table = ink_hash_table_create(InkHashTableKeyType_Word);
00706 
00707   ctx = SSLDefaultServerContext();
00708   ssl = SSL_new(ctx);
00709   ciphers = SSL_get_ciphers(ssl);
00710 
00711   for (int index = 0; index < sk_SSL_CIPHER_num(ciphers); index++) {
00712     SSL_CIPHER * cipher = sk_SSL_CIPHER_value(ciphers, index);
00713     const char * cipherName = SSL_CIPHER_get_name(cipher);
00714     std::string  statName = "proxy.process.ssl.cipher.user_agent." + std::string(cipherName);
00715 
00716     
00717     if ((ssl_cipher_stats_start + index) > ssl_cipher_stats_end) {
00718       
00719       SSLError("too many ciphers to register metric '%s', increase SSL_Stats::ssl_cipher_stats_end",
00720                statName.c_str());
00721       continue;
00722     }
00723 
00724     
00725     if (!ink_hash_table_isbound(ssl_cipher_name_table, cipherName)) {
00726       ink_hash_table_insert(ssl_cipher_name_table, cipherName, (void *)(intptr_t) (ssl_cipher_stats_start + index));
00727       
00728       RecRegisterRawStat(ssl_rsb, RECT_PROCESS, statName.c_str(),
00729                          RECD_INT, RECP_NON_PERSISTENT, (int) ssl_cipher_stats_start + index,
00730                          RecRawStatSyncSum);
00731       SSL_CLEAR_DYN_STAT((int) ssl_cipher_stats_start + index);
00732       Debug("ssl", "registering SSL cipher metric '%s'", statName.c_str());
00733     }
00734   }
00735 
00736   SSL_free(ssl);
00737   SSL_CTX_free(ctx);
00738 }
00739 
00740 
00741 static bool
00742 increment_ssl_client_error(unsigned long err)
00743 {
00744   
00745   if (ERR_LIB_SSL != ERR_GET_LIB(err)) {
00746     SSL_INCREMENT_DYN_STAT(ssl_user_agent_other_errors_stat);
00747     return false;
00748   }
00749 
00750   
00751   
00752   
00753   switch (ERR_GET_REASON(err)) {
00754   case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:
00755     SSL_INCREMENT_DYN_STAT(ssl_user_agent_expired_cert_stat);
00756     break;
00757   case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
00758     SSL_INCREMENT_DYN_STAT(ssl_user_agent_revoked_cert_stat);
00759     break;
00760   case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
00761     SSL_INCREMENT_DYN_STAT(ssl_user_agent_unknown_cert_stat);
00762     break;
00763   case SSL_R_CERTIFICATE_VERIFY_FAILED:
00764     SSL_INCREMENT_DYN_STAT(ssl_user_agent_cert_verify_failed_stat);
00765     break;
00766   case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
00767     SSL_INCREMENT_DYN_STAT(ssl_user_agent_bad_cert_stat);
00768     break;
00769   case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:
00770     SSL_INCREMENT_DYN_STAT(ssl_user_agent_decryption_failed_stat);
00771     break;
00772   case SSL_R_WRONG_VERSION_NUMBER:
00773     SSL_INCREMENT_DYN_STAT(ssl_user_agent_wrong_version_stat);
00774     break;
00775   case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
00776     SSL_INCREMENT_DYN_STAT(ssl_user_agent_unknown_ca_stat);
00777     break;
00778   default:
00779     SSL_INCREMENT_DYN_STAT(ssl_user_agent_other_errors_stat);
00780     return false;
00781   }
00782 
00783   return true;
00784 }
00785 
00786 
00787 
00788 static bool
00789 increment_ssl_server_error(unsigned long err)
00790 {
00791   
00792   if (ERR_LIB_SSL != ERR_GET_LIB(err)) {
00793     SSL_INCREMENT_DYN_STAT(ssl_origin_server_other_errors_stat);
00794     return false;
00795   }
00796 
00797   
00798   
00799   
00800   switch (ERR_GET_REASON(err)) {
00801   case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:
00802     SSL_INCREMENT_DYN_STAT(ssl_origin_server_expired_cert_stat);
00803     break;
00804   case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
00805     SSL_INCREMENT_DYN_STAT(ssl_origin_server_revoked_cert_stat);
00806     break;
00807   case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
00808     SSL_INCREMENT_DYN_STAT(ssl_origin_server_unknown_cert_stat);
00809     break;
00810   case SSL_R_CERTIFICATE_VERIFY_FAILED:
00811     SSL_INCREMENT_DYN_STAT(ssl_origin_server_cert_verify_failed_stat);
00812     break;
00813   case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
00814     SSL_INCREMENT_DYN_STAT(ssl_origin_server_bad_cert_stat);
00815     break;
00816   case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:
00817     SSL_INCREMENT_DYN_STAT(ssl_origin_server_decryption_failed_stat);
00818     break;
00819   case SSL_R_WRONG_VERSION_NUMBER:
00820     SSL_INCREMENT_DYN_STAT(ssl_origin_server_wrong_version_stat);
00821     break;
00822   case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
00823     SSL_INCREMENT_DYN_STAT(ssl_origin_server_unknown_ca_stat);
00824     break;
00825   default:
00826     SSL_INCREMENT_DYN_STAT(ssl_origin_server_other_errors_stat);
00827     return false;
00828   }
00829 
00830   return true;
00831 }
00832 
00833 void
00834 SSLDiagnostic(const SrcLoc& loc, bool debug, SSLNetVConnection * vc, const char * fmt, ...)
00835 {
00836   unsigned long l;
00837   char buf[256];
00838   const char *file, *data;
00839   int line, flags;
00840   unsigned long es;
00841   va_list ap;
00842 
00843   ip_text_buffer ip_buf;
00844   bool ip_buf_flag = false;
00845   if (vc) {
00846     ats_ip_ntop(vc->get_remote_addr(), ip_buf, sizeof(ip_buf));
00847     ip_buf_flag = true;
00848   }
00849 
00850   es = CRYPTO_thread_id();
00851   while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
00852     if (debug) {
00853       if (unlikely(diags->on())) {
00854         diags->log("ssl", DL_Debug, loc.file, loc.func, loc.line,
00855             "SSL::%lu:%s:%s:%d%s%s%s%s", es, ERR_error_string(l, buf), file, line,
00856           (flags & ERR_TXT_STRING) ? ":" : "", (flags & ERR_TXT_STRING) ? data : "",
00857           ip_buf_flag? ": peer address is " : "", ip_buf);
00858       }
00859     } else {
00860       diags->error(DL_Error, loc.file, loc.func, loc.line,
00861           "SSL::%lu:%s:%s:%d%s%s%s%s", es, ERR_error_string(l, buf), file, line,
00862           (flags & ERR_TXT_STRING) ? ":" : "", (flags & ERR_TXT_STRING) ? data : "",
00863           ip_buf_flag? ": peer address is " : "", ip_buf);
00864     }
00865 
00866     
00867     
00868     if (vc) {
00869       
00870       if (vc->getSSLClientConnection()) {
00871         increment_ssl_server_error(l); 
00872       } else {
00873         increment_ssl_client_error(l); 
00874       }
00875     }
00876   }
00877 
00878   va_start(ap, fmt);
00879   if (debug) {
00880     diags->log_va("ssl", DL_Debug, &loc, fmt, ap);
00881   } else {
00882     diags->error_va(DL_Error, loc.file, loc.func, loc.line, fmt, ap);
00883   }
00884   va_end(ap);
00885 
00886 }
00887 
00888 const char *
00889 SSLErrorName(int ssl_error)
00890 {
00891   static const char * names[] =  {
00892     "SSL_ERROR_NONE",
00893     "SSL_ERROR_SSL",
00894     "SSL_ERROR_WANT_READ",
00895     "SSL_ERROR_WANT_WRITE",
00896     "SSL_ERROR_WANT_X509_LOOKUP",
00897     "SSL_ERROR_SYSCALL",
00898     "SSL_ERROR_ZERO_RETURN",
00899     "SSL_ERROR_WANT_CONNECT",
00900     "SSL_ERROR_WANT_ACCEPT"
00901   };
00902 
00903   if (ssl_error < 0 || ssl_error >= (int)countof(names)) {
00904     return "unknown SSL error";
00905   }
00906 
00907   return names[ssl_error];
00908 }
00909 
00910 void
00911 SSLDebugBufferPrint(const char * tag, const char * buffer, unsigned buflen, const char * message)
00912 {
00913   if (is_debug_tag_set(tag)) {
00914     if (message != NULL) {
00915       fprintf(stdout, "%s\n", message);
00916     }
00917     for (unsigned ii = 0; ii < buflen; ii++) {
00918       putc(buffer[ii], stdout);
00919     }
00920     putc('\n', stdout);
00921   }
00922 }
00923 
00924 SSL_CTX *
00925 SSLDefaultServerContext()
00926 {
00927   ink_ssl_method_t meth = NULL;
00928 
00929   meth = SSLv23_server_method();
00930   return SSL_CTX_new(meth);
00931 }
00932 
00933 static bool
00934 SSLPrivateKeyHandler(
00935     SSL_CTX * ctx,
00936     const SSLConfigParams * params,
00937     const ats_scoped_str& completeServerCertPath,
00938     const char * keyPath)
00939 {
00940   if (!keyPath) {
00941     
00942     if (!SSL_CTX_use_PrivateKey_file(ctx, completeServerCertPath, SSL_FILETYPE_PEM)) {
00943       SSLError("failed to load server private key from %s", (const char *) completeServerCertPath);
00944       return false;
00945     }
00946   } else if (params->serverKeyPathOnly != NULL) {
00947     ats_scoped_str completeServerKeyPath(Layout::get()->relative_to(params->serverKeyPathOnly, keyPath));
00948     if (!SSL_CTX_use_PrivateKey_file(ctx, completeServerKeyPath, SSL_FILETYPE_PEM)) {
00949       SSLError("failed to load server private key from %s", (const char *) completeServerKeyPath);
00950       return false;
00951     }
00952   } else {
00953     SSLError("empty SSL private key path in records.config");
00954   }
00955 
00956   if (!SSL_CTX_check_private_key(ctx)) {
00957     SSLError("server private key does not match the certificate public key");
00958     return false;
00959   }
00960 
00961   return true;
00962 }
00963 
00964 SSL_CTX *
00965 SSLInitServerContext(
00966     const SSLConfigParams * params,
00967     const ssl_user_config & sslMultCertSettings)
00968 {
00969   int         session_id_context;
00970   int         server_verify_client;
00971   ats_scoped_str  completeServerCertPath;
00972   SSL_CTX *   ctx = SSLDefaultServerContext();
00973 
00974   
00975   SSL_CTX_set_options(ctx, params->ssl_ctx_options);
00976 
00977   switch (params->ssl_session_cache) {
00978   case SSLConfigParams::SSL_SESSION_CACHE_MODE_OFF:
00979     SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF|SSL_SESS_CACHE_NO_INTERNAL);
00980     break;
00981   case SSLConfigParams::SSL_SESSION_CACHE_MODE_SERVER:
00982     SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
00983     SSL_CTX_sess_set_cache_size(ctx, params->ssl_session_cache_size);
00984     if (params->ssl_session_cache_timeout) {
00985         SSL_CTX_set_timeout(ctx, params->ssl_session_cache_timeout);
00986     }
00987     break;
00988   }
00989 
00990 #ifdef SSL_MODE_RELEASE_BUFFERS
00991   if (OPENSSL_VERSION_NUMBER > 0x1000107fL) {
00992     Debug("ssl", "enabling SSL_MODE_RELEASE_BUFFERS");
00993     SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
00994   }
00995 #endif
00996 
00997 #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
00998   SSL_CTX_set_options(ctx, SSL_OP_SAFARI_ECDHE_ECDSA_BUG);
00999 #endif
01000 
01001   SSL_CTX_set_quiet_shutdown(ctx, 1);
01002 
01003   
01004   passphrase_cb_userdata ud(params, sslMultCertSettings.dialog, sslMultCertSettings.first_cert, sslMultCertSettings.key);
01005 
01006   if (sslMultCertSettings.dialog) {
01007     pem_password_cb * passwd_cb = NULL;
01008     if (strncmp(sslMultCertSettings.dialog, "exec:", 5) == 0) {
01009       ud._serverDialog = &sslMultCertSettings.dialog[5];
01010       
01011       if (!ssl_private_key_validate_exec(ud._serverDialog)) {
01012         SSLError("failed to access '%s' pass phrase program: %s", (const char *) ud._serverDialog, strerror(errno));
01013         goto fail;
01014       }
01015       passwd_cb = ssl_private_key_passphrase_callback_exec;
01016     } else if (strcmp(sslMultCertSettings.dialog, "builtin") == 0) {
01017       passwd_cb = ssl_private_key_passphrase_callback_builtin;
01018     } else { 
01019       SSLError("unknown " SSL_KEY_DIALOG " configuration value '%s'", (const char *)sslMultCertSettings.dialog);
01020       goto fail;
01021     }
01022     SSL_CTX_set_default_passwd_cb(ctx, passwd_cb);
01023     SSL_CTX_set_default_passwd_cb_userdata(ctx, &ud);
01024   }
01025 
01026   if (!params->serverCertChainFilename && !sslMultCertSettings.ca && sslMultCertSettings.cert) {
01027     SimpleTokenizer cert_tok((const char *)sslMultCertSettings.cert, SSL_CERT_SEPARATE_DELIM);
01028     SimpleTokenizer key_tok((sslMultCertSettings.key ? (const char *)sslMultCertSettings.key : ""), SSL_CERT_SEPARATE_DELIM);
01029 
01030     if (sslMultCertSettings.key && cert_tok.getNumTokensRemaining() != key_tok.getNumTokensRemaining()) {
01031         Error("the number of certificates in ssl_cert_name and ssl_key_name doesn't match");
01032         goto fail;
01033     }
01034 
01035     for (const char * certname = cert_tok.getNext(); certname; certname = cert_tok.getNext()) {
01036       completeServerCertPath = Layout::relative_to(params->serverCertPathOnly, certname);
01037       if (SSL_CTX_use_certificate_chain_file(ctx, completeServerCertPath) < 0) {
01038         SSLError("failed to load certificate chain from %s", (const char *)completeServerCertPath);
01039         goto fail;
01040       }
01041 
01042       const char * keyPath = key_tok.getNext();
01043       if (!SSLPrivateKeyHandler(ctx, params, completeServerCertPath, keyPath)) {
01044         goto fail;
01045       }
01046     }
01047   } else if (sslMultCertSettings.first_cert) { 
01048       completeServerCertPath = Layout::relative_to(params->serverCertPathOnly, sslMultCertSettings.first_cert);
01049       if (!SSL_CTX_use_certificate_chain_file(ctx, completeServerCertPath)) {
01050           SSLError("failed to load certificate from %s", (const char *) completeServerCertPath);
01051           goto fail;
01052       }
01053 
01054     
01055     if (params->serverCertChainFilename) {
01056       ats_scoped_str completeServerCertChainPath(Layout::relative_to(params->serverCertPathOnly, params->serverCertChainFilename));
01057       if (!SSL_CTX_add_extra_chain_cert_file(ctx, completeServerCertChainPath)) {
01058         SSLError("failed to load global certificate chain from %s", (const char *) completeServerCertChainPath);
01059         goto fail;
01060       }
01061     }
01062 
01063     
01064     if (sslMultCertSettings.ca) {
01065       ats_scoped_str completeServerCertChainPath(Layout::relative_to(params->serverCertPathOnly, sslMultCertSettings.ca));
01066       if (!SSL_CTX_add_extra_chain_cert_file(ctx, completeServerCertChainPath)) {
01067         SSLError("failed to load certificate chain from %s", (const char *) completeServerCertChainPath);
01068         goto fail;
01069       }
01070     }
01071 
01072     if (!SSLPrivateKeyHandler(ctx, params, completeServerCertPath, sslMultCertSettings.key)) {
01073       goto fail;
01074     }
01075   }
01076 
01077   
01078   
01079   
01080   
01081   
01082   
01083   
01084   
01085   
01086   
01087   
01088   
01089   if (!sslMultCertSettings.ca && params->serverCACertPath != NULL) {
01090     if ((!SSL_CTX_load_verify_locations(ctx, params->serverCACertFilename, params->serverCACertPath)) ||
01091         (!SSL_CTX_set_default_verify_paths(ctx))) {
01092       SSLError("invalid CA Certificate file or CA Certificate path");
01093       goto fail;
01094     }
01095   }
01096 
01097   if (params->clientCertLevel != 0) {
01098 
01099     if (params->serverCACertFilename != NULL && params->serverCACertPath != NULL) {
01100       if ((!SSL_CTX_load_verify_locations(ctx, params->serverCACertFilename, params->serverCACertPath)) ||
01101           (!SSL_CTX_set_default_verify_paths(ctx))) {
01102         SSLError("CA Certificate file or CA Certificate path invalid");
01103         goto fail;
01104       }
01105     }
01106 
01107     if (params->clientCertLevel == 2) {
01108       server_verify_client = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE;
01109     } else if (params->clientCertLevel == 1) {
01110       server_verify_client = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
01111     } else {
01112       
01113       server_verify_client = SSL_VERIFY_NONE;
01114       Error("illegal client certification level %d in records.config", server_verify_client);
01115     }
01116 
01117     
01118     
01119     session_id_context = 1;
01120     SSL_CTX_set_session_id_context(ctx, (const unsigned char *) &session_id_context, sizeof(session_id_context));
01121 
01122     SSL_CTX_set_verify(ctx, server_verify_client, NULL);
01123     SSL_CTX_set_verify_depth(ctx, params->verify_depth); 
01124 
01125     SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(params->serverCACertFilename));
01126   }
01127 
01128   if (params->cipherSuite != NULL) {
01129     if (!SSL_CTX_set_cipher_list(ctx, params->cipherSuite)) {
01130       SSLError("invalid cipher suite in records.config");
01131       goto fail;
01132     }
01133   }
01134 #define SSL_CLEAR_PW_REFERENCES(UD,CTX) { \
01135   memset(static_cast<void *>(&UD),0,sizeof(UD));\
01136   SSL_CTX_set_default_passwd_cb(CTX, NULL);\
01137   SSL_CTX_set_default_passwd_cb_userdata(CTX, NULL);\
01138   }
01139   SSL_CLEAR_PW_REFERENCES(ud,ctx)
01140   return ssl_context_enable_ecdh(ctx);
01141 
01142 fail:
01143   SSL_CLEAR_PW_REFERENCES(ud,ctx)
01144   SSL_CTX_free(ctx);
01145 
01146   return NULL;
01147 }
01148 
01149 SSL_CTX *
01150 SSLInitClientContext(const SSLConfigParams * params)
01151 {
01152   ink_ssl_method_t meth = NULL;
01153   SSL_CTX * client_ctx = NULL;
01154   char * clientKeyPtr = NULL;
01155 
01156   
01157   
01158   
01159 
01160   meth = SSLv23_client_method();
01161   client_ctx = SSL_CTX_new(meth);
01162 
01163   
01164   SSL_CTX_set_options(client_ctx, params->ssl_ctx_options);
01165   if (!client_ctx) {
01166     SSLError("cannot create new client context");
01167     return NULL;
01168   }
01169 
01170   if (params->ssl_client_ctx_protocols) {
01171     SSL_CTX_set_options(client_ctx, params->ssl_client_ctx_protocols);
01172   }
01173   if (params->client_cipherSuite != NULL) {
01174     if (!SSL_CTX_set_cipher_list(client_ctx, params->client_cipherSuite)) {
01175       SSLError("invalid client cipher suite in records.config");
01176       goto fail;
01177     }
01178   }
01179 
01180   
01181   
01182   clientKeyPtr = params->clientKeyPath;
01183   if (clientKeyPtr == NULL) {
01184     clientKeyPtr = params->clientCertPath;
01185   }
01186 
01187   if (params->clientCertPath != 0) {
01188     if (!SSL_CTX_use_certificate_chain_file(client_ctx, params->clientCertPath)) {
01189       SSLError("failed to load client certificate from %s", params->clientCertPath);
01190       goto fail;
01191     }
01192 
01193     if (!SSL_CTX_use_PrivateKey_file(client_ctx, clientKeyPtr, SSL_FILETYPE_PEM)) {
01194       SSLError("failed to load client private key file from %s", clientKeyPtr);
01195       goto fail;
01196     }
01197 
01198     if (!SSL_CTX_check_private_key(client_ctx)) {
01199       SSLError("client private key (%s) does not match the certificate public key (%s)",
01200           clientKeyPtr, params->clientCertPath);
01201       goto fail;
01202     }
01203   }
01204 
01205   if (params->clientVerify) {
01206     int client_verify_server;
01207 
01208     client_verify_server = params->clientVerify ? SSL_VERIFY_PEER : SSL_VERIFY_NONE;
01209     SSL_CTX_set_verify(client_ctx, client_verify_server, NULL);
01210     SSL_CTX_set_verify_depth(client_ctx, params->client_verify_depth);
01211 
01212     if (params->clientCACertFilename != NULL && params->clientCACertPath != NULL) {
01213       if (!SSL_CTX_load_verify_locations(client_ctx, params->clientCACertFilename, params->clientCACertPath)) {
01214         SSLError("invalid client CA Certificate file (%s) or CA Certificate path (%s)",
01215             params->clientCACertFilename, params->clientCACertPath);
01216         goto fail;
01217       }
01218     }
01219 
01220     if (!SSL_CTX_set_default_verify_paths(client_ctx)) {
01221       SSLError("failed to set the default verify paths");
01222       goto fail;
01223     }
01224   }
01225 
01226   if (SSLConfigParams::init_ssl_ctx_cb) {
01227     SSLConfigParams::init_ssl_ctx_cb(client_ctx, false);
01228   }
01229 
01230   return client_ctx;
01231 
01232 fail:
01233   SSL_CTX_free(client_ctx);
01234   return NULL;
01235 }
01236 
01237 static char *
01238 asn1_strdup(ASN1_STRING * s)
01239 {
01240   
01241   ink_assert(ASN1_STRING_type(s) == V_ASN1_IA5STRING ||
01242     ASN1_STRING_type(s) == V_ASN1_UTF8STRING ||
01243     ASN1_STRING_type(s) == V_ASN1_PRINTABLESTRING ||
01244     ASN1_STRING_type(s) == V_ASN1_T61STRING);
01245 
01246   return ats_strndup((const char *)ASN1_STRING_data(s), ASN1_STRING_length(s));
01247 }
01248 
01249 
01250 
01251 
01252 static void
01253 ssl_index_certificate(SSLCertLookup * lookup, SSL_CTX * ctx, const char * certfile)
01254 {
01255   X509_NAME *   subject = NULL;
01256   X509 *        cert;
01257   ats_file_bio  bio(certfile, "r");
01258 
01259   cert = PEM_read_bio_X509_AUX(bio.bio, NULL, NULL, NULL);
01260   if (NULL == cert) {
01261     return;
01262   }
01263 
01264   
01265   subject = X509_get_subject_name(cert);
01266   if (subject) {
01267     int pos = -1;
01268     for (;;) {
01269       pos = X509_NAME_get_index_by_NID(subject, NID_commonName, pos);
01270       if (pos == -1) {
01271         break;
01272       }
01273 
01274       X509_NAME_ENTRY * e = X509_NAME_get_entry(subject, pos);
01275       ASN1_STRING * cn = X509_NAME_ENTRY_get_data(e);
01276       ats_scoped_str name(asn1_strdup(cn));
01277 
01278       Debug("ssl", "mapping '%s' to certificate %s", (const char *) name, certfile);
01279       lookup->insert(ctx, name);
01280     }
01281   }
01282 
01283 #if HAVE_OPENSSL_TS_H
01284   
01285   GENERAL_NAMES * names = (GENERAL_NAMES *) X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
01286   if (names) {
01287     unsigned count = sk_GENERAL_NAME_num(names);
01288     for (unsigned i = 0; i < count; ++i) {
01289       GENERAL_NAME * name;
01290 
01291       name = sk_GENERAL_NAME_value(names, i);
01292       if (name->type == GEN_DNS) {
01293         ats_scoped_str dns(asn1_strdup(name->d.dNSName));
01294         Debug("ssl", "mapping '%s' to certificate %s", (const char *) dns, certfile);
01295         lookup->insert(ctx, dns);
01296       }
01297     }
01298 
01299     GENERAL_NAMES_free(names);
01300   }
01301 #endif // HAVE_OPENSSL_TS_H
01302   X509_free(cert);
01303 }
01304 
01305 
01306 
01307 
01308 static void
01309 ssl_callback_info(const SSL *ssl, int where, int ret)
01310 {
01311   Debug("ssl", "ssl_callback_info ssl: %p where: %d ret: %d", ssl, where, ret);
01312   SSLNetVConnection * netvc = (SSLNetVConnection *)SSL_get_app_data(ssl);
01313 
01314   if ((where & SSL_CB_ACCEPT_LOOP) && netvc->getSSLHandShakeComplete() == true &&
01315       SSLConfigParams::ssl_allow_client_renegotiation == false) {
01316     int state = SSL_get_state(ssl);
01317 
01318     if (state == SSL3_ST_SR_CLNT_HELLO_A || state == SSL23_ST_SR_CLNT_HELLO_A) {
01319       netvc->setSSLClientRenegotiationAbort(true);
01320       Debug("ssl", "ssl_callback_info trying to renegotiate from the client");
01321     }
01322   }
01323   if (where & SSL_CB_HANDSHAKE_DONE) {
01324     
01325     const SSL_CIPHER * cipher = SSL_get_current_cipher(ssl);
01326     if (cipher) {
01327       const char * cipherName = SSL_CIPHER_get_name(cipher);
01328       
01329       InkHashTableValue data;
01330       if (ink_hash_table_lookup(ssl_cipher_name_table, cipherName, &data)) {
01331         SSL_INCREMENT_DYN_STAT((intptr_t)data);
01332       }
01333     }
01334   }
01335 }
01336 
01337 static bool
01338 ssl_store_ssl_context(
01339     const SSLConfigParams * params,
01340     SSLCertLookup *         lookup,
01341     const ssl_user_config & sslMultCertSettings)
01342 {
01343   SSL_CTX *   ctx;
01344   ats_scoped_str  certpath;
01345   ats_scoped_str  session_key_path;
01346 
01347   ctx = ssl_context_enable_sni(SSLInitServerContext(params, sslMultCertSettings), lookup);
01348   if (!ctx) {
01349     return false;
01350   }
01351 
01352   SSL_CTX_set_info_callback(ctx, ssl_callback_info);
01353 
01354 #if TS_USE_TLS_NPN
01355   SSL_CTX_set_next_protos_advertised_cb(ctx, SSLNetVConnection::advertise_next_protocol, NULL);
01356 #endif 
01357 
01358 #if TS_USE_TLS_ALPN
01359   SSL_CTX_set_alpn_select_cb(ctx, SSLNetVConnection::select_next_protocol, NULL);
01360 #endif 
01361 
01362   certpath = Layout::relative_to(params->serverCertPathOnly, sslMultCertSettings.first_cert);
01363 
01364   
01365   if (sslMultCertSettings.addr) {
01366     if (strcmp(sslMultCertSettings.addr, "*") == 0) {
01367       lookup->ssl_default = ctx;
01368       lookup->insert(ctx, sslMultCertSettings.addr);
01369     } else {
01370       IpEndpoint ep;
01371 
01372       if (ats_ip_pton(sslMultCertSettings.addr, &ep) == 0) {
01373         Debug("ssl", "mapping '%s' to certificate %s", (const char *)sslMultCertSettings.addr, (const char *)certpath);
01374         lookup->insert(ctx, ep);
01375       } else {
01376         Error("'%s' is not a valid IPv4 or IPv6 address", (const char *)sslMultCertSettings.addr);
01377       }
01378     }
01379   }
01380 
01381 #if defined(SSL_OP_NO_TICKET)
01382   
01383   if (sslMultCertSettings.session_ticket_enabled == 0) {
01384     SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
01385     Debug("ssl", "ssl session ticket is disabled");
01386   }
01387 #endif
01388 
01389   
01390   if (sslMultCertSettings.session_ticket_enabled != 0 && sslMultCertSettings.ticket_key_filename) {
01391     ats_scoped_str ticket_key_path(Layout::relative_to(params->serverCertPathOnly, sslMultCertSettings.ticket_key_filename));
01392     ssl_context_enable_tickets(ctx, ticket_key_path);
01393   }
01394 
01395 #ifdef HAVE_OPENSSL_OCSP_STAPLING
01396   if (SSLConfigParams::ssl_ocsp_enabled) {
01397     Debug("ssl", "ssl ocsp stapling is enabled");
01398     SSL_CTX_set_tlsext_status_cb(ctx, ssl_callback_ocsp_stapling);
01399     if (!ssl_stapling_init_cert(ctx, (const char *)certpath)) {
01400       Error("fail to configure SSL_CTX for OCSP Stapling info");
01401     }
01402   } else {
01403     Debug("ssl", "ssl ocsp stapling is disabled");
01404   }
01405 #else
01406   if (SSLConfigParams::ssl_ocsp_enabled) {
01407     Error("fail to enable ssl ocsp stapling, this openssl version does not support it");
01408   }
01409 #endif 
01410 
01411   
01412   
01413   
01414   Debug("ssl", "importing SNI names from %s", (const char *)certpath);
01415   ssl_index_certificate(lookup, ctx, certpath);
01416 
01417   if (SSLConfigParams::init_ssl_ctx_cb) {
01418     SSLConfigParams::init_ssl_ctx_cb(ctx, true);
01419   }
01420 
01421   return true;
01422 }
01423 
01424 static bool
01425 ssl_extract_certificate(
01426     const matcher_line * line_info,
01427     ssl_user_config & sslMultCertSettings)
01428 
01429 {
01430   for (int i = 0; i < MATCHER_MAX_TOKENS; ++i) {
01431     const char * label;
01432     const char * value;
01433 
01434     label = line_info->line[0][i];
01435     value = line_info->line[1][i];
01436 
01437     if (label == NULL) {
01438       continue;
01439     }
01440 
01441     if (strcasecmp(label, SSL_IP_TAG) == 0) {
01442       sslMultCertSettings.addr = ats_strdup(value);
01443     }
01444 
01445     if (strcasecmp(label, SSL_CERT_TAG) == 0) {
01446       sslMultCertSettings.cert = ats_strdup(value);
01447     }
01448 
01449     if (strcasecmp(label, SSL_CA_TAG) == 0) {
01450       sslMultCertSettings.ca = ats_strdup(value);
01451     }
01452 
01453     if (strcasecmp(label, SSL_PRIVATE_KEY_TAG) == 0) {
01454       sslMultCertSettings.key = ats_strdup(value);
01455     }
01456 
01457     if (strcasecmp(label, SSL_SESSION_TICKET_ENABLED) == 0) {
01458       sslMultCertSettings.session_ticket_enabled = atoi(value);
01459     }
01460 
01461     if (strcasecmp(label, SSL_SESSION_TICKET_KEY_FILE_TAG) == 0) {
01462       sslMultCertSettings.ticket_key_filename = ats_strdup(value);
01463     }
01464 
01465     if (strcasecmp(label, SSL_KEY_DIALOG) == 0) {
01466       sslMultCertSettings.dialog = ats_strdup(value);
01467     }
01468   }
01469   if (!sslMultCertSettings.cert) {
01470     Error("missing %s tag", SSL_CERT_TAG);
01471     return false;
01472   }
01473 
01474   SimpleTokenizer cert_tok(sslMultCertSettings.cert, SSL_CERT_SEPARATE_DELIM);
01475   const char * first_cert = cert_tok.getNext();
01476   if (first_cert) {
01477       sslMultCertSettings.first_cert = ats_strdup(first_cert);
01478   }
01479 
01480   return true;
01481 }
01482 
01483 bool
01484 SSLParseCertificateConfiguration(
01485     const SSLConfigParams * params,
01486     SSLCertLookup *         lookup)
01487 {
01488   char *      tok_state = NULL;
01489   char *      line = NULL;
01490   ats_scoped_str  file_buf;
01491   unsigned    line_num = 0;
01492   matcher_line line_info;
01493 
01494   const matcher_tags sslCertTags = {
01495     NULL, NULL, NULL, NULL, NULL, NULL, false
01496   };
01497 
01498   Note("loading SSL certificate configuration from %s", params->configFilePath);
01499 
01500   if (params->configFilePath) {
01501     file_buf = readIntoBuffer(params->configFilePath, __func__, NULL);
01502   }
01503 
01504   if (!file_buf) {
01505     Error("failed to read SSL certificate configuration from %s", params->configFilePath);
01506     return false;
01507   }
01508 
01509   
01510   uint32_t elevate_setting = 0;
01511   REC_ReadConfigInteger(elevate_setting, "proxy.config.ssl.cert.load_elevated");
01512   ElevateAccess elevate_access(elevate_setting != 0); 
01513 
01514   line = tokLine(file_buf, &tok_state);
01515   while (line != NULL) {
01516 
01517     line_num++;
01518 
01519     
01520     while (*line && isspace(*line)) {
01521       line++;
01522     }
01523 
01524     if (*line != '\0' && *line != '#') {
01525       ssl_user_config sslMultiCertSettings;
01526       const char * errPtr;
01527 
01528       errPtr = parseConfigLine(line, &line_info, &sslCertTags);
01529 
01530       if (errPtr != NULL) {
01531         RecSignalWarning(REC_SIGNAL_CONFIG_ERROR, "%s: discarding %s entry at line %d: %s",
01532                      __func__, params->configFilePath, line_num, errPtr);
01533       } else {
01534         if (ssl_extract_certificate(&line_info, sslMultiCertSettings)) {
01535           if (!ssl_store_ssl_context(params, lookup, sslMultiCertSettings)) {
01536             Error("failed to load SSL certificate specification from %s line %u",
01537                 params->configFilePath, line_num);
01538           }
01539         } else {
01540           RecSignalWarning(REC_SIGNAL_CONFIG_ERROR, "%s: discarding invalid %s entry at line %u",
01541                        __func__, params->configFilePath, line_num);
01542         }
01543       }
01544 
01545     }
01546 
01547     line = tokLine(NULL, &tok_state);
01548   }
01549 
01550   
01551   
01552   
01553   if (lookup->ssl_default == NULL) {
01554     ssl_user_config sslMultiCertSettings;
01555     sslMultiCertSettings.addr = ats_strdup("*");
01556     ssl_store_ssl_context(params, lookup, sslMultiCertSettings);
01557   }
01558 
01559   return true;
01560 }
01561 
01562 #if HAVE_OPENSSL_SESSION_TICKETS
01563 
01564 static void
01565 session_ticket_free(void * , void * ptr, CRYPTO_EX_DATA * ,
01566     int , long , void * )
01567 {
01568   ssl_ticket_key_t * key = (ssl_ticket_key_t *)ptr;
01569   delete key;
01570 }
01571 
01572 
01573 
01574 
01575 
01576 
01577 static int
01578 ssl_callback_session_ticket(
01579     SSL * ssl,
01580     unsigned char * keyname,
01581     unsigned char * iv,
01582     EVP_CIPHER_CTX * cipher_ctx,
01583     HMAC_CTX * hctx,
01584     int enc)
01585 {
01586   ssl_ticket_key_t* ssl_ticket_key = (ssl_ticket_key_t*) SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl), ssl_session_ticket_index);
01587 
01588   if (NULL == ssl_ticket_key) {
01589     Error("ssl ticket key is null.");
01590     return -1;
01591   }
01592 
01593   if (enc == 1) {
01594     memcpy(keyname, ssl_ticket_key->key_name, 16);
01595     RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH);
01596     EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL, ssl_ticket_key->aes_key, iv);
01597     HMAC_Init_ex(hctx, ssl_ticket_key->hmac_secret, 16, evp_md_func, NULL);
01598 
01599     Debug("ssl", "create ticket for a new session.");
01600     SSL_INCREMENT_DYN_STAT(ssl_total_tickets_created_stat);
01601     return 0;
01602   } else if (enc == 0) {
01603     if (memcmp(keyname, ssl_ticket_key->key_name, 16)) {
01604       Debug("ssl", "keyname is not consistent.");
01605       SSL_INCREMENT_DYN_STAT(ssl_total_tickets_not_found_stat);
01606       return 0;
01607     }
01608 
01609     EVP_DecryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL, ssl_ticket_key->aes_key, iv);
01610     HMAC_Init_ex(hctx, ssl_ticket_key->hmac_secret, 16, evp_md_func, NULL);
01611 
01612     Debug("ssl", "verify the ticket for an existing session.");
01613     SSL_INCREMENT_DYN_STAT(ssl_total_tickets_verified_stat);
01614     return 1;
01615   }
01616 
01617   return -1;
01618 }
01619 #endif 
01620 
01621 void
01622 SSLReleaseContext(SSL_CTX * ctx)
01623 {
01624   SSL_CTX_free(ctx);
01625 }