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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2