⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tport_tls.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE tport_tls.c * @brief TLS interface *  * @author Mikko Haataja <ext-Mikko.A.Haataja@nokia.com> * @author Pekka Pessi <ext-Pekka.Pessi@nokia.com> * * Copyright 2001, 2002 Nokia Research Center.  All rights reserved. * */#include "config.h"#define OPENSSL_NO_KRB5 oh-no#include <openssl/lhash.h>#include <openssl/bn.h>#include <openssl/x509.h>#include <openssl/x509v3.h>#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/pem.h>#include <openssl/rand.h>#include <openssl/bio.h>#include <openssl/opensslv.h>#include <sofia-sip/su_types.h>#include <sofia-sip/su.h>#include <sofia-sip/su_wait.h>#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#if HAVE_SIGPIPE#include <signal.h>#endif#include "tport_tls.h"#include "tport_internal.h"char const tls_version[] = OPENSSL_VERSION_TEXT;enum  { tls_master, tls_slave };struct tls_s {  SSL_CTX *ctx;  SSL *con;  BIO *bio_con;  int type;  int verified;  /* Receiving */  int read_events;  void *read_buffer;  size_t read_buffer_len;  /* Sending */  int   write_events;  void *write_buffer;  size_t write_buffer_len;  /* Host names */  char *hosts[TLS_MAX_HOSTS + 1];};enum { tls_buffer_size = 16384 };/** Log TLS error(s). * * Log the TLS error specified by the error code @a e and all the errors in * the queue. The error code @a e implies no error, and it is not logged. */staticvoid tls_log_errors(unsigned level, char const *s, unsigned long e){  if (e == 0)    e = ERR_get_error();  if (!tport_log->log_init)    su_log_init(tport_log);  if (s == NULL) s = "tls";  for (; e != 0; e = ERR_get_error()) {    if (level <= tport_log->log_level) {      const char *error = ERR_lib_error_string(e);      const char *func = ERR_func_error_string(e);      const char *reason = ERR_reason_error_string(e);      su_llog(tport_log, level, "%s: %08lx:%s:%s:%s\n", 	      s, e, error, func, reason);    }  }}statictls_t *tls_create(int type){  tls_t *tls = calloc(1, sizeof(*tls));  if (tls)    tls->type = type;  return tls;}staticvoid tls_set_default(tls_issues_t *i){  i->verify_depth = i->verify_depth == 0 ? 2 : i->verify_depth;  i->cert = i->cert ? i->cert : "agent.pem";  i->key = i->key ? i->key : i->cert;  i->randFile = i->randFile ? i->randFile : "tls_seed.dat";  i->CAfile = i->CAfile ? i->CAfile : "cafile.pem";  i->cipher = i->cipher ? i->cipher : "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";  /* Default SIP cipher */  /* "RSA-WITH-AES-128-CBC-SHA"; */  /* RFC-2543-compatibility ciphersuite */  /* TLS_RSA_WITH_3DES_EDE_CBC_SHA; */}staticint tls_verify_cb(int ok, X509_STORE_CTX *store){  if (!ok)  {    char data[256];    X509 *cert = X509_STORE_CTX_get_current_cert(store);    int  depth = X509_STORE_CTX_get_error_depth(store);    int  err = X509_STORE_CTX_get_error(store);    SU_DEBUG_1(("-Error with certificate at depth: %i\n", depth));    X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);    SU_DEBUG_1(("  issuer   = %s\n", data));    X509_NAME_oneline(X509_get_subject_name(cert), data, 256);    SU_DEBUG_1(("  subject  = %s\n", data));    SU_DEBUG_1(("  err %i:%s\n", err, X509_verify_cert_error_string(err)));  }   return 1;			/* Always return "ok" */}staticint tls_init_context(tls_t *tls, tls_issues_t const *ti){  static int initialized = 0;  if (!initialized) {    initialized = 1;    SSL_library_init();    SSL_load_error_strings();    if (ti->randFile &&	!RAND_load_file(ti->randFile, 1024 * 1024)) {      if (ti->configured > 1) {	SU_DEBUG_3(("%s: cannot open randFile %s\n", 		   "tls_init_context", ti->randFile));	tls_log_errors(3, "tls_init_context", 0);      }      /* errno = EIO; */      /* return -1; */    }  }#if HAVE_SIGPIPE  /* Avoid possible SIGPIPE when sending close_notify */  signal(SIGPIPE, SIG_IGN);#endif  if (tls->ctx == NULL) {    SSL_METHOD *meth;    /* meth = SSLv3_method(); */    /* meth = SSLv23_method(); */    if (ti->version)      meth = TLSv1_method();    else      meth = SSLv23_method();    tls->ctx = SSL_CTX_new(meth);  }  if (tls->ctx == NULL) {    tls_log_errors(1, "tls_init_context", 0);    errno = EIO;    return -1;  }  if (!SSL_CTX_use_certificate_file(tls->ctx, 				    ti->cert,				    SSL_FILETYPE_PEM)) {    if (ti->configured > 0) {      SU_DEBUG_1(("%s: invalid local certificate: %s\n",		 "tls_init_context", ti->cert));      tls_log_errors(1, "tls_init_context", 0);#if require_client_certificate      errno = EIO;      return -1;#endif    }  }  if (!SSL_CTX_use_PrivateKey_file(tls->ctx,                                    ti->key,                                    SSL_FILETYPE_PEM)) {    if (ti->configured > 0) {      tls_log_errors(1, "tls_init_context", 0);#if require_client_certificate      errno = EIO;      return -1;#endif    }  }  if (!SSL_CTX_check_private_key(tls->ctx)) {    if (ti->configured > 0) {      SU_DEBUG_1(("%s: private key does not match the certificate public key\n",		  "tls_init_context"));    }#if require_client_certificate    errno = EIO;    return -1;#endif  }  if (!SSL_CTX_load_verify_locations(tls->ctx,                                      ti->CAfile,                                      ti->CApath)) {    if (ti->configured > 0)      tls_log_errors(1, "tls_init_context", 0);    errno = EIO;    return -1;  }  SSL_CTX_set_verify_depth(tls->ctx, ti->verify_depth);  SSL_CTX_set_verify(tls->ctx, 		     getenv("SSL_VERIFY_PEER") ? SSL_VERIFY_PEER : SSL_VERIFY_NONE		     /* SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT */,                     tls_verify_cb);  if (!SSL_CTX_set_cipher_list(tls->ctx, ti->cipher)) {    SU_DEBUG_1(("%s: error setting cipher list\n", "tls_init_context"));    tls_log_errors(1, "tls_init_context", 0);    errno = EIO;    return -1;  }  return 0;}void tls_free(tls_t *tls){  int k;  if (!tls)    return;  if (tls->read_buffer)    free(tls->read_buffer), tls->read_buffer = NULL;  if (tls->con != NULL)    SSL_shutdown(tls->con);  if (tls->ctx != NULL && tls->type != tls_slave)    SSL_CTX_free(tls->ctx);  if (tls->bio_con != NULL)    BIO_free(tls->bio_con);  for (k = 0; k < TLS_MAX_HOSTS; k++)    if (tls->hosts[k]) {      free(tls->hosts[k]), tls->hosts[k] = NULL;    }  free(tls);}int tls_get_socket(tls_t *tls){  int sock = -1;  if (tls != NULL && tls->bio_con != NULL)    BIO_get_fd(tls->bio_con, &sock);  return sock;}tls_t *tls_init_master(tls_issues_t *ti){  /* Default id in case RAND fails */   unsigned char sessionId[32] = "sofia/tls";   tls_t *tls;#if HAVE_SIGPIPE  signal(SIGPIPE, SIG_IGN);  /* Ignore spurios SIGPIPE from OpenSSL */#endif  tls_set_default(ti);  if (!(tls = tls_create(tls_master)))    return NULL;  if (tls_init_context(tls, ti) < 0) {    int err = errno;    tls_free(tls);    errno = err;    return NULL;  }  RAND_pseudo_bytes(sessionId, sizeof(sessionId));  SSL_CTX_set_session_id_context(tls->ctx,                                 (void*) sessionId,				 sizeof(sessionId));     if (ti->CAfile != NULL)    SSL_CTX_set_client_CA_list(tls->ctx,                               SSL_load_client_CA_file(ti->CAfile));#if 0  if (sock != -1) {    tls->bio_con = BIO_new_socket(sock, BIO_NOCLOSE);    if (tls->bio_con == NULL) {      tls_log_errors(1, "tls_init_master", 0);      tls_free(tls);      errno = EIO;      return NULL;    }  }#endif  return tls;}tls_t *tls_clone(tls_t *master, int sock, int accept){  tls_t *tls = tls_create(tls_slave);  if (tls) {    tls->ctx = master->ctx;    if (!(tls->read_buffer = malloc(tls_buffer_size)))      free(tls), tls = NULL;  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -