(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.70                 "Now locking for %d", Threads::id());*/
 480                               SSLContextRep::_sslLocks.get()[type].lock( );
 481 kumpf            1.15     }
 482                           else
 483                           {
 484 h.sterling       1.26         /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 485 mike             1.70                 "Now unlocking for %d", Threads::id());*/
 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.70      CRYPTO_set_id_callback((CRYPTO_SET_ID_CALLBACK) Threads::id);
 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.70                 "Before calling SSL_load_error_strings %d", Threads::id());
 587 kumpf            1.15 
 588                                   SSL_load_error_strings();
 589                       
 590                                   Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 591 mike             1.70                 "After calling SSL_load_error_strings %d", Threads::id());
 592 kumpf            1.15 
 593                                   Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 594 mike             1.70                 "Before calling SSL_library_init %d", Threads::id());
 595 kumpf            1.15 
 596                                   SSL_library_init();
 597                       
 598                                   Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 599 mike             1.70                 "After calling SSL_library_init %d", Threads::id());
 600 david.dillard    1.59         }
 601                       
 602 kumpf            1.15     _countRep++;
 603 a.arora          1.35     }  // mutex unlocks here
 604 kumpf            1.1  
 605 kumpf            1.14     _randomInit(randomFile);
 606 kumpf            1.1  
 607 kumpf            1.9      _sslContext = _makeSSLContext();
 608                       
 609                           PEG_METHOD_EXIT();
 610                       }
 611                       
 612                       SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep)
 613                       {
 614                           PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
 615                       
 616 h.sterling       1.26     _trustStore = sslContextRep._trustStore;
 617 kumpf            1.9      _certPath = sslContextRep._certPath;
 618 kumpf            1.16     _keyPath = sslContextRep._keyPath;
 619 h.sterling       1.47     _crlPath = sslContextRep._crlPath;
 620 h.sterling       1.50     _crlStore = sslContextRep._crlStore;
 621 h.sterling       1.26     _verifyPeer = sslContextRep._verifyPeer;
 622 h.sterling       1.28     _certificateVerifyFunction = sslContextRep._certificateVerifyFunction;
 623 kumpf            1.9      _randomFile = sslContextRep._randomFile;
 624 kumpf            1.15 
 625                           // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.
 626                           {
 627 a.arora          1.35         AutoMutex autoMut(_countRepMutex);
 628 kumpf            1.15         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 629                                    "Value of Countrep in copy constructor %d", _countRep);
 630                               if ( _countRep == 0 )
 631                               {
 632                                   init_ssl();
 633 david.dillard    1.59         }
 634                       
 635 kumpf            1.15     _countRep++;
 636 a.arora          1.35     }  // mutex unlocks here
 637 kumpf            1.15 
 638 kumpf            1.9      _sslContext = _makeSSLContext();
 639                           PEG_METHOD_EXIT();
 640                       }
 641 kumpf            1.11 
 642 kumpf            1.9  //
 643                       // Destructor
 644                       //
 645                       
 646                       SSLContextRep::~SSLContextRep()
 647                       {
 648                           PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::~SSLContextRep()");
 649                       
 650                           SSL_CTX_free(_sslContext);
 651                       
 652 kumpf            1.15     // Decrement the SSLContextRep object _counter.
 653                           {
 654 a.arora          1.35         AutoMutex autoMut(_countRepMutex);
 655                               _countRep--;
 656                               // Free SSL locks if no instances of SSLContextRep exist.
 657 david.dillard    1.59 
 658 kumpf            1.15         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 659                                       "Value of Countrep in destructor %d", _countRep);
 660                               if ( _countRep == 0 )
 661                               {
 662                                   free_ssl();
 663                               }
 664 david.dillard    1.59 
 665 kumpf            1.15     }
 666 kumpf            1.9      PEG_METHOD_EXIT();
 667                       }
 668                       
 669 kumpf            1.14 //
 670                       // initialize OpenSSL's PRNG
 671                       //
 672                       void SSLContextRep::_randomInit(const String& randomFile)
 673                       {
 674                           PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_randomInit()");
 675                       
 676                           Boolean ret;
 677                           int retVal = 0;
 678                       
 679                       #ifdef PEGASUS_SSL_RANDOMFILE
 680                           if ( RAND_status() == 0 )
 681                           {
 682                               //
 683                               // Initialise OpenSSL random number generator.
 684                               //
 685                               if ( randomFile == String::EMPTY )
 686                               {
 687                                   PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 688                                       "Random seed file is required.");
 689                                   PEG_METHOD_EXIT();
 690 humberto         1.18             //l10n
 691                                   //throw( SSLException("Random seed file required"));
 692                                   MessageLoaderParms parms("Common.SSLContext.RANDOM_SEED_FILE_REQUIRED",
 693 h.sterling       1.47                                      "Random seed file required");
 694 david.dillard    1.59             throw SSLException(parms);
 695 kumpf            1.14         }
 696                       
 697                               //
 698                               // Try the given random seed file
 699                               //
 700                               ret = FileSystem::exists(randomFile);
 701                               if( ret )
 702                               {
 703 david.dillard    1.59             retVal = RAND_load_file(randomFile.getCString(), -1);
 704 kumpf            1.14             if ( retVal < 0 )
 705                                   {
 706                                       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 707                                           "Not enough seed data in seed file: " + randomFile);
 708                                       PEG_METHOD_EXIT();
 709 humberto         1.18                 //l10n
 710 h.sterling       1.47         // do not put in $0 in default message, but pass in filename for bundle message
 711 humberto         1.18                 //throw( SSLException("Not enough seed data in random seed file."));
 712                                       MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
 713 h.sterling       1.47                                          "Not enough seed data in random seed file.",
 714                                                                randomFile);
 715                                       throw SSLException(parms);
 716 kumpf            1.14             }
 717                               }
 718 kumpf            1.16         else
 719                               {
 720                                   PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 721                                       "seed file - " + randomFile + " does not exist.");
 722                                   PEG_METHOD_EXIT();
 723 humberto         1.18             //l10n
 724                                   //throw( SSLException("Seed file '" + randomFile + "' does not exist."));
 725                                   MessageLoaderParms parms("Common.SSLContext.SEED_FILE_DOES_NOT_EXIST",
 726 h.sterling       1.47                                      "Seed file '$0' does not exist.",
 727                                                            randomFile);
 728 tony             1.24             throw SSLException(parms);
 729 kumpf            1.16         }
 730 kumpf            1.14 
 731                               if ( RAND_status() == 0 )
 732                               {
 733                                   //
 734                                   // Try to do more seeding
 735                                   //
 736                                   long seedNumber;
 737 david.dillard    1.59         #if defined(PEGASUS_COMPILER_MSVC)
 738 tony             1.24             srand((unsigned int)time(NULL)); // Initialize
 739                                   seedNumber = rand();
 740                               #else
 741 kumpf            1.14             srandom((unsigned int)time(NULL)); // Initialize
 742                                   seedNumber = random();
 743 tony             1.24         #endif
 744 kumpf            1.14             RAND_seed((unsigned char *) &seedNumber, sizeof(seedNumber));
 745                       
 746                                   int  seedRet = RAND_status();
 747                                   if ( seedRet == 0 )
 748                                   {
 749                                       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 750 kumpf            1.15                     "Not enough seed data in random seed file, RAND_status = " +
 751                                           seedRet);
 752 kumpf            1.14                 PEG_METHOD_EXIT();
 753 humberto         1.22                 //l10n 485
 754 h.sterling       1.47         // do not put in $0 in default message, but pass in filename for bundle message
 755 humberto         1.18                 //throw( SSLException("Not enough seed data in random seed file."));
 756                                       MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
 757 h.sterling       1.47                                          "Not enough seed data in random seed file.",
 758                                                                randomFile);
 759                                       throw SSLException(parms);
 760 kumpf            1.14             }
 761                               }
 762                           }
 763                       #endif  /* PEGASUS_SSL_RANDOMFILE */
 764                       
 765                           int  seedRet = RAND_status();
 766                           if ( seedRet == 0 )
 767                           {
 768                               PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 769                                   "Not enough seed data , RAND_status = " + seedRet );
 770                               PEG_METHOD_EXIT();
 771 humberto         1.18         //l10n
 772                               //throw( SSLException("Not enough seed data."));
 773                               MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA",
 774 h.sterling       1.47                                  "Not enough seed data.");
 775 tony             1.24         throw SSLException(parms);
 776 kumpf            1.14     }
 777                       
 778                           PEG_METHOD_EXIT();
 779                       }
 780                       
 781 kumpf            1.9  SSL_CTX * SSLContextRep::_makeSSLContext()
 782                       {
 783                           PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()");
 784                       
 785                           SSL_CTX * sslContext = 0;
 786                       
 787 kumpf            1.1      //
 788                           // create SSL Context Area
 789                           //
 790                       
 791 kumpf            1.9      if (!( sslContext = SSL_CTX_new(SSLv23_method()) ))
 792 kumpf            1.3      {
 793                               PEG_METHOD_EXIT();
 794 humberto         1.18         //l10n
 795                               //throw( SSLException("Could not get SSL CTX"));
 796                               MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET",
 797 h.sterling       1.47                                  "Could not get SSL CTX");
 798 tony             1.24         throw SSLException(parms);
 799 kumpf            1.3      }
 800                       
 801 kumpf            1.14 #ifdef PEGASUS_SSL_WEAKENCRYPTION
 802 humberto         1.18     if (!(SSL_CTX_set_cipher_list(sslContext, SSL_TXT_EXP40))){
 803 h.sterling       1.47         //l10n
 804 humberto         1.18         //throw( SSLException("Could not set the cipher list"));
 805                               MessageLoaderParms parms("Common.SSLContext.COULD_NOT_SET_CIPHER_LIST",
 806 h.sterling       1.47                                  "Could not set the cipher list");
 807 tony             1.24         throw SSLException(parms);
 808 humberto         1.18     }
 809 kumpf            1.3  #endif
 810 kumpf            1.1  
 811                           //
 812                           // set overall SSL Context flags
 813                           //
 814                       
 815 kumpf            1.9      SSL_CTX_set_quiet_shutdown(sslContext, 1);
 816                           SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);
 817 marek            1.68     SSL_CTX_set_mode(sslContext, SSL_MODE_ENABLE_PARTIAL_WRITE);
 818 kumpf            1.14     SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
 819 kumpf            1.1  
 820 h.sterling       1.50     int options = SSL_OP_ALL;
 821 h.sterling       1.49 #ifndef PEGASUS_ENABLE_SSLV2 //SSLv2 is disabled by default
 822 h.sterling       1.50     options |= SSL_OP_NO_SSLv2;
 823 h.sterling       1.49 #endif
 824 h.sterling       1.50     SSL_CTX_set_options(sslContext, options);
 825 h.sterling       1.49 
 826 h.sterling       1.26     if (_verifyPeer)
 827 kumpf            1.1      {
 828 h.sterling       1.26         //ATTN: We might still need a flag to specify SSL_VERIFY_FAIL_IF_NO_PEER_CERT
 829 david.dillard    1.59         // If SSL_VERIFY_FAIL_IF_NO_PEER_CERT is ON, SSL will immediately be terminated
 830                               // if the client sends no certificate or sends an untrusted certificate.  The
 831 kumpf            1.27         // callback function is not called in this case; the handshake is simply terminated.
 832 h.sterling       1.26         // This value has NO effect in from a client perspective
 833                       
 834 h.sterling       1.28         if (_certificateVerifyFunction != NULL)
 835 h.sterling       1.26         {
 836 david.dillard    1.59             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
 837 kumpf            1.27                 "---> SSL: certificate verification callback specified");
 838 david.dillard    1.59             SSL_CTX_set_verify(sslContext,
 839 kumpf            1.27                 SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, prepareForCallback);
 840                               }
 841 h.sterling       1.26         else
 842                               {
 843 kumpf            1.27             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Trust Store specified");
 844 david.dillard    1.59             SSL_CTX_set_verify(sslContext,
 845                                       SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
 846 kumpf            1.27                 prepareForCallback);
 847 h.sterling       1.26         }
 848 kumpf            1.1      }
 849 kumpf            1.14     else
 850                           {
 851 kumpf            1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
 852                                   "---> SSL: Trust Store and certificate verification callback are NOT specified");
 853                               SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
 854 kumpf            1.14     }
 855 kumpf            1.1  
 856                           //
 857 kumpf            1.27     // Check if there is CA certificate file or directory specified. If specified,
 858                           // and is not empty, load the certificates from the Trust store.
 859 h.sterling       1.26     //
 860 kumpf            1.27     if (_trustStore != String::EMPTY)
 861 kumpf            1.14     {
 862                               //
 863 h.sterling       1.26         // The truststore may be a single file of CA certificates OR
 864                               // a directory containing multiple CA certificates.
 865 david.dillard    1.59         // Check which one it is, and call the load_verify_locations function
 866 h.sterling       1.26         // with the appropriate parameter.  Note: It is possible to have both
 867 david.dillard    1.59         // options, in which case the CA file takes precedence over the CA path.
 868 h.sterling       1.26         // However, since there is currently only one trust parameter to the
 869 david.dillard    1.59         // SSL functions, only allow one choice here.
 870 kumpf            1.27         //
 871                               if (FileSystem::isDirectory(_trustStore))
 872                               {
 873 david.dillard    1.59             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
 874 kumpf            1.27                             "---> SSL: Truststore is a directory");
 875                                   //
 876                                   // load certificates from the trust store
 877                                   //
 878                                   PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 879                                       "---> SSL: Loading certificates from the trust store: " + _trustStore);
 880                       
 881                                   if ((!SSL_CTX_load_verify_locations(sslContext, NULL, _trustStore.getCString())) ||
 882                                       (!SSL_CTX_set_default_verify_paths(sslContext)))
 883                                   {
 884                                       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 885                                           "---> SSL: Could not load certificates from the trust store: " + _trustStore);
 886                                       //l10n
 887                                       MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
 888                                           "Could not load certificates in to trust store.");
 889                                       PEG_METHOD_EXIT();
 890                                       throw SSLException(parms);
 891                                   }
 892 h.sterling       1.26 
 893 david.dillard    1.59         }
 894 kumpf            1.27         else if (FileSystem::exists(_trustStore))
 895 h.sterling       1.26         {
 896 david.dillard    1.59             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
 897 kumpf            1.27                             "---> SSL: Truststore is a file");
 898                                   //
 899                                   // Get size of the trust store file:
 900                                   //
 901                                   Uint32 fileSize = 0;
 902 h.sterling       1.26 
 903 kumpf            1.27             FileSystem::getFileSize(_trustStore, fileSize);
 904 h.sterling       1.26 
 905 kumpf            1.27             if (fileSize > 0)
 906                                   {
 907                                       //
 908                                       // load certificates from the trust store
 909                                       //
 910                                       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 911                                           "---> SSL: Loading certificates from the trust store: " + _trustStore);
 912                       
 913                                       if ((!SSL_CTX_load_verify_locations(sslContext, _trustStore.getCString(), NULL)) ||
 914                                           (!SSL_CTX_set_default_verify_paths(sslContext)))
 915                                       {
 916                                           PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 917                                               "---> SSL: Could not load certificates from the trust store: " + _trustStore);
 918                                           //l10n
 919                                           MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
 920                                               "Could not load certificates in to trust store.");
 921                                           PEG_METHOD_EXIT();
 922                                           throw SSLException(parms);
 923                                       }
 924                                   }
 925                                   else
 926 kumpf            1.27             {
 927                                       //
 928                                       // no certificates found in the trust store
 929                                       //
 930                                       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 931                                           "---> SSL: No certificates to load from the trust store: " + _trustStore);
 932                                   }
 933 kumpf            1.14         }
 934                           }
 935                       
 936 david.dillard    1.59     if (_crlPath != String::EMPTY)
 937 h.sterling       1.47     {
 938 h.sterling       1.40         //need to save this -- can we make it static since there's only one CRL for cimserver?
 939 h.sterling       1.47         X509_LOOKUP* pLookup;
 940 david.dillard    1.59 
 941 h.sterling       1.47         _crlStore = X509_STORE_new();
 942 h.sterling       1.40 
 943 h.sterling       1.47         //the validity of the crlstore was checked in ConfigManager during server startup
 944                               if (FileSystem::isDirectory(_crlPath))
 945 h.sterling       1.40         {
 946                                   Tracer::trace(TRC_SSL, Tracer::LEVEL3,
 947 h.sterling       1.47                           "---> SSL: CRL store is a directory in %s", (const char*)_crlPath.getCString());
 948 h.sterling       1.40 
 949                                   if ((pLookup = X509_STORE_add_lookup(_crlStore, X509_LOOKUP_hash_dir())) == NULL)
 950 h.sterling       1.47             {
 951                                       MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CRLS",
 952                                                                "Could not load certificate revocation list.");
 953                                       X509_STORE_free(_crlStore);
 954 h.sterling       1.40                 PEG_METHOD_EXIT();
 955                                       throw SSLException(parms);
 956 h.sterling       1.47             }
 957 h.sterling       1.40 
 958                                   X509_LOOKUP_add_dir(pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
 959                       
 960 david.dillard    1.59             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
 961 h.sterling       1.40                             "---> SSL: Successfully configured CRL directory");
 962                       
 963 david.dillard    1.59         } else
 964 h.sterling       1.47         {
 965 h.sterling       1.40             Tracer::trace(TRC_SSL, Tracer::LEVEL3,
 966 h.sterling       1.47                           "---> SSL: CRL store is the file %s", (const char*)_crlPath.getCString());
 967 h.sterling       1.40 
 968                                   if ((pLookup = X509_STORE_add_lookup(_crlStore, X509_LOOKUP_file())) == NULL)
 969 h.sterling       1.47             {
 970 h.sterling       1.40                 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CRLS",
 971 h.sterling       1.47                                          "Could not load certificate revocation list.");
 972                                       X509_STORE_free(_crlStore);
 973 h.sterling       1.40                 PEG_METHOD_EXIT();
 974                                       throw SSLException(parms);
 975 h.sterling       1.47             }
 976 h.sterling       1.40 
 977 h.sterling       1.47             X509_LOOKUP_load_file(pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
 978 david.dillard    1.59 
 979                                   PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
 980                                                   "---> SSL: Successfully configured CRL file");
 981 h.sterling       1.47         }
 982                           }
 983 h.sterling       1.40 
 984 kumpf            1.17     Boolean keyLoaded = false;
 985 kumpf            1.27 
 986 kumpf            1.1      //
 987 david.dillard    1.59     // Check if there is a certificate file (file containing server
 988                           // certificate) specified. If specified, validate and load the
 989 kumpf            1.16     // certificate.
 990 kumpf            1.14     //
 991 kumpf            1.27     if (_certPath != String::EMPTY)
 992 kumpf            1.14     {
 993                               //
 994                               // load the specified server certificates
 995                               //
 996 kumpf            1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
 997                                   "---> SSL: Loading server certificate from: " + _certPath);
 998 kumpf            1.1  
 999 david.dillard    1.59         if (SSL_CTX_use_certificate_file(sslContext,
1000 kumpf            1.27             _certPath.getCString(), SSL_FILETYPE_PEM) <=0)
1001 kumpf            1.14         {
1002 kumpf            1.27             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1003                                       "---> SSL: No server certificate found in " + _certPath);
1004 humberto         1.18             MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_SERVER_CERTIFICATE",
1005 h.sterling       1.47                                      "Could not get server certificate.");
1006 kumpf            1.27             PEG_METHOD_EXIT();
1007 tony             1.24             throw SSLException(parms);
1008 kumpf            1.14         }
1009 kumpf            1.17 
1010 kumpf            1.16         //
1011                               // If there is no key file (file containing server
1012 h.sterling       1.26         // private key) specified, then try loading the key from the certificate file.
1013 kumpf            1.27         // As of 2.4, if a keyfile is specified, its location is verified during server
1014                               // startup and will throw an error if the path is invalid.
1015 kumpf            1.16         //
1016 kumpf            1.27         if (_keyPath == String::EMPTY)
1017 kumpf            1.16         {
1018 kumpf            1.27             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1019                                       "---> SSL: loading private key from: " + _certPath);
1020 kumpf            1.16             //
1021                                   // load the private key and check for validity
1022                                   //
1023 kumpf            1.27             if (!_verifyPrivateKey(sslContext, _certPath))
1024 kumpf            1.16             {
1025 humberto         1.18                 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
1026 h.sterling       1.47                                          "Could not get private key.");
1027 kumpf            1.27                 PEG_METHOD_EXIT();
1028 h.sterling       1.47                 throw SSLException(parms);
1029 kumpf            1.16             }
1030 kumpf            1.17             keyLoaded = true;
1031 kumpf            1.16         }
1032                           }
1033 kumpf            1.14 
1034 kumpf            1.16     //
1035 kumpf            1.17     // Check if there is a key file (file containing server
1036                           // private key) specified and the key was not already loaded.
1037                           // If specified, validate and load the key.
1038 kumpf            1.16     //
1039 kumpf            1.27     if (_keyPath != String::EMPTY && !keyLoaded)
1040 kumpf            1.16     {
1041 kumpf            1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1042                                   "---> SSL: loading private key from: " + _keyPath);
1043 kumpf            1.14         //
1044                               // load given private key and check for validity
1045                               //
1046 kumpf            1.27         if (!_verifyPrivateKey(sslContext, _keyPath))
1047 kumpf            1.14         {
1048 humberto         1.18             MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
1049 h.sterling       1.47                                          "Could not get private key.");
1050 kumpf            1.27             PEG_METHOD_EXIT();
1051 tony             1.24             throw SSLException(parms);
1052 kumpf            1.14         }
1053 kumpf            1.17         keyLoaded = true;
1054 kumpf            1.14     }
1055                       
1056                           PEG_METHOD_EXIT();
1057                           return sslContext;
1058                       }
1059                       
1060 kumpf            1.27 Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx, const String& keyPath)
1061 kumpf            1.14 {
1062                           PEG_METHOD_ENTER(TRC_SSL, "_verifyPrivateKey()");
1063                       
1064 kumpf            1.27     if (SSL_CTX_use_PrivateKey_file(ctx, keyPath.getCString(), SSL_FILETYPE_PEM) <= 0)
1065 kumpf            1.3      {
1066 kumpf            1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1067 kumpf            1.16             "---> SSL: no private key found in " + String(keyPath));
1068 kumpf            1.3          PEG_METHOD_EXIT();
1069 kumpf            1.14         return false;
1070                           }
1071                       
1072                           if (!SSL_CTX_check_private_key(ctx))
1073                           {
1074 kumpf            1.27         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1075 kumpf            1.14             "---> SSL: Private and public key do not match");
1076                               PEG_METHOD_EXIT();
1077                               return false;
1078 kumpf            1.3      }
1079 kumpf            1.1  
1080 kumpf            1.3      PEG_METHOD_EXIT();
1081 kumpf            1.14     return true;
1082 kumpf            1.1  }
1083                       
1084 david.dillard    1.59 SSL_CTX * SSLContextRep::getContext() const
1085 kumpf            1.1  {
1086 kumpf            1.9      return _sslContext;
1087 kumpf            1.1  }
1088 h.sterling       1.26 
1089                       String SSLContextRep::getTrustStore() const
1090                       {
1091                           return _trustStore;
1092                       }
1093                       
1094                       String SSLContextRep::getCertPath() const
1095                       {
1096                           return _certPath;
1097                       }
1098                       
1099                       String SSLContextRep::getKeyPath() const
1100                       {
1101                           return _keyPath;
1102                       }
1103                       
1104 dave.sudlik      1.55 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1105 david.dillard    1.59 String SSLContextRep::getTrustStoreUserName() const
1106                       {
1107                           return String::EMPTY;
1108 dave.sudlik      1.55 }
1109                       #endif
1110                       
1111 h.sterling       1.40 String SSLContextRep::getCRLPath() const
1112 h.sterling       1.26 {
1113 h.sterling       1.40     return _crlPath;
1114 h.sterling       1.26 }
1115                       
1116 h.sterling       1.40 X509_STORE* SSLContextRep::getCRLStore() const
1117 h.sterling       1.26 {
1118 h.sterling       1.40     return _crlStore;
1119 h.sterling       1.26 }
1120                       
1121 h.sterling       1.50 void SSLContextRep::setCRLStore(X509_STORE* store)
1122                       {
1123                           _crlStore = store;
1124                       }
1125                       
1126 h.sterling       1.40 Boolean SSLContextRep::isPeerVerificationEnabled() const
1127 h.sterling       1.26 {
1128 h.sterling       1.40     return _verifyPeer;
1129 h.sterling       1.26 }
1130                       
1131 h.sterling       1.28 SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const
1132                       {
1133                           return _certificateVerifyFunction;
1134                       }
1135                       
1136 david.dillard    1.59 #else
1137 kumpf            1.1  
1138                       //
1139 kumpf            1.9  // these definitions are used if ssl is not available
1140 kumpf            1.1  //
1141                       
1142 h.sterling       1.26 SSLContextRep::SSLContextRep(const String& trustStore,
1143 kumpf            1.16                        const String& certPath,
1144                                              const String& keyPath,
1145 h.sterling       1.41                        const String& crlPath,
1146 kumpf            1.9                         SSLCertificateVerifyFunction* verifyCert,
1147 h.sterling       1.41                        const String& randomFile)
1148                       {}
1149 h.sterling       1.26 
1150 kumpf            1.9  SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep) {}
1151                       
1152 kumpf            1.1  SSLContextRep::~SSLContextRep() {}
1153                       
1154 kumpf            1.9  SSL_CTX * SSLContextRep::_makeSSLContext() { return 0; }
1155                       
1156 david.dillard    1.59 Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx,
1157 kumpf            1.27                                          const String& keyPath) { return false; }
1158 kumpf            1.14 
1159 kumpf            1.9  SSL_CTX * SSLContextRep::getContext() const { return 0; }
1160 kumpf            1.15 
1161 h.sterling       1.26 String SSLContextRep::getTrustStore() const { return String::EMPTY; }
1162                       
1163                       String SSLContextRep::getCertPath() const { return String::EMPTY; }
1164                       
1165                       String SSLContextRep::getKeyPath() const { return String::EMPTY; }
1166                       
1167 dave.sudlik      1.55 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1168                       String SSLContextRep::getTrustStoreUserName() const { return String::EMPTY; }
1169                       #endif
1170                       
1171 h.sterling       1.40 String SSLContextRep::getCRLPath() const { return String::EMPTY; }
1172 h.sterling       1.26 
1173 h.sterling       1.40 X509_STORE* SSLContextRep::getCRLStore() const { return NULL; }
1174 h.sterling       1.26 
1175 h.sterling       1.50 void SSLContextRep::setCRLStore(X509_STORE* store) { }
1176                       
1177 h.sterling       1.40 Boolean SSLContextRep::isPeerVerificationEnabled() const { return false; }
1178 h.sterling       1.26 
1179 h.sterling       1.28 SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const { return NULL; }
1180                       
1181 kumpf            1.15 void SSLContextRep::init_ssl() {}
1182                       
1183                       void SSLContextRep::free_ssl() {}
1184 kumpf            1.1  
1185                       #endif // end of PEGASUS_HAS_SSL
1186                       
1187                       ///////////////////////////////////////////////////////////////////////////////
1188                       //
1189                       // SSLContext
1190                       //
1191                       ///////////////////////////////////////////////////////////////////////////////
1192                       
1193                       
1194                       SSLContext::SSLContext(
1195 h.sterling       1.26     const String& trustStore,
1196 kumpf            1.9      SSLCertificateVerifyFunction* verifyCert,
1197 kumpf            1.13     const String& randomFile)
1198                       {
1199 h.sterling       1.40     _rep = new SSLContextRep(trustStore, String::EMPTY, String::EMPTY, String::EMPTY, verifyCert, randomFile);
1200 kumpf            1.13 }
1201                       
1202 kumpf            1.14 SSLContext::SSLContext(
1203 h.sterling       1.26     const String& trustStore,
1204 kumpf            1.14     const String& certPath,
1205 kumpf            1.16     const String& keyPath,
1206 kumpf            1.14     SSLCertificateVerifyFunction* verifyCert,
1207                           const String& randomFile)
1208                       {
1209 h.sterling       1.40     _rep = new SSLContextRep(trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
1210 h.sterling       1.30 }
1211                       
1212 h.sterling       1.40 //PEP187
1213 h.sterling       1.26 SSLContext::SSLContext(
1214                               const String& trustStore,
1215                               const String& certPath,
1216                               const String& keyPath,
1217 h.sterling       1.47         const String& crlPath,
1218 h.sterling       1.26         SSLCertificateVerifyFunction* verifyCert,
1219                               const String& randomFile)
1220                       {
1221 sushma.fernandes 1.66 #ifndef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
1222                           if ( crlPath.size() > 0 )
1223                           {
1224                               MessageLoaderParms parms("Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
1225                                                        "SSL CRL verification is not enabled.");
1226                               throw Exception(parms);
1227                           }
1228                       #endif
1229 h.sterling       1.40     _rep = new SSLContextRep(trustStore, certPath, keyPath, crlPath, verifyCert, randomFile);
1230 kumpf            1.14 }
1231                       
1232 dave.sudlik      1.55 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1233                       SSLContext::SSLContext(
1234                           const String& trustStore,
1235                           const String& certPath,
1236                           const String& keyPath,
1237                           SSLCertificateVerifyFunction* verifyCert,
1238                           String trustStoreUserName,
1239                           const String& randomFile)
1240                       {
1241                           _rep = new SSLContextRep(trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
1242                       }
1243                       #endif
1244                       
1245 kumpf            1.9  SSLContext::SSLContext(const SSLContext& sslContext)
1246                       {
1247                           _rep = new SSLContextRep(*sslContext._rep);
1248 kumpf            1.12 }
1249                       
1250                       // Dummy constructor made private to disallow default construction
1251                       SSLContext::SSLContext()
1252                       {
1253 kumpf            1.9  }
1254                       
1255 david.dillard    1.59 SSLContext::~SSLContext()
1256 kumpf            1.1  {
1257                           delete _rep;
1258                       }
1259                       
1260 h.sterling       1.26 String SSLContext::getTrustStore() const
1261                       {
1262                           return (_rep->getTrustStore());
1263                       }
1264                       
1265                       String SSLContext::getCertPath() const
1266                       {
1267                           return (_rep->getCertPath());
1268                       }
1269                       
1270                       String SSLContext::getKeyPath() const
1271                       {
1272 david.dillard    1.59     return (_rep->getKeyPath());
1273 h.sterling       1.26 }
1274                       
1275 h.sterling       1.40 String SSLContext::getCRLPath() const
1276 h.sterling       1.26 {
1277 sushma.fernandes 1.66 #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
1278 david.dillard    1.59     return (_rep->getCRLPath());
1279 sushma.fernandes 1.66 #else
1280                           MessageLoaderParms parms("Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
1281                                                    "SSL CRL verification is not enabled.");
1282                           throw Exception(parms);
1283                       #endif
1284 h.sterling       1.26 }
1285                       
1286 h.sterling       1.40 X509_STORE* SSLContext::getCRLStore() const
1287 h.sterling       1.26 {
1288 sushma.fernandes 1.66 #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
1289 david.dillard    1.59     return (_rep->getCRLStore());
1290 sushma.fernandes 1.66 #else
1291                           MessageLoaderParms parms("Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
1292                                                    "SSL CRL verification is not enabled.");
1293                           throw Exception(parms);
1294                       #endif
1295 h.sterling       1.26 }
1296                       
1297 h.sterling       1.40 Boolean SSLContext::isPeerVerificationEnabled() const
1298 h.sterling       1.26 {
1299 h.sterling       1.40     return (_rep->isPeerVerificationEnabled());
1300 h.sterling       1.26 }
1301 kumpf            1.1  
1302 dave.sudlik      1.55 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1303                       String SSLContext::getTrustStoreUserName() const
1304                       {
1305                       	return (_rep->getTrustStoreUserName());
1306                       }
1307                       #endif
1308                       
1309 h.sterling       1.28 SSLCertificateVerifyFunction* SSLContext::getSSLCertificateVerifyFunction() const
1310                       {
1311                           return (_rep->getSSLCertificateVerifyFunction());
1312                       }
1313                       
1314 kumpf            1.1  ///////////////////////////////////////////////////////////////////////////////
1315                       //
1316 kumpf            1.9  // SSLCertificateInfo
1317 kumpf            1.1  //
1318                       ///////////////////////////////////////////////////////////////////////////////
1319 kumpf            1.16 //
1320                       // Certificate validation result codes.
1321                       //
1322                       const int    SSLCertificateInfo::V_OK                                       = 0;
1323                       
1324                       const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT            = 2;
1325                       const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_CRL                    = 3;
1326                       const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     = 4;
1327                       const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      = 5;
1328                       const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   = 6;
1329                       const int    SSLCertificateInfo::V_ERR_CERT_SIGNATURE_FAILURE               = 7;
1330                       const int    SSLCertificateInfo::V_ERR_CRL_SIGNATURE_FAILURE                = 8;
1331                       const int    SSLCertificateInfo::V_ERR_CERT_NOT_YET_VALID                   = 9;
1332                       const int    SSLCertificateInfo::V_ERR_CERT_HAS_EXPIRED                     = 10;
1333                       const int    SSLCertificateInfo::V_ERR_CRL_NOT_YET_VALID                    = 11;
1334                       const int    SSLCertificateInfo::V_ERR_CRL_HAS_EXPIRED                      = 12;
1335                       const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       = 13;
1336                       const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        = 14;
1337                       const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       = 15;
1338                       const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       = 16;
1339                       const int    SSLCertificateInfo::V_ERR_OUT_OF_MEM                           = 17;
1340 kumpf            1.16 const int    SSLCertificateInfo::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          = 18;
1341                       const int    SSLCertificateInfo::V_ERR_SELF_SIGNED_CERT_IN_CHAIN            = 19;
1342                       const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    = 20;
1343                       const int    SSLCertificateInfo::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      = 21;
1344                       const int    SSLCertificateInfo::V_ERR_CERT_CHAIN_TOO_LONG                  = 22;
1345                       const int    SSLCertificateInfo::V_ERR_CERT_REVOKED                         = 23;
1346                       const int    SSLCertificateInfo::V_ERR_INVALID_CA                           = 24;
1347                       const int    SSLCertificateInfo::V_ERR_PATH_LENGTH_EXCEEDED                 = 25;
1348                       const int    SSLCertificateInfo::V_ERR_INVALID_PURPOSE                      = 26;
1349                       const int    SSLCertificateInfo::V_ERR_CERT_UNTRUSTED                       = 27;
1350                       const int    SSLCertificateInfo::V_ERR_CERT_REJECTED                        = 28;
1351                       const int    SSLCertificateInfo::V_ERR_SUBJECT_ISSUER_MISMATCH              = 29;
1352                       const int    SSLCertificateInfo::V_ERR_AKID_SKID_MISMATCH                   = 30;
1353                       const int    SSLCertificateInfo::V_ERR_AKID_ISSUER_SERIAL_MISMATCH          = 31;
1354                       const int    SSLCertificateInfo::V_ERR_KEYUSAGE_NO_CERTSIGN                 = 32;
1355                       
1356                       const int    SSLCertificateInfo::V_ERR_APPLICATION_VERIFICATION             = 50;
1357 kumpf            1.1  
1358 kumpf            1.9  class SSLCertificateInfoRep
1359                       {
1360                       public:
1361 kumpf            1.16     String    subjectName;
1362                           String    issuerName;
1363                           Uint32    depth;
1364                           Uint32    errorCode;
1365                           Uint32    respCode;
1366                           String    errorString;
1367                           Uint32    versionNumber;
1368                           long      serialNumber;
1369                           CIMDateTime    notBefore;
1370                           CIMDateTime    notAfter;
1371 kumpf            1.9  };
1372                       
1373                       
1374                       SSLCertificateInfo::SSLCertificateInfo(
1375 kumpf            1.1      const String subjectName,
1376                           const String issuerName,
1377                           const int errorDepth,
1378 kumpf            1.14     const int errorCode,
1379                           const int respCode)
1380 kumpf            1.1  {
1381 kumpf            1.9      _rep = new SSLCertificateInfoRep();
1382                           _rep->subjectName = subjectName;
1383                           _rep->issuerName = issuerName;
1384 kumpf            1.16     _rep->versionNumber = 0;
1385                           _rep->serialNumber = 0;
1386 h.sterling       1.26     _rep->notBefore = CIMDateTime();
1387                           _rep->notAfter = CIMDateTime();
1388 kumpf            1.16     _rep->depth = errorDepth;
1389 kumpf            1.9      _rep->errorCode = errorCode;
1390 kumpf            1.16     _rep->errorString = String::EMPTY;
1391                           _rep->respCode = respCode;
1392                       }
1393                       
1394                       SSLCertificateInfo::SSLCertificateInfo(
1395                           const String subjectName,
1396                           const String issuerName,
1397                           const Uint32 versionNumber,
1398                           const long serialNumber,
1399                           const CIMDateTime notBefore,
1400                           const CIMDateTime notAfter,
1401                           const Uint32 depth,
1402                           const Uint32 errorCode,
1403                           const String errorString,
1404                           const Uint32 respCode)
1405                       {
1406                           _rep = new SSLCertificateInfoRep();
1407                           _rep->subjectName = subjectName;
1408                           _rep->issuerName = issuerName;
1409                           _rep->versionNumber = versionNumber;
1410                           _rep->serialNumber = serialNumber;
1411 kumpf            1.16     _rep->notBefore = notBefore;
1412                           _rep->notAfter = notAfter;
1413                           _rep->depth = depth;
1414                           _rep->errorCode = errorCode;
1415                           _rep->errorString = errorString;
1416 kumpf            1.14     _rep->respCode = respCode;
1417 kumpf            1.9  }
1418                       
1419                       SSLCertificateInfo::SSLCertificateInfo(
1420                           const SSLCertificateInfo& certificateInfo)
1421                       {
1422                           _rep = new SSLCertificateInfoRep();
1423                           _rep->subjectName = certificateInfo._rep->subjectName;
1424                           _rep->issuerName = certificateInfo._rep->issuerName;
1425 kumpf            1.16     _rep->versionNumber = certificateInfo._rep->versionNumber;
1426                           _rep->serialNumber = certificateInfo._rep->serialNumber;
1427                           _rep->notBefore = certificateInfo._rep->notBefore;
1428                           _rep->notAfter = certificateInfo._rep->notAfter;
1429                           _rep->depth = certificateInfo._rep->depth;
1430 kumpf            1.9      _rep->errorCode = certificateInfo._rep->errorCode;
1431 kumpf            1.16     _rep->errorString = certificateInfo._rep->errorString;
1432 kumpf            1.9      _rep->respCode = certificateInfo._rep->respCode;
1433 kumpf            1.11 }
1434                       
1435                       // Dummy constructor made private to disallow default construction
1436                       SSLCertificateInfo::SSLCertificateInfo()
1437                       {
1438 kumpf            1.1  }
1439                       
1440 kumpf            1.9  SSLCertificateInfo::~SSLCertificateInfo()
1441 kumpf            1.1  {
1442 kumpf            1.9      delete _rep;
1443 kumpf            1.1  }
1444                       
1445 kumpf            1.9  String SSLCertificateInfo::getSubjectName() const
1446 kumpf            1.1  {
1447 kumpf            1.9      return (_rep->subjectName);
1448 kumpf            1.1  }
1449                       
1450 kumpf            1.9  String SSLCertificateInfo::getIssuerName() const
1451 kumpf            1.1  {
1452 kumpf            1.9      return (_rep->issuerName);
1453 kumpf            1.1  }
1454                       
1455 kumpf            1.16 Uint32 SSLCertificateInfo::getVersionNumber() const
1456                       {
1457                           return (_rep->versionNumber);
1458                       }
1459                       
1460                       long SSLCertificateInfo::getSerialNumber() const
1461 kumpf            1.1  {
1462 kumpf            1.16     return (_rep->serialNumber);
1463 kumpf            1.1  }
1464                       
1465 kumpf            1.16 CIMDateTime SSLCertificateInfo::getNotBefore() const
1466                       {
1467                           return (_rep->notBefore);
1468                       }
1469                       
1470 david.dillard    1.59 CIMDateTime SSLCertificateInfo::getNotAfter() const
1471 kumpf            1.16 {
1472                           return (_rep->notAfter);
1473                       }
1474                       
1475                       Uint32 SSLCertificateInfo::getErrorDepth() const
1476                       {
1477                           return (_rep->depth);
1478                       }
1479                       
1480                       Uint32 SSLCertificateInfo::getErrorCode()  const
1481 kumpf            1.1  {
1482 kumpf            1.9      return (_rep->errorCode);
1483 kumpf            1.14 }
1484                       
1485 kumpf            1.16 void SSLCertificateInfo::setErrorCode(const int errorCode)
1486                       {
1487                           _rep->errorCode = errorCode;
1488                       }
1489                       
1490                       String SSLCertificateInfo::getErrorString() const
1491                       {
1492                           return (_rep->errorString);
1493                       }
1494                       
1495                       Uint32 SSLCertificateInfo::getResponseCode()  const
1496 kumpf            1.14 {
1497                           return (_rep->respCode);
1498 kumpf            1.1  }
1499                       
1500 kumpf            1.9  void SSLCertificateInfo::setResponseCode(const int respCode)
1501 kumpf            1.1  {
1502 kumpf            1.9      _rep->respCode = respCode;
1503 kumpf            1.1  }
1504                       
1505 h.sterling       1.28 String SSLCertificateInfo::toString() const
1506                       {
1507                           char buf[1024];
1508 david.dillard    1.59 
1509 h.sterling       1.28     String s;
1510                       
1511                           s.append("Subject Name:\n\t");
1512                           s.append(_rep->subjectName);
1513                           s.append("\n");
1514 david.dillard    1.59 
1515 h.sterling       1.28     s.append("Issuer Name:\n\t");
1516                           s.append(_rep->issuerName);
1517                           s.append("\n");
1518 david.dillard    1.59 
1519 h.sterling       1.28     sprintf(buf, "Depth: %d\n", _rep->depth);
1520                           s.append(buf);
1521 david.dillard    1.59 
1522 h.sterling       1.28     sprintf(buf, "Error code: %d\n", _rep->errorCode);
1523                           s.append(buf);
1524 david.dillard    1.59 
1525 h.sterling       1.28     sprintf(buf, "Response (preverify) code: %d\n", _rep->respCode);
1526                           s.append(buf);
1527                       
1528                           s.append("Error string: ");
1529                           s.append(_rep->errorString);
1530                           s.append("\n");
1531 david.dillard    1.59 
1532 h.sterling       1.28     sprintf(buf, "Version number: %d\n", _rep->versionNumber);
1533                           s.append(buf);
1534                       
1535 h.sterling       1.57     sprintf(buf, "Serial number: %lu\n", _rep->serialNumber);
1536 h.sterling       1.28     s.append(buf);
1537 david.dillard    1.59 
1538 h.sterling       1.28     s.append("Not before date: ");
1539                           s.append((_rep->notBefore).toString());
1540                           s.append("\n");
1541                       
1542                           s.append("Not after date: ");
1543                           s.append((_rep->notAfter).toString());
1544                           s.append("\n");
1545                       
1546                           return s;
1547                       }
1548                       
1549 dave.sudlik      1.55 ///////////////////////////////////////////////////////////////////////////////
1550                       //
1551                       // SSLCallbackInfo
1552                       //
1553                       ///////////////////////////////////////////////////////////////////////////////
1554                       
1555                       SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert)
1556                       {
1557                           _rep = new SSLCallbackInfoRep();
1558                           _rep->verifyCertificateCallback = verifyCert;
1559                           _rep->crlStore = NULL;
1560                       }
1561                       
1562 h.sterling       1.40 SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert, X509_STORE* crlStore)
1563 h.sterling       1.28 {
1564 dave.sudlik      1.55     _rep = new SSLCallbackInfoRep();
1565                           _rep->verifyCertificateCallback = verifyCert;
1566                           _rep->crlStore = crlStore;
1567 h.sterling       1.28 }
1568                       
1569                       SSLCallbackInfo::~SSLCallbackInfo()
1570                       {
1571 h.sterling       1.63     PEG_METHOD_ENTER(TRC_SSL, "SSLCallbackInfo::~SSLCallbackInfo");
1572                           for (Uint32 i = 0; i < _rep->peerCertificate.size(); i++)
1573 h.sterling       1.28     {
1574 h.sterling       1.63         delete _rep->peerCertificate[i];
1575 h.sterling       1.28     }
1576 dave.sudlik      1.55     delete _rep;
1577 h.sterling       1.63     PEG_METHOD_EXIT();
1578 h.sterling       1.28 }
1579                       
1580 kumpf            1.1  PEGASUS_NAMESPACE_END
1581                       

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2