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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2