(file) Return to SSLContext.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

   1 karl  1.23 //%2003////////////////////////////////////////////////////////////////////////
   2 kumpf 1.1  //
   3 karl  1.23 // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
   4            // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
   5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
   6            // IBM Corp.; EMC Corporation, The Open Group.
   7 kumpf 1.1  //
   8            // Permission is hereby granted, free of charge, to any person obtaining a copy
   9 kumpf 1.2  // of this software and associated documentation files (the "Software"), to
  10            // deal in the Software without restriction, including without limitation the
  11            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  12 kumpf 1.1  // sell copies of the Software, and to permit persons to whom the Software is
  13            // furnished to do so, subject to the following conditions:
  14            // 
  15 kumpf 1.2  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  16 kumpf 1.1  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  17            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  18 kumpf 1.2  // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  19            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  21 kumpf 1.1  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23            //
  24            //==============================================================================
  25            //
  26            // Author: Markus Mueller (sedgewick_de@yahoo.de)
  27            //
  28 kumpf 1.9  // Modified By: Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)
  29            //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
  30 h.sterling 1.26 //              Sushma Fernandes, Hewlett-Packard Company (sushma_fernandes@hp.com)
  31                 //              Heather Sterling, IBM (hsterl@us.ibm.com)
  32 kumpf      1.1  //
  33                 //%/////////////////////////////////////////////////////////////////////////////
  34                 
  35                 #ifdef PEGASUS_HAS_SSL
  36 mday       1.19 #define OPENSSL_NO_KRB5 1
  37 kumpf      1.1  #include <openssl/err.h>
  38                 #include <openssl/ssl.h>
  39                 #include <openssl/rand.h>
  40                 #else
  41                 #define SSL_CTX void
  42                 #endif // end of PEGASUS_HAS_SSL
  43                 #include <Pegasus/Common/Destroyer.h>
  44                 #include <Pegasus/Common/Socket.h>
  45                 #include <Pegasus/Common/Tracer.h>
  46 kumpf      1.14 #include <Pegasus/Common/FileSystem.h>
  47 kumpf      1.16 #include <time.h>
  48 humberto   1.18 #include <Pegasus/Common/MessageLoader.h> //l10n
  49 kumpf      1.1  
  50                 #include "SSLContext.h"
  51                 #include "SSLContextRep.h"
  52                 
  53 kumpf      1.16 typedef struct Timestamp 
  54                 {
  55                     char year[4];
  56                     char month[2];
  57                     char day[2];
  58                     char hour[2];
  59                     char minutes[2];
  60                     char seconds[2];
  61                     char dot;
  62                     char microSeconds[6];
  63                     char plusOrMinus;
  64                     char utcOffset[3];
  65                     char padding[3];
  66                 } Timestamp_t;
  67                 
  68 kumpf      1.1  PEGASUS_USING_STD;
  69                 
  70                 PEGASUS_NAMESPACE_BEGIN
  71                 
  72                 //
  73                 // use the following definitions only if SSL is available
  74                 // 
  75 kumpf      1.3  #ifdef PEGASUS_HAS_SSL
  76 kumpf      1.1  
  77 kumpf      1.15 // Mutex for SSL locks.
  78                 Mutex* SSLContextRep::_sslLocks = 0;
  79                 
  80                 // Mutex for _countRep.
  81                 Mutex SSLContextRep::_countRepMutex;
  82                 
  83                 // Initialise _count for SSLContextRep objects.
  84                 int SSLContextRep::_countRep = 0;
  85                 
  86 kumpf      1.16 
  87                 //
  88                 // Convert ASN1_UTCTIME to CIMDateTime
  89                 //
  90                 CIMDateTime getDateTime(const ASN1_UTCTIME *utcTime)
  91                 {
  92                     struct tm time;
  93                     int offset;
  94                     Timestamp_t timeStamp;
  95                     char tempString[80];
  96                     char plusOrMinus = '+';
  97                 
  98                     memset(&time, '\0', sizeof(time));
  99                 
 100                 #define g2(p) ( ( (p)[0] - '0' ) * 10 + (p)[1] - '0' )
 101                 
 102                     time.tm_year = g2(utcTime->data);
 103                 
 104                     if(time.tm_year < 50)
 105                     {
 106                         time.tm_year += 100;
 107 kumpf      1.16     }
 108                     time.tm_mon = g2(utcTime->data + 2) - 1;
 109                     time.tm_mday = g2(utcTime->data + 4);
 110                     time.tm_hour = g2(utcTime->data + 6);
 111                     time.tm_min = g2(utcTime->data + 8);
 112                     time.tm_sec = g2(utcTime->data + 10);
 113                 
 114                     if(utcTime->data[12] == 'Z')
 115                     {
 116                         offset = 0;
 117                     }
 118                     else
 119                     {
 120                         offset = g2(utcTime->data + 13) * 60 + g2(utcTime->data + 15);
 121                         if(utcTime->data[12] == '-')
 122                         {
 123                             plusOrMinus = '-';
 124                         }
 125                     }
 126                 #undef g2
 127                 
 128 kumpf      1.16     int year = 1900;
 129                     memset((void *)&timeStamp, 0, sizeof(Timestamp_t));
 130                 
 131                     // Format the date.
 132                     sprintf((char *) &timeStamp,"%04d%02d%02d%02d%02d%02d.%06d%04d",
 133                             year + time.tm_year,
 134                             time.tm_mon + 1,  
 135                             time.tm_mday,
 136                             time.tm_hour,
 137                             time.tm_min,
 138                             time.tm_sec,
 139                             0,
 140                             offset);
 141                 
 142                     timeStamp.plusOrMinus = plusOrMinus;
 143                 
 144                     CIMDateTime dateTime;
 145                 
 146                     dateTime.clear();
 147                     strcpy(tempString, (char *)&timeStamp);
 148                     dateTime.set(tempString);
 149 kumpf      1.16 
 150                     return (dateTime);
 151                 }
 152                 
 153                 //
 154                 // Callback function that is called by the OpenSSL library. This function
 155                 // extracts X509 certficate information and pass that on to client application
 156                 // callback function.
 157                 //
 158                 int prepareForCallback(int preVerifyOk, X509_STORE_CTX *ctx)
 159 kumpf      1.1  {
 160 kumpf      1.3      PEG_METHOD_ENTER(TRC_SSL, "prepareForCallback()");
 161 kumpf      1.1  
 162                     char   buf[256];
 163 kumpf      1.16     X509   *currentCert;
 164 h.sterling 1.28     SSL    *ssl;
 165 kumpf      1.16     int    verifyError = X509_V_OK;
 166 kumpf      1.1  
 167 h.sterling 1.28     //
 168                     // get the verification callback info specific to each SSL connection
 169                     //
 170                     ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
 171                     SSLCallbackInfo* exData = (SSLCallbackInfo*) SSL_get_ex_data(ssl, SSL_CALLBACK_INDEX);
 172                 
 173                     //
 174 h.sterling 1.26     // If the SSLContext does not have an additional callback
 175                     // simply return the preverification error.
 176                     // We do not need to go through the additional steps.
 177 h.sterling 1.28     //
 178                     if (exData->verifyCertificateCallback == NULL)
 179 h.sterling 1.26     {
 180                         return (preVerifyOk);
 181                     }
 182                 
 183 kumpf      1.16     //
 184                     // get the current certificate
 185                     //
 186                     currentCert = X509_STORE_CTX_get_current_cert(ctx);
 187 kumpf      1.1  
 188 kumpf      1.16     //
 189                     // get the default verification error code
 190                     //
 191                     int errorCode = X509_STORE_CTX_get_error(ctx);
 192                 
 193                     //
 194                     // get the depth of certificate chain
 195                     //
 196                     int depth = X509_STORE_CTX_get_error_depth(ctx);
 197 kumpf      1.1  
 198 kumpf      1.16     //
 199                     // get the version on the certificate
 200                     //
 201                     long version = X509_get_version(currentCert);
 202 kumpf      1.1  
 203 kumpf      1.16     //
 204                     // get the serial number of the certificate
 205                     //
 206                     long serialNumber = ASN1_INTEGER_get(X509_get_serialNumber(currentCert));
 207                 
 208                     //
 209                     // get the validity of the certificate
 210                     //
 211                     CIMDateTime notBefore = getDateTime(X509_get_notBefore(currentCert));
 212                 
 213                     CIMDateTime notAfter = getDateTime(X509_get_notAfter(currentCert));
 214                 
 215                     //
 216                     // get the subject name on the certificate
 217                     //
 218                     X509_NAME_oneline(X509_get_subject_name(currentCert), buf, 256);
 219                     String subjectName = String(buf);
 220                 
 221                     //
 222                     // get the default verification error string 
 223                     //
 224 kumpf      1.16     String errorStr = String(X509_verify_cert_error_string(errorCode));
 225 kumpf      1.1  
 226 kumpf      1.16     //
 227                     // log the error string if the default verification was failed
 228                     //
 229                     if (!preVerifyOk)
 230 kumpf      1.1      {
 231 kumpf      1.3          PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, 
 232 kumpf      1.16             "---> SSL: certificate default verification error: " + errorStr);
 233 kumpf      1.1      }
 234                 
 235 kumpf      1.16     //
 236                     // get the issuer name on the certificate
 237                     //
 238                     if (!preVerifyOk && (errorCode == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))
 239 kumpf      1.1      {
 240                         X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
 241                     }
 242                     else
 243                     {
 244 kumpf      1.16         X509_NAME_oneline(X509_get_issuer_name(currentCert), buf, 256);
 245 kumpf      1.1      }
 246 kumpf      1.16     String issuerName = String(buf);
 247 kumpf      1.1  
 248 h.sterling 1.28 //    SSLCertificateInfo certInfo(subjectName, issuerName, version, serialNumber,
 249                 //        notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk);
 250                 
 251                     exData->_peerCertificate = new SSLCertificateInfo(subjectName, issuerName, version, serialNumber,
 252                         notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk);
 253                 
 254 kumpf      1.1      //
 255 h.sterling 1.28     // Call the application callback.
 256                     // Note that the verification result does not automatically get set to X509_V_OK if the callback is successful.
 257                     // This is because OpenSSL retains the original default error in case we want to use it later.
 258                     // To set the error, we could use X509_STORE_CTX_set_error(ctx, verifyError); but there is no real benefit to doing that here.
 259 kumpf      1.1      //
 260 h.sterling 1.28     if (exData->verifyCertificateCallback(*exData->_peerCertificate))//certInfo)) 
 261 kumpf      1.1      {
 262 kumpf      1.16         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 263 h.sterling 1.28             "--> SSL: verifyCertificateCallback() returned X509_V_OK");
 264                 
 265                         PEG_METHOD_EXIT();
 266                         return 1;
 267 kumpf      1.16     }
 268 h.sterling 1.28     else // verification failed, handshake will be immediately terminated
 269 kumpf      1.16     {
 270                         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 271 h.sterling 1.28             "--> SSL: verifyCertificateCallback() returned error %d", exData->_peerCertificate->getErrorCode());
 272                       
 273                         PEG_METHOD_EXIT();
 274                         return 0; 
 275 kumpf      1.1      }
 276                 }
 277                 
 278 kumpf      1.15 //
 279                 // Implement OpenSSL locking callback.
 280                 //
 281                 void pegasus_locking_callback( int 		mode, 
 282                                                int 		type, 
 283                                                const char* 	file, 
 284                                                int 		line)
 285                 {
 286                     // Check whether the mode is lock or unlock.
 287                 
 288                     if ( mode & CRYPTO_LOCK )
 289                     {
 290 h.sterling 1.26         /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 291                                 "Now locking for %d", pegasus_thread_self());*/
 292 kumpf      1.15         SSLContextRep::_sslLocks[type].lock( pegasus_thread_self() );
 293                     }
 294                     else
 295                     {
 296 h.sterling 1.26         /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 297                                 "Now unlocking for %d", pegasus_thread_self());*/
 298 kumpf      1.15         SSLContextRep::_sslLocks[type].unlock( );
 299                     }
 300                 }
 301                 
 302                 //
 303                 // Initialize OpenSSL Locking and id callbacks.
 304                 //
 305                 void SSLContextRep::init_ssl()
 306                 {
 307                      // Allocate Memory for _sslLocks. SSL locks needs to be able to handle
 308                      // up to CRYPTO_num_locks() different mutex locks.
 309                      PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 310                            "Initialized SSL callback.");
 311                 
 312                      _sslLocks= new Mutex[CRYPTO_num_locks()];
 313                 
 314                      // Set the ID callback. The ID callback returns a thread ID.
 315                 
 316                      CRYPTO_set_id_callback((unsigned long (*)())pegasus_thread_self);
 317                 
 318                      // Set the locking callback to pegasus_locking_callback.
 319 kumpf      1.15 
 320                      CRYPTO_set_locking_callback((void (*)(int,int,const char *,int))pegasus_locking_callback);
 321                 
 322                 }
 323                 
 324                 // Free OpenSSL Locking and id callbacks.
 325                 void SSLContextRep::free_ssl()
 326                 {
 327                     // Cleanup _sslLocks and set locking & id callback to NULL.
 328                 
 329                     CRYPTO_set_locking_callback(NULL);
 330                     CRYPTO_set_id_callback     (NULL);
 331                     PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 332                              "Freed SSL callback.");
 333                 
 334                     delete []_sslLocks;
 335                 }
 336                 
 337 kumpf      1.1  
 338                 //
 339                 // SSL context area
 340                 //
 341                 // For the OSs that don't have /dev/random device file,
 342                 // must enable PEGASUS_SSL_RANDOMFILE flag.
 343                 //
 344 h.sterling 1.26 SSLContextRep::SSLContextRep(const String& trustStore,
 345 kumpf      1.16                        const String& certPath,
 346                                        const String& keyPath,
 347 kumpf      1.9                         SSLCertificateVerifyFunction* verifyCert,
 348 kumpf      1.13                        const String& randomFile)
 349 kumpf      1.1  {
 350 kumpf      1.3      PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
 351 kumpf      1.1  
 352 h.sterling 1.26     _trustStore = trustStore;
 353 kumpf      1.16 
 354 h.sterling 1.26     _certPath = certPath;
 355 kumpf      1.1  
 356 h.sterling 1.26     _keyPath = keyPath;
 357 kumpf      1.14 
 358 h.sterling 1.28     _certificateVerifyFunction = verifyCert;
 359 kumpf      1.1  
 360 h.sterling 1.26 	_trustStoreAutoUpdate = false;
 361                 
 362                 	_trustStoreUserName = String::EMPTY;
 363                 
 364 h.sterling 1.28     //
 365 h.sterling 1.26     // If a truststore and/or peer verification function is specified, enable peer verification
 366 h.sterling 1.28     //
 367 h.sterling 1.26     if (trustStore != String::EMPTY || verifyCert != NULL)
 368                     {
 369                         _verifyPeer = true;
 370                     } 
 371                     else
 372                     {
 373                         _verifyPeer = false;
 374                     }
 375                 
 376 h.sterling 1.28     //
 377                     // Initialize SSL callbacks and increment the SSLContextRep object _counter.
 378                     //
 379 h.sterling 1.26     _countRepMutex.lock(pegasus_thread_self());
 380                 
 381                     try
 382                     {
 383                         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 384                                 "Value of Countrep in constructor %d", _countRep);
 385                         if ( _countRep == 0 )
 386                         {
 387                             init_ssl();
 388                 
 389                             //
 390                             // load SSL library
 391                             //
 392                             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 393                                 "Before calling SSL_load_error_strings %d", pegasus_thread_self());
 394                 
 395                             SSL_load_error_strings();
 396                 
 397                             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 398                                 "After calling SSL_load_error_strings %d", pegasus_thread_self());
 399                 
 400 h.sterling 1.26             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 401                                 "Before calling SSL_library_init %d", pegasus_thread_self());
 402                 
 403                             SSL_library_init();
 404                 
 405                             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 406                                 "After calling SSL_library_init %d", pegasus_thread_self());
 407                 
 408                         } 
 409                     }
 410                     catch(...)
 411                     {
 412                         _countRepMutex.unlock();
 413                         throw;
 414                     }
 415                     _countRep++;
 416                     _countRepMutex.unlock();
 417                 
 418                     _randomInit(randomFile);
 419                 
 420                     _sslContext = _makeSSLContext();
 421 h.sterling 1.26 
 422                     PEG_METHOD_EXIT();
 423                 }
 424                 
 425                 #ifdef PEGASUS_USE_SSL_CLIENT_VERIFICATION
 426                 SSLContextRep::SSLContextRep(
 427                                        const String& trustStore,
 428                                        const String& certPath,
 429                                        const String& keyPath,
 430                                        SSLCertificateVerifyFunction* verifyCert,
 431                                        Boolean trustStoreAutoUpdate,
 432                 					   String trustStoreUserName,
 433                                        const String& randomFile)
 434                 {
 435                     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
 436                 
 437                     _trustStore = trustStore;
 438                 
 439                     _certPath = certPath;
 440                 
 441                     _keyPath = keyPath;
 442 h.sterling 1.26 
 443 h.sterling 1.28     _certificateVerifyFunction = verifyCert;
 444 h.sterling 1.26 
 445                     _trustStoreAutoUpdate = trustStoreAutoUpdate;
 446                 
 447                 	_trustStoreUserName = trustStoreUserName;
 448                 
 449 h.sterling 1.28     //
 450 h.sterling 1.26     // If a truststore and/or peer verification function is specified, enable peer verification
 451 h.sterling 1.28     //
 452 h.sterling 1.26     if (trustStore != String::EMPTY || verifyCert != NULL)
 453                     {
 454                         _verifyPeer = true;
 455                     } 
 456                     else
 457                     {
 458                         _verifyPeer = false;
 459                     }
 460 kumpf      1.15 
 461 h.sterling 1.28     //
 462 kumpf      1.15     // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.
 463 h.sterling 1.28     //
 464 kumpf      1.15     _countRepMutex.lock(pegasus_thread_self());
 465                 
 466                     try
 467                     {
 468                         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 469                                 "Value of Countrep in constructor %d", _countRep);
 470                         if ( _countRep == 0 )
 471                         {
 472                             init_ssl();
 473                 
 474                             //
 475                             // load SSL library
 476                             //
 477                             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 478                                 "Before calling SSL_load_error_strings %d", pegasus_thread_self());
 479                 
 480                             SSL_load_error_strings();
 481                 
 482                             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 483                                 "After calling SSL_load_error_strings %d", pegasus_thread_self());
 484                 
 485 kumpf      1.15             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 486                                 "Before calling SSL_library_init %d", pegasus_thread_self());
 487                 
 488                             SSL_library_init();
 489                 
 490                             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 491                                 "After calling SSL_library_init %d", pegasus_thread_self());
 492                 
 493                         } 
 494                     }
 495                     catch(...)
 496                     {
 497                         _countRepMutex.unlock();
 498                         throw;
 499                     }
 500                     _countRep++;
 501                     _countRepMutex.unlock();
 502 kumpf      1.1  
 503 kumpf      1.14     _randomInit(randomFile);
 504 kumpf      1.1  
 505 kumpf      1.9      _sslContext = _makeSSLContext();
 506                 
 507                     PEG_METHOD_EXIT();
 508                 }
 509 h.sterling 1.26 #endif
 510 kumpf      1.9  
 511                 SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep)
 512                 {
 513                     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
 514                 
 515 h.sterling 1.26     _trustStore = sslContextRep._trustStore;
 516 kumpf      1.9      _certPath = sslContextRep._certPath;
 517 kumpf      1.16     _keyPath = sslContextRep._keyPath;
 518 h.sterling 1.26     _verifyPeer = sslContextRep._verifyPeer;
 519                     _trustStoreAutoUpdate = sslContextRep._trustStoreAutoUpdate;
 520                 	_trustStoreUserName = sslContextRep._trustStoreUserName;
 521 h.sterling 1.28     _certificateVerifyFunction = sslContextRep._certificateVerifyFunction;
 522 kumpf      1.9      _randomFile = sslContextRep._randomFile;
 523 kumpf      1.15 
 524                     // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.
 525                     _countRepMutex.lock(pegasus_thread_self());
 526                     try
 527                     {
 528                         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 529                              "Value of Countrep in copy constructor %d", _countRep);
 530                         if ( _countRep == 0 )
 531                         {
 532                             init_ssl();
 533                         } 
 534                     }
 535                     catch(...)
 536                     {
 537                         _countRepMutex.unlock();
 538                         throw;
 539                     }
 540                     _countRep++;
 541                     _countRepMutex.unlock();
 542                 
 543 kumpf      1.9      _sslContext = _makeSSLContext();
 544                     PEG_METHOD_EXIT();
 545                 }
 546 kumpf      1.11 
 547 kumpf      1.9  //
 548                 // Destructor
 549                 //
 550                 
 551                 SSLContextRep::~SSLContextRep()
 552                 {
 553                     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::~SSLContextRep()");
 554                 
 555                     SSL_CTX_free(_sslContext);
 556                 
 557 kumpf      1.15     // Decrement the SSLContextRep object _counter.
 558                     _countRepMutex.lock(pegasus_thread_self());
 559                     _countRep--;
 560                     // Free SSL locks if no instances of SSLContextRep exist.
 561                     try
 562                     {
 563                         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 564                                 "Value of Countrep in destructor %d", _countRep);
 565                         if ( _countRep == 0 )
 566                         {
 567                             free_ssl();
 568                         }
 569                     }
 570                     catch(...)
 571                     {
 572                         _countRepMutex.unlock();
 573                         throw;
 574                     }
 575                     _countRepMutex.unlock();
 576 kumpf      1.9      PEG_METHOD_EXIT();
 577                 }
 578                 
 579 kumpf      1.14 //
 580                 // initialize OpenSSL's PRNG
 581                 //
 582                 void SSLContextRep::_randomInit(const String& randomFile)
 583                 {
 584                     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_randomInit()");
 585                 
 586                     Boolean ret;
 587                     int retVal = 0;
 588                 
 589 kumpf      1.15     const int DEV_RANDOM_BYTES = 64;	        /* how many bytes to read */
 590 kumpf      1.14     const String devRandom = "/dev/random";     /* random device name */
 591                     const String devUrandom = "/dev/urandom";   /* pseudo-random device name */
 592                 
 593                 #ifdef PEGASUS_SSL_DEVRANDOM
 594                 
 595                     if ( FileSystem::exists(devRandom) )
 596                     {
 597                         while ( RAND_status() == 0 )
 598                         {
 599                             //
 600 kumpf      1.15             // Always attempt to seed from good entropy sources, first
 601 kumpf      1.14             // try /dev/random
 602                             //
 603                             retVal = RAND_load_file(devRandom.getCString(), DEV_RANDOM_BYTES);
 604 kumpf      1.15             if (retVal <= 0)
 605 kumpf      1.14             {
 606                                 break;
 607                             }
 608                         }
 609                     }
 610                 
 611                     if ( FileSystem::exists(devUrandom) )
 612                     {
 613                         while ( RAND_status() == 0 )
 614                         {
 615                             //
 616                             // If there isn't /dev/random try /dev/urandom
 617                             //
 618                             retVal = RAND_load_file(devUrandom.getCString(), DEV_RANDOM_BYTES);
 619 kumpf      1.15             if (retVal <= 0)
 620 kumpf      1.14             {
 621                                 break;
 622                             }
 623                         }
 624                     }
 625                 #endif  /* PEGASUS_SSL_DEVRANDOM */
 626                 
 627                 
 628                 #ifdef PEGASUS_SSL_RANDOMFILE
 629                     if ( RAND_status() == 0 )
 630                     {
 631                         //
 632                         // Initialise OpenSSL random number generator.
 633                         //
 634                         if ( randomFile == String::EMPTY )
 635                         {
 636                             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 637                                 "Random seed file is required.");
 638                             PEG_METHOD_EXIT();
 639 humberto   1.18             //l10n
 640                             //throw( SSLException("Random seed file required"));
 641                             MessageLoaderParms parms("Common.SSLContext.RANDOM_SEED_FILE_REQUIRED",
 642                             						 "Random seed file required");
 643 tony       1.24             throw SSLException(parms);						 
 644 kumpf      1.14         }
 645                 
 646                         //
 647                         // Try the given random seed file
 648                         //
 649                         ret = FileSystem::exists(randomFile);
 650                         if( ret )
 651                         {
 652 kumpf      1.15             retVal = RAND_load_file(randomFile.getCString(), -1); 
 653 kumpf      1.14             if ( retVal < 0 )
 654                             {
 655                                 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 656                                     "Not enough seed data in seed file: " + randomFile);
 657                                 PEG_METHOD_EXIT();
 658 humberto   1.18                 //l10n
 659 humberto   1.22 		// do not put in $0 in default message, but pass in filename for bundle message
 660 humberto   1.18                 //throw( SSLException("Not enough seed data in random seed file."));
 661                                 MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
 662 humberto   1.21             						     "Not enough seed data in random seed file.",
 663                             						     randomFile);
 664 tony       1.24             	throw SSLException(parms);
 665 kumpf      1.14             }
 666                         }
 667 kumpf      1.16         else
 668                         {
 669                             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 670                                 "seed file - " + randomFile + " does not exist.");
 671                             PEG_METHOD_EXIT();
 672 humberto   1.18             //l10n
 673                             //throw( SSLException("Seed file '" + randomFile + "' does not exist."));
 674                             MessageLoaderParms parms("Common.SSLContext.SEED_FILE_DOES_NOT_EXIST",
 675                             						 "Seed file '$0' does not exist.",
 676                             						 randomFile);
 677 tony       1.24             throw SSLException(parms);
 678 kumpf      1.16         }
 679 kumpf      1.14 
 680                         if ( RAND_status() == 0 )
 681                         {
 682                             //
 683                             // Try to do more seeding
 684                             //
 685                             long seedNumber;
 686 tony       1.24         #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC)
 687                             srand((unsigned int)time(NULL)); // Initialize
 688                             seedNumber = rand();
 689                         #else
 690 kumpf      1.14             srandom((unsigned int)time(NULL)); // Initialize
 691                             seedNumber = random();
 692 tony       1.24         #endif
 693 kumpf      1.14             RAND_seed((unsigned char *) &seedNumber, sizeof(seedNumber));
 694                 
 695                             int  seedRet = RAND_status();
 696                             if ( seedRet == 0 )
 697                             {
 698                                 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 699 kumpf      1.15                     "Not enough seed data in random seed file, RAND_status = " +
 700                                     seedRet);
 701 kumpf      1.14                 PEG_METHOD_EXIT();
 702 humberto   1.22                 //l10n 485
 703                 		// do not put in $0 in default message, but pass in filename for bundle message
 704 humberto   1.18                 //throw( SSLException("Not enough seed data in random seed file."));
 705                                 MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
 706 humberto   1.22             						     "Not enough seed data in random seed file.",
 707                             						     randomFile);
 708 tony       1.24             	throw SSLException(parms);
 709 kumpf      1.14             }
 710                         }
 711                     }
 712                 #endif  /* PEGASUS_SSL_RANDOMFILE */
 713                 
 714                     int  seedRet = RAND_status();
 715                     if ( seedRet == 0 )
 716                     {
 717                         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 718                             "Not enough seed data , RAND_status = " + seedRet );
 719                         PEG_METHOD_EXIT();
 720 humberto   1.18         //l10n
 721                         //throw( SSLException("Not enough seed data."));
 722                         MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA",
 723                             					 "Not enough seed data.");
 724 tony       1.24         throw SSLException(parms);
 725 kumpf      1.14     }
 726                 
 727                     PEG_METHOD_EXIT();
 728                 }
 729                 
 730 kumpf      1.9  SSL_CTX * SSLContextRep::_makeSSLContext()
 731                 {
 732                     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()");
 733                 
 734                     SSL_CTX * sslContext = 0;
 735                 
 736 kumpf      1.1      //
 737                     // create SSL Context Area
 738                     //
 739                 
 740 kumpf      1.9      if (!( sslContext = SSL_CTX_new(SSLv23_method()) ))
 741 kumpf      1.3      {
 742                         PEG_METHOD_EXIT();
 743 humberto   1.18         //l10n
 744                         //throw( SSLException("Could not get SSL CTX"));
 745                         MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET",
 746 humberto   1.20             					 "Could not get SSL CTX");
 747 tony       1.24         throw SSLException(parms);
 748 kumpf      1.3      }
 749                 
 750 kumpf      1.14 #ifdef PEGASUS_SSL_WEAKENCRYPTION
 751 humberto   1.18     if (!(SSL_CTX_set_cipher_list(sslContext, SSL_TXT_EXP40))){
 752                     	//l10n
 753                         //throw( SSLException("Could not set the cipher list"));
 754                         MessageLoaderParms parms("Common.SSLContext.COULD_NOT_SET_CIPHER_LIST",
 755                             					 "Could not set the cipher list");
 756 tony       1.24         throw SSLException(parms);
 757 humberto   1.18     }
 758 kumpf      1.3  #endif
 759 kumpf      1.1  
 760                     //
 761                     // set overall SSL Context flags
 762                     //
 763                 
 764 kumpf      1.9      SSL_CTX_set_quiet_shutdown(sslContext, 1);
 765                     SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);
 766                     SSL_CTX_set_options(sslContext,SSL_OP_ALL);
 767 kumpf      1.14     SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
 768 kumpf      1.1  
 769 h.sterling 1.26     if (_verifyPeer)
 770 kumpf      1.1      {
 771 h.sterling 1.26         //ATTN: We might still need a flag to specify SSL_VERIFY_FAIL_IF_NO_PEER_CERT
 772 kumpf      1.27         // If SSL_VERIFY_FAIL_IF_NO_PEER_CERT is ON, SSL will immediately be terminated 
 773                         // if the client sends no certificate or sends an untrusted certificate.  The 
 774                         // callback function is not called in this case; the handshake is simply terminated.
 775 h.sterling 1.26         // This value has NO effect in from a client perspective
 776                 
 777 h.sterling 1.28         if (_certificateVerifyFunction != NULL)
 778 h.sterling 1.26         {
 779 kumpf      1.27             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, 
 780                                 "---> SSL: certificate verification callback specified");
 781                             SSL_CTX_set_verify(sslContext, 
 782                                 SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, prepareForCallback);
 783                         }
 784 h.sterling 1.26         else
 785                         {
 786 kumpf      1.27             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Trust Store specified");
 787                             SSL_CTX_set_verify(sslContext, 
 788                                 SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 
 789                                 prepareForCallback);
 790 h.sterling 1.26         }
 791 kumpf      1.1      }
 792 kumpf      1.14     else
 793                     {
 794 kumpf      1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
 795                             "---> SSL: Trust Store and certificate verification callback are NOT specified");
 796                         SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
 797 kumpf      1.14     }
 798 kumpf      1.1  
 799                     //
 800 kumpf      1.27     // Check if there is CA certificate file or directory specified. If specified,
 801                     // and is not empty, load the certificates from the Trust store.
 802 h.sterling 1.26     //
 803 kumpf      1.27     if (_trustStore != String::EMPTY)
 804 kumpf      1.14     {
 805                         //
 806 h.sterling 1.26         // The truststore may be a single file of CA certificates OR
 807                         // a directory containing multiple CA certificates.
 808                         // Check which one it is, and call the load_verify_locations function 
 809                         // with the appropriate parameter.  Note: It is possible to have both
 810 kumpf      1.27         // options, in which case the CA file takes precedence over the CA path.  
 811 h.sterling 1.26         // However, since there is currently only one trust parameter to the
 812                         // SSL functions, only allow one choice here.  
 813 kumpf      1.27         //
 814                         if (FileSystem::isDirectory(_trustStore))
 815                         {
 816                             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, 
 817                                             "---> SSL: Truststore is a directory");
 818                             //
 819                             // load certificates from the trust store
 820                             //
 821                             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 822                                 "---> SSL: Loading certificates from the trust store: " + _trustStore);
 823                 
 824                             if ((!SSL_CTX_load_verify_locations(sslContext, NULL, _trustStore.getCString())) ||
 825                                 (!SSL_CTX_set_default_verify_paths(sslContext)))
 826                             {
 827                                 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 828                                     "---> SSL: Could not load certificates from the trust store: " + _trustStore);
 829                                 //l10n
 830                                 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
 831                                     "Could not load certificates in to trust store.");
 832                                 PEG_METHOD_EXIT();
 833                                 throw SSLException(parms);
 834 kumpf      1.27             }
 835 h.sterling 1.26 
 836 kumpf      1.27         } 
 837                         else if (FileSystem::exists(_trustStore))
 838 h.sterling 1.26         {
 839 kumpf      1.27             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, 
 840                                             "---> SSL: Truststore is a file");
 841                             //
 842                             // Get size of the trust store file:
 843                             //
 844                             Uint32 fileSize = 0;
 845 h.sterling 1.26 
 846 kumpf      1.27             FileSystem::getFileSize(_trustStore, fileSize);
 847 h.sterling 1.26 
 848 kumpf      1.27             if (fileSize > 0)
 849                             {
 850                                 //
 851                                 // load certificates from the trust store
 852                                 //
 853                                 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 854                                     "---> SSL: Loading certificates from the trust store: " + _trustStore);
 855                 
 856                                 if ((!SSL_CTX_load_verify_locations(sslContext, _trustStore.getCString(), NULL)) ||
 857                                     (!SSL_CTX_set_default_verify_paths(sslContext)))
 858                                 {
 859                                     PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 860                                         "---> SSL: Could not load certificates from the trust store: " + _trustStore);
 861                                     //l10n
 862                                     MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
 863                                         "Could not load certificates in to trust store.");
 864                                     PEG_METHOD_EXIT();
 865                                     throw SSLException(parms);
 866                                 }
 867                             }
 868                             else
 869 kumpf      1.27             {
 870                                 //
 871                                 // no certificates found in the trust store
 872                                 //
 873                                 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 874                                     "---> SSL: No certificates to load from the trust store: " + _trustStore);
 875                             }
 876 kumpf      1.14         }
 877                     }
 878                 
 879 kumpf      1.17     Boolean keyLoaded = false;
 880 kumpf      1.27 
 881 kumpf      1.1      //
 882 kumpf      1.16     // Check if there is a certificate file (file containing server 
 883                     // certificate) specified. If specified, validate and load the 
 884                     // certificate.
 885 kumpf      1.14     //
 886 kumpf      1.27     if (_certPath != String::EMPTY)
 887 kumpf      1.14     {
 888                         //
 889                         // load the specified server certificates
 890                         //
 891 kumpf      1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 892                             "---> SSL: Loading server certificate from: " + _certPath);
 893 kumpf      1.1  
 894 kumpf      1.27         if (SSL_CTX_use_certificate_file(sslContext, 
 895                             _certPath.getCString(), SSL_FILETYPE_PEM) <=0)
 896 kumpf      1.14         {
 897 kumpf      1.27             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 898                                 "---> SSL: No server certificate found in " + _certPath);
 899 humberto   1.18             MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_SERVER_CERTIFICATE",
 900                             					     "Could not get server certificate.");
 901 kumpf      1.27             PEG_METHOD_EXIT();
 902 tony       1.24             throw SSLException(parms);
 903 kumpf      1.14         }
 904 kumpf      1.17 
 905 kumpf      1.16         //
 906                         // If there is no key file (file containing server
 907 h.sterling 1.26         // private key) specified, then try loading the key from the certificate file.
 908 kumpf      1.27         // As of 2.4, if a keyfile is specified, its location is verified during server
 909                         // startup and will throw an error if the path is invalid.
 910 kumpf      1.16         //
 911 kumpf      1.27         if (_keyPath == String::EMPTY)
 912 kumpf      1.16         {
 913 kumpf      1.27             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 914                                 "---> SSL: loading private key from: " + _certPath);
 915 kumpf      1.16             //
 916                             // load the private key and check for validity
 917                             //
 918 kumpf      1.27             if (!_verifyPrivateKey(sslContext, _certPath))
 919 kumpf      1.16             {
 920 humberto   1.18                 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
 921                             					         "Could not get private key.");
 922 kumpf      1.27                 PEG_METHOD_EXIT();
 923 tony       1.24             	throw SSLException(parms);
 924 kumpf      1.16             }
 925 kumpf      1.17             keyLoaded = true;
 926 kumpf      1.16         }
 927                     }
 928 kumpf      1.14 
 929 kumpf      1.16     //
 930 kumpf      1.17     // Check if there is a key file (file containing server
 931                     // private key) specified and the key was not already loaded.
 932                     // If specified, validate and load the key.
 933 kumpf      1.16     //
 934 kumpf      1.27     if (_keyPath != String::EMPTY && !keyLoaded)
 935 kumpf      1.16     {
 936 kumpf      1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 937                             "---> SSL: loading private key from: " + _keyPath);
 938 kumpf      1.14         //
 939                         // load given private key and check for validity
 940                         //
 941 kumpf      1.27         if (!_verifyPrivateKey(sslContext, _keyPath))
 942 kumpf      1.14         {
 943 humberto   1.18             MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
 944                             					         "Could not get private key.");
 945 kumpf      1.27             PEG_METHOD_EXIT();
 946 tony       1.24             throw SSLException(parms);
 947 kumpf      1.14         }
 948 kumpf      1.17         keyLoaded = true;
 949 kumpf      1.14     }
 950                 
 951                     PEG_METHOD_EXIT();
 952                     return sslContext;
 953                 }
 954                 
 955 kumpf      1.27 Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx, const String& keyPath)
 956 kumpf      1.14 {
 957                     PEG_METHOD_ENTER(TRC_SSL, "_verifyPrivateKey()");
 958                 
 959 kumpf      1.27     if (SSL_CTX_use_PrivateKey_file(ctx, keyPath.getCString(), SSL_FILETYPE_PEM) <= 0)
 960 kumpf      1.3      {
 961 kumpf      1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 962 kumpf      1.16             "---> SSL: no private key found in " + String(keyPath));
 963 kumpf      1.3          PEG_METHOD_EXIT();
 964 kumpf      1.14         return false;
 965                     }
 966                 
 967                     if (!SSL_CTX_check_private_key(ctx))
 968                     {
 969 kumpf      1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 970 kumpf      1.14             "---> SSL: Private and public key do not match");
 971                         PEG_METHOD_EXIT();
 972                         return false;
 973 kumpf      1.3      }
 974 kumpf      1.1  
 975 kumpf      1.3      PEG_METHOD_EXIT();
 976 kumpf      1.14     return true;
 977 kumpf      1.1  }
 978                 
 979                 SSL_CTX * SSLContextRep::getContext() const 
 980                 {
 981 kumpf      1.9      return _sslContext;
 982 kumpf      1.1  }
 983 h.sterling 1.26 
 984                 String SSLContextRep::getTrustStore() const
 985                 {
 986                     return _trustStore;
 987                 }
 988                 
 989                 String SSLContextRep::getCertPath() const
 990                 {
 991                     return _certPath;
 992                 }
 993                 
 994                 String SSLContextRep::getKeyPath() const
 995                 {
 996                     return _keyPath;
 997                 }
 998                 
 999                 Boolean SSLContextRep::isPeerVerificationEnabled() const
1000                 {
1001                     return _verifyPeer;
1002                 }
1003                 
1004 h.sterling 1.26 Boolean SSLContextRep::isTrustStoreAutoUpdateEnabled() const
1005                 {
1006                     return _trustStoreAutoUpdate;
1007                 }
1008                 
1009                 String SSLContextRep::getTrustStoreUserName() const
1010                 {
1011                 	return _trustStoreUserName;
1012                 }
1013                 
1014 h.sterling 1.28 SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const
1015                 {
1016                     return _certificateVerifyFunction;
1017                 }
1018                 
1019 kumpf      1.1  #else 
1020                 
1021                 //
1022 kumpf      1.9  // these definitions are used if ssl is not available
1023 kumpf      1.1  //
1024                 
1025 h.sterling 1.26 SSLContextRep::SSLContextRep(const String& trustStore,
1026 kumpf      1.16                        const String& certPath,
1027                                        const String& keyPath,
1028 kumpf      1.9                         SSLCertificateVerifyFunction* verifyCert,
1029 kumpf      1.13                        const String& randomFile) {}
1030 kumpf      1.1  
1031 h.sterling 1.26 #ifdef PEGASUS_USE_SSL_CLIENT_VERIFICATION
1032                 SSLContextRep::SSLContextRep(const String& trustStore,
1033                                        const String& certPath,
1034                                        const String& keyPath,
1035                                        SSLCertificateVerifyFunction* verifyCert,
1036                                        Boolean trustStoreAutoUpdate,
1037                 					   String trustStoreUserName,
1038                                        const String& randomFile) {}
1039                 #endif
1040                 
1041 kumpf      1.9  SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep) {}
1042                 
1043 kumpf      1.1  SSLContextRep::~SSLContextRep() {}
1044                 
1045 kumpf      1.9  SSL_CTX * SSLContextRep::_makeSSLContext() { return 0; }
1046                 
1047 kumpf      1.27 Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx, 
1048                                                          const String& keyPath) { return false; }
1049 kumpf      1.14 
1050 kumpf      1.9  SSL_CTX * SSLContextRep::getContext() const { return 0; }
1051 kumpf      1.15 
1052 h.sterling 1.26 String SSLContextRep::getTrustStore() const { return String::EMPTY; }
1053                 
1054                 String SSLContextRep::getCertPath() const { return String::EMPTY; }
1055                 
1056                 String SSLContextRep::getKeyPath() const { return String::EMPTY; }
1057                 
1058                 Boolean SSLContextRep::isPeerVerificationEnabled() const { return false; }
1059                 
1060                 Boolean SSLContextRep::isTrustStoreAutoUpdateEnabled() const { return false; }
1061                 
1062                 String SSLContextRep::getTrustStoreUserName() const { return String::EMPTY; }
1063                 
1064 h.sterling 1.28 SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const { return NULL; }
1065                 
1066 kumpf      1.15 void SSLContextRep::init_ssl() {}
1067                 
1068                 void SSLContextRep::free_ssl() {}
1069 kumpf      1.1  
1070                 #endif // end of PEGASUS_HAS_SSL
1071                 
1072                 ///////////////////////////////////////////////////////////////////////////////
1073                 //
1074                 // SSLContext
1075                 //
1076                 ///////////////////////////////////////////////////////////////////////////////
1077                 
1078                 
1079                 SSLContext::SSLContext(
1080 h.sterling 1.26     const String& trustStore,
1081 kumpf      1.9      SSLCertificateVerifyFunction* verifyCert,
1082 kumpf      1.13     const String& randomFile)
1083                 {
1084 h.sterling 1.26 #ifdef PEGASUS_USE_SSL_CLIENT_VERIFICATION
1085                     _rep = new SSLContextRep(trustStore, String::EMPTY, String::EMPTY,  verifyCert, false, String::EMPTY, randomFile);
1086                 #else
1087                     _rep = new SSLContextRep(trustStore, String::EMPTY, String::EMPTY,  verifyCert, randomFile);
1088                 #endif
1089 kumpf      1.13 }
1090                 
1091 kumpf      1.25 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1092 kumpf      1.13 SSLContext::SSLContext(
1093                     const String& certPath,
1094                     SSLCertificateVerifyFunction* verifyCert,
1095 kumpf      1.1      const String& randomFile,
1096 kumpf      1.6      Boolean isCIMClient)
1097 kumpf      1.1  {
1098 h.sterling 1.26 #ifdef PEGASUS_USE_SSL_CLIENT_VERIFICATION
1099                     _rep = new SSLContextRep(certPath, String::EMPTY, String::EMPTY,  verifyCert, false, String::EMPTY, randomFile);
1100                 #else
1101 kumpf      1.16     _rep = new SSLContextRep(certPath, String::EMPTY, String::EMPTY,  verifyCert, randomFile);
1102 h.sterling 1.26 #endif
1103 kumpf      1.16 }
1104                 
1105                 SSLContext::SSLContext(
1106                     const String& certPath,
1107                     const String& certKeyPath,
1108                     SSLCertificateVerifyFunction* verifyCert,
1109                     const String& randomFile)
1110                 {
1111 h.sterling 1.26 #ifdef PEGASUS_USE_SSL_CLIENT_VERIFICATION
1112                     _rep = new SSLContextRep(certPath, certKeyPath, String::EMPTY, verifyCert, false, String::EMPTY, randomFile);
1113                 #else
1114 kumpf      1.16     _rep = new SSLContextRep(certPath, certKeyPath, String::EMPTY, verifyCert, randomFile);
1115 h.sterling 1.26 #endif
1116 kumpf      1.1  }
1117 kumpf      1.13 #endif
1118 kumpf      1.1  
1119 kumpf      1.14 SSLContext::SSLContext(
1120 h.sterling 1.26     const String& trustStore,
1121 kumpf      1.14     const String& certPath,
1122 kumpf      1.16     const String& keyPath,
1123 kumpf      1.14     SSLCertificateVerifyFunction* verifyCert,
1124                     const String& randomFile)
1125                 {
1126 h.sterling 1.26 #ifdef PEGASUS_USE_SSL_CLIENT_VERIFICATION
1127                     _rep = new SSLContextRep(trustStore, certPath, keyPath, verifyCert, false, String::EMPTY, randomFile);
1128                 #else
1129                     _rep = new SSLContextRep(trustStore, certPath, keyPath, verifyCert, randomFile);
1130                 #endif
1131                 }
1132                 
1133                 #ifdef PEGASUS_USE_SSL_CLIENT_VERIFICATION
1134                 SSLContext::SSLContext(
1135                         const String& trustStore,
1136                         const String& certPath,
1137                         const String& keyPath,
1138                         SSLCertificateVerifyFunction* verifyCert,
1139                         Boolean trustStoreAutoUpdate,
1140                 		String trustStoreUserName,
1141                         const String& randomFile)
1142                 {
1143                     _rep = new SSLContextRep(trustStore, certPath, keyPath, verifyCert, trustStoreAutoUpdate, trustStoreUserName, randomFile);
1144 kumpf      1.14 }
1145 h.sterling 1.26 #endif
1146                 
1147 kumpf      1.14 
1148 kumpf      1.9  SSLContext::SSLContext(const SSLContext& sslContext)
1149                 {
1150                     _rep = new SSLContextRep(*sslContext._rep);
1151 kumpf      1.12 }
1152                 
1153                 // Dummy constructor made private to disallow default construction
1154                 SSLContext::SSLContext()
1155                 {
1156 kumpf      1.9  }
1157                 
1158 kumpf      1.1  SSLContext::~SSLContext() 
1159                 {
1160                     delete _rep;
1161                 }
1162                 
1163 h.sterling 1.26 String SSLContext::getTrustStore() const
1164                 {
1165                     return (_rep->getTrustStore());
1166                 }
1167                 
1168                 String SSLContext::getCertPath() const
1169                 {
1170                     return (_rep->getCertPath());
1171                 }
1172                 
1173                 String SSLContext::getKeyPath() const
1174                 {
1175                     return (_rep->getKeyPath()); 
1176                 }
1177                 
1178                 Boolean SSLContext::isPeerVerificationEnabled() const
1179                 {
1180                     return (_rep->isPeerVerificationEnabled());
1181                 }
1182                 
1183                 Boolean SSLContext::isTrustStoreAutoUpdateEnabled() const
1184 h.sterling 1.26 {
1185                     return (_rep->isTrustStoreAutoUpdateEnabled());
1186                 }
1187                 
1188                 String SSLContext::getTrustStoreUserName() const
1189                 {
1190                 	return (_rep->getTrustStoreUserName());
1191                 }
1192 kumpf      1.1  
1193 h.sterling 1.28 SSLCertificateVerifyFunction* SSLContext::getSSLCertificateVerifyFunction() const
1194                 {
1195                     return (_rep->getSSLCertificateVerifyFunction());
1196                 }
1197                 
1198 kumpf      1.1  ///////////////////////////////////////////////////////////////////////////////
1199                 //
1200 kumpf      1.9  // SSLCertificateInfo
1201 kumpf      1.1  //
1202                 ///////////////////////////////////////////////////////////////////////////////
1203 kumpf      1.16 //
1204                 // Certificate validation result codes.
1205                 //
1206                 const int    SSLCertificateInfo::V_OK                                       = 0;
1207                 
1208                 const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT            = 2;
1209                 const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_CRL                    = 3;
1210                 const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     = 4;
1211                 const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      = 5;
1212                 const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   = 6;
1213                 const int    SSLCertificateInfo::V_ERR_CERT_SIGNATURE_FAILURE               = 7;
1214                 const int    SSLCertificateInfo::V_ERR_CRL_SIGNATURE_FAILURE                = 8;
1215                 const int    SSLCertificateInfo::V_ERR_CERT_NOT_YET_VALID                   = 9;
1216                 const int    SSLCertificateInfo::V_ERR_CERT_HAS_EXPIRED                     = 10;
1217                 const int    SSLCertificateInfo::V_ERR_CRL_NOT_YET_VALID                    = 11;
1218                 const int    SSLCertificateInfo::V_ERR_CRL_HAS_EXPIRED                      = 12;
1219                 const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       = 13;
1220                 const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        = 14;
1221                 const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       = 15;
1222                 const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       = 16;
1223                 const int    SSLCertificateInfo::V_ERR_OUT_OF_MEM                           = 17;
1224 kumpf      1.16 const int    SSLCertificateInfo::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          = 18;
1225                 const int    SSLCertificateInfo::V_ERR_SELF_SIGNED_CERT_IN_CHAIN            = 19;
1226                 const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    = 20;
1227                 const int    SSLCertificateInfo::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      = 21;
1228                 const int    SSLCertificateInfo::V_ERR_CERT_CHAIN_TOO_LONG                  = 22;
1229                 const int    SSLCertificateInfo::V_ERR_CERT_REVOKED                         = 23;
1230                 const int    SSLCertificateInfo::V_ERR_INVALID_CA                           = 24;
1231                 const int    SSLCertificateInfo::V_ERR_PATH_LENGTH_EXCEEDED                 = 25;
1232                 const int    SSLCertificateInfo::V_ERR_INVALID_PURPOSE                      = 26;
1233                 const int    SSLCertificateInfo::V_ERR_CERT_UNTRUSTED                       = 27;
1234                 const int    SSLCertificateInfo::V_ERR_CERT_REJECTED                        = 28;
1235                 const int    SSLCertificateInfo::V_ERR_SUBJECT_ISSUER_MISMATCH              = 29;
1236                 const int    SSLCertificateInfo::V_ERR_AKID_SKID_MISMATCH                   = 30;
1237                 const int    SSLCertificateInfo::V_ERR_AKID_ISSUER_SERIAL_MISMATCH          = 31;
1238                 const int    SSLCertificateInfo::V_ERR_KEYUSAGE_NO_CERTSIGN                 = 32;
1239                 
1240                 const int    SSLCertificateInfo::V_ERR_APPLICATION_VERIFICATION             = 50;
1241 kumpf      1.1  
1242 kumpf      1.9  class SSLCertificateInfoRep
1243                 {
1244                 public:
1245 kumpf      1.16     String    subjectName;
1246                     String    issuerName;
1247                     Uint32    depth;
1248                     Uint32    errorCode;
1249                     Uint32    respCode;
1250                     String    errorString;
1251                     Uint32    versionNumber;
1252                     long      serialNumber;
1253                     CIMDateTime    notBefore;
1254                     CIMDateTime    notAfter;
1255 kumpf      1.9  };
1256                 
1257                 
1258                 SSLCertificateInfo::SSLCertificateInfo(
1259 kumpf      1.1      const String subjectName,
1260                     const String issuerName,
1261                     const int errorDepth,
1262 kumpf      1.14     const int errorCode,
1263                     const int respCode)
1264 kumpf      1.1  {
1265 kumpf      1.9      _rep = new SSLCertificateInfoRep();
1266                     _rep->subjectName = subjectName;
1267                     _rep->issuerName = issuerName;
1268 kumpf      1.16     _rep->versionNumber = 0;
1269                     _rep->serialNumber = 0;
1270 h.sterling 1.26     _rep->notBefore = CIMDateTime();
1271                     _rep->notAfter = CIMDateTime();
1272 kumpf      1.16     _rep->depth = errorDepth;
1273 kumpf      1.9      _rep->errorCode = errorCode;
1274 kumpf      1.16     _rep->errorString = String::EMPTY;
1275                     _rep->respCode = respCode;
1276                 }
1277                 
1278                 SSLCertificateInfo::SSLCertificateInfo(
1279                     const String subjectName,
1280                     const String issuerName,
1281                     const Uint32 versionNumber,
1282                     const long serialNumber,
1283                     const CIMDateTime notBefore,
1284                     const CIMDateTime notAfter,
1285                     const Uint32 depth,
1286                     const Uint32 errorCode,
1287                     const String errorString,
1288                     const Uint32 respCode)
1289                 {
1290                     _rep = new SSLCertificateInfoRep();
1291                     _rep->subjectName = subjectName;
1292                     _rep->issuerName = issuerName;
1293                     _rep->versionNumber = versionNumber;
1294                     _rep->serialNumber = serialNumber;
1295 kumpf      1.16     _rep->notBefore = notBefore;
1296                     _rep->notAfter = notAfter;
1297                     _rep->depth = depth;
1298                     _rep->errorCode = errorCode;
1299                     _rep->errorString = errorString;
1300 kumpf      1.14     _rep->respCode = respCode;
1301 kumpf      1.9  }
1302                 
1303                 SSLCertificateInfo::SSLCertificateInfo(
1304                     const SSLCertificateInfo& certificateInfo)
1305                 {
1306                     _rep = new SSLCertificateInfoRep();
1307                     _rep->subjectName = certificateInfo._rep->subjectName;
1308                     _rep->issuerName = certificateInfo._rep->issuerName;
1309 kumpf      1.16     _rep->versionNumber = certificateInfo._rep->versionNumber;
1310                     _rep->serialNumber = certificateInfo._rep->serialNumber;
1311                     _rep->notBefore = certificateInfo._rep->notBefore;
1312                     _rep->notAfter = certificateInfo._rep->notAfter;
1313                     _rep->depth = certificateInfo._rep->depth;
1314 kumpf      1.9      _rep->errorCode = certificateInfo._rep->errorCode;
1315 kumpf      1.16     _rep->errorString = certificateInfo._rep->errorString;
1316 kumpf      1.9      _rep->respCode = certificateInfo._rep->respCode;
1317 kumpf      1.11 }
1318                 
1319                 // Dummy constructor made private to disallow default construction
1320                 SSLCertificateInfo::SSLCertificateInfo()
1321                 {
1322 kumpf      1.1  }
1323                 
1324 kumpf      1.9  SSLCertificateInfo::~SSLCertificateInfo()
1325 kumpf      1.1  {
1326 kumpf      1.9      delete _rep;
1327 kumpf      1.1  }
1328                 
1329 kumpf      1.9  String SSLCertificateInfo::getSubjectName() const
1330 kumpf      1.1  {
1331 kumpf      1.9      return (_rep->subjectName);
1332 kumpf      1.1  }
1333                 
1334 kumpf      1.9  String SSLCertificateInfo::getIssuerName() const
1335 kumpf      1.1  {
1336 kumpf      1.9      return (_rep->issuerName);
1337 kumpf      1.1  }
1338                 
1339 kumpf      1.16 Uint32 SSLCertificateInfo::getVersionNumber() const
1340                 {
1341                     return (_rep->versionNumber);
1342                 }
1343                 
1344                 long SSLCertificateInfo::getSerialNumber() const
1345 kumpf      1.1  {
1346 kumpf      1.16     return (_rep->serialNumber);
1347 kumpf      1.1  }
1348                 
1349 kumpf      1.16 CIMDateTime SSLCertificateInfo::getNotBefore() const
1350                 {
1351                     return (_rep->notBefore);
1352                 }
1353                 
1354                 CIMDateTime SSLCertificateInfo::getNotAfter() const 
1355                 {
1356                     return (_rep->notAfter);
1357                 }
1358                 
1359                 Uint32 SSLCertificateInfo::getErrorDepth() const
1360                 {
1361                     return (_rep->depth);
1362                 }
1363                 
1364                 Uint32 SSLCertificateInfo::getErrorCode()  const
1365 kumpf      1.1  {
1366 kumpf      1.9      return (_rep->errorCode);
1367 kumpf      1.14 }
1368                 
1369 kumpf      1.16 void SSLCertificateInfo::setErrorCode(const int errorCode)
1370                 {
1371                     _rep->errorCode = errorCode;
1372                 }
1373                 
1374                 String SSLCertificateInfo::getErrorString() const
1375                 {
1376                     return (_rep->errorString);
1377                 }
1378                 
1379                 Uint32 SSLCertificateInfo::getResponseCode()  const
1380 kumpf      1.14 {
1381                     return (_rep->respCode);
1382 kumpf      1.1  }
1383                 
1384 kumpf      1.9  void SSLCertificateInfo::setResponseCode(const int respCode)
1385 kumpf      1.1  {
1386 kumpf      1.9      _rep->respCode = respCode;
1387 kumpf      1.1  }
1388                 
1389 h.sterling 1.28 String SSLCertificateInfo::toString() const
1390                 {
1391                     char buf[1024];
1392                     
1393                     String s;
1394                 
1395                     s.append("Subject Name:\n\t");
1396                     s.append(_rep->subjectName);
1397                     s.append("\n");
1398                     
1399                     s.append("Issuer Name:\n\t");
1400                     s.append(_rep->issuerName);
1401                     s.append("\n");
1402                     
1403                     sprintf(buf, "Depth: %d\n", _rep->depth);
1404                     s.append(buf);
1405                     
1406                     sprintf(buf, "Error code: %d\n", _rep->errorCode);
1407                     s.append(buf);
1408                     
1409                     sprintf(buf, "Response (preverify) code: %d\n", _rep->respCode);
1410 h.sterling 1.28     s.append(buf);
1411                 
1412                     s.append("Error string: ");
1413                     s.append(_rep->errorString);
1414                     s.append("\n");
1415                     
1416                     sprintf(buf, "Version number: %d\n", _rep->versionNumber);
1417                     s.append(buf);
1418                 
1419                     sprintf(buf, "Serial number: %ld\n", _rep->serialNumber);
1420                     s.append(buf);
1421                     
1422                     s.append("Not before date: ");
1423                     s.append((_rep->notBefore).toString());
1424                     s.append("\n");
1425                 
1426                     s.append("Not after date: ");
1427                     s.append((_rep->notAfter).toString());
1428                     s.append("\n");
1429                 
1430                     return s;
1431 h.sterling 1.28 }
1432                 
1433                 SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert)
1434                 {
1435                     verifyCertificateCallback = verifyCert;
1436                     _peerCertificate = NULL;  
1437                 }
1438                 
1439                 SSLCallbackInfo::~SSLCallbackInfo()
1440                 {
1441                     if (_peerCertificate) 
1442                     {
1443                         delete _peerCertificate;
1444                     }
1445                 }
1446                 
1447 kumpf      1.1  PEGASUS_NAMESPACE_END
1448                 

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2