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 "$Id: SSL_Context.cpp 78902 2007-07-15 13:11:08Z sowayaa $")
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 int
00463 ACE_SSL_Context::certificate (X509* cert)
00464 {
00465
00466
00467 if (this->certificate_.type () != -1)
00468 return 0;
00469
00470 this->check_context();
00471
00472 if (::SSL_CTX_use_certificate (this->context_, cert) <= 0)
00473 {
00474 return -1;
00475 }
00476 else
00477 {
00478
00479
00480 this->certificate_ = ACE_SSL_Data_File ("MEMORY CERTIFICATE");
00481
00482 return 0;
00483 }
00484 }
00485
00486 void
00487 ACE_SSL_Context::set_verify_peer (int strict, int once, int depth)
00488 {
00489 this->check_context ();
00490
00491
00492
00493 int verify_mode = SSL_VERIFY_PEER;
00494 if (once)
00495 verify_mode |= SSL_VERIFY_CLIENT_ONCE;
00496 if (strict)
00497 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00498
00499
00500 this->default_verify_mode (verify_mode);
00501
00502
00503
00504 if (depth > 0)
00505 ::SSL_CTX_set_verify_depth (this->context_, depth + 1);
00506 }
00507
00508
00509 int
00510 ACE_SSL_Context::random_seed (const char * seed)
00511 {
00512 ::RAND_seed (seed, ACE_OS::strlen (seed));
00513
00514 #if OPENSSL_VERSION_NUMBER >= 0x00905100L
00515
00516 return (::RAND_status () == 1 ? 0 : -1);
00517 #else
00518 return 0;
00519 #endif
00520 }
00521
00522 int
00523 ACE_SSL_Context::egd_file (const char * socket_file)
00524 {
00525 #if OPENSSL_VERSION_NUMBER < 0x00905100L
00526
00527 ACE_UNUSED_ARG (socket_file);
00528 ACE_NOTSUP_RETURN (-1);
00529 #else
00530
00531
00532
00533 if (::RAND_egd (socket_file) > 0)
00534 return 0;
00535 else
00536 return -1;
00537 #endif
00538 }
00539
00540 int
00541 ACE_SSL_Context::seed_file (const char * seed_file, long bytes)
00542 {
00543
00544
00545
00546 if (::RAND_load_file (seed_file, bytes) > 0)
00547 #if OPENSSL_VERSION_NUMBER >= 0x00905100L
00548
00549 return (::RAND_status () == 1 ? 0 : -1);
00550 #else
00551 return 0;
00552 #endif
00553 else
00554 return -1;
00555 }
00556
00557 void
00558 ACE_SSL_Context::report_error (unsigned long error_code)
00559 {
00560 if (error_code == 0)
00561 return;
00562
00563 char error_string[256];
00564
00565 (void) ::ERR_error_string (error_code, error_string);
00566
00567 ACE_ERROR ((LM_ERROR,
00568 ACE_TEXT ("ACE_SSL (%P|%t) error code: %u - %C\n"),
00569 error_code,
00570 error_string));
00571 }
00572
00573 void
00574 ACE_SSL_Context::report_error (void)
00575 {
00576 unsigned long err = ::ERR_get_error ();
00577 ACE_SSL_Context::report_error (err);
00578 ACE_OS::last_error (err);
00579 }
00580
00581 int
00582 ACE_SSL_Context::dh_params (const char *file_name,
00583 int type)
00584 {
00585 if (this->dh_params_.type () != -1)
00586 return 0;
00587
00588
00589 if (type != SSL_FILETYPE_PEM)
00590 return -1;
00591
00592 this->dh_params_ = ACE_SSL_Data_File (file_name, type);
00593
00594 this->check_context ();
00595
00596 {
00597
00598 DH * ret=0;
00599 BIO * bio = 0;
00600
00601 if ((bio = ::BIO_new_file (this->dh_params_.file_name (), "r")) == 0)
00602 {
00603 this->dh_params_ = ACE_SSL_Data_File ();
00604 return -1;
00605 }
00606
00607 ret = PEM_read_bio_DHparams (bio, 0, 0, 0);
00608 BIO_free (bio);
00609
00610 if (ret == 0)
00611 {
00612 this->dh_params_ = ACE_SSL_Data_File ();
00613 return -1;
00614 }
00615
00616 if (::SSL_CTX_set_tmp_dh (this->context_, ret) < 0)
00617 {
00618 this->dh_params_ = ACE_SSL_Data_File ();
00619 return -1;
00620 }
00621 DH_free (ret);
00622 }
00623
00624 return 0;
00625 }
00626
00627
00628
00629 #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
00630
00631 template ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX> *
00632 ACE_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::singleton_;
00633
00634 #endif
00635
00636 ACE_END_VERSIONED_NAMESPACE_DECL