|
@@ -1,244 +0,0 @@
|
|
-/*
|
|
|
|
- * $Id$
|
|
|
|
- *
|
|
|
|
- * Copyright (C) 2001-2003 Fhg Fokus
|
|
|
|
- *
|
|
|
|
- * This file is part of ser, a free SIP server.
|
|
|
|
- *
|
|
|
|
- * ser is free software; you can redistribute it and/or modify
|
|
|
|
- * it under the terms of the GNU General Public License as published by
|
|
|
|
- * the Free Software Foundation; either version 2 of the License, or
|
|
|
|
- * (at your option) any later version
|
|
|
|
- *
|
|
|
|
- * For a license to use the ser software under conditions
|
|
|
|
- * other than those described here, or to purchase support for this
|
|
|
|
- * software, please contact iptel.org by e-mail at the following addresses:
|
|
|
|
- * [email protected]
|
|
|
|
- *
|
|
|
|
- * ser 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 General Public License for more details.
|
|
|
|
- *
|
|
|
|
- * You should have received a copy of the GNU General Public License
|
|
|
|
- * along with this program; if not, write to the Free Software
|
|
|
|
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
- */
|
|
|
|
-/*
|
|
|
|
- * tls initialization & cleanup functions
|
|
|
|
- *
|
|
|
|
- * History:
|
|
|
|
- * --------
|
|
|
|
- * 2003-06-29 created by andrei
|
|
|
|
- */
|
|
|
|
-#ifdef USE_TLS
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-#include <openssl/ssl.h>
|
|
|
|
-#include <openssl/err.h>
|
|
|
|
-
|
|
|
|
-#include "mem/mem.h"
|
|
|
|
-#include "mem/shm_mem.h"
|
|
|
|
-#include "tcp_init.h"
|
|
|
|
-#include "dprint.h"
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-#if OPENSSL_VERSION_NUMBER < 0x00906000L /* 0.9.6*/
|
|
|
|
-#error "OpenSSL 0.9.6 or greater required"
|
|
|
|
-/* it might work ok with older versions (I think
|
|
|
|
- * >= 0.9.4 should be ok), but I didn't test them
|
|
|
|
- * so try them at your own risk :-) -- andrei
|
|
|
|
- */
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/* global tls related data */
|
|
|
|
-SSL_CTX* default_ctx=0 ; /* global ssl context */
|
|
|
|
-
|
|
|
|
-int tls_log=L_INFO; /* tls log level */
|
|
|
|
-int tls_require_cert=0; /* require client certificate */
|
|
|
|
-char* tls_pkey_file=0; /* private key file name */
|
|
|
|
-char* tls_cert_file=0; /* certificate file name */
|
|
|
|
-char* tls_ca_file=0; /* CA list file name */
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/* inits a sock_info structure with tls data
|
|
|
|
- * (calls tcp_init for the tcp part)
|
|
|
|
- * returns 0 on success, -1 on error */
|
|
|
|
-int tls_init(struct socket_info* sock_info)
|
|
|
|
-{
|
|
|
|
- int ret;
|
|
|
|
- if ((ret=tcp_init(sock_info))!=0){
|
|
|
|
- LOG(L_ERR, "ERROR: tls_init: tcp_init failed on"
|
|
|
|
- "%.*s:%d\n", sock_info->address_str.len,
|
|
|
|
- sock_info->address_str.s, sock_info->port_no);
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
- sock_info->proto=PROTO_TLS;
|
|
|
|
- /* tls specific stuff */
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/* malloc & friends functions that will be used
|
|
|
|
- * by libssl (we need most ssl info in shared mem.)*/
|
|
|
|
-
|
|
|
|
-void* tls_malloc(size_t size)
|
|
|
|
-{
|
|
|
|
- return shm_malloc(size);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void tls_free(void* ptr)
|
|
|
|
-{
|
|
|
|
- shm_free(ptr);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void* tls_realloc(void* ptr, size_t size)
|
|
|
|
-{
|
|
|
|
- return shm_realloc(ptr, size);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/* print the ssl error stack */
|
|
|
|
-void tls_dump_errors(char* s)
|
|
|
|
-{
|
|
|
|
- long err;
|
|
|
|
- if ( 1 /*default_ctx */) /* only if ssl was initialized */
|
|
|
|
- while((err=ERR_get_error()))
|
|
|
|
- LOG(L_ERR, "%s%s\n", (s)?s:"", ERR_error_string(err,0));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/* inits ser tls support
|
|
|
|
- * returns 0 on success, <0 on error */
|
|
|
|
-int init_tls()
|
|
|
|
-{
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- if (tls_pkey_file==0)
|
|
|
|
- tls_pkey_file=TLS_PKEY_FILE;
|
|
|
|
- if (tls_cert_file==0)
|
|
|
|
- tls_cert_file=TLS_CERT_FILE;
|
|
|
|
- if (tls_ca_file==0)
|
|
|
|
- tls_ca_file=TLS_CA_FILE;
|
|
|
|
-
|
|
|
|
- DBG("initializing openssl...\n");
|
|
|
|
- SSL_library_init(); /* don't use shm_ for SSL_library_init() */
|
|
|
|
- /* init mem. alloc. for libcrypt & openssl */
|
|
|
|
- CRYPTO_set_mem_functions(tls_malloc, tls_realloc,
|
|
|
|
- tls_free);
|
|
|
|
-
|
|
|
|
- /* init the openssl library */
|
|
|
|
- SSL_load_error_strings(); /* readable error messages*/
|
|
|
|
- /* seed the PRNG, nothing on linux because openssl should automatically
|
|
|
|
- use /dev/urandom, see RAND_seed, RAND_add */
|
|
|
|
-
|
|
|
|
- /* create the ssl context */
|
|
|
|
- DBG("creating the ssl context...\n");
|
|
|
|
- default_ctx=SSL_CTX_new(TLSv1_method());
|
|
|
|
- if (default_ctx==0){
|
|
|
|
- LOG(L_ERR, "init_tls: failed to create ssl context\n");
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
- /* no passwd: */
|
|
|
|
- /* SSL_CTX_set_default_passwd_cb(ctx, callback); */
|
|
|
|
-
|
|
|
|
- /* set options, e.g SSL_OP_NO_SSLv2,
|
|
|
|
- * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
|
|
|
- */
|
|
|
|
- /* SSL_CTX_set_options(ctx, options); */
|
|
|
|
-
|
|
|
|
- /* mode, e.g. SSL_MODE_ENABLE_PARTIAL_WRITE,
|
|
|
|
- * SSL_MODE_AUTO_RETRY */
|
|
|
|
- /* SSL_CTX_set_mode(ctx, mode); */
|
|
|
|
-
|
|
|
|
- /* using certificates (we don't allow anonymous ciphers => at least
|
|
|
|
- * the server must have a cert)*/
|
|
|
|
- /* private key */
|
|
|
|
- if (SSL_CTX_use_PrivateKey_file(default_ctx, tls_pkey_file,
|
|
|
|
- SSL_FILETYPE_PEM)!=1){
|
|
|
|
- LOG(L_ERR, "init_tls: failed to load private key from \"%s\"\n",
|
|
|
|
- tls_pkey_file);
|
|
|
|
- goto error_certs;
|
|
|
|
- }
|
|
|
|
- if (SSL_CTX_use_certificate_chain_file(default_ctx, tls_cert_file)!=1){
|
|
|
|
- /* better than *_use_certificate_file
|
|
|
|
- * see SSL_CTX_use_certificate(3)/Notes */
|
|
|
|
- LOG(L_ERR, "init_tls: failed to load certificate from \"%s\"\n",
|
|
|
|
- tls_cert_file);
|
|
|
|
- goto error_certs;
|
|
|
|
- }
|
|
|
|
- /* check if private key corresponds to the loaded ceritficate */
|
|
|
|
- if (SSL_CTX_check_private_key(default_ctx)!=1){
|
|
|
|
- LOG(L_CRIT, "init_tls: private key \"%s\" does not match the"
|
|
|
|
- " certificate file \"%s\"\n", tls_pkey_file, tls_cert_file);
|
|
|
|
- goto error_certs;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* set session id context, usefull for reusing stored sessions */
|
|
|
|
- /*
|
|
|
|
- if (SSL_CTX_set_session_id_context(ctx, version, version_len)!=1){
|
|
|
|
- LOG(L_CRIT, "init_tls: failed to set session id\n");
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- /* set cert. verifications options */
|
|
|
|
- /* verify peer if it has a cert (to fail for no cert. add
|
|
|
|
- * | SSL_VERIFY_FAIL_IF_NO_PEER_CERT ); forces the server to send
|
|
|
|
- * a client certificate request */
|
|
|
|
- SSL_CTX_set_verify(default_ctx, SSL_VERIFY_PEER | ( (tls_require_cert)?
|
|
|
|
- SSL_VERIFY_FAIL_IF_NO_PEER_CERT:0 ), 0);
|
|
|
|
- /* SSL_CTX_set_verify_depth(ctx, 2); -- default 9 */
|
|
|
|
- /* CA locations, list */
|
|
|
|
- if (tls_ca_file){
|
|
|
|
- if (SSL_CTX_load_verify_locations(default_ctx, tls_ca_file, 0 )!=1){
|
|
|
|
- /* we don't support ca path, we load them only from files */
|
|
|
|
- LOG(L_CRIT, "init_tls: error while processing CA locations\n");
|
|
|
|
- goto error_certs;
|
|
|
|
- }
|
|
|
|
- SSL_CTX_set_client_CA_list(default_ctx,
|
|
|
|
- SSL_load_client_CA_file(tls_ca_file));
|
|
|
|
- if (SSL_CTX_get_client_CA_list(default_ctx)==0){
|
|
|
|
- LOG(L_CRIT, "init_tls: error setting client CA list from <%s>\n",
|
|
|
|
- tls_ca_file);
|
|
|
|
- goto error_certs;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* DH tmp key generation -- see DSA_generate_parameters,
|
|
|
|
- * SSL_CTX_set_tmp_dh, SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE */
|
|
|
|
-
|
|
|
|
- /* RSA tmp key generation => we don't care, we won't accept
|
|
|
|
- * connection to export restricted applications and tls does not
|
|
|
|
- * allow a tmp key in another sitaution */
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-error_certs:
|
|
|
|
- /*
|
|
|
|
- SSL_CTX_free(ctx);
|
|
|
|
- ctx=0;
|
|
|
|
- */
|
|
|
|
-error:
|
|
|
|
- tls_dump_errors("tls_init:");
|
|
|
|
- return -1;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-void destroy_tls()
|
|
|
|
-{
|
|
|
|
- if(default_ctx){
|
|
|
|
- DBG("destroy_tls...\n");
|
|
|
|
- SSL_CTX_free(default_ctx);
|
|
|
|
- ERR_free_strings();
|
|
|
|
- default_ctx=0;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#endif
|
|
|