00001 #include "SSL_Context.h"
00002
00003 #include "sslconf.h"
00004
00005 #if !defined(__ACE_INLINE__)
00006 #include "SSL_Context.inl"
00007 #endif
00008
00009 #include "ace/Guard_T.h"
00010 #include "ace/Object_Manager.h"
00011 #include "ace/Log_Msg.h"
00012 #include "ace/Singleton.h"
00013 #include "ace/Synch_Traits.h"
00014 #include "ace/ACE.h"
00015 #include "ace/OS_NS_errno.h"
00016 #include "ace/OS_NS_string.h"
00017
00018 #ifdef ACE_HAS_THREADS
00019 # include "ace/Thread_Mutex.h"
00020 # include "ace/OS_NS_Thread.h"
00021 #endif
00022
00023 #include <openssl/x509.h>
00024 #include <openssl/err.h>
00025 #include <openssl/rand.h>
00026 #include <openssl/safestack.h>
00027
00028 ACE_RCSID (ACE_SSL,
00029 SSL_Context,
00030 "SSL_Context.cpp,v 1.61 2006/06/22 15:10:08 shuston Exp")
00031
00032
00033 namespace
00034 {
00035
00036
00037 int ssl_library_init_count = 0;
00038
00039
00040
00041
00042 #ifdef ACE_HAS_THREADS
00043
00044
00045 ACE_SSL_Context::lock_type * ssl_locks = 0;
00046
00047
00048 #endif
00049 }
00050
00051 #ifdef ACE_HAS_THREADS
00052
00053 # if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
00054 # define ACE_SSL_LOCKING_CALLBACK_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_SSL_locking_callback)
00055 # define ACE_SSL_THREAD_ID_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_SSL_thread_id)
00056 # else
00057 # define ACE_SSL_LOCKING_CALLBACK_NAME ACE_SSL_locking_callback
00058 # define ACE_SSL_THREAD_ID_NAME ACE_SSL_thread_id
00059 # endif
00060
00061
00062
00063 extern "C"
00064 {
00065 void
00066 ACE_SSL_LOCKING_CALLBACK_NAME (int mode,
00067 int type,
00068 const char * ,
00069 int )
00070 {
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 if (mode & CRYPTO_LOCK)
00084 (void) ssl_locks[type].acquire ();
00085 else
00086 (void) ssl_locks[type].release ();
00087 }
00088
00089
00090
00091
00092
00093 unsigned long
00094 ACE_SSL_THREAD_ID_NAME (void)
00095 {
00096 return (unsigned long) ACE_VERSIONED_NAMESPACE_NAME::ACE_OS::thr_self ();
00097 }
00098 }
00099 #endif
00100
00101
00102
00103
00104 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00105
00106 #ifdef ACE_HAS_THREADS
00107 ACE_SSL_Context::lock_type * ACE_SSL_Context::locks_ = 0;
00108 #endif
00109
00110 ACE_SSL_Context::ACE_SSL_Context (void)
00111 : context_ (0),
00112 mode_ (-1),
00113 default_verify_mode_ (SSL_VERIFY_NONE),
00114 have_ca_ (0)
00115 {
00116 ACE_SSL_Context::ssl_library_init ();
00117 }
00118
00119 ACE_SSL_Context::~ACE_SSL_Context (void)
00120 {
00121 if (this->context_)
00122 {
00123 ::SSL_CTX_free (this->context_);
00124 this->context_ = 0;
00125 }
00126
00127 ACE_SSL_Context::ssl_library_fini ();
00128 }
00129
00130 ACE_SSL_Context *
00131 ACE_SSL_Context::instance (void)
00132 {
00133 return ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::instance ();
00134 }
00135
00136 void
00137 ACE_SSL_Context::ssl_library_init (void)
00138 {
00139 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex,
00140 ace_ssl_mon,
00141 *ACE_Static_Object_Lock::instance ()));
00142
00143 if (ssl_library_init_count == 0)
00144 {
00145
00146
00147 #ifdef ACE_HAS_THREADS
00148 int const num_locks = ::CRYPTO_num_locks ();
00149
00150 this->locks_ = new lock_type[num_locks];
00151 ssl_locks = this->locks_;
00152
00153 # if !defined (WIN32)
00154
00155
00156 ::CRYPTO_set_id_callback (ACE_SSL_THREAD_ID_NAME);
00157 # endif
00158 ::CRYPTO_set_locking_callback (ACE_SSL_LOCKING_CALLBACK_NAME);
00159 #endif
00160
00161 ::SSLeay_add_ssl_algorithms ();
00162 ::SSL_load_error_strings ();
00163
00164
00165
00166
00167
00168 #ifdef WIN32
00169
00170 ::RAND_screen ();
00171 #endif
00172
00173 #if OPENSSL_VERSION_NUMBER >= 0x00905100L
00174
00175
00176 const char *egd_socket_file =
00177 ACE_OS::getenv (ACE_SSL_EGD_FILE_ENV);
00178
00179 if (egd_socket_file != 0)
00180 (void) this->egd_file (egd_socket_file);
00181 #endif
00182
00183 const char *rand_file =
00184 ACE_OS::getenv (ACE_SSL_RAND_FILE_ENV);
00185
00186 if (rand_file != 0)
00187 (void) this->seed_file (rand_file);
00188
00189
00190
00191
00192 }
00193
00194 ++ssl_library_init_count;
00195 }
00196
00197 void
00198 ACE_SSL_Context::ssl_library_fini (void)
00199 {
00200 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex,
00201 ace_ssl_mon,
00202 *ACE_Static_Object_Lock::instance ()));
00203
00204 --ssl_library_init_count;
00205 if (ssl_library_init_count == 0)
00206 {
00207 ::ERR_free_strings ();
00208 ::EVP_cleanup ();
00209
00210
00211
00212 #ifdef ACE_HAS_THREADS
00213 ::CRYPTO_set_locking_callback (0);
00214 ssl_locks = 0;
00215
00216 delete [] this->locks_;
00217 this->locks_ = 0;
00218
00219 #endif
00220 }
00221 }
00222
00223 int
00224 ACE_SSL_Context::set_mode (int mode)
00225 {
00226 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00227 ace_ssl_mon,
00228 *ACE_Static_Object_Lock::instance (),
00229 -1));
00230
00231 if (this->context_ != 0)
00232 return -1;
00233
00234 SSL_METHOD *method = 0;
00235
00236 switch (mode)
00237 {
00238 case ACE_SSL_Context::SSLv2_client:
00239 method = ::SSLv2_client_method ();
00240 break;
00241 case ACE_SSL_Context::SSLv2_server:
00242 method = ::SSLv2_server_method ();
00243 break;
00244 case ACE_SSL_Context::SSLv2:
00245 method = ::SSLv2_method ();
00246 break;
00247 case ACE_SSL_Context::SSLv3_client:
00248 method = ::SSLv3_client_method ();
00249 break;
00250 case ACE_SSL_Context::SSLv3_server:
00251 method = ::SSLv3_server_method ();
00252 break;
00253 case ACE_SSL_Context::SSLv3:
00254 method = ::SSLv3_method ();
00255 break;
00256 case ACE_SSL_Context::SSLv23_client:
00257 method = ::SSLv23_client_method ();
00258 break;
00259 case ACE_SSL_Context::SSLv23_server:
00260 method = ::SSLv23_server_method ();
00261 break;
00262 case ACE_SSL_Context::SSLv23:
00263 method = ::SSLv23_method ();
00264 break;
00265 case ACE_SSL_Context::TLSv1_client:
00266 method = ::TLSv1_client_method ();
00267 break;
00268 case ACE_SSL_Context::TLSv1_server:
00269 method = ::TLSv1_server_method ();
00270 break;
00271 case ACE_SSL_Context::TLSv1:
00272 method = ::TLSv1_method ();
00273 break;
00274 default:
00275 method = ::SSLv3_method ();
00276 break;
00277 }
00278
00279 this->context_ = ::SSL_CTX_new (method);
00280 if (this->context_ == 0)
00281 return -1;
00282
00283 this->mode_ = mode;
00284
00285
00286
00287
00288
00289
00290
00291 (void) this->load_trusted_ca ();
00292
00293 return 0;
00294 }
00295
00296 int
00297 ACE_SSL_Context::load_trusted_ca (const char* ca_file,
00298 const char* ca_dir,
00299 bool use_env_defaults)
00300 {
00301 this->check_context ();
00302
00303 if (ca_file == 0 && use_env_defaults)
00304 {
00305
00306 ca_file = ACE_OS::getenv (ACE_SSL_CERT_FILE_ENV);
00307 if (ca_file == 0)
00308 ca_file = ACE_DEFAULT_SSL_CERT_FILE;
00309 }
00310
00311 if (ca_dir == 0 && use_env_defaults)
00312 {
00313
00314 ca_dir = ACE_OS::getenv (ACE_SSL_CERT_DIR_ENV);
00315 if (ca_dir == 0)
00316 ca_dir = ACE_DEFAULT_SSL_CERT_DIR;
00317 }
00318
00319
00320 if (::SSL_CTX_load_verify_locations (this->context_,
00321 ca_file,
00322 ca_dir) <= 0)
00323 {
00324 if (ACE::debug ())
00325 ACE_SSL_Context::report_error ();
00326 return -1;
00327 }
00328
00329 ++this->have_ca_;
00330
00331
00332
00333 if (mode_ == SSLv23
00334 || mode_ == SSLv23_server
00335 || mode_ == TLSv1
00336 || mode_ == TLSv1_server
00337 || mode_ == SSLv3
00338 || mode_ == SSLv3_server
00339 || mode_ == SSLv2
00340 || mode_ == SSLv2_server)
00341 {
00342
00343
00344
00345 STACK_OF (X509_NAME) * cert_names;
00346 cert_names = ::SSL_CTX_get_client_CA_list (this->context_);
00347 bool error = false;
00348
00349
00350
00351
00352 if (ca_file)
00353 {
00354 if (cert_names == 0)
00355 {
00356 if ((cert_names = ::SSL_load_client_CA_file (ca_file)) != 0)
00357 ::SSL_CTX_set_client_CA_list (this->context_, cert_names);
00358 else
00359 error = true;
00360 }
00361 else
00362 {
00363
00364 error = (0 == ::SSL_add_file_cert_subjects_to_stack (cert_names,
00365 ca_file));
00366 }
00367
00368 if (error)
00369 {
00370 if (ACE::debug ())
00371 ACE_SSL_Context::report_error ();
00372 return -1;
00373 }
00374 }
00375
00376
00377
00378
00379 #if defined (OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090801fL)
00380 # if !defined (OPENSSL_SYS_VMS) && !defined (OPENSSL_SYS_MACINTOSH_CLASSIC)
00381
00382 if (ca_dir != 0)
00383 {
00384 if (cert_names == 0)
00385 {
00386 if ((cert_names = sk_X509_NAME_new_null ()) == 0)
00387 {
00388 if (ACE::debug ())
00389 ACE_SSL_Context::report_error ();
00390 return -1;
00391 }
00392 ::SSL_CTX_set_client_CA_list (this->context_, cert_names);
00393 }
00394 if (0 == ::SSL_add_dir_cert_subjects_to_stack (cert_names, ca_dir))
00395 {
00396 if (ACE::debug ())
00397 ACE_SSL_Context::report_error ();
00398 return -1;
00399 }
00400 }
00401 # endif
00402 #endif
00403
00404 }
00405
00406 return 0;
00407 }
00408
00409
00410 int
00411 ACE_SSL_Context::private_key (const char *file_name,
00412 int type)
00413 {
00414 if (this->private_key_.type () != -1)
00415 return 0;
00416
00417 this->check_context ();
00418
00419 this->private_key_ = ACE_SSL_Data_File (file_name, type);
00420
00421 if (::SSL_CTX_use_PrivateKey_file (this->context_,
00422 this->private_key_.file_name (),
00423 this->private_key_.type ()) <= 0)
00424 {
00425 this->private_key_ = ACE_SSL_Data_File ();
00426 return -1;
00427 }
00428 else
00429 return this->verify_private_key ();
00430 }
00431
00432 int
00433 ACE_SSL_Context::verify_private_key (void)
00434 {
00435 this->check_context ();
00436
00437 return (::SSL_CTX_check_private_key (this->context_) <= 0 ? -1 : 0);
00438 }
00439
00440 int
00441 ACE_SSL_Context::certificate (const char *file_name,
00442 int type)
00443 {
00444 if (this->certificate_.type () != -1)
00445 return 0;
00446
00447 this->certificate_ = ACE_SSL_Data_File (file_name, type);
00448
00449 this->check_context ();
00450
00451 if (::SSL_CTX_use_certificate_file (this->context_,
00452 this->certificate_.file_name (),
00453 this->certificate_.type ()) <= 0)
00454 {
00455 this->certificate_ = ACE_SSL_Data_File ();
00456 return -1;
00457 }
00458 else
00459 return 0;
00460 }
00461
00462 void
00463 ACE_SSL_Context::set_verify_peer (int strict, int once, int depth)
00464 {
00465 this->check_context ();
00466
00467
00468
00469 int verify_mode = SSL_VERIFY_PEER;
00470 if (once)
00471 verify_mode |= SSL_VERIFY_CLIENT_ONCE;
00472 if (strict)
00473 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00474
00475
00476 this->default_verify_mode (verify_mode);
00477
00478
00479
00480 if (depth > 0)
00481 ::SSL_CTX_set_verify_depth (this->context_, depth + 1);
00482 }
00483
00484
00485 int
00486 ACE_SSL_Context::random_seed (const char * seed)
00487 {
00488 ::RAND_seed (seed, ACE_OS::strlen (seed));
00489
00490 #if OPENSSL_VERSION_NUMBER >= 0x00905100L
00491
00492 return (::RAND_status () == 1 ? 0 : -1);
00493 #else
00494 return 0;
00495 #endif
00496 }
00497
00498 int
00499 ACE_SSL_Context::egd_file (const char * socket_file)
00500 {
00501 #if OPENSSL_VERSION_NUMBER < 0x00905100L
00502
00503 ACE_UNUSED_ARG (socket_file);
00504 ACE_NOTSUP_RETURN (-1);
00505 #else
00506
00507
00508
00509 if (::RAND_egd (socket_file) > 0)
00510 return 0;
00511 else
00512 return -1;
00513 #endif
00514 }
00515
00516 int
00517 ACE_SSL_Context::seed_file (const char * seed_file, long bytes)
00518 {
00519
00520
00521
00522 if (::RAND_load_file (seed_file, bytes) > 0)
00523 #if OPENSSL_VERSION_NUMBER >= 0x00905100L
00524
00525 return (::RAND_status () == 1 ? 0 : -1);
00526 #else
00527 return 0;
00528 #endif
00529 else
00530 return -1;
00531 }
00532
00533 void
00534 ACE_SSL_Context::report_error (unsigned long error_code)
00535 {
00536 if (error_code == 0)
00537 return;
00538
00539 char error_string[256];
00540
00541 (void) ::ERR_error_string (error_code, error_string);
00542
00543 ACE_ERROR ((LM_ERROR,
00544 ACE_TEXT ("ACE_SSL (%P|%t) error code: %u - %C\n"),
00545 error_code,
00546 error_string));
00547 }
00548
00549 void
00550 ACE_SSL_Context::report_error (void)
00551 {
00552 unsigned long error = ::ERR_get_error ();
00553 ACE_SSL_Context::report_error (error);
00554 ACE_OS::last_error (error);
00555 }
00556
00557 int
00558 ACE_SSL_Context::dh_params (const char *file_name,
00559 int type)
00560 {
00561 if (this->dh_params_.type () != -1)
00562 return 0;
00563
00564
00565 if (type != SSL_FILETYPE_PEM)
00566 return -1;
00567
00568 this->dh_params_ = ACE_SSL_Data_File (file_name, type);
00569
00570 this->check_context ();
00571
00572 {
00573
00574 DH * ret=0;
00575 BIO * bio = 0;
00576
00577 if ((bio = ::BIO_new_file (this->dh_params_.file_name (), "r")) == NULL)
00578 {
00579 this->dh_params_ = ACE_SSL_Data_File ();
00580 return -1;
00581 }
00582
00583 ret = PEM_read_bio_DHparams (bio, NULL, NULL, NULL);
00584 BIO_free (bio);
00585
00586 if (ret == 0)
00587 {
00588 this->dh_params_ = ACE_SSL_Data_File ();
00589 return -1;
00590 }
00591
00592 if (::SSL_CTX_set_tmp_dh (this->context_, ret) < 0)
00593 {
00594 this->dh_params_ = ACE_SSL_Data_File ();
00595 return -1;
00596 }
00597 DH_free (ret);
00598 }
00599
00600 return 0;
00601 }
00602
00603
00604
00605 #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
00606
00607 template ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX> *
00608 ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::singleton_;
00609
00610 #endif
00611
00612 ACE_END_VERSIONED_NAMESPACE_DECL