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

📄 tport_tls.c

📁 this is simple sip stack.
💻 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 <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <signal.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 <poll.h>#include "tport_tls.h"char const tls_version[] = OPENSSL_VERSION_TEXT;enum  { tls_master, tls_slave };struct tls_s {  SSL_CTX *ctx;  SSL *con;  BIO *bio_con;  BIO *bio_err;  int type;  int verified;  /* Receiving */  int read_events;  void *read_buffer;  int read_buffer_len;  /* Sending */  int   write_events;  void *write_buffer;  int   write_buffer_len;  /* Host names */  char *hosts[TLS_MAX_HOSTS + 1];};enum { tls_buffer_size = 16384 };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){  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);#if nomore   509_NAME_oneline(X509_get_subject_name(cert), data, 256);  fprintf(stderr,"depth=%d %s\n",depth,data);#endif  if (!ok)  {    fprintf(stderr, "-Error with certificate at depth: %i\n", depth);    X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);    fprintf(stderr, "  issuer   = %s\n", data);    X509_NAME_oneline(X509_get_subject_name(cert), data, 256);    fprintf(stderr, "  subject  = %s\n", data);    fprintf(stderr, "  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) {	BIO_printf(tls->bio_err, "%s: cannot open randFile %s\n", 		   "tls_init_context", ti->randFile);	ERR_print_errors(tls->bio_err);      }      /* errno = EIO; */      /* return -1; */    }  }  /* Avoid possible SIGPIPE when sending close_notify */  signal(SIGPIPE, SIG_IGN);  if (tls->bio_err == NULL)    tls->bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);  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) {    ERR_print_errors(tls->bio_err);    errno = EIO;    return -1;  }  if (!SSL_CTX_use_certificate_file(tls->ctx, 				    ti->cert,				    SSL_FILETYPE_PEM)) {    if (ti->configured > 0) {      BIO_printf(tls->bio_err, "%s: invalid certificate: %s\n",		 "tls_init_context", ti->cert);      ERR_print_errors(tls->bio_err);#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) {      ERR_print_errors(tls->bio_err);#if require_client_certificate      errno = EIO;      return -1;#endif    }  }  if (!SSL_CTX_check_private_key(tls->ctx)) {    if (ti->configured > 0) {      BIO_printf(tls->bio_err,		 "Private key does not match the certificate public key\n");    }#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)      ERR_print_errors(tls->bio_err);    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)) {    BIO_printf(tls->bio_err,"error setting cipher list\n");    ERR_print_errors(tls->bio_err);    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);  if (tls->bio_err != NULL && tls->type != tls_slave)    BIO_free(tls->bio_err);  for (k = 0; k < TLS_MAX_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;  signal(SIGPIPE, SIG_IGN);  /* Ignore spurios SIGPIPE from OpenSSL */  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) {      BIO_printf(tls->bio_err, "tls_init_master: BIO_new_socket failed\n");      ERR_print_errors(tls->bio_err);      tls_free(tls);      errno = EIO;      return NULL;    }  }#endif  return tls;}#if 0static int tls_accept(tls_t *tls){  int ret = SSL_accept(tls->con);  int verify_result;  if (ret <= 0) {    int err = SSL_get_error(tls->con, ret);    switch(err) {    case SSL_ERROR_WANT_READ:      return errno = EAGAIN, tls->read_events = POLLIN, 0;    case SSL_ERROR_WANT_WRITE:      return errno = EAGAIN, tls->read_events = POLLOUT, 0;    default:          BIO_printf(tls->bio_err, "SSL_connect failed: %d %s\n",                  err,                 ERR_error_string(err, NULL));      ERR_print_errors(tls->bio_err);      return -1;    }  }  verify_result = SSL_get_verify_result(tls->con);  if (verify_result != X509_V_OK) {    BIO_printf(tls->bio_err,                "Client certificate doesn't verify: %s\n",               X509_verify_cert_error_string(verify_result));#if 0    tls_free(tls);    return NULL;#endif  }  if (SSL_get_peer_certificate(tls->con) == NULL) {    BIO_printf(tls->bio_err, "Client didn't send certificate\n");#if 0    tls_free(tls);    return NULL;#endif  }

⌨️ 快捷键说明

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