Document return values
[ACE_TAO.git] / ACE / ace / SSL / SSL_Context.cpp
blob9313dc5717f9b49317ca0bd7b438ca6079831dda
1 #include "SSL_Context.h"
3 #include "sslconf.h"
5 #if !defined(__ACE_INLINE__)
6 #include "SSL_Context.inl"
7 #endif /* __ACE_INLINE__ */
9 #include "ace/Guard_T.h"
10 #include "ace/Object_Manager.h"
11 #include "ace/Log_Category.h"
12 #include "ace/Singleton.h"
13 #include "ace/Synch_Traits.h"
14 #include "ace/Truncate.h"
15 #include "ace/ACE.h"
16 #include "ace/INET_Addr.h"
17 #include "ace/OS_NS_errno.h"
18 #include "ace/OS_NS_string.h"
19 #include "ace/OS_NS_ctype.h"
20 #include "ace/OS_NS_netdb.h"
22 #ifdef ACE_HAS_THREADS
23 # include "ace/Thread_Mutex.h"
24 # include "ace/OS_NS_Thread.h"
25 #endif /* ACE_HAS_THREADS */
27 #include <openssl/x509.h>
28 #include <openssl/x509v3.h>
29 #include <openssl/err.h>
30 #include <openssl/rand.h>
31 #include <openssl/safestack.h>
33 namespace
35 /// Reference count of the number of times the ACE_SSL_Context was
36 /// initialized.
37 int ssl_library_init_count = 0;
39 // @@ This should also be done with a singleton, otherwise it is not
40 // thread safe and/or portable to some weird platforms...
42 #if defined(ACE_HAS_THREADS) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
43 /// Array of mutexes used internally by OpenSSL when the SSL
44 /// application is multithreaded.
45 ACE_SSL_Context::lock_type * ssl_locks = 0;
47 // @@ This should also be managed by a singleton.
48 #endif /* ACE_HAS_THREADS && OPENSSL_VERSION_NUMBER < 0x10100000L */
51 #if defined (ACE_HAS_THREADS) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
53 # if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
54 # define ACE_SSL_LOCKING_CALLBACK_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_SSL_locking_callback)
55 # define ACE_SSL_THREAD_ID_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ACE_SSL_thread_id)
56 # else
57 # define ACE_SSL_LOCKING_CALLBACK_NAME ACE_SSL_locking_callback
58 # define ACE_SSL_THREAD_ID_NAME ACE_SSL_thread_id
59 # endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */
61 extern "C"
63 void
64 ACE_SSL_LOCKING_CALLBACK_NAME (int mode,
65 int type,
66 const char * /* file */,
67 int /* line */)
69 // #ifdef undef
70 // fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
71 // CRYPTO_thread_id(),
72 // (mode&CRYPTO_LOCK)?"l":"u",
73 // (type&CRYPTO_READ)?"r":"w",file,line);
74 // #endif
75 // /*
76 // if (CRYPTO_LOCK_SSL_CERT == type)
77 // fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
78 // CRYPTO_thread_id(),
79 // mode,file,line);
80 // */
81 if (mode & CRYPTO_LOCK)
82 (void) ssl_locks[type].acquire ();
83 else
84 (void) ssl_locks[type].release ();
87 // -------------------------------
89 // Return the current thread ID. OpenSSL uses this on platforms
90 // that need it.
91 unsigned long
92 ACE_SSL_THREAD_ID_NAME ()
94 return (unsigned long) ACE_VERSIONED_NAMESPACE_NAME::ACE_OS::thr_self ();
97 #endif /* ACE_HAS_THREADS && (OPENSSL_VERSION_NUMBER < 0x10100000L) */
100 // ****************************************************************
102 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
104 #if defined (ACE_HAS_THREADS) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
105 ACE_SSL_Context::lock_type * ACE_SSL_Context::locks_ = 0;
106 #endif /* ACE_HAS_THREADS && (OPENSSL_VERSION_NUMBER < 0x10100000L) */
108 ACE_SSL_Context::ACE_SSL_Context ()
109 : context_ (0),
110 mode_ (-1),
111 default_verify_mode_ (SSL_VERIFY_NONE),
112 default_verify_callback_ (0),
113 have_ca_ (0)
115 ACE_TRACE ("ACE_SSL_Context::ACE_SSL_Context");
117 ACE_SSL_Context::ssl_library_init ();
120 ACE_SSL_Context::~ACE_SSL_Context ()
122 ACE_TRACE ("ACE_SSL_Context::~ACE_SSL_Context");
124 if (this->context_)
126 ::SSL_CTX_free (this->context_);
127 this->context_ = 0;
130 ACE_SSL_Context::ssl_library_fini ();
133 ACE_SSL_Context *
134 ACE_SSL_Context::instance ()
136 ACE_TRACE ("ACE_SSL_Context::instance");
138 return ACE_Unmanaged_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::instance ();
141 void
142 ACE_SSL_Context::close ()
144 ACE_TRACE ("ACE_SSL_Context::close");
146 ACE_Unmanaged_Singleton<ACE_SSL_Context, ACE_SYNCH_MUTEX>::close ();
149 void
150 ACE_SSL_Context::ssl_library_init ()
152 ACE_TRACE ("ACE_SSL_Context::ssl_library_init");
154 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex,
155 ace_ssl_mon,
156 *ACE_Static_Object_Lock::instance ()));
158 if (ssl_library_init_count == 0)
160 // Initialize the locking callbacks before initializing anything
161 // else.
162 #if defined(ACE_HAS_THREADS) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
163 int const num_locks = ::CRYPTO_num_locks ();
165 this->locks_ = new lock_type[num_locks];
166 ssl_locks = this->locks_;
168 # if !defined (WIN32)
169 // This call isn't necessary on some platforms. See the CRYPTO
170 // library's threads(3) man page for details.
171 ::CRYPTO_set_id_callback (ACE_SSL_THREAD_ID_NAME);
172 # endif /* !WIN32 */
173 ::CRYPTO_set_locking_callback (ACE_SSL_LOCKING_CALLBACK_NAME);
174 #endif /* ACE_HAS_THREADS && OPENSSL_VERSION_NUMBER < 0x10100000L */
176 ::SSLeay_add_ssl_algorithms ();
177 ::SSL_load_error_strings ();
179 // Seed the random number generator. Note that the random
180 // number generator can be seeded more than once to "stir" its
181 // state.
183 #ifdef WIN32
184 // Seed the random number generator by sampling the screen.
185 # if OPENSSL_VERSION_NUMBER < 0x10100000L
186 ::RAND_screen ();
187 # else
188 ::RAND_poll ();
189 # endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
190 #endif /* WIN32 */
192 #if OPENSSL_VERSION_NUMBER >= 0x00905100L
193 // OpenSSL < 0.9.5 doesn't have EGD support.
195 const char *egd_socket_file =
196 ACE_OS::getenv (ACE_SSL_EGD_FILE_ENV);
198 if (egd_socket_file != 0)
199 (void) this->egd_file (egd_socket_file);
200 #endif /* OPENSSL_VERSION_NUMBER */
202 const char *rand_file = ACE_OS::getenv (ACE_SSL_RAND_FILE_ENV);
204 if (rand_file != 0)
206 (void) this->seed_file (rand_file);
209 // Initialize the mutexes that will be used by the SSL and
210 // crypto library.
213 ++ssl_library_init_count;
216 void
217 ACE_SSL_Context::ssl_library_fini ()
219 ACE_TRACE ("ACE_SSL_Context::ssl_library_fini");
221 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex,
222 ace_ssl_mon,
223 *ACE_Static_Object_Lock::instance ()));
225 --ssl_library_init_count;
226 if (ssl_library_init_count == 0)
228 #if OPENSSL_VERSION_NUMBER < 0x10100000L
229 ::ERR_free_strings ();
230 ::EVP_cleanup ();
232 // Clean up the locking callbacks after everything else has been
233 // cleaned up.
234 #ifdef ACE_HAS_THREADS
235 ::CRYPTO_set_locking_callback (0);
236 ssl_locks = 0;
238 delete [] this->locks_;
239 this->locks_ = 0;
240 #endif /* ACE_HAS_THREADS && */
241 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
246 ACE_SSL_Context::set_mode (int mode)
248 ACE_TRACE ("ACE_SSL_Context::set_mode");
250 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
251 ace_ssl_mon,
252 *ACE_Static_Object_Lock::instance (),
253 -1));
255 if (this->context_ != 0)
256 return -1;
258 #if OPENSSL_VERSION_NUMBER >= 0x10000002
259 const SSL_METHOD *method = 0;
260 #else
261 SSL_METHOD *method = 0;
262 #endif
264 switch (mode)
266 case ACE_SSL_Context::SSLv23_client:
267 method = ::SSLv23_client_method ();
268 break;
269 case ACE_SSL_Context::SSLv23_server:
270 method = ::SSLv23_server_method ();
271 break;
272 case ACE_SSL_Context::SSLv23:
273 method = ::SSLv23_method ();
274 break;
275 default:
276 method = ::SSLv23_method ();
277 break;
280 this->context_ = ::SSL_CTX_new (method);
281 if (this->context_ == 0)
282 return -1;
284 this->mode_ = mode;
286 // Load the trusted certificate authority (default) certificate
287 // locations. But do not return -1 on error, doing so confuses CTX
288 // allocation (severe error) with the less important loading of CA
289 // certificate location error. If it is important for your
290 // application then call ACE_SSL_Context::have_trusted_ca(),
291 // immediately following this call to set_mode().
292 (void) this->load_trusted_ca ();
294 return 0;
298 ACE_SSL_Context::filter_versions (const char* versionlist)
300 ACE_TRACE ("ACE_SSL_Context::filter_versions");
302 this->check_context ();
304 ACE_CString vlist = versionlist;
305 ACE_CString seplist = " ,;";
306 ACE_CString::size_type pos = 0;
307 bool match = false;
309 for (; pos < vlist.length (); pos++)
311 vlist[pos] = ACE_OS::ace_tolower (vlist[pos]);
314 #if defined (SSL_OP_NO_SSLv2)
315 pos = vlist.find("sslv2");
316 match = pos != ACE_CString::npos &&
317 (pos == vlist.length () - 5 ||
318 seplist.find (vlist[pos + 5]) != ACE_CString::npos);
319 if (!match)
321 ::SSL_CTX_set_options (this->context_, SSL_OP_NO_SSLv2);
323 #endif /* SSL_OP_NO_SSLv2 */
325 #if defined (SSL_OP_NO_SSLv3)
326 pos = vlist.find("sslv3");
327 match = pos != ACE_CString::npos &&
328 (pos == vlist.length () - 5 ||
329 seplist.find (vlist[pos + 5]) != ACE_CString::npos);
330 if (!match)
332 ::SSL_CTX_set_options (this->context_, SSL_OP_NO_SSLv3);
334 #endif /* SSL_OP_NO_SSLv3 */
336 #if defined (SSL_OP_NO_TLSv1)
337 pos = vlist.find("tlsv1");
338 match = pos != ACE_CString::npos &&
339 (pos == vlist.length () - 5 ||
340 seplist.find (vlist[pos + 5]) != ACE_CString::npos);
341 if (!match)
343 ::SSL_CTX_set_options (this->context_, SSL_OP_NO_TLSv1);
345 #endif /* SSL_OP_NO_TLSv1 */
347 #if defined (SSL_OP_NO_TLSv1_1)
348 pos = vlist.find("tlsv1.1");
349 match = pos != ACE_CString::npos &&
350 (pos == vlist.length () - 7 ||
351 seplist.find (vlist[pos + 7]) != ACE_CString::npos);
352 if (!match)
354 ::SSL_CTX_set_options (this->context_, SSL_OP_NO_TLSv1_1);
356 #endif /* SSL_OP_NO_TLSv1_1 */
358 #if defined (SSL_OP_NO_TLSv1_2)
359 pos = vlist.find("tlsv1.2");
360 match = pos != ACE_CString::npos &&
361 (pos == vlist.length () - 7 ||
362 seplist.find (vlist[pos + 7]) != ACE_CString::npos);
363 if (!match)
365 ::SSL_CTX_set_options (this->context_, SSL_OP_NO_TLSv1_2);
367 #endif /* SSL_OP_NO_TLSv1_2 */
369 #if defined (SSL_OP_NO_TLSv1_3)
370 pos = vlist.find("tlsv1.3");
371 match = pos != ACE_CString::npos &&
372 (pos == vlist.length() - 7 ||
373 seplist.find(vlist[pos + 7]) != ACE_CString::npos);
374 if (!match)
376 ::SSL_CTX_set_options(this->context_, SSL_OP_NO_TLSv1_3);
378 #endif /* SSL_OP_NO_TLSv1_3 */
379 return 0;
382 bool
383 ACE_SSL_Context::check_host (const ACE_INET_Addr &host, SSL *peerssl)
385 ACE_TRACE ("ACE_SSL_Context::check_host");
387 #if defined (OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10002001L)
389 this->check_context ();
391 char name[MAXHOSTNAMELEN+1];
393 if (peerssl == 0 || host.get_host_name (name, MAXHOSTNAMELEN) == -1)
395 return false;
398 #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
399 X509* cert = ::SSL_get1_peer_certificate(peerssl);
400 #else
401 X509* cert = ::SSL_get_peer_certificate(peerssl);
402 #endif
404 if (cert == 0)
406 return false;
409 char *peer = 0;
410 char **peerarg = ACE::debug () ? &peer : 0;
411 int const flags = X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT;
412 size_t const len = ACE_OS::strlen (name);
414 int const result = ::X509_check_host (cert, name, len, flags, peerarg);
416 if (ACE::debug ())
418 ACELIB_DEBUG ((LM_DEBUG,
419 ACE_TEXT ("ACE (%P|%t) SSL_Context::check_host ")
420 ACE_TEXT ("name <%C> returns %d, peer <%C>\n"),
421 name, result, peer));
423 if (peer != 0)
425 ::OPENSSL_free (peer);
428 ::X509_free (cert);
430 return result == 1;
431 #else
432 ACE_UNUSED_ARG (host);
433 ACE_UNUSED_ARG (peerssl);
435 return false;
436 #endif /* OPENSSL_VERSION_NUMBER */
440 ACE_SSL_Context::load_trusted_ca (const char* ca_file,
441 const char* ca_dir,
442 bool use_env_defaults)
444 ACE_TRACE ("ACE_SSL_Context::load_trusted_ca");
446 this->check_context ();
448 if (ca_file == 0 && use_env_defaults)
450 // Use the default environment settings.
451 ca_file = ACE_OS::getenv (ACE_SSL_CERT_FILE_ENV);
452 #ifdef ACE_DEFAULT_SSL_CERT_FILE
453 if (ca_file == 0)
454 ca_file = ACE_DEFAULT_SSL_CERT_FILE;
455 #endif
458 if (ca_dir == 0 && use_env_defaults)
460 // Use the default environment settings.
461 ca_dir = ACE_OS::getenv (ACE_SSL_CERT_DIR_ENV);
462 #ifdef ACE_DEFAULT_SSL_CERT_DIR
463 if (ca_dir == 0)
464 ca_dir = ACE_DEFAULT_SSL_CERT_DIR;
465 #endif
468 // NOTE: SSL_CTX_load_verify_locations() returns 0 on error.
469 if (::SSL_CTX_load_verify_locations (this->context_,
470 ca_file,
471 ca_dir) <= 0)
473 if (ACE::debug ())
474 ACE_SSL_Context::report_error ();
475 return -1;
478 ++this->have_ca_;
480 // For TLS/SSL servers scan all certificates in ca_file and ca_dir and
481 // list them as acceptable CAs when requesting a client certificate.
482 if (mode_ == SSLv23 || mode_ == SSLv23_server)
484 // Note: The STACK_OF(X509_NAME) pointer is a copy of the pointer in
485 // the CTX; any changes to it by way of these function calls will
486 // change the CTX directly.
487 STACK_OF (X509_NAME) * cert_names = 0;
488 cert_names = ::SSL_CTX_get_client_CA_list (this->context_);
490 // Add CAs from both the file and dir, if specified. There should
491 // already be a STACK_OF(X509_NAME) in the CTX, but if not, we create
492 // one.
493 if (ca_file)
495 bool error = false;
496 if (cert_names == 0)
498 if ((cert_names = ::SSL_load_client_CA_file (ca_file)) != 0)
499 ::SSL_CTX_set_client_CA_list (this->context_, cert_names);
500 else
501 error = true;
503 else
505 // Add new certificate names to the list.
506 error = (0 == ::SSL_add_file_cert_subjects_to_stack (cert_names,
507 ca_file));
510 if (error)
512 if (ACE::debug ())
513 ACE_SSL_Context::report_error ();
514 return -1;
518 // SSL_add_dir_cert_subjects_to_stack is defined at 0.9.8a (but not
519 // on Mac Classic); it may be available earlier. Change
520 // this comparison if so. It's still (1.0.1g) broken on windows too.
521 #if defined (OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090801fL)
522 # if !defined (OPENSSL_SYS_MACINTOSH_CLASSIC)
523 # if !defined (OPENSSL_SYS_WIN32)
525 if (ca_dir != 0)
527 if (cert_names == 0)
529 if ((cert_names = sk_X509_NAME_new_null ()) == 0)
531 if (ACE::debug ())
532 ACE_SSL_Context::report_error ();
533 return -1;
535 ::SSL_CTX_set_client_CA_list (this->context_, cert_names);
537 if (0 == ::SSL_add_dir_cert_subjects_to_stack (cert_names, ca_dir))
539 if (ACE::debug ())
540 ACE_SSL_Context::report_error ();
541 return -1;
544 # endif /* !OPENSSL_SYS_WIN32 */
545 # endif /* !OPENSSL_SYS_MACINTOSH_CLASSIC */
546 #endif /* OPENSSL_VERSION_NUMBER >= 0.9.8a release */
550 return 0;
554 ACE_SSL_Context::private_key (const char *file_name,
555 int type)
557 ACE_TRACE ("ACE_SSL_Context::private_key");
559 if (this->private_key_.type () != -1)
560 return 0;
562 this->check_context ();
564 this->private_key_ = ACE_SSL_Data_File (file_name, type);
566 if (::SSL_CTX_use_PrivateKey_file (this->context_,
567 this->private_key_.file_name (),
568 this->private_key_.type ()) <= 0)
570 this->private_key_ = ACE_SSL_Data_File ();
571 return -1;
573 else
574 return this->verify_private_key ();
578 ACE_SSL_Context::verify_private_key ()
580 ACE_TRACE ("ACE_SSL_Context::verify_private_key");
582 this->check_context ();
584 return (::SSL_CTX_check_private_key (this->context_) <= 0 ? -1 : 0);
588 ACE_SSL_Context::certificate (const char *file_name,
589 int type)
591 ACE_TRACE ("ACE_SSL_Context::certificate:file_name:type");
593 if (this->certificate_.type () != -1)
594 return 0;
596 this->certificate_ = ACE_SSL_Data_File (file_name, type);
598 this->check_context ();
600 if (::SSL_CTX_use_certificate_file (this->context_,
601 this->certificate_.file_name (),
602 this->certificate_.type ()) <= 0)
604 this->certificate_ = ACE_SSL_Data_File ();
605 return -1;
607 else
608 return 0;
612 ACE_SSL_Context::certificate (X509* cert)
614 ACE_TRACE ("ACE_SSL_Context::certificate:cert");
616 // Is it really a good idea to return 0 if we're not setting the
617 // certificate?
618 if (this->certificate_.type () != -1)
619 return 0;
621 this->check_context();
623 if (::SSL_CTX_use_certificate (this->context_, cert) <= 0)
625 return -1;
627 else
629 // No file is associated with the certificate, set this to a fictional
630 // value so we don't reset it later.
631 this->certificate_ = ACE_SSL_Data_File ("MEMORY CERTIFICATE");
633 return 0;
638 ACE_SSL_Context::certificate_chain (const char *file_name, int type)
640 ACE_TRACE ("ACE_SSL_Context::certificate_chain:file_name");
642 this->certificate_ = ACE_SSL_Data_File (file_name, type);
644 this->check_context ();
646 if (::SSL_CTX_use_certificate_chain_file (this->context_,
647 this->certificate_.file_name ()) <= 0)
649 return -1;
651 else
652 return 0;
655 void
656 ACE_SSL_Context::set_verify_peer (int strict, int once, int depth)
658 ACE_TRACE ("ACE_SSL_Context::set_verify_peer");
660 this->check_context ();
662 // Setup the peer verification mode.
663 int verify_mode = SSL_VERIFY_PEER;
664 if (once)
665 verify_mode |= SSL_VERIFY_CLIENT_ONCE;
666 if (strict)
667 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
669 // set the default verify mode
670 this->default_verify_mode (verify_mode);
672 // Set the max certificate depth but later let the verify_callback
673 // catch the depth error by adding one to the required depth.
674 if (depth > 0)
675 ::SSL_CTX_set_verify_depth (this->context_, depth + 1);
679 ACE_SSL_Context::random_seed (const char * seed)
681 ACE_TRACE ("ACE_SSL_Context::random_seed");
683 int len = ACE_Utils::truncate_cast<int> (ACE_OS::strlen (seed));
684 ::RAND_seed (seed, len);
686 #if OPENSSL_VERSION_NUMBER >= 0x00905100L
687 // RAND_status() returns 1 if the PRNG has enough entropy.
688 return (::RAND_status () == 1 ? 0 : -1);
689 #else
690 return 0; // Ugly, but OpenSSL <= 0.9.4 doesn't have RAND_status().
691 #endif /* OPENSSL_VERSION_NUMBER >= 0x00905100L */
695 ACE_SSL_Context::egd_file (const char * socket_file)
697 ACE_TRACE ("ACE_SSL_Context::egd_file");
699 #if OPENSSL_VERSION_NUMBER < 0x00905100L || defined (OPENSSL_NO_EGD)
700 // OpenSSL < 0.9.5 doesn't have EGD support. OpenSSL 1.1 and newer
701 // disable egd by default
702 ACE_UNUSED_ARG (socket_file);
703 ACE_NOTSUP_RETURN (-1);
704 #else
705 // RAND_egd() returns the amount of entropy used to seed the random
706 // number generator. The actual value should be greater than 16,
707 // i.e. 128 bits.
708 if (::RAND_egd (socket_file) > 0)
709 return 0;
710 else
711 return -1;
712 #endif /* OPENSSL_VERSION_NUMBER < 0x00905100L */
716 ACE_SSL_Context::seed_file (const char * seed_file, long bytes)
718 ACE_TRACE ("ACE_SSL_Context::seed_file");
720 // RAND_load_file() returns the number of bytes used to seed the
721 // random number generator. If the file reads ok, check RAND_status to
722 // see if it got enough entropy.
723 if (::RAND_load_file (seed_file, bytes) > 0)
724 #if OPENSSL_VERSION_NUMBER >= 0x00905100L
725 // RAND_status() returns 1 if the PRNG has enough entropy.
726 return (::RAND_status () == 1 ? 0 : -1);
727 #else
728 return 0; // Ugly, but OpenSSL <= 0.9.4 doesn't have RAND_status().
729 #endif /* OPENSSL_VERSION_NUMBER >= 0x00905100L */
730 else
731 return -1;
734 void
735 ACE_SSL_Context::report_error (unsigned long error_code)
737 ACE_TRACE ("ACE_SSL_Context::report_error:error_code");
739 if (error_code != 0)
741 char error_string[256];
743 // OpenSSL < 0.9.6a doesn't have ERR_error_string_n() function.
744 #if OPENSSL_VERSION_NUMBER >= 0x0090601fL
745 (void) ::ERR_error_string_n (error_code, error_string, sizeof error_string);
746 #else /* OPENSSL_VERSION_NUMBER >= 0x0090601fL */
747 (void) ::ERR_error_string (error_code, error_string);
748 #endif /* OPENSSL_VERSION_NUMBER >= 0x0090601fL */
750 ACELIB_ERROR ((LM_ERROR,
751 ACE_TEXT ("ACE_SSL (%P|%t) error code: %u - %C\n"),
752 error_code,
753 error_string));
757 void
758 ACE_SSL_Context::report_error ()
760 ACE_TRACE ("ACE_SSL_Context::report_error");
762 unsigned long const err = ::ERR_get_error ();
763 ACE_SSL_Context::report_error (err);
764 ACE_OS::last_error (err);
768 ACE_SSL_Context::dh_params (const char *file_name,
769 int type)
771 ACE_TRACE ("ACE_SSL_Context::dh_params");
773 if (this->dh_params_.type () != -1)
774 return 0;
776 // For now we only support PEM encodings
777 if (type != SSL_FILETYPE_PEM)
778 return -1;
780 this->dh_params_ = ACE_SSL_Data_File (file_name, type);
782 this->check_context ();
785 // Swiped from Rescorla's examples and the OpenSSL s_server.c app
786 DH * ret = nullptr;
787 BIO * bio = nullptr;
789 if ((bio = ::BIO_new_file (this->dh_params_.file_name (), "r")) == 0)
791 this->dh_params_ = ACE_SSL_Data_File ();
792 return -1;
795 ret = PEM_read_bio_DHparams (bio, 0, 0, 0);
796 BIO_free (bio);
798 if (ret == 0)
800 this->dh_params_ = ACE_SSL_Data_File ();
801 return -1;
804 if (::SSL_CTX_set_tmp_dh (this->context_, ret) < 0)
806 this->dh_params_ = ACE_SSL_Data_File ();
807 return -1;
809 DH_free (ret);
812 return 0;
815 // ****************************************************************
816 ACE_SINGLETON_TEMPLATE_INSTANTIATE(ACE_Unmanaged_Singleton, ACE_SSL_Context, ACE_SYNCH_MUTEX)
818 ACE_END_VERSIONED_NAMESPACE_DECL