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

   1 martin 1.102 //%LICENSE////////////////////////////////////////////////////////////////
   2 martin 1.103 //
   3 martin 1.102 // Licensed to The Open Group (TOG) under one or more contributor license
   4              // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
   5              // this work for additional information regarding copyright ownership.
   6              // Each contributor licenses this file to you under the OpenPegasus Open
   7              // Source License; you may not use this file except in compliance with the
   8              // License.
   9 martin 1.103 //
  10 martin 1.102 // Permission is hereby granted, free of charge, to any person obtaining a
  11              // copy of this software and associated documentation files (the "Software"),
  12              // to deal in the Software without restriction, including without limitation
  13              // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  14              // and/or sell copies of the Software, and to permit persons to whom the
  15              // Software is furnished to do so, subject to the following conditions:
  16 martin 1.103 //
  17 martin 1.102 // The above copyright notice and this permission notice shall be included
  18              // in all copies or substantial portions of the Software.
  19 martin 1.103 //
  20 martin 1.102 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21 martin 1.103 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22 martin 1.102 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  23              // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  24              // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25              // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26              // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27 martin 1.103 //
  28 martin 1.102 //////////////////////////////////////////////////////////////////////////
  29 kumpf  1.1   //
  30              //%/////////////////////////////////////////////////////////////////////////////
  31              
  32              #ifdef PEGASUS_HAS_SSL
  33 kumpf  1.78  # include <Pegasus/Common/Config.h>
  34 kumpf  1.80  # include <Pegasus/Common/Executor.h>
  35 kumpf  1.78  # include <Pegasus/Common/Network.h>
  36              # define OPENSSL_NO_KRB5 1
  37              # include <openssl/err.h>
  38              # include <openssl/ssl.h>
  39              # include <openssl/rand.h>
  40 kumpf  1.1   #else
  41 kumpf  1.78  # define SSL_CTX void
  42 kumpf  1.1   #endif // end of PEGASUS_HAS_SSL
  43 kumpf  1.78  
  44              #include <time.h>
  45 kumpf  1.1   #include <Pegasus/Common/Socket.h>
  46              #include <Pegasus/Common/Tracer.h>
  47 kumpf  1.14  #include <Pegasus/Common/FileSystem.h>
  48 kumpf  1.75  #include <Pegasus/Common/MessageLoader.h>
  49 kumpf  1.1   
  50              #include "SSLContext.h"
  51              #include "SSLContextRep.h"
  52              
  53 ouyang.jian 1.88  #ifdef PEGASUS_OS_PASE
  54                   # include <ILEWrapper/ILEUtilities.h>
  55                   #endif
  56 david.dillard 1.38  
  57 h.sterling    1.42  typedef struct x509_store_ctx_st X509_STORE_CTX;
  58 david.dillard 1.38  
  59 david.dillard 1.59  typedef struct Timestamp
  60 kumpf         1.16  {
  61                         char year[4];
  62                         char month[2];
  63                         char day[2];
  64                         char hour[2];
  65                         char minutes[2];
  66                         char seconds[2];
  67                         char dot;
  68                         char microSeconds[6];
  69                         char plusOrMinus;
  70                         char utcOffset[3];
  71                         char padding[3];
  72                     } Timestamp_t;
  73                     
  74 kumpf         1.1   PEGASUS_USING_STD;
  75                     
  76                     PEGASUS_NAMESPACE_BEGIN
  77                     
  78 h.sterling    1.32  const int SSLCallbackInfo::SSL_CALLBACK_INDEX = 0;
  79                     
  80 kumpf         1.1   //
  81                     // use the following definitions only if SSL is available
  82 david.dillard 1.59  //
  83 kumpf         1.3   #ifdef PEGASUS_HAS_SSL
  84 kumpf         1.1   
  85 kumpf         1.93  AutoArrayPtr<Mutex> SSLEnvironmentInitializer::_sslLocks;
  86                     int SSLEnvironmentInitializer::_instanceCount = 0;
  87                     Mutex SSLEnvironmentInitializer::_instanceCountMutex;
  88 kumpf         1.15  
  89 kumpf         1.16  
  90                     //
  91                     // Convert ASN1_UTCTIME to CIMDateTime
  92                     //
  93                     CIMDateTime getDateTime(const ASN1_UTCTIME *utcTime)
  94                     {
  95                         struct tm time;
  96                         int offset;
  97                         Timestamp_t timeStamp;
  98                         char tempString[80];
  99                         char plusOrMinus = '+';
 100 kumpf         1.34      unsigned char* utcTimeData = utcTime->data;
 101 kumpf         1.16  
 102                         memset(&time, '\0', sizeof(time));
 103                     
 104                     #define g2(p) ( ( (p)[0] - '0' ) * 10 + (p)[1] - '0' )
 105                     
 106 kumpf         1.34      if (utcTime->type == V_ASN1_GENERALIZEDTIME)
 107                         {
 108                             time.tm_year = g2(utcTimeData) * 100;
 109                             utcTimeData += 2;  // Remaining data is equivalent to ASN1_UTCTIME type
 110                             time.tm_year += g2(utcTimeData);
 111                         }
 112                         else
 113 kumpf         1.16      {
 114 kumpf         1.34          time.tm_year = g2(utcTimeData);
 115                             if (time.tm_year < 50)
 116                             {
 117                                 time.tm_year += 2000;
 118                             }
 119                             else
 120                             {
 121                                 time.tm_year += 1900;
 122                             }
 123 kumpf         1.16      }
 124                     
 125 kumpf         1.34      time.tm_mon = g2(utcTimeData + 2) - 1;
 126                         time.tm_mday = g2(utcTimeData + 4);
 127                         time.tm_hour = g2(utcTimeData + 6);
 128                         time.tm_min = g2(utcTimeData + 8);
 129                         time.tm_sec = g2(utcTimeData + 10);
 130                     
 131                         if (utcTimeData[12] == 'Z')
 132 kumpf         1.16      {
 133                             offset = 0;
 134                         }
 135                         else
 136                         {
 137 kumpf         1.34          offset = g2(utcTimeData + 13) * 60 + g2(utcTimeData + 15);
 138                             if (utcTimeData[12] == '-')
 139 kumpf         1.16          {
 140                                 plusOrMinus = '-';
 141                             }
 142                         }
 143                     #undef g2
 144                     
 145                         memset((void *)&timeStamp, 0, sizeof(Timestamp_t));
 146                     
 147                         // Format the date.
 148                         sprintf((char *) &timeStamp,"%04d%02d%02d%02d%02d%02d.%06d%04d",
 149 kumpf         1.34              time.tm_year,
 150 david.dillard 1.59              time.tm_mon + 1,
 151 kumpf         1.16              time.tm_mday,
 152                                 time.tm_hour,
 153                                 time.tm_min,
 154                                 time.tm_sec,
 155                                 0,
 156                                 offset);
 157                     
 158                         timeStamp.plusOrMinus = plusOrMinus;
 159                     
 160                         CIMDateTime dateTime;
 161                     
 162                         dateTime.clear();
 163                         strcpy(tempString, (char *)&timeStamp);
 164                         dateTime.set(tempString);
 165                     
 166 kumpf         1.75      return dateTime;
 167 kumpf         1.16  }
 168                     
 169                     //
 170 h.sterling    1.40  // Static class used to define C++ callback functions for OpenSSL.
 171 david.dillard 1.38  //
 172                     class SSLCallback
 173                     {
 174                     
 175                     public:
 176 kumpf         1.75      static int verificationCallback(
 177                             int preVerifyOk,
 178                             X509_STORE_CTX* ctx);
 179                         static int verificationCRLCallback(
 180                             int ok,
 181                             X509_STORE_CTX* ctx,
 182                             X509_STORE* sslCRLStore);
 183 david.dillard 1.38  };
 184                     
 185                     //
 186 kumpf         1.16  // Callback function that is called by the OpenSSL library. This function
 187 h.sterling    1.40  // checks whether the certificate is listed in any of the CRL's
 188                     //
 189 h.sterling    1.47  // return 1 if revoked, 0 otherwise
 190                     //
 191 kumpf         1.75  int SSLCallback::verificationCRLCallback(
 192                         int ok,
 193                         X509_STORE_CTX* ctx,
 194                         X509_STORE* sslCRLStore)
 195 h.sterling    1.40  {
 196 h.sterling    1.47      PEG_METHOD_ENTER(TRC_SSL, "SSLCallback::verificationCRLCallback");
 197 david.dillard 1.59  
 198 h.sterling    1.47      char buf[1024];
 199 h.sterling    1.46  
 200 h.sterling    1.47      //check whether a CRL store was specified
 201 h.sterling    1.46      if (sslCRLStore == NULL)
 202                         {
 203 marek         1.77          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 204 kumpf         1.75              "---> SSL: CRL store is NULL");
 205 h.sterling    1.62          PEG_METHOD_EXIT();
 206 h.sterling    1.47          return 0;
 207 h.sterling    1.46      }
 208                     
 209 h.sterling    1.47      //get the current certificate info
 210                         X509* currentCert;
 211                         X509_NAME* issuerName;
 212                         X509_NAME* subjectName;
 213                         ASN1_INTEGER* serialNumber;
 214 h.sterling    1.46  
 215                         currentCert = X509_STORE_CTX_get_current_cert(ctx);
 216 h.sterling    1.47      subjectName = X509_get_subject_name(currentCert);
 217                         issuerName = X509_get_issuer_name(currentCert);
 218                         serialNumber = X509_get_serialNumber(currentCert);
 219 h.sterling    1.46  
 220 h.sterling    1.47      //log certificate information
 221                         //this is information in the "public" key, so it does no harm to log it
 222 h.sterling    1.46      X509_NAME_oneline(issuerName, buf, sizeof(buf));
 223 marek         1.77      PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
 224 kumpf         1.75          "---> SSL: Certificate Data: Issuer/Subject");
 225 marek         1.77      PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, buf);
 226 h.sterling    1.47      X509_NAME_oneline(subjectName, buf, sizeof(buf));
 227 marek         1.77      PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, buf);
 228 h.sterling    1.47  
 229                         //initialize the CRL store
 230                         X509_STORE_CTX crlStoreCtx;
 231                         X509_STORE_CTX_init(&crlStoreCtx, sslCRLStore, NULL, NULL);
 232                     
 233 marek         1.77      PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
 234 kumpf         1.75          "---> SSL: Initialized CRL store");
 235 h.sterling    1.47  
 236                         //attempt to get a CRL issued by the certificate's issuer
 237                         X509_OBJECT obj;
 238 kumpf         1.75      if (X509_STORE_get_by_subject(
 239                                 &crlStoreCtx, X509_LU_CRL, issuerName, &obj) <= 0)
 240 h.sterling    1.47      {
 241 kumpf         1.91          X509_STORE_CTX_cleanup(&crlStoreCtx);
 242 marek         1.77          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 243 kumpf         1.75              "---> SSL: No CRL by that issuer");
 244 h.sterling    1.62          PEG_METHOD_EXIT();
 245 david.dillard 1.59          return 0;
 246 h.sterling    1.47      }
 247                         X509_STORE_CTX_cleanup(&crlStoreCtx);
 248 h.sterling    1.46  
 249 h.sterling    1.47      //get CRL
 250 h.sterling    1.46      X509_CRL* crl = obj.data.crl;
 251 h.sterling    1.47      if (crl == NULL)
 252                         {
 253 marek         1.77          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL is null");
 254 h.sterling    1.62          PEG_METHOD_EXIT();
 255 h.sterling    1.47          return 0;
 256 kumpf         1.75      }
 257                         else
 258 h.sterling    1.47      {
 259 marek         1.77          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
 260 kumpf         1.75              "---> SSL: Found CRL by that issuer");
 261 h.sterling    1.47      }
 262 h.sterling    1.46  
 263 h.sterling    1.47      //get revoked certificates
 264 h.sterling    1.46      STACK_OF(X509_REVOKED)* revokedCerts = NULL;
 265                         revokedCerts = X509_CRL_get_REVOKED(crl);
 266 h.sterling    1.47      int numRevoked = sk_X509_REVOKED_num(revokedCerts);
 267 marek         1.77      PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
 268 kumpf         1.75          "---> SSL: Number of certificates revoked by the issuer %d\n",
 269 marek         1.77          numRevoked));
 270 h.sterling    1.46  
 271 h.sterling    1.47      //check whether the subject's certificate is revoked
 272                         X509_REVOKED* revokedCert = NULL;
 273                         for (int i = 0; i < sk_X509_REVOKED_num(revokedCerts); i++)
 274                         {
 275                             revokedCert = (X509_REVOKED *)sk_value(X509_CRL_get_REVOKED(crl), i);
 276 h.sterling    1.46  
 277 h.sterling    1.47          //a matching serial number indicates revocation
 278 david.dillard 1.59          if (ASN1_INTEGER_cmp(revokedCert->serialNumber, serialNumber) == 0)
 279 h.sterling    1.47          {
 280 marek         1.77              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL2,
 281 kumpf         1.75                  "---> SSL: Certificate is revoked");
 282 h.sterling    1.47              X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
 283 kumpf         1.92              X509_CRL_free(crl);
 284 h.sterling    1.62              PEG_METHOD_EXIT();
 285 h.sterling    1.47              return 1;
 286                             }
 287                         }
 288 h.sterling    1.40  
 289 kumpf         1.92      X509_CRL_free(crl);
 290                     
 291 marek         1.77      PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
 292 kumpf         1.75          "---> SSL: Certificate is not revoked at this level");
 293 h.sterling    1.47  
 294                         PEG_METHOD_EXIT();
 295                         return 0;
 296 h.sterling    1.40  }
 297                     
 298                     //
 299                     // Callback function that is called by the OpenSSL library. This function
 300 kumpf         1.16  // extracts X509 certficate information and pass that on to client application
 301                     // callback function.
 302 kumpf         1.75  // We HAVE to build the certificate in all cases since it's needed to get
 303                     // the associated username out of the repository later in the transaction.
 304 kumpf         1.16  //
 305 kumpf         1.75  int SSLCallback::verificationCallback(int preVerifyOk, X509_STORE_CTX* ctx)
 306 kumpf         1.1   {
 307 david.dillard 1.38      PEG_METHOD_ENTER(TRC_SSL, "SSLCallback::callback()");
 308 kumpf         1.1       char   buf[256];
 309 kumpf         1.16      X509   *currentCert;
 310 h.sterling    1.28      SSL    *ssl;
 311 h.sterling    1.47      int    revoked = -1;
 312 david.dillard 1.59  
 313 marek         1.77      PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
 314 kumpf         1.89          "--->SSL: Preverify result %d", preVerifyOk));
 315 kumpf         1.1   
 316 h.sterling    1.28      //
 317                         // get the verification callback info specific to each SSL connection
 318                         //
 319 kumpf         1.75      ssl = (SSL*) X509_STORE_CTX_get_ex_data(
 320                             ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
 321                         SSLCallbackInfo* exData = (SSLCallbackInfo*) SSL_get_ex_data(
 322                             ssl, SSLCallbackInfo::SSL_CALLBACK_INDEX);
 323 h.sterling    1.28  
 324 sushma.fernandes 1.66  #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
 325 kumpf            1.16      //
 326 h.sterling       1.47      // Check to see if a CRL path is defined
 327                            //
 328 david.dillard    1.59      if (exData->_rep->crlStore != NULL)
 329 h.sterling       1.47      {
 330 kumpf            1.75          revoked = verificationCRLCallback(
 331                                    preVerifyOk,ctx,exData->_rep->crlStore);
 332 marek            1.77          PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
 333                                    "---> SSL: CRL callback returned %d", revoked));
 334 h.sterling       1.46  
 335 h.sterling       1.47          if (revoked) //with the SSL callbacks '0' indicates failure
 336                                {
 337                                    PEG_METHOD_EXIT();
 338 h.sterling       1.46              return 0;
 339 h.sterling       1.47          }
 340                            }
 341                        
 342 marek            1.77      PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
 343                                "---> SSL: CRL callback returned %d", revoked));
 344 sushma.fernandes 1.66  #endif
 345 h.sterling       1.40  
 346                            //
 347 kumpf            1.16      // get the current certificate
 348                            //
 349                            currentCert = X509_STORE_CTX_get_current_cert(ctx);
 350 kumpf            1.1   
 351 kumpf            1.16      //
 352                            // get the default verification error code
 353                            //
 354                            int errorCode = X509_STORE_CTX_get_error(ctx);
 355                        
 356                            //
 357                            // get the depth of certificate chain
 358                            //
 359                            int depth = X509_STORE_CTX_get_error_depth(ctx);
 360 kumpf            1.1   
 361 kumpf            1.16      //
 362                            // get the version on the certificate
 363                            //
 364                            long version = X509_get_version(currentCert);
 365 kumpf            1.1   
 366 kumpf            1.16      //
 367                            // get the serial number of the certificate
 368                            //
 369                            long serialNumber = ASN1_INTEGER_get(X509_get_serialNumber(currentCert));
 370                        
 371                            //
 372                            // get the validity of the certificate
 373                            //
 374                            CIMDateTime notBefore = getDateTime(X509_get_notBefore(currentCert));
 375                        
 376                            CIMDateTime notAfter = getDateTime(X509_get_notAfter(currentCert));
 377                        
 378                            //
 379                            // get the subject name on the certificate
 380                            //
 381                            X509_NAME_oneline(X509_get_subject_name(currentCert), buf, 256);
 382                            String subjectName = String(buf);
 383                        
 384                            //
 385 david.dillard    1.59      // get the default verification error string
 386 kumpf            1.16      //
 387                            String errorStr = String(X509_verify_cert_error_string(errorCode));
 388 kumpf            1.1   
 389 kumpf            1.16      //
 390                            // log the error string if the default verification was failed
 391                            //
 392                            if (!preVerifyOk)
 393 kumpf            1.1       {
 394 marek            1.98          PEG_TRACE((TRC_SSL, Tracer::LEVEL2,
 395 kumpf            1.75              "---> SSL: certificate default verification error: %s",
 396 marek            1.77              (const char*)errorStr.getCString()));
 397 kumpf            1.1       }
 398                        
 399 kumpf            1.16      //
 400                            // get the issuer name on the certificate
 401                            //
 402 sushma.fernandes 1.64      X509_NAME_oneline(X509_get_issuer_name(currentCert), buf, 256);
 403 kumpf            1.16      String issuerName = String(buf);
 404 kumpf            1.1   
 405 h.sterling       1.47      //
 406                            // Create the certificate object
 407                            //
 408 kumpf            1.75  
 409                            // insert at the beginning of the array so that the peer certificate is
 410                            // first and the root CA is last
 411                            exData->_rep->peerCertificate.insert(0, new SSLCertificateInfo(
 412                                subjectName, issuerName, version, serialNumber,
 413 h.sterling       1.63          notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk));
 414                        
 415 marek            1.77      PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "Created SSLCertificateInfo");
 416 h.sterling       1.63  
 417 kumpf            1.75      // NOT_YET_VALID checks do not work correctly on subsequent tries --
 418                            // Bugzilla#4283
 419                            // call this prior to calling the user-specified callback in case they
 420                            // want to override it
 421                            if (errorCode == X509_V_OK &&
 422                                (CIMDateTime::getDifference(
 423                                     CIMDateTime::getCurrentDateTime(), notBefore) > 0))
 424 h.sterling       1.54      {
 425 marek            1.98          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL2,
 426 kumpf            1.75              "Certificate was not yet valid.");
 427 sushma.fernandes 1.79  
 428 kumpf            1.75          X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_NOT_YET_VALID);
 429 david.dillard    1.59      }
 430 h.sterling       1.54  
 431 kumpf            1.1       //
 432 kumpf            1.75      // Call the user-specified application callback if it is specified.
 433                            // If it is null, return OpenSSL's verification code.
 434                            // Note that the verification result does not automatically get set
 435                            // to X509_V_OK if the callback is successful.
 436                            // This is because OpenSSL retains the original default error in case
 437                            // we want to use it later.
 438                            // To set the error, we could use X509_STORE_CTX_set_error(ctx,
 439 kumpf            1.97      // X509_V_OK); but there is no real benefit to doing that here.
 440 kumpf            1.1       //
 441 h.sterling       1.58      if (exData->_rep->verifyCertificateCallback == NULL)
 442 kumpf            1.1       {
 443 kumpf            1.89          PEG_METHOD_EXIT();
 444 h.sterling       1.58          return preVerifyOk;
 445 kumpf            1.75      }
 446                            else
 447 kumpf            1.16      {
 448 kumpf            1.75          if (exData->_rep->verifyCertificateCallback(
 449                                        *exData->_rep->peerCertificate[0]))
 450 h.sterling       1.58          {
 451 marek            1.77              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
 452 kumpf            1.75                  "--> SSL: _rep->verifyCertificateCallback() returned "
 453                                            "X509_V_OK");
 454 h.sterling       1.58              PEG_METHOD_EXIT();
 455                                    return 1;
 456                                }
 457                                else // verification failed, handshake will be immediately terminated
 458                                {
 459 marek            1.98              PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 460 kumpf            1.75                  "--> SSL: _rep->verifyCertificateCallback() returned error %d",
 461 marek            1.77                  exData->_rep->peerCertificate[0]->getErrorCode()));
 462 david.dillard    1.59  
 463 h.sterling       1.58              PEG_METHOD_EXIT();
 464 david.dillard    1.59              return 0;
 465 h.sterling       1.58          }
 466 kumpf            1.1       }
 467                        }
 468                        
 469 kumpf            1.15  //
 470 kumpf            1.75  // Callback function called by OpenSSL.  This request is merely forwarded
 471                        // to the static function SSLCallback::callback().  The SSLCallback class
 472                        // is a friend class of the Pegasus SSL related classes needed to complete
 473                        // the callback.
 474 david.dillard    1.38  //
 475                        extern "C" int prepareForCallback(int preVerifyOk, X509_STORE_CTX *ctx)
 476                        {
 477 h.sterling       1.40      return SSLCallback::verificationCallback(preVerifyOk, ctx);
 478 david.dillard    1.38  }
 479                        
 480                        //
 481 kumpf            1.1   // SSL context area
 482                        //
 483                        // For the OSs that don't have /dev/random device file,
 484                        // must enable PEGASUS_SSL_RANDOMFILE flag.
 485                        //
 486 h.sterling       1.26  SSLContextRep::SSLContextRep(
 487 kumpf            1.75      const String& trustStore,
 488                            const String& certPath,
 489                            const String& keyPath,
 490                            const String& crlPath,
 491                            SSLCertificateVerifyFunction* verifyCert,
 492                            const String& randomFile)
 493 h.sterling       1.26  {
 494                            PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
 495                        
 496                            _trustStore = trustStore;
 497                            _certPath = certPath;
 498                            _keyPath = keyPath;
 499 h.sterling       1.40      _crlPath = crlPath;
 500                            _certificateVerifyFunction = verifyCert;
 501 h.sterling       1.26  
 502 h.sterling       1.28      //
 503 kumpf            1.75      // If a truststore and/or peer verification function is specified,
 504                            // enable peer verification
 505 h.sterling       1.28      //
 506 kumpf            1.93      _verifyPeer = (trustStore != String::EMPTY || verifyCert != NULL);
 507 kumpf            1.1   
 508 kumpf            1.14      _randomInit(randomFile);
 509 kumpf            1.1   
 510 kumpf            1.9       _sslContext = _makeSSLContext();
 511                        
 512                            PEG_METHOD_EXIT();
 513                        }
 514                        
 515                        SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep)
 516                        {
 517                            PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
 518                        
 519 h.sterling       1.26      _trustStore = sslContextRep._trustStore;
 520 kumpf            1.9       _certPath = sslContextRep._certPath;
 521 kumpf            1.16      _keyPath = sslContextRep._keyPath;
 522 h.sterling       1.47      _crlPath = sslContextRep._crlPath;
 523 h.sterling       1.26      _verifyPeer = sslContextRep._verifyPeer;
 524 h.sterling       1.28      _certificateVerifyFunction = sslContextRep._certificateVerifyFunction;
 525 kumpf            1.9       _randomFile = sslContextRep._randomFile;
 526 kumpf            1.15  
 527 kumpf            1.93      _sslContext = _makeSSLContext();
 528 david.dillard    1.59  
 529 kumpf            1.9       PEG_METHOD_EXIT();
 530                        }
 531 kumpf            1.11  
 532 kumpf            1.9   //
 533                        // Destructor
 534                        //
 535                        
 536                        SSLContextRep::~SSLContextRep()
 537                        {
 538                            PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::~SSLContextRep()");
 539                        
 540                            SSL_CTX_free(_sslContext);
 541                        
 542                            PEG_METHOD_EXIT();
 543                        }
 544                        
 545 kumpf            1.14  //
 546                        // initialize OpenSSL's PRNG
 547                        //
 548                        void SSLContextRep::_randomInit(const String& randomFile)
 549                        {
 550                            PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_randomInit()");
 551                        
 552                            Boolean ret;
 553                            int retVal = 0;
 554                        
 555 ouyang.jian      1.88  #if defined(PEGASUS_SSL_RANDOMFILE) && !defined(PEGASUS_OS_PASE)
 556 kumpf            1.14      if ( RAND_status() == 0 )
 557                            {
 558                                //
 559                                // Initialise OpenSSL random number generator.
 560                                //
 561                                if ( randomFile == String::EMPTY )
 562                                {
 563 marek            1.98              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
 564 kumpf            1.14                  "Random seed file is required.");
 565                                    PEG_METHOD_EXIT();
 566 kumpf            1.75              MessageLoaderParms parms(
 567                                        "Common.SSLContext.RANDOM_SEED_FILE_REQUIRED",
 568                                        "Random seed file required");
 569 david.dillard    1.59              throw SSLException(parms);
 570 kumpf            1.14          }
 571                        
 572                                //
 573                                // Try the given random seed file
 574                                //
 575                                ret = FileSystem::exists(randomFile);
 576 kumpf            1.75          if (ret)
 577 kumpf            1.14          {
 578 david.dillard    1.59              retVal = RAND_load_file(randomFile.getCString(), -1);
 579 kumpf            1.14              if ( retVal < 0 )
 580                                    {
 581 thilo.boehm      1.101                 PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 582                                            "Not enough seed data in seed file: %s",
 583                                            (const char*)randomFile.getCString()));
 584 kumpf            1.14                  PEG_METHOD_EXIT();
 585 kumpf            1.75                  // do not put in $0 in default message, but pass in filename
 586                                        // for bundle message
 587                                        MessageLoaderParms parms(
 588                                            "Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
 589                                            "Not enough seed data in random seed file.",
 590                                            randomFile);
 591 h.sterling       1.47                  throw SSLException(parms);
 592 kumpf            1.14              }
 593                                }
 594 kumpf            1.16          else
 595                                {
 596 thilo.boehm      1.101             PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 597 kumpf            1.104                 "Seed file \'%s\' does not exist.",
 598 thilo.boehm      1.101                 (const char*)randomFile.getCString()));
 599 kumpf            1.16              PEG_METHOD_EXIT();
 600 kumpf            1.75              MessageLoaderParms parms(
 601                                        "Common.SSLContext.SEED_FILE_DOES_NOT_EXIST",
 602                                        "Seed file '$0' does not exist.",
 603                                        randomFile);
 604 tony             1.24              throw SSLException(parms);
 605 kumpf            1.16          }
 606 kumpf            1.14  
 607                                if ( RAND_status() == 0 )
 608                                {
 609                                    //
 610                                    // Try to do more seeding
 611                                    //
 612                                    long seedNumber;
 613 kumpf            1.85  # if defined(PEGASUS_COMPILER_MSVC)
 614 tony             1.24              srand((unsigned int)time(NULL)); // Initialize
 615                                    seedNumber = rand();
 616 kumpf            1.85  # else
 617 kumpf            1.14              srandom((unsigned int)time(NULL)); // Initialize
 618                                    seedNumber = random();
 619 kumpf            1.85  # endif
 620 kumpf            1.14              RAND_seed((unsigned char *) &seedNumber, sizeof(seedNumber));
 621                        
 622                                    int  seedRet = RAND_status();
 623                                    if ( seedRet == 0 )
 624                                    {
 625 marek            1.98                  PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 626 kumpf            1.82                      "Not enough seed data in random seed file, "
 627                                                "RAND_status = %d",
 628                                            seedRet));
 629 kumpf            1.14                  PEG_METHOD_EXIT();
 630 kumpf            1.75                  // do not put in $0 in default message, but pass in filename
 631                                        // for bundle message
 632                                        MessageLoaderParms parms(
 633                                            "Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
 634                                            "Not enough seed data in random seed file.",
 635                                            randomFile);
 636 h.sterling       1.47                  throw SSLException(parms);
 637 kumpf            1.14              }
 638                                }
 639                            }
 640                        #endif  /* PEGASUS_SSL_RANDOMFILE */
 641                        
 642 ouyang.jian      1.88  #ifdef PEGASUS_OS_PASE
 643                            if (RAND_status() == 0)
 644                            {
 645                                // generate random number for pase must use specify function
 646                                unsigned char prn[1024];
 647 ouyang.jian      1.94          umeGenerateRandomNumber(prn, sizeof(prn));
 648 ouyang.jian      1.88          RAND_seed(prn, 1024);
 649                            }
 650                        #endif
 651                        
 652 kumpf            1.75      int seedRet = RAND_status();
 653                            if (seedRet == 0)
 654 kumpf            1.14      {
 655 marek            1.98          PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 656 kumpf            1.82              "Not enough seed data, RAND_status = %d",
 657                                    seedRet));
 658 kumpf            1.14          PEG_METHOD_EXIT();
 659 kumpf            1.75          MessageLoaderParms parms(
 660                                    "Common.SSLContext.NOT_ENOUGH_SEED_DATA",
 661                                    "Not enough seed data.");
 662 tony             1.24          throw SSLException(parms);
 663 kumpf            1.14      }
 664                        
 665                            PEG_METHOD_EXIT();
 666                        }
 667                        
 668 kumpf            1.75  SSL_CTX* SSLContextRep::_makeSSLContext()
 669 kumpf            1.9   {
 670                            PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()");
 671                        
 672                            SSL_CTX * sslContext = 0;
 673                        
 674 kumpf            1.1       //
 675                            // create SSL Context Area
 676                            //
 677                        
 678 kumpf            1.75      if (!(sslContext = SSL_CTX_new(SSLv23_method())))
 679 kumpf            1.3       {
 680                                PEG_METHOD_EXIT();
 681 kumpf            1.75          MessageLoaderParms parms(
 682                                    "Common.SSLContext.COULD_NOT_GET",
 683                                    "Could not get SSL CTX");
 684 tony             1.24          throw SSLException(parms);
 685 kumpf            1.3       }
 686                        
 687 kumpf            1.14  #ifdef PEGASUS_SSL_WEAKENCRYPTION
 688 kumpf            1.75      if (!(SSL_CTX_set_cipher_list(sslContext, SSL_TXT_EXP40)))
 689                            {
 690                                MessageLoaderParms parms(
 691                                    "Common.SSLContext.COULD_NOT_SET_CIPHER_LIST",
 692                                    "Could not set the cipher list");
 693 tony             1.24          throw SSLException(parms);
 694 humberto         1.18      }
 695 kumpf            1.3   #endif
 696 kumpf            1.1   
 697                            //
 698                            // set overall SSL Context flags
 699                            //
 700                        
 701 kumpf            1.9       SSL_CTX_set_quiet_shutdown(sslContext, 1);
 702                            SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);
 703 marek            1.68      SSL_CTX_set_mode(sslContext, SSL_MODE_ENABLE_PARTIAL_WRITE);
 704 kumpf            1.14      SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
 705 kumpf            1.1   
 706 h.sterling       1.50      int options = SSL_OP_ALL;
 707 h.sterling       1.49  #ifndef PEGASUS_ENABLE_SSLV2 //SSLv2 is disabled by default
 708 h.sterling       1.50      options |= SSL_OP_NO_SSLv2;
 709 h.sterling       1.49  #endif
 710 h.sterling       1.50      SSL_CTX_set_options(sslContext, options);
 711 h.sterling       1.49  
 712 h.sterling       1.26      if (_verifyPeer)
 713 kumpf            1.1       {
 714 kumpf            1.75          // ATTN: We might still need a flag to specify
 715                                // SSL_VERIFY_FAIL_IF_NO_PEER_CERT
 716                                // If SSL_VERIFY_FAIL_IF_NO_PEER_CERT is ON, SSL will immediately be
 717                                // terminated if the client sends no certificate or sends an
 718                                // untrusted certificate.  The callback function is not called in
 719                                // this case; the handshake is simply terminated.
 720 h.sterling       1.26          // This value has NO effect in from a client perspective
 721                        
 722 h.sterling       1.28          if (_certificateVerifyFunction != NULL)
 723 h.sterling       1.26          {
 724 marek            1.77              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 725 kumpf            1.27                  "---> SSL: certificate verification callback specified");
 726 david.dillard    1.59              SSL_CTX_set_verify(sslContext,
 727 kumpf            1.27                  SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, prepareForCallback);
 728                                }
 729 h.sterling       1.26          else
 730                                {
 731 marek            1.77              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 732 kumpf            1.75                  "---> SSL: Trust Store specified");
 733 david.dillard    1.59              SSL_CTX_set_verify(sslContext,
 734 kumpf            1.75                  SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE |
 735                                            SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
 736 kumpf            1.27                  prepareForCallback);
 737 h.sterling       1.26          }
 738 kumpf            1.1       }
 739 kumpf            1.14      else
 740                            {
 741 marek            1.77          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 742 kumpf            1.75              "---> SSL: Trust Store and certificate verification callback "
 743                                        "are NOT specified");
 744 kumpf            1.27          SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
 745 kumpf            1.14      }
 746 kumpf            1.1   
 747                            //
 748 kumpf            1.75      // Check if there is CA certificate file or directory specified. If
 749                            // specified, and is not empty, load the certificates from the Trust store.
 750 h.sterling       1.26      //
 751 kumpf            1.27      if (_trustStore != String::EMPTY)
 752 kumpf            1.14      {
 753                                //
 754 h.sterling       1.26          // The truststore may be a single file of CA certificates OR
 755                                // a directory containing multiple CA certificates.
 756 david.dillard    1.59          // Check which one it is, and call the load_verify_locations function
 757 h.sterling       1.26          // with the appropriate parameter.  Note: It is possible to have both
 758 david.dillard    1.59          // options, in which case the CA file takes precedence over the CA path.
 759 h.sterling       1.26          // However, since there is currently only one trust parameter to the
 760 david.dillard    1.59          // SSL functions, only allow one choice here.
 761 kumpf            1.27          //
 762                                if (FileSystem::isDirectory(_trustStore))
 763                                {
 764 marek            1.77              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 765 kumpf            1.27                              "---> SSL: Truststore is a directory");
 766                                    //
 767                                    // load certificates from the trust store
 768                                    //
 769 thilo.boehm      1.101             PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
 770                                        "---> SSL: Loading certificates from the trust store: %s",
 771                                        (const char*)_trustStore.getCString()));
 772 kumpf            1.27  
 773 kumpf            1.75              if ((!SSL_CTX_load_verify_locations(
 774                                             sslContext, NULL, _trustStore.getCString())) ||
 775 kumpf            1.27                  (!SSL_CTX_set_default_verify_paths(sslContext)))
 776                                    {
 777 thilo.boehm      1.101                 PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 778                                            "---> SSL: Could not load certificates from the "
 779                                            "trust store: %s ",(const char*)_trustStore.getCString()));
 780 kumpf            1.75                  MessageLoaderParms parms(
 781                                            "Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
 782 kumpf            1.27                      "Could not load certificates in to trust store.");
 783                                        PEG_METHOD_EXIT();
 784                                        throw SSLException(parms);
 785                                    }
 786 h.sterling       1.26  
 787 david.dillard    1.59          }
 788 kumpf            1.27          else if (FileSystem::exists(_trustStore))
 789 h.sterling       1.26          {
 790 marek            1.77              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 791 kumpf            1.75                  "---> SSL: Truststore is a file");
 792 kumpf            1.27              //
 793                                    // Get size of the trust store file:
 794                                    //
 795                                    Uint32 fileSize = 0;
 796 h.sterling       1.26  
 797 kumpf            1.27              FileSystem::getFileSize(_trustStore, fileSize);
 798 h.sterling       1.26  
 799 kumpf            1.27              if (fileSize > 0)
 800                                    {
 801                                        //
 802                                        // load certificates from the trust store
 803                                        //
 804 thilo.boehm      1.101                 PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
 805                                            "---> SSL: Loading certificates from the trust store: %s",
 806                                            (const char*)_trustStore.getCString()));
 807 kumpf            1.27  
 808 kumpf            1.75                  if ((!SSL_CTX_load_verify_locations(
 809                                                 sslContext, _trustStore.getCString(), NULL)) ||
 810 kumpf            1.27                      (!SSL_CTX_set_default_verify_paths(sslContext)))
 811                                        {
 812 thilo.boehm      1.101                     PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 813                                                "---> SSL: Could not load certificates from the "
 814                                                "trust store: %s",
 815                                                (const char*)_trustStore.getCString()));
 816 kumpf            1.75                      MessageLoaderParms parms(
 817                                                "Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
 818 kumpf            1.27                          "Could not load certificates in to trust store.");
 819                                            PEG_METHOD_EXIT();
 820                                            throw SSLException(parms);
 821                                        }
 822                                    }
 823                                    else
 824                                    {
 825                                        //
 826                                        // no certificates found in the trust store
 827                                        //
 828 thilo.boehm      1.101                 PEG_TRACE((TRC_SSL, Tracer::LEVEL2,
 829                                            "---> SSL: No certificates to load from the "
 830                                            "trust store: %s",(const char*)_trustStore.getCString()));
 831 kumpf            1.27              }
 832 kumpf            1.14          }
 833                            }
 834                        
 835 david.dillard    1.59      if (_crlPath != String::EMPTY)
 836 h.sterling       1.47      {
 837 kumpf            1.75          // need to save this -- can we make it static since there's only
 838                                // one CRL for cimserver?
 839 h.sterling       1.47          X509_LOOKUP* pLookup;
 840 david.dillard    1.59  
 841 kumpf            1.92          _crlStore.reset(X509_STORE_new());
 842 dmitry.mikulin   1.99          if (_crlStore.get() == NULL)
 843                                {
 844                                    PEG_METHOD_EXIT();
 845                                    throw PEGASUS_STD(bad_alloc)();
 846                                }
 847 h.sterling       1.40  
 848 kumpf            1.75          // the validity of the crlstore was checked in ConfigManager
 849                                // during server startup
 850 h.sterling       1.47          if (FileSystem::isDirectory(_crlPath))
 851 h.sterling       1.40          {
 852 marek            1.77              PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
 853 kumpf            1.75                  "---> SSL: CRL store is a directory in %s",
 854 marek            1.77                  (const char*)_crlPath.getCString()));
 855 h.sterling       1.40  
 856 kumpf            1.75              if ((pLookup = X509_STORE_add_lookup(
 857 kumpf            1.92                       _crlStore.get(), X509_LOOKUP_hash_dir())) == NULL)
 858 h.sterling       1.47              {
 859 kumpf            1.75                  MessageLoaderParms parms(
 860                                            "Common.SSLContext.COULD_NOT_LOAD_CRLS",
 861                                            "Could not load certificate revocation list.");
 862 kumpf            1.92                  _crlStore.reset();
 863 h.sterling       1.40                  PEG_METHOD_EXIT();
 864                                        throw SSLException(parms);
 865 h.sterling       1.47              }
 866 h.sterling       1.40  
 867 kumpf            1.75              X509_LOOKUP_add_dir(
 868                                        pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
 869 h.sterling       1.40  
 870 marek            1.77              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 871 kumpf            1.75                  "---> SSL: Successfully configured CRL directory");
 872                                }
 873                                else
 874 h.sterling       1.47          {
 875 marek            1.77              PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
 876 kumpf            1.75                  "---> SSL: CRL store is the file %s",
 877 marek            1.77                  (const char*)_crlPath.getCString()));
 878 h.sterling       1.40  
 879 kumpf            1.75              if ((pLookup = X509_STORE_add_lookup(
 880 kumpf            1.92                     _crlStore.get(), X509_LOOKUP_file())) == NULL)
 881 h.sterling       1.47              {
 882 kumpf            1.75                  MessageLoaderParms parms(
 883                                            "Common.SSLContext.COULD_NOT_LOAD_CRLS",
 884                                            "Could not load certificate revocation list.");
 885 kumpf            1.92                  _crlStore.reset();
 886 h.sterling       1.40                  PEG_METHOD_EXIT();
 887                                        throw SSLException(parms);
 888 h.sterling       1.47              }
 889 h.sterling       1.40  
 890 kumpf            1.75              X509_LOOKUP_load_file(
 891                                        pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
 892 david.dillard    1.59  
 893 marek            1.77              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
 894 kumpf            1.75                  "---> SSL: Successfully configured CRL file");
 895 h.sterling       1.47          }
 896                            }
 897 h.sterling       1.40  
 898 kumpf            1.17      Boolean keyLoaded = false;
 899 kumpf            1.27  
 900 kumpf            1.1       //
 901 david.dillard    1.59      // Check if there is a certificate file (file containing server
 902                            // certificate) specified. If specified, validate and load the
 903 kumpf            1.16      // certificate.
 904 kumpf            1.14      //
 905 kumpf            1.27      if (_certPath != String::EMPTY)
 906 kumpf            1.14      {
 907                                //
 908                                // load the specified server certificates
 909                                //
 910 thilo.boehm      1.101         PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
 911                                    "---> SSL: Loading server certificate from: %s",
 912                                    (const char*)_certPath.getCString()));
 913 kumpf            1.1   
 914 david.dillard    1.59          if (SSL_CTX_use_certificate_file(sslContext,
 915 kumpf            1.27              _certPath.getCString(), SSL_FILETYPE_PEM) <=0)
 916 kumpf            1.14          {
 917 thilo.boehm      1.101             PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 918                                        "---> SSL: No server certificate found in %s",
 919                                        (const char*)_certPath.getCString()));
 920 kumpf            1.75              MessageLoaderParms parms(
 921 harsha.bm        1.105                 "Common.SSLContext.COULD_NOT_ACCESS_SERVER_CERTIFICATE",
 922                                        "Could not access server certificate in $0.",
 923                                        (const char*)_certPath.getCString());
 924 kumpf            1.27              PEG_METHOD_EXIT();
 925 tony             1.24              throw SSLException(parms);
 926 kumpf            1.14          }
 927 kumpf            1.17  
 928 kumpf            1.16          //
 929                                // If there is no key file (file containing server
 930 kumpf            1.75          // private key) specified, then try loading the key from the
 931                                // certificate file.
 932                                // As of 2.4, if a keyfile is specified, its location is verified
 933                                // during server startup and will throw an error if the path is invalid.
 934 kumpf            1.16          //
 935 kumpf            1.27          if (_keyPath == String::EMPTY)
 936 kumpf            1.16          {
 937 thilo.boehm      1.101             PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
 938                                        "---> SSL: Key file empty, loading private key from "
 939                                        "certificate file: %s",(const char*)_certPath.getCString()));
 940 kumpf            1.16              //
 941                                    // load the private key and check for validity
 942                                    //
 943 kumpf            1.27              if (!_verifyPrivateKey(sslContext, _certPath))
 944 kumpf            1.16              {
 945 kumpf            1.75                  MessageLoaderParms parms(
 946                                            "Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
 947                                            "Could not get private key.");
 948 kumpf            1.27                  PEG_METHOD_EXIT();
 949 h.sterling       1.47                  throw SSLException(parms);
 950 kumpf            1.16              }
 951 kumpf            1.17              keyLoaded = true;
 952 kumpf            1.16          }
 953                            }
 954 kumpf            1.14  
 955 kumpf            1.16      //
 956 kumpf            1.17      // Check if there is a key file (file containing server
 957                            // private key) specified and the key was not already loaded.
 958                            // If specified, validate and load the key.
 959 kumpf            1.16      //
 960 kumpf            1.27      if (_keyPath != String::EMPTY && !keyLoaded)
 961 kumpf            1.16      {
 962 thilo.boehm      1.101         PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
 963                                    "---> SSL: loading private key from: %s",
 964                                    (const char*)_keyPath.getCString()));
 965 kumpf            1.14          //
 966                                // load given private key and check for validity
 967                                //
 968 kumpf            1.27          if (!_verifyPrivateKey(sslContext, _keyPath))
 969 kumpf            1.14          {
 970 kumpf            1.75              MessageLoaderParms parms(
 971                                        "Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
 972                                        "Could not get private key.");
 973 kumpf            1.27              PEG_METHOD_EXIT();
 974 tony             1.24              throw SSLException(parms);
 975 kumpf            1.14          }
 976 kumpf            1.17          keyLoaded = true;
 977 kumpf            1.14      }
 978                        
 979                            PEG_METHOD_EXIT();
 980                            return sslContext;
 981                        }
 982                        
 983 kumpf            1.27  Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx, const String& keyPath)
 984 kumpf            1.14  {
 985                            PEG_METHOD_ENTER(TRC_SSL, "_verifyPrivateKey()");
 986                        
 987 kumpf            1.80      // Open the private key file.
 988                        
 989                            FILE* is = Executor::openFile(keyPath.getCString(), 'r');
 990                        
 991                            if (!is)
 992                            {
 993 thilo.boehm      1.101         PEG_TRACE((TRC_SSL, Tracer::LEVEL1,
 994                                    "---> SSL: failed to open private key file: %s",
 995                                    (const char*)keyPath.getCString()));
 996 kumpf            1.80          return false;
 997                            }
 998                        
 999                            // Read the private key from the input stream.
1000                        
1001                            EVP_PKEY* pkey;
1002                            pkey = PEM_read_PrivateKey(is, NULL, NULL, NULL);
1003                        
1004                            if (!pkey)
1005                            {
1006 kumpf            1.82          PEG_TRACE_CSTRING(
1007 thilo.boehm      1.101             TRC_SSL, Tracer::LEVEL1, "---> SSL: failed to create private key");
1008 kumpf            1.80          return false;
1009                            }
1010                        
1011                            // Close the input stream.
1012                        
1013                            fclose(is);
1014                        
1015                            // Associate the new private key with the SSL context object.
1016                        
1017                            if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0)
1018 kumpf            1.3       {
1019 kumpf            1.90          EVP_PKEY_free(pkey);
1020 thilo.boehm      1.101         PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
1021                                    "---> SSL: no private key found in %s",
1022                                    (const char*)keyPath.getCString()));
1023 kumpf            1.3           PEG_METHOD_EXIT();
1024 kumpf            1.14          return false;
1025                            }
1026                        
1027 kumpf            1.90      EVP_PKEY_free(pkey);
1028                        
1029 kumpf            1.80      // Check private key for validity.
1030                        
1031 kumpf            1.14      if (!SSL_CTX_check_private_key(ctx))
1032                            {
1033 marek            1.98          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
1034 kumpf            1.14              "---> SSL: Private and public key do not match");
1035                                PEG_METHOD_EXIT();
1036                                return false;
1037 kumpf            1.3       }
1038 kumpf            1.1   
1039 kumpf            1.3       PEG_METHOD_EXIT();
1040 kumpf            1.14      return true;
1041 kumpf            1.1   }
1042                        
1043 kumpf            1.75  SSL_CTX* SSLContextRep::getContext() const
1044 kumpf            1.1   {
1045 kumpf            1.9       return _sslContext;
1046 kumpf            1.1   }
1047 h.sterling       1.26  
1048                        String SSLContextRep::getTrustStore() const
1049                        {
1050                            return _trustStore;
1051                        }
1052                        
1053                        String SSLContextRep::getCertPath() const
1054                        {
1055                            return _certPath;
1056                        }
1057                        
1058                        String SSLContextRep::getKeyPath() const
1059                        {
1060                            return _keyPath;
1061                        }
1062                        
1063 dave.sudlik      1.55  #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1064 david.dillard    1.59  String SSLContextRep::getTrustStoreUserName() const
1065                        {
1066                            return String::EMPTY;
1067 dave.sudlik      1.55  }
1068                        #endif
1069                        
1070 h.sterling       1.40  String SSLContextRep::getCRLPath() const
1071 h.sterling       1.26  {
1072 h.sterling       1.40      return _crlPath;
1073 h.sterling       1.26  }
1074                        
1075 kumpf            1.92  SharedPtr<X509_STORE, FreeX509STOREPtr> SSLContextRep::getCRLStore() const
1076 h.sterling       1.26  {
1077 h.sterling       1.40      return _crlStore;
1078 h.sterling       1.26  }
1079                        
1080 h.sterling       1.50  void SSLContextRep::setCRLStore(X509_STORE* store)
1081                        {
1082 kumpf            1.92      _crlStore.reset(store);
1083 h.sterling       1.50  }
1084                        
1085 h.sterling       1.40  Boolean SSLContextRep::isPeerVerificationEnabled() const
1086 h.sterling       1.26  {
1087 h.sterling       1.40      return _verifyPeer;
1088 h.sterling       1.26  }
1089                        
1090 kumpf            1.75  SSLCertificateVerifyFunction*
1091                            SSLContextRep::getSSLCertificateVerifyFunction() const
1092 h.sterling       1.28  {
1093                            return _certificateVerifyFunction;
1094                        }
1095                        
1096 kumpf            1.95  void SSLContextRep::validateCertificate()
1097                        {
1098                            BIO* in = BIO_new_file(_certPath.getCString(), "r");
1099                            PEGASUS_ASSERT(in != NULL);
1100                            X509* cert = PEM_read_bio_X509(in, NULL, 0, NULL);
1101                            BIO_free(in);
1102                            PEGASUS_ASSERT(cert != NULL);
1103                        
1104                            if (X509_cmp_current_time(X509_get_notBefore(cert)) > 0)
1105                            {
1106                                X509_free(cert);
1107                                MessageLoaderParms parms(
1108                                   "Common.SSLContext.CERTIFICATE_NOT_YET_VALID",
1109                                   "Certificate $0 is not yet valid.",
1110                                   _certPath);
1111                                throw SSLException(parms);
1112                            }
1113                        
1114                            if (X509_cmp_current_time(X509_get_notAfter(cert)) < 0)
1115                            {
1116                                X509_free(cert);
1117 kumpf            1.95          MessageLoaderParms parms(
1118                                   "Common.SSLContext.CERTIFICATE_EXPIRED",
1119                                   "Certificate $0 has expired.",
1120                                   _certPath);
1121                                throw SSLException(parms);
1122                            }
1123                        
1124                            X509_free(cert);
1125                        }
1126                        
1127 david.dillard    1.59  #else
1128 kumpf            1.1   
1129                        //
1130 kumpf            1.9   // these definitions are used if ssl is not available
1131 kumpf            1.1   //
1132                        
1133 kumpf            1.75  SSLContextRep::SSLContextRep(
1134                            const String& trustStore,
1135                            const String& certPath,
1136                            const String& keyPath,
1137                            const String& crlPath,
1138                            SSLCertificateVerifyFunction* verifyCert,
1139                            const String& randomFile)
1140                        {
1141                        }
1142 h.sterling       1.26  
1143 kumpf            1.9   SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep) {}
1144                        
1145 kumpf            1.1   SSLContextRep::~SSLContextRep() {}
1146                        
1147 kumpf            1.75  SSL_CTX* SSLContextRep::_makeSSLContext() { return 0; }
1148 kumpf            1.9   
1149 kumpf            1.75  Boolean SSLContextRep::_verifyPrivateKey(
1150                            SSL_CTX *ctx,
1151                            const String& keyPath)
1152                        {
1153                            return false;
1154                        }
1155 kumpf            1.14  
1156 kumpf            1.75  SSL_CTX* SSLContextRep::getContext() const { return 0; }
1157 kumpf            1.15  
1158 h.sterling       1.26  String SSLContextRep::getTrustStore() const { return String::EMPTY; }
1159                        
1160                        String SSLContextRep::getCertPath() const { return String::EMPTY; }
1161                        
1162                        String SSLContextRep::getKeyPath() const { return String::EMPTY; }
1163                        
1164 dave.sudlik      1.55  #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1165                        String SSLContextRep::getTrustStoreUserName() const { return String::EMPTY; }
1166                        #endif
1167                        
1168 h.sterling       1.40  String SSLContextRep::getCRLPath() const { return String::EMPTY; }
1169 h.sterling       1.26  
1170 kumpf            1.92  SharedPtr<X509_STORE, FreeX509STOREPtr> SSLContextRep::getCRLStore() const
1171                        {
1172                            return SharedPtr<X509_STORE, FreeX509STOREPtr>();
1173                        }
1174 h.sterling       1.26  
1175 h.sterling       1.50  void SSLContextRep::setCRLStore(X509_STORE* store) { }
1176                        
1177 h.sterling       1.40  Boolean SSLContextRep::isPeerVerificationEnabled() const { return false; }
1178 h.sterling       1.26  
1179 kumpf            1.75  SSLCertificateVerifyFunction*
1180                            SSLContextRep::getSSLCertificateVerifyFunction() const
1181                        {
1182                            return NULL;
1183                        }
1184 h.sterling       1.28  
1185 kumpf            1.95  void SSLContextRep::validateCertificate() { }
1186                        
1187 kumpf            1.1   #endif // end of PEGASUS_HAS_SSL
1188                        
1189                        ///////////////////////////////////////////////////////////////////////////////
1190                        //
1191                        // SSLContext
1192                        //
1193                        ///////////////////////////////////////////////////////////////////////////////
1194                        
1195                        
1196                        SSLContext::SSLContext(
1197 h.sterling       1.26      const String& trustStore,
1198 kumpf            1.9       SSLCertificateVerifyFunction* verifyCert,
1199 kumpf            1.13      const String& randomFile)
1200                        {
1201 kumpf            1.75      _rep = new SSLContextRep(
1202                                trustStore,
1203                                String::EMPTY,
1204                                String::EMPTY,
1205                                String::EMPTY,
1206                                verifyCert,
1207                                randomFile);
1208 kumpf            1.13  }
1209                        
1210 kumpf            1.14  SSLContext::SSLContext(
1211 h.sterling       1.26      const String& trustStore,
1212 kumpf            1.14      const String& certPath,
1213 kumpf            1.16      const String& keyPath,
1214 kumpf            1.14      SSLCertificateVerifyFunction* verifyCert,
1215                            const String& randomFile)
1216                        {
1217 kumpf            1.75      _rep = new SSLContextRep(
1218                                trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
1219 h.sterling       1.30  }
1220                        
1221 h.sterling       1.40  //PEP187
1222 h.sterling       1.26  SSLContext::SSLContext(
1223                                const String& trustStore,
1224                                const String& certPath,
1225                                const String& keyPath,
1226 h.sterling       1.47          const String& crlPath,
1227 h.sterling       1.26          SSLCertificateVerifyFunction* verifyCert,
1228                                const String& randomFile)
1229                        {
1230 sushma.fernandes 1.66  #ifndef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
1231 kumpf            1.75      if (crlPath.size() > 0)
1232 sushma.fernandes 1.66      {
1233 kumpf            1.75          MessageLoaderParms parms(
1234                                    "Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
1235                                    "SSL CRL verification is not enabled.");
1236 sushma.fernandes 1.66          throw Exception(parms);
1237                            }
1238                        #endif
1239 kumpf            1.75      _rep = new SSLContextRep(
1240                                trustStore, certPath, keyPath, crlPath, verifyCert, randomFile);
1241 kumpf            1.14  }
1242                        
1243 dave.sudlik      1.55  #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1244                        SSLContext::SSLContext(
1245                            const String& trustStore,
1246                            const String& certPath,
1247                            const String& keyPath,
1248                            SSLCertificateVerifyFunction* verifyCert,
1249                            String trustStoreUserName,
1250                            const String& randomFile)
1251                        {
1252 kumpf            1.75      _rep = new SSLContextRep(
1253                                trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
1254 dave.sudlik      1.55  }
1255                        #endif
1256                        
1257 kumpf            1.9   SSLContext::SSLContext(const SSLContext& sslContext)
1258                        {
1259                            _rep = new SSLContextRep(*sslContext._rep);
1260 kumpf            1.12  }
1261                        
1262                        // Dummy constructor made private to disallow default construction
1263                        SSLContext::SSLContext()
1264                        {
1265 kumpf            1.9   }
1266                        
1267 david.dillard    1.59  SSLContext::~SSLContext()
1268 kumpf            1.1   {
1269                            delete _rep;
1270                        }
1271                        
1272 h.sterling       1.26  String SSLContext::getTrustStore() const
1273                        {
1274 kumpf            1.75      return _rep->getTrustStore();
1275 h.sterling       1.26  }
1276                        
1277                        String SSLContext::getCertPath() const
1278                        {
1279 kumpf            1.75      return _rep->getCertPath();
1280 h.sterling       1.26  }
1281                        
1282                        String SSLContext::getKeyPath() const
1283                        {
1284 kumpf            1.75      return _rep->getKeyPath();
1285 h.sterling       1.26  }
1286                        
1287 h.sterling       1.40  String SSLContext::getCRLPath() const
1288 h.sterling       1.26  {
1289 sushma.fernandes 1.66  #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
1290 kumpf            1.75      return _rep->getCRLPath();
1291 sushma.fernandes 1.66  #else
1292 kumpf            1.75      MessageLoaderParms parms(
1293                                "Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
1294                                "SSL CRL verification is not enabled.");
1295 sushma.fernandes 1.66      throw Exception(parms);
1296 kumpf            1.76      PEGASUS_UNREACHABLE(return String::EMPTY;)
1297 sushma.fernandes 1.66  #endif
1298 h.sterling       1.26  }
1299                        
1300 h.sterling       1.40  X509_STORE* SSLContext::getCRLStore() const
1301 h.sterling       1.26  {
1302 sushma.fernandes 1.66  #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
1303 kumpf            1.92      return _rep->getCRLStore().get();
1304 sushma.fernandes 1.66  #else
1305 kumpf            1.75      MessageLoaderParms parms(
1306                                "Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
1307                                "SSL CRL verification is not enabled.");
1308 sushma.fernandes 1.66      throw Exception(parms);
1309 kumpf            1.76      PEGASUS_UNREACHABLE(return 0;)
1310 sushma.fernandes 1.66  #endif
1311 h.sterling       1.26  }
1312                        
1313 h.sterling       1.40  Boolean SSLContext::isPeerVerificationEnabled() const
1314 h.sterling       1.26  {
1315 kumpf            1.75      return _rep->isPeerVerificationEnabled();
1316 h.sterling       1.26  }
1317 kumpf            1.1   
1318 dave.sudlik      1.55  #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1319                        String SSLContext::getTrustStoreUserName() const
1320                        {
1321 kumpf            1.75      return _rep->getTrustStoreUserName();
1322 dave.sudlik      1.55  }
1323                        #endif
1324                        
1325 kumpf            1.75  SSLCertificateVerifyFunction*
1326                            SSLContext::getSSLCertificateVerifyFunction() const
1327 h.sterling       1.28  {
1328 kumpf            1.75      return _rep->getSSLCertificateVerifyFunction();
1329 h.sterling       1.28  }
1330                        
1331 kumpf            1.96  void SSLContext::_validateCertificate()
1332                        {
1333                            _rep->validateCertificate();
1334                        }
1335                        
1336 kumpf            1.1   ///////////////////////////////////////////////////////////////////////////////
1337                        //
1338 kumpf            1.9   // SSLCertificateInfo
1339 kumpf            1.1   //
1340                        ///////////////////////////////////////////////////////////////////////////////
1341 kumpf            1.16  //
1342                        // Certificate validation result codes.
1343                        //
1344 kumpf            1.75  const int    SSLCertificateInfo::V_OK                                      = 0;
1345 kumpf            1.16  
1346 kumpf            1.75  const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT           = 2;
1347                        const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_CRL                   = 3;
1348                        const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE    = 4;
1349                        const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE     = 5;
1350                        const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY  = 6;
1351                        const int    SSLCertificateInfo::V_ERR_CERT_SIGNATURE_FAILURE              = 7;
1352                        const int    SSLCertificateInfo::V_ERR_CRL_SIGNATURE_FAILURE               = 8;
1353                        const int    SSLCertificateInfo::V_ERR_CERT_NOT_YET_VALID                  = 9;
1354                        const int    SSLCertificateInfo::V_ERR_CERT_HAS_EXPIRED                    = 10;
1355                        const int    SSLCertificateInfo::V_ERR_CRL_NOT_YET_VALID                   = 11;
1356                        const int    SSLCertificateInfo::V_ERR_CRL_HAS_EXPIRED                     = 12;
1357                        const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD      = 13;
1358                        const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD       = 14;
1359                        const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD      = 15;
1360                        const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD      = 16;
1361                        const int    SSLCertificateInfo::V_ERR_OUT_OF_MEM                          = 17;
1362                        const int    SSLCertificateInfo::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT         = 18;
1363                        const int    SSLCertificateInfo::V_ERR_SELF_SIGNED_CERT_IN_CHAIN           = 19;
1364                        const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY   = 20;
1365                        const int    SSLCertificateInfo::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE     = 21;
1366                        const int    SSLCertificateInfo::V_ERR_CERT_CHAIN_TOO_LONG                 = 22;
1367 kumpf            1.75  const int    SSLCertificateInfo::V_ERR_CERT_REVOKED                        = 23;
1368                        const int    SSLCertificateInfo::V_ERR_INVALID_CA                          = 24;
1369                        const int    SSLCertificateInfo::V_ERR_PATH_LENGTH_EXCEEDED                = 25;
1370                        const int    SSLCertificateInfo::V_ERR_INVALID_PURPOSE                     = 26;
1371                        const int    SSLCertificateInfo::V_ERR_CERT_UNTRUSTED                      = 27;
1372                        const int    SSLCertificateInfo::V_ERR_CERT_REJECTED                       = 28;
1373                        const int    SSLCertificateInfo::V_ERR_SUBJECT_ISSUER_MISMATCH             = 29;
1374                        const int    SSLCertificateInfo::V_ERR_AKID_SKID_MISMATCH                  = 30;
1375                        const int    SSLCertificateInfo::V_ERR_AKID_ISSUER_SERIAL_MISMATCH         = 31;
1376                        const int    SSLCertificateInfo::V_ERR_KEYUSAGE_NO_CERTSIGN                = 32;
1377 kumpf            1.16  
1378 kumpf            1.75  const int    SSLCertificateInfo::V_ERR_APPLICATION_VERIFICATION            = 50;
1379 kumpf            1.1   
1380 kumpf            1.9   class SSLCertificateInfoRep
1381                        {
1382                        public:
1383 kumpf            1.16      String    subjectName;
1384                            String    issuerName;
1385                            Uint32    depth;
1386                            Uint32    errorCode;
1387                            Uint32    respCode;
1388                            String    errorString;
1389                            Uint32    versionNumber;
1390                            long      serialNumber;
1391                            CIMDateTime    notBefore;
1392                            CIMDateTime    notAfter;
1393 kumpf            1.9   };
1394                        
1395                        
1396                        SSLCertificateInfo::SSLCertificateInfo(
1397 kumpf            1.1       const String subjectName,
1398                            const String issuerName,
1399                            const int errorDepth,
1400 kumpf            1.14      const int errorCode,
1401                            const int respCode)
1402 kumpf            1.1   {
1403 kumpf            1.9       _rep = new SSLCertificateInfoRep();
1404                            _rep->subjectName = subjectName;
1405                            _rep->issuerName = issuerName;
1406 kumpf            1.16      _rep->versionNumber = 0;
1407                            _rep->serialNumber = 0;
1408 h.sterling       1.26      _rep->notBefore = CIMDateTime();
1409                            _rep->notAfter = CIMDateTime();
1410 kumpf            1.16      _rep->depth = errorDepth;
1411 kumpf            1.9       _rep->errorCode = errorCode;
1412 kumpf            1.16      _rep->errorString = String::EMPTY;
1413                            _rep->respCode = respCode;
1414                        }
1415                        
1416                        SSLCertificateInfo::SSLCertificateInfo(
1417                            const String subjectName,
1418                            const String issuerName,
1419                            const Uint32 versionNumber,
1420                            const long serialNumber,
1421                            const CIMDateTime notBefore,
1422                            const CIMDateTime notAfter,
1423                            const Uint32 depth,
1424                            const Uint32 errorCode,
1425                            const String errorString,
1426                            const Uint32 respCode)
1427                        {
1428                            _rep = new SSLCertificateInfoRep();
1429                            _rep->subjectName = subjectName;
1430                            _rep->issuerName = issuerName;
1431                            _rep->versionNumber = versionNumber;
1432                            _rep->serialNumber = serialNumber;
1433 kumpf            1.16      _rep->notBefore = notBefore;
1434                            _rep->notAfter = notAfter;
1435                            _rep->depth = depth;
1436                            _rep->errorCode = errorCode;
1437                            _rep->errorString = errorString;
1438 kumpf            1.14      _rep->respCode = respCode;
1439 kumpf            1.9   }
1440                        
1441                        SSLCertificateInfo::SSLCertificateInfo(
1442                            const SSLCertificateInfo& certificateInfo)
1443                        {
1444                            _rep = new SSLCertificateInfoRep();
1445                            _rep->subjectName = certificateInfo._rep->subjectName;
1446                            _rep->issuerName = certificateInfo._rep->issuerName;
1447 kumpf            1.16      _rep->versionNumber = certificateInfo._rep->versionNumber;
1448                            _rep->serialNumber = certificateInfo._rep->serialNumber;
1449                            _rep->notBefore = certificateInfo._rep->notBefore;
1450                            _rep->notAfter = certificateInfo._rep->notAfter;
1451                            _rep->depth = certificateInfo._rep->depth;
1452 kumpf            1.9       _rep->errorCode = certificateInfo._rep->errorCode;
1453 kumpf            1.16      _rep->errorString = certificateInfo._rep->errorString;
1454 kumpf            1.9       _rep->respCode = certificateInfo._rep->respCode;
1455 kumpf            1.11  }
1456                        
1457                        // Dummy constructor made private to disallow default construction
1458                        SSLCertificateInfo::SSLCertificateInfo()
1459                        {
1460 kumpf            1.1   }
1461                        
1462 kumpf            1.9   SSLCertificateInfo::~SSLCertificateInfo()
1463 kumpf            1.1   {
1464 kumpf            1.9       delete _rep;
1465 kumpf            1.1   }
1466                        
1467 kumpf            1.9   String SSLCertificateInfo::getSubjectName() const
1468 kumpf            1.1   {
1469 kumpf            1.75      return _rep->subjectName;
1470 kumpf            1.1   }
1471                        
1472 kumpf            1.9   String SSLCertificateInfo::getIssuerName() const
1473 kumpf            1.1   {
1474 kumpf            1.75      return _rep->issuerName;
1475 kumpf            1.1   }
1476                        
1477 kumpf            1.16  Uint32 SSLCertificateInfo::getVersionNumber() const
1478                        {
1479 kumpf            1.75      return _rep->versionNumber;
1480 kumpf            1.16  }
1481                        
1482                        long SSLCertificateInfo::getSerialNumber() const
1483 kumpf            1.1   {
1484 kumpf            1.75      return _rep->serialNumber;
1485 kumpf            1.1   }
1486                        
1487 kumpf            1.16  CIMDateTime SSLCertificateInfo::getNotBefore() const
1488                        {
1489 kumpf            1.75      return _rep->notBefore;
1490 kumpf            1.16  }
1491                        
1492 david.dillard    1.59  CIMDateTime SSLCertificateInfo::getNotAfter() const
1493 kumpf            1.16  {
1494 kumpf            1.75      return _rep->notAfter;
1495 kumpf            1.16  }
1496                        
1497                        Uint32 SSLCertificateInfo::getErrorDepth() const
1498                        {
1499 kumpf            1.75      return _rep->depth;
1500 kumpf            1.16  }
1501                        
1502                        Uint32 SSLCertificateInfo::getErrorCode()  const
1503 kumpf            1.1   {
1504 kumpf            1.75      return _rep->errorCode;
1505 kumpf            1.14  }
1506                        
1507 kumpf            1.16  void SSLCertificateInfo::setErrorCode(const int errorCode)
1508                        {
1509                            _rep->errorCode = errorCode;
1510                        }
1511                        
1512                        String SSLCertificateInfo::getErrorString() const
1513                        {
1514 kumpf            1.75      return _rep->errorString;
1515 kumpf            1.16  }
1516                        
1517                        Uint32 SSLCertificateInfo::getResponseCode()  const
1518 kumpf            1.14  {
1519 kumpf            1.75      return _rep->respCode;
1520 kumpf            1.1   }
1521                        
1522 kumpf            1.9   void SSLCertificateInfo::setResponseCode(const int respCode)
1523 kumpf            1.1   {
1524 kumpf            1.9       _rep->respCode = respCode;
1525 kumpf            1.1   }
1526                        
1527 h.sterling       1.28  String SSLCertificateInfo::toString() const
1528                        {
1529                            char buf[1024];
1530 david.dillard    1.59  
1531 h.sterling       1.28      String s;
1532                        
1533                            s.append("Subject Name:\n\t");
1534                            s.append(_rep->subjectName);
1535                            s.append("\n");
1536 david.dillard    1.59  
1537 h.sterling       1.28      s.append("Issuer Name:\n\t");
1538                            s.append(_rep->issuerName);
1539                            s.append("\n");
1540 david.dillard    1.59  
1541 kumpf            1.100     sprintf(buf, "Depth: %u\n", _rep->depth);
1542 h.sterling       1.28      s.append(buf);
1543 david.dillard    1.59  
1544 kumpf            1.100     sprintf(buf, "Error code: %u\n", _rep->errorCode);
1545 h.sterling       1.28      s.append(buf);
1546 david.dillard    1.59  
1547 kumpf            1.100     sprintf(buf, "Response (preverify) code: %u\n", _rep->respCode);
1548 h.sterling       1.28      s.append(buf);
1549                        
1550                            s.append("Error string: ");
1551                            s.append(_rep->errorString);
1552                            s.append("\n");
1553 david.dillard    1.59  
1554 kumpf            1.100     sprintf(buf, "Version number: %u\n", _rep->versionNumber);
1555 h.sterling       1.28      s.append(buf);
1556                        
1557 kumpf            1.100     sprintf(buf, "Serial number: %lu\n", (unsigned long)_rep->serialNumber);
1558 h.sterling       1.28      s.append(buf);
1559 david.dillard    1.59  
1560 h.sterling       1.28      s.append("Not before date: ");
1561                            s.append((_rep->notBefore).toString());
1562                            s.append("\n");
1563                        
1564                            s.append("Not after date: ");
1565                            s.append((_rep->notAfter).toString());
1566                            s.append("\n");
1567                        
1568                            return s;
1569                        }
1570                        
1571 dave.sudlik      1.55  ///////////////////////////////////////////////////////////////////////////////
1572                        //
1573                        // SSLCallbackInfo
1574                        //
1575                        ///////////////////////////////////////////////////////////////////////////////
1576                        
1577                        SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert)
1578                        {
1579                            _rep = new SSLCallbackInfoRep();
1580                            _rep->verifyCertificateCallback = verifyCert;
1581                            _rep->crlStore = NULL;
1582                        }
1583                        
1584 kumpf            1.75  SSLCallbackInfo::SSLCallbackInfo(
1585                            SSLCertificateVerifyFunction* verifyCert,
1586                            X509_STORE* crlStore)
1587 h.sterling       1.28  {
1588 dave.sudlik      1.55      _rep = new SSLCallbackInfoRep();
1589                            _rep->verifyCertificateCallback = verifyCert;
1590                            _rep->crlStore = crlStore;
1591 h.sterling       1.28  }
1592                        
1593 sushma.fernandes 1.79  SSLCallbackInfo::SSLCallbackInfo(
1594                            SSLCertificateVerifyFunction* verifyCert,
1595                            X509_STORE* crlStore,
1596                            String ipAddress)
1597                        {
1598                            _rep = new SSLCallbackInfoRep();
1599                            _rep->verifyCertificateCallback = verifyCert;
1600                            _rep->crlStore = crlStore;
1601                            _rep->ipAddress = ipAddress;
1602                        }
1603                        
1604 h.sterling       1.28  SSLCallbackInfo::~SSLCallbackInfo()
1605                        {
1606 h.sterling       1.63      PEG_METHOD_ENTER(TRC_SSL, "SSLCallbackInfo::~SSLCallbackInfo");
1607                            for (Uint32 i = 0; i < _rep->peerCertificate.size(); i++)
1608 h.sterling       1.28      {
1609 h.sterling       1.63          delete _rep->peerCertificate[i];
1610 h.sterling       1.28      }
1611 dave.sudlik      1.55      delete _rep;
1612 h.sterling       1.63      PEG_METHOD_EXIT();
1613 h.sterling       1.28  }
1614                        
1615 kumpf            1.1   PEGASUS_NAMESPACE_END
1616                        

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2