SSLIOP_CredentialsAcquirer.cpp

Go to the documentation of this file.
00001 // SSLIOP_CredentialsAcquirer.cpp,v 1.5 2006/04/19 13:17:39 jwillemsen Exp
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  /* TAO_HAS_VERSIONED_NAMESPACE == 1 */
00029 
00030 
00031 extern "C"
00032 int
00033 TAO_SSLIOP_PASSWORD_CALLBACK_NAME (char *buf,
00034                                    int size,
00035                                    int /* rwflag */,
00036                                    void *userdata)
00037 {
00038   // @@ I'm probably over complicating this implementation, but that's
00039   //    what you get when you try to be overly efficient.  :-)
00040   //        -Ossama
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;  // Include the NULL terminator
00051 
00052       // Clear the portion of the buffer that exceeds the space that
00053       // will be occupied by the password.
00054       if (copy_len < size)
00055         ACE_OS::memset (buf + copy_len, 0, size - copy_len);
00056 
00057       // Make sure we don't overflow the OpenSSL supplied buffer.
00058       // Truncate the password if necessary.
00059       copy_len = (copy_len > size) ? size : copy_len;
00060 
00061       ACE_OS::memcpy (buf, password, copy_len);
00062 
00063       // NULL terminate the truncated password.
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;  // @@ Really?
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   // SSL/TLS credentials is single-step process from the point-of-view
00120   // of the caller.
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   // SSL/TLS credentials acquisition does generate continuation data.
00130   ACE_THROW_RETURN (CORBA::BAD_INV_ORDER (), 0);
00131 }
00132 
00133 SecurityLevel3::AcquisitionStatus
00134 TAO::SSLIOP::CredentialsAcquirer::continue_acquisition (
00135     const CORBA::Any & /* acquisition_arguments */
00136     ACE_ENV_ARG_DECL)
00137   ACE_THROW_SPEC ((CORBA::SystemException))
00138 {
00139   // SSL/TLS credentials acquisition does generate continuation data.
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   // Verify that the private key is consistent with the certificate.
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       // Release our reference to the CredentialsCurator.
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   // No password is used or needed when reading ASN.1 encoded
00238   // certificates.
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       // ASN.1/DER encoded certificate
00251 
00252       // No password is used or needed when reading ASN.1 encoded
00253       // certificates.
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       // Read ASN.1 / DER encoded X.509 certificate from a file, and
00273       // convert it to OpenSSL's internal X.509 format.
00274       x = ::d2i_X509_fp (fp, 0);
00275     }
00276   else
00277     {
00278       // PEM encoded certificate
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       // Read PEM encoded X.509 certificate from a file, and convert
00295       // it to OpenSSL's internal X.509 format.
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   // No password is used or needed when reading ASN.1 encoded
00314   // private keys.
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       // ASN.1/DER encoded private key
00327 
00328       // No password is used or needed when reading ASN.1 encoded
00329       // private keys.
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       // Read ASN.1 / DER encoded private key from a file, and convert
00350       // it to OpenSSL's internal private key format.
00351       evp = ::d2i_PrivateKey_fp (fp, 0);
00352     }
00353   else
00354     {
00355       // PEM encoded private key
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       // Read PEM encoded private key from a file, and convert it to
00373       // OpenSSL's internal private key format.
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

Generated on Thu Nov 9 13:54:14 2006 for TAO_SSLIOP by doxygen 1.3.6