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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2