summaryrefslogtreecommitdiff
path: root/ace/SSL/SSL_Context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/SSL/SSL_Context.cpp')
-rw-r--r--ace/SSL/SSL_Context.cpp567
1 files changed, 0 insertions, 567 deletions
diff --git a/ace/SSL/SSL_Context.cpp b/ace/SSL/SSL_Context.cpp
deleted file mode 100644
index 76ad6aafc29..00000000000
--- a/ace/SSL/SSL_Context.cpp
+++ /dev/null
@@ -1,567 +0,0 @@
-#include "SSL_Context.h"
-
-#include "sslconf.h"
-
-#if !defined(__ACE_INLINE__)
-#include "SSL_Context.inl"
-#endif /* __ACE_INLINE__ */
-
-#include "ace/Guard_T.h"
-#include "ace/Object_Manager.h"
-#include "ace/Log_Msg.h"
-#include "ace/Singleton.h"
-#include "ace/Synch_Traits.h"
-#include "ace/ACE.h"
-#include "ace/OS_NS_errno.h"
-#include "ace/OS_NS_string.h"
-
-#ifdef ACE_HAS_THREADS
-# include "ace/Thread_Mutex.h"
-# include "ace/Synch_Traits.h"
-# include "ace/Auto_Ptr.h"
-# include "ace/OS_NS_Thread.h"
-#endif /* ACE_HAS_THREADS */
-
-#include <openssl/x509.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-
-ACE_RCSID (ACE_SSL,
- SSL_Context,
- "$Id$")
-
-
-namespace
-{
- /// Reference count of the number of times the ACE_SSL_Context was
- /// initialized.
- int ssl_library_init_count = 0;
-
- // @@ This should also be done with a singleton, otherwise it is not
- // thread safe and/or portable to some weird platforms...
-
-#ifdef ACE_HAS_THREADS
- /// Array of mutexes used internally by OpenSSL when the SSL
- /// application is multithreaded.
- ACE_Auto_Basic_Array_Ptr<ACE_SYNCH_MUTEX> ssl_locks;
-
- // @@ This should also be managed by a singleton.
-#endif
-}
-
-#ifdef ACE_HAS_THREADS
-
-# if (defined (ACE_HAS_VERSIONED_NAMESPACE) \
- && ACE_HAS_VERSIONED_NAMESPACE == 1) \
- && !(defined (_MSC_VER) && _MSC_VER <= 1200)
-// MSVC++ 6's preprocessor can't handle macro expansions required by
-// the versioned namespace support. *sigh*
-
-# define ACE_SSL_LOCKING_CALLBACK_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_SSL_locking_callback)
-# define ACE_SSL_THREAD_ID_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_SSL_thread_id)
-
-# else
-
-# define ACE_SSL_LOCKING_CALLBACK_NAME ACE_SSL_locking_callback
-# define ACE_SSL_THREAD_ID_NAME ACE_SSL_thread_id
-
-# endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */
-
-
-
-extern "C"
-{
- void
- ACE_SSL_LOCKING_CALLBACK_NAME (int mode,
- int type,
- const char * /* file */,
- int /* line */)
- {
- // #ifdef undef
- // fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
- // CRYPTO_thread_id(),
- // (mode&CRYPTO_LOCK)?"l":"u",
- // (type&CRYPTO_READ)?"r":"w",file,line);
- // #endif
- // /*
- // if (CRYPTO_LOCK_SSL_CERT == type)
- // fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
- // CRYPTO_thread_id(),
- // mode,file,line);
- // */
- if (mode & CRYPTO_LOCK)
- (void) ssl_locks[type].acquire ();
- else
- (void) ssl_locks[type].release ();
- }
-
- // -------------------------------
-
- // Return the current thread ID. OpenSSL uses this on platforms
- // that need it.
- unsigned long
- ACE_SSL_THREAD_ID_NAME (void)
- {
- return (unsigned long) ACE_VERSIONED_NAMESPACE_NAME::ACE_OS::thr_self ();
- }
-}
-#endif /* ACE_HAS_THREADS */
-
-
-// ****************************************************************
-
-ACE_BEGIN_VERSIONED_NAMESPACE_DECL
-
-ACE_SSL_Context::ACE_SSL_Context (void)
- : context_ (0),
- mode_ (-1),
- default_verify_mode_ (SSL_VERIFY_NONE),
- have_ca_ (0)
-{
- ACE_SSL_Context::ssl_library_init ();
-}
-
-ACE_SSL_Context::~ACE_SSL_Context (void)
-{
- if (this->context_)
- {
- ::SSL_CTX_free (this->context_);
- this->context_ = 0;
- }
-
- ACE_SSL_Context::ssl_library_fini ();
-}
-
-ACE_SSL_Context *
-ACE_SSL_Context::instance (void)
-{
- return ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::instance ();
-}
-
-void
-ACE_SSL_Context::ssl_library_init (void)
-{
- ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex,
- ace_ssl_mon,
- *ACE_Static_Object_Lock::instance ()));
-
- if (ssl_library_init_count == 0)
- {
- // Initialize the locking callbacks before initializing anything
- // else.
-#ifdef ACE_HAS_THREADS
- int const num_locks = ::CRYPTO_num_locks ();
-
- ssl_locks.reset (new ACE_SYNCH_MUTEX[num_locks]);
-
-# if !defined (WIN32)
- // This call isn't necessary on some platforms. See the CRYPTO
- // library's threads(3) man page for details.
- ::CRYPTO_set_id_callback (ACE_SSL_THREAD_ID_NAME);
-# endif /* !WIN32 */
- ::CRYPTO_set_locking_callback (ACE_SSL_LOCKING_CALLBACK_NAME);
-#endif /* ACE_HAS_THREADS */
-
- ::SSLeay_add_ssl_algorithms ();
- ::SSL_load_error_strings ();
-
- // Seed the random number generator. Note that the random
- // number generator can be seeded more than once to "stir" its
- // state.
-
-#ifdef WIN32
- // Seed the random number generator by sampling the screen.
- ::RAND_screen ();
-#endif /* WIN32 */
-
-#if OPENSSL_VERSION_NUMBER >= 0x00905100L
- // OpenSSL < 0.9.5 doesn't have EGD support.
-
- const char *egd_socket_file =
- ACE_OS::getenv (ACE_SSL_EGD_FILE_ENV);
-
- if (egd_socket_file != 0)
- (void) this->egd_file (egd_socket_file);
-#endif /* OPENSSL_VERSION_NUMBER */
-
- const char *rand_file =
- ACE_OS::getenv (ACE_SSL_RAND_FILE_ENV);
-
- if (rand_file != 0)
- (void) this->seed_file (rand_file);
-
- // Initialize the mutexes that will be used by the SSL and
- // crypto library.
-
- }
-
- ++ssl_library_init_count;
-}
-
-void
-ACE_SSL_Context::ssl_library_fini (void)
-{
- ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex,
- ace_ssl_mon,
- *ACE_Static_Object_Lock::instance ()));
-
- --ssl_library_init_count;
- if (ssl_library_init_count == 0)
- {
- ::ERR_free_strings ();
- ::EVP_cleanup ();
-
- // Clean up the locking callbacks after everything else has been
- // cleaned up.
-#ifdef ACE_HAS_THREADS
- ::CRYPTO_set_locking_callback (0);
-#endif /* ACE_HAS_THREADS */
- }
-}
-
-int
-ACE_SSL_Context::set_mode (int mode)
-{
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
- ace_ssl_mon,
- *ACE_Static_Object_Lock::instance (),
- -1));
-
- if (this->context_ != 0)
- return -1;
-
- SSL_METHOD *method = 0;
-
- switch (mode)
- {
- case ACE_SSL_Context::SSLv2_client:
- method = ::SSLv2_client_method ();
- break;
- case ACE_SSL_Context::SSLv2_server:
- method = ::SSLv2_server_method ();
- break;
- case ACE_SSL_Context::SSLv2:
- method = ::SSLv2_method ();
- break;
- case ACE_SSL_Context::SSLv3_client:
- method = ::SSLv3_client_method ();
- break;
- case ACE_SSL_Context::SSLv3_server:
- method = ::SSLv3_server_method ();
- break;
- case ACE_SSL_Context::SSLv3:
- method = ::SSLv3_method ();
- break;
- case ACE_SSL_Context::SSLv23_client:
- method = ::SSLv23_client_method ();
- break;
- case ACE_SSL_Context::SSLv23_server:
- method = ::SSLv23_server_method ();
- break;
- case ACE_SSL_Context::SSLv23:
- method = ::SSLv23_method ();
- break;
- case ACE_SSL_Context::TLSv1_client:
- method = ::TLSv1_client_method ();
- break;
- case ACE_SSL_Context::TLSv1_server:
- method = ::TLSv1_server_method ();
- break;
- case ACE_SSL_Context::TLSv1:
- method = ::TLSv1_method ();
- break;
- default:
- method = ::SSLv3_method ();
- break;
- }
-
- this->context_ = ::SSL_CTX_new (method);
- if (this->context_ == 0)
- return -1;
-
- this->mode_ = mode;
-
- // Load the trusted certificate authority (default) certificate
- // locations. But do not return -1 on error, doing so confuses CTX
- // allocation (severe error) with the less important loading of CA
- // certificate location error. If it is important for your
- // application then call ACE_SSL_Context::have_trusted_ca(),
- // immediately following this call to set_mode().
- (void) this->load_trusted_ca ();
-
- return 0;
-}
-
-int
-ACE_SSL_Context::load_trusted_ca (const char* ca_file, const char* ca_dir)
-{
- this->check_context ();
-
- if (ca_file == 0)
- {
- // Use the default environment settings.
- ca_file = ACE_OS::getenv (ACE_SSL_CERT_FILE_ENV);
- if (ca_file == 0)
- ca_file = ACE_DEFAULT_SSL_CERT_FILE;
- }
-
- if (ca_dir == 0)
- {
- // Use the default environment settings.
- ca_dir = ACE_OS::getenv (ACE_SSL_CERT_DIR_ENV);
- if (ca_dir == 0)
- ca_dir = ACE_DEFAULT_SSL_CERT_DIR;
- }
-
- // NOTE: SSL_CTX_load_verify_locations() returns 0 on error.
- if (::SSL_CTX_load_verify_locations (this->context_,
- ca_file,
- ca_dir) <= 0)
- {
- if (ACE::debug ())
- ACE_SSL_Context::report_error ();
- return -1;
- }
- else
- {
- ++this->have_ca_;
-
- // for TLS/SSL servers scan all certificates in ca_file and list
- // then as acceptable CAs when requesting a client certificate.
- if (mode_ == SSLv23
- || mode_ == SSLv23_server
- || mode_ == TLSv1
- || mode_ == TLSv1_server
- || mode_ == SSLv3
- || mode_ == SSLv3_server
- || mode_ == SSLv2
- || mode_ == SSLv2_server)
- {
- STACK_OF (X509_NAME) * cert_names;
- cert_names = ::SSL_CTX_get_client_CA_list (this->context_);
-
- if (cert_names == 0)
- {
- // Set the first certificate authorith list.
- cert_names = ::SSL_load_client_CA_file (ca_file);
- if (cert_names != 0 )
- ::SSL_CTX_set_client_CA_list (this->context_,
- cert_names);
- }
- else
- {
- // Add new certificate names to the list.
- if (!::SSL_add_file_cert_subjects_to_stack (cert_names,
- ca_file))
- cert_names = 0;
- }
-
- if (cert_names == 0)
- {
- if (ACE::debug ())
- ACE_SSL_Context::report_error ();
- return -1;
- }
-
- // @todo
- // If warranted do the same for ca_dir when the function
- // SSL_add_dir_cert_subjects_to_stack() is portable to
- // WIN32, VMS, MAC_OS_pre_X (nb. it is not defined for those
- // platforms by OpenSSL).
- }
- }
-
- return 0;
-}
-
-
-int
-ACE_SSL_Context::private_key (const char *file_name,
- int type)
-{
- if (this->private_key_.type () != -1)
- return 0;
-
- this->check_context ();
-
- this->private_key_ = ACE_SSL_Data_File (file_name, type);
-
- if (::SSL_CTX_use_PrivateKey_file (this->context_,
- this->private_key_.file_name (),
- this->private_key_.type ()) <= 0)
- return -1;
- else
- return this->verify_private_key ();
-}
-
-int
-ACE_SSL_Context::verify_private_key (void)
-{
- this->check_context ();
-
- return (::SSL_CTX_check_private_key (this->context_) <= 0 ? -1 : 0);
-}
-
-int
-ACE_SSL_Context::certificate (const char *file_name,
- int type)
-{
- if (this->certificate_.type () != -1)
- return 0;
-
- this->certificate_ = ACE_SSL_Data_File (file_name, type);
-
- this->check_context ();
-
- if (::SSL_CTX_use_certificate_file (this->context_,
- this->certificate_.file_name (),
- this->certificate_.type ()) <= 0)
- return -1;
- else
- return 0;
-}
-
-void
-ACE_SSL_Context::set_verify_peer (int strict, int once, int depth)
-{
- this->check_context ();
-
- // Setup the peer verififcation mode.
-
- int verify_mode = SSL_VERIFY_PEER;
- if (once)
- verify_mode |= SSL_VERIFY_CLIENT_ONCE;
- if (strict)
- verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
-
- // set the default verify mode
- this->default_verify_mode (verify_mode);
-
- // Set the max certificate depth but later let the verify_callback
- // catch the depth error by adding one to the required depth.
- if (depth > 0)
- ::SSL_CTX_set_verify_depth (this->context_, depth + 1);
-}
-
-
-int
-ACE_SSL_Context::random_seed (const char * seed)
-{
- ::RAND_seed (seed, ACE_OS::strlen (seed));
-
-#if OPENSSL_VERSION_NUMBER >= 0x00905100L
- // RAND_status() returns 1 if the PRNG has enough entropy.
- return (::RAND_status () == 1 ? 0 : -1);
-#else
- return 0; // Ugly, but OpenSSL <= 0.9.4 doesn't have RAND_status().
-#endif /* OPENSSL_VERSION_NUMBER >= 0x00905100L */
-}
-
-int
-ACE_SSL_Context::egd_file (const char * socket_file)
-{
-#if OPENSSL_VERSION_NUMBER < 0x00905100L
- // OpenSSL < 0.9.5 doesn't have EGD support.
- ACE_UNUSED_ARG (socket_file);
- ACE_NOTSUP_RETURN (-1);
-#else
- // RAND_egd() returns the amount of entropy used to seed the random
- // number generator. The actually value should be greater than 16,
- // i.e. 128 bits.
- if (::RAND_egd (socket_file) > 0)
- return 0;
- else
- return -1;
-#endif /* OPENSSL_VERSION_NUMBER >= 0x00905100L */
-}
-
-int
-ACE_SSL_Context::seed_file (const char * seed_file, long bytes)
-{
- // RAND_load_file() returns the number of bytes used to seed the
- // random number generator.
- if (::RAND_load_file (seed_file, bytes) > 0)
- return 0;
- else
- return -1;
-}
-
-void
-ACE_SSL_Context::report_error (unsigned long error_code)
-{
- if (error_code == 0)
- return;
-
- char error_string[256];
-
- (void) ::ERR_error_string (error_code, error_string);
-
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("ACE_SSL (%P|%t) error code: %u - %C\n"),
- error_code,
- error_string));
-}
-
-void
-ACE_SSL_Context::report_error (void)
-{
- unsigned long error = ::ERR_get_error ();
- ACE_SSL_Context::report_error (error);
- ACE_OS::last_error (error);
-}
-
-int
-ACE_SSL_Context::dh_params (const char *file_name,
- int type)
-{
- if (this->dh_params_.type () != -1)
- return 0;
-
- this->dh_params_ = ACE_SSL_Data_File (file_name, type);
-
- this->check_context ();
-
- {
- // For now we only support PEM encodings
- if (this->dh_params_.type () != SSL_FILETYPE_PEM)
- return -1;
-
- // Swiped from Rescorla's examples and the OpenSSL s_server.c app
- DH * ret=0;
- BIO * bio = 0;
-
- if ((bio = ::BIO_new_file (this->dh_params_.file_name (), "r")) == NULL)
- return -1;
-
- ret = PEM_read_bio_DHparams (bio, NULL, NULL, NULL);
- BIO_free (bio);
-
- if (ret == 0)
- return -1;
-
- if(::SSL_CTX_set_tmp_dh (this->context_, ret) < 0)
- return -1;
- DH_free (ret);
- }
-
- return 0;
-}
-
-// ****************************************************************
-
-#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
-
-template class ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>;
-
-#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
-
-#pragma instantiate ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>
-
-#elif defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
-
-template ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX> *
- ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::singleton_;
-
-#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
-
-ACE_END_VERSIONED_NAMESPACE_DECL