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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2