00001
00002
00003 #include "orbsvcs/SSLIOP/SSLIOP_CredentialsAcquirer.h"
00004 #include "orbsvcs/SSLIOP/SSLIOP_OwnCredentials.h"
00005
00006 #include "tao/debug.h"
00007 #include "tao/ORB_Constants.h"
00008
00009 #include "ace/SSL/SSL_Context.h"
00010
00011 #include "ace/OS_NS_stdio.h"
00012
00013 #include <openssl/x509.h>
00014 #include <openssl/pem.h>
00015
00016
00017 ACE_RCSID (SSLIOP,
00018 SSLIOP_CredentialsAcquirer,
00019 "SSLIOP_CredentialsAcquirer.cpp,v 1.5 2006/04/19 13:17:39 jwillemsen Exp")
00020
00021
00022
00023
00024 #if (defined (TAO_HAS_VERSIONED_NAMESPACE) && TAO_HAS_VERSIONED_NAMESPACE == 1)
00025 # define TAO_SSLIOP_PASSWORD_CALLBACK_NAME ACE_PREPROC_CONCATENATE(TAO_VERSIONED_NAMESPACE_NAME, _TAO_SSLIOP_password_callback)
00026 #else
00027 # define TAO_SSLIOP_PASSWORD_CALLBACK_NAME TAO_SSLIOP_password_callback
00028 #endif
00029
00030
00031 extern "C"
00032 int
00033 TAO_SSLIOP_PASSWORD_CALLBACK_NAME (char *buf,
00034 int size,
00035 int ,
00036 void *userdata)
00037 {
00038
00039
00040
00041
00042 const char * password = static_cast<char *> (userdata);
00043
00044 int pwlen = -1;
00045
00046 if (password != 0)
00047 {
00048 pwlen = ACE_OS::strlen (password);
00049
00050 int copy_len = pwlen + 1;
00051
00052
00053
00054 if (copy_len < size)
00055 ACE_OS::memset (buf + copy_len, 0, size - copy_len);
00056
00057
00058
00059 copy_len = (copy_len > size) ? size : copy_len;
00060
00061 ACE_OS::memcpy (buf, password, copy_len);
00062
00063
00064 if (copy_len > size)
00065 {
00066 pwlen = size - 1;
00067 buf[pwlen] = '\0';
00068 }
00069 }
00070
00071 return pwlen;
00072 }
00073
00074
00075
00076 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00077
00078 TAO::SSLIOP::CredentialsAcquirer::CredentialsAcquirer (
00079 TAO::SL3::CredentialsCurator_ptr curator,
00080 const CORBA::Any & acquisition_arguments)
00081 : lock_ (),
00082 curator_ (TAO::SL3::CredentialsCurator::_duplicate (curator)),
00083 acquisition_arguments_ (acquisition_arguments),
00084 destroyed_ (false)
00085 {
00086 }
00087
00088 TAO::SSLIOP::CredentialsAcquirer::~CredentialsAcquirer (void)
00089 {
00090 }
00091
00092 char *
00093 TAO::SSLIOP::CredentialsAcquirer::acquisition_method (ACE_ENV_SINGLE_ARG_DECL)
00094 ACE_THROW_SPEC ((CORBA::SystemException))
00095 {
00096 this->check_validity (ACE_ENV_SINGLE_ARG_PARAMETER);
00097 ACE_CHECK_RETURN (0);
00098
00099 return CORBA::string_dup ("SL3TLS");
00100 }
00101
00102 SecurityLevel3::AcquisitionStatus
00103 TAO::SSLIOP::CredentialsAcquirer::current_status (ACE_ENV_SINGLE_ARG_DECL)
00104 ACE_THROW_SPEC ((CORBA::SystemException))
00105 {
00106 this->check_validity (ACE_ENV_SINGLE_ARG_PARAMETER);
00107 ACE_CHECK_RETURN (SecurityLevel3::AQST_Failed);
00108
00109 return SecurityLevel3::AQST_Succeeded;
00110 }
00111
00112 CORBA::ULong
00113 TAO::SSLIOP::CredentialsAcquirer::nth_iteration (ACE_ENV_SINGLE_ARG_DECL)
00114 ACE_THROW_SPEC ((CORBA::SystemException))
00115 {
00116 this->check_validity (ACE_ENV_SINGLE_ARG_PARAMETER);
00117 ACE_CHECK_RETURN (0);
00118
00119
00120
00121 return 1;
00122 }
00123
00124 CORBA::Any *
00125 TAO::SSLIOP::CredentialsAcquirer::get_continuation_data (
00126 ACE_ENV_SINGLE_ARG_DECL)
00127 ACE_THROW_SPEC ((CORBA::SystemException))
00128 {
00129
00130 ACE_THROW_RETURN (CORBA::BAD_INV_ORDER (), 0);
00131 }
00132
00133 SecurityLevel3::AcquisitionStatus
00134 TAO::SSLIOP::CredentialsAcquirer::continue_acquisition (
00135 const CORBA::Any &
00136 ACE_ENV_ARG_DECL)
00137 ACE_THROW_SPEC ((CORBA::SystemException))
00138 {
00139
00140 ACE_THROW_RETURN (CORBA::BAD_INV_ORDER (),
00141 SecurityLevel3::AQST_Failed);
00142 }
00143
00144 SecurityLevel3::OwnCredentials_ptr
00145 TAO::SSLIOP::CredentialsAcquirer::get_credentials (CORBA::Boolean on_list
00146 ACE_ENV_ARG_DECL)
00147 ACE_THROW_SPEC ((CORBA::SystemException))
00148 {
00149 this->check_validity (ACE_ENV_SINGLE_ARG_PARAMETER);
00150 ACE_CHECK_RETURN (SecurityLevel3::OwnCredentials::_nil ());
00151
00152 ::SSLIOP::AuthData *data;
00153
00154 if (!(this->acquisition_arguments_ >>= data))
00155 ACE_THROW_RETURN (CORBA::BAD_PARAM (),
00156 SecurityLevel3::OwnCredentials::_nil ());
00157
00158 TAO::SSLIOP::X509_var x509 = this->make_X509 (data->certificate);
00159
00160 if (x509.in () == 0)
00161 ACE_THROW_RETURN (CORBA::BAD_PARAM (),
00162 SecurityLevel3::OwnCredentials::_nil ());
00163
00164 TAO::SSLIOP::EVP_PKEY_var evp = this->make_EVP_PKEY (data->key);
00165
00166 if (evp.in () == 0)
00167 ACE_THROW_RETURN (CORBA::BAD_PARAM (),
00168 SecurityLevel3::OwnCredentials::_nil ());
00169
00170
00171 if (::X509_check_private_key (x509.in (), evp.in ()) != 1)
00172 {
00173 if (TAO_debug_level > 0)
00174 ACE_DEBUG ((LM_ERROR,
00175 ACE_TEXT ("(%P|%t) ERROR: Private key is not ")
00176 ACE_TEXT ("consistent with X.509 certificate")));
00177
00178 ACE_THROW_RETURN (CORBA::BAD_PARAM (),
00179 SecurityLevel3::OwnCredentials::_nil ());
00180 }
00181
00182 TAO::SSLIOP::OwnCredentials * creds;
00183 ACE_NEW_THROW_EX (creds,
00184 TAO::SSLIOP::OwnCredentials (x509.in (), evp.in ()),
00185 CORBA::NO_MEMORY ());
00186 ACE_CHECK_RETURN (SecurityLevel3::OwnCredentials::_nil ());
00187
00188 SecurityLevel3::OwnCredentials_var credentials = creds;
00189
00190 if (on_list)
00191 {
00192 this->curator_->_tao_add_own_credentials (creds
00193 ACE_ENV_ARG_PARAMETER);
00194 ACE_CHECK_RETURN (SecurityLevel3::OwnCredentials::_nil ());
00195 }
00196
00197 this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00198 ACE_CHECK_RETURN (SecurityLevel3::OwnCredentials::_nil ());
00199
00200 return credentials._retn ();
00201 }
00202
00203 void
00204 TAO::SSLIOP::CredentialsAcquirer::destroy (ACE_ENV_SINGLE_ARG_DECL)
00205 ACE_THROW_SPEC ((CORBA::SystemException))
00206 {
00207 this->check_validity (ACE_ENV_SINGLE_ARG_PARAMETER);
00208 ACE_CHECK;
00209
00210 ACE_GUARD (TAO_SYNCH_MUTEX,
00211 guard,
00212 this->lock_);
00213
00214 if (!this->destroyed_)
00215 {
00216 this->destroyed_ = true;
00217
00218
00219 (void) this->curator_.out ();
00220 }
00221 }
00222
00223 void
00224 TAO::SSLIOP::CredentialsAcquirer::check_validity (ACE_ENV_SINGLE_ARG_DECL)
00225 {
00226 ACE_GUARD (TAO_SYNCH_MUTEX,
00227 guard,
00228 this->lock_);
00229
00230 if (this->destroyed_)
00231 ACE_THROW (CORBA::BAD_INV_ORDER ());
00232 }
00233
00234 ::X509 *
00235 TAO::SSLIOP::CredentialsAcquirer::make_X509 (const ::SSLIOP::File &certificate)
00236 {
00237
00238
00239
00240 const char *filename = certificate.filename.in ();
00241
00242 if (filename == 0)
00243 return 0;
00244
00245 FILE *fp = 0;
00246 ::X509 *x = 0;
00247
00248 if (certificate.type == ::SSLIOP::ASN1)
00249 {
00250
00251
00252
00253
00254
00255 const char *filename = certificate.filename.in ();
00256
00257 if (filename == 0)
00258 return 0;
00259
00260 fp = ACE_OS::fopen (filename, "rb");
00261
00262 if (fp == 0)
00263 {
00264 if (TAO_debug_level > 0)
00265 ACE_ERROR ((LM_ERROR,
00266 ACE_TEXT ("(%P|%t) SSLIOP::CredentialsAcquirer::make_X509 - %p\n"),
00267 ACE_TEXT ("fopen")));
00268
00269 return 0;
00270 }
00271
00272
00273
00274 x = ::d2i_X509_fp (fp, 0);
00275 }
00276 else
00277 {
00278
00279
00280 fp = ACE_OS::fopen (filename, "r");
00281
00282 if (fp == 0)
00283 {
00284 if (TAO_debug_level > 0)
00285 ACE_ERROR ((LM_ERROR,
00286 ACE_TEXT ("(%P|%t) SSLIOP::CredentialsAcquirer::make_X509 - %p\n"),
00287 ACE_TEXT ("fopen")));
00288
00289 return 0;
00290 }
00291
00292 const char *password = certificate.password.in ();
00293
00294
00295
00296 x = PEM_read_X509 (fp,
00297 0,
00298 TAO_SSLIOP_PASSWORD_CALLBACK_NAME,
00299 const_cast<char *> (password));
00300 }
00301
00302 (void) ACE_OS::fclose (fp);
00303
00304 if (x == 0 && TAO_debug_level > 0)
00305 ACE_SSL_Context::report_error ();
00306
00307 return x;
00308 }
00309
00310 ::EVP_PKEY *
00311 TAO::SSLIOP::CredentialsAcquirer::make_EVP_PKEY (const ::SSLIOP::File &key)
00312 {
00313
00314
00315
00316 const char *filename = key.filename.in ();
00317
00318 if (filename == 0)
00319 return 0;
00320
00321 FILE *fp = 0;
00322 ::EVP_PKEY *evp = 0;
00323
00324 if (key.type == ::SSLIOP::ASN1)
00325 {
00326
00327
00328
00329
00330
00331 const char *filename = key.filename.in ();
00332
00333 if (filename == 0)
00334 return 0;
00335
00336 fp = ACE_OS::fopen (filename, "rb");
00337
00338 if (fp == 0)
00339 {
00340 if (TAO_debug_level > 0)
00341 ACE_ERROR ((LM_ERROR,
00342 ACE_TEXT ("(%P|%t) SSLIOP::CredentialsAcquirer::make_EVP_PKEY ")
00343 ACE_TEXT ("- %p\n"),
00344 ACE_TEXT ("fopen")));
00345
00346 return 0;
00347 }
00348
00349
00350
00351 evp = ::d2i_PrivateKey_fp (fp, 0);
00352 }
00353 else
00354 {
00355
00356
00357 fp = ACE_OS::fopen (filename, "r");
00358
00359 if (fp == 0)
00360 {
00361 if (TAO_debug_level > 0)
00362 ACE_ERROR ((LM_ERROR,
00363 ACE_TEXT ("(%P|%t) SSLIOP::CredentialsAcquirer::make_EVP_PKEY ")
00364 ACE_TEXT ("- %p\n"),
00365 ACE_TEXT ("fopen")));
00366
00367 return 0;
00368 }
00369
00370 const char *password = key.password.in ();
00371
00372
00373
00374 evp = PEM_read_PrivateKey (fp,
00375 0,
00376 TAO_SSLIOP_PASSWORD_CALLBACK_NAME,
00377 const_cast<char *> (password));
00378 }
00379
00380 (void) ACE_OS::fclose (fp);
00381
00382 if (evp == 0 && TAO_debug_level > 0)
00383 ACE_SSL_Context::report_error ();
00384
00385 return evp;
00386 }
00387
00388 TAO_END_VERSIONED_NAMESPACE_DECL