(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 gs.keenan        1.73 #if defined(PEGASUS_HAVE_PTHREADS) && !defined(PEGASUS_OS_VMS)
 508 kumpf            1.15      // Set the ID callback. The ID callback returns a thread ID.
 509 kumpf            1.74      CRYPTO_set_id_callback((CRYPTO_SET_ID_CALLBACK) pthread_self);
 510 gs.keenan        1.73 #endif
 511 kumpf            1.15 
 512                            // Set the locking callback to pegasus_locking_callback.
 513                       
 514 david.dillard    1.38      CRYPTO_set_locking_callback((CRYPTO_SET_LOCKING_CALLBACK) pegasus_locking_callback);
 515 kumpf            1.15 
 516                       }
 517                       
 518                       // Free OpenSSL Locking and id callbacks.
 519                       void SSLContextRep::free_ssl()
 520                       {
 521                           // Cleanup _sslLocks and set locking & id callback to NULL.
 522                       
 523                           CRYPTO_set_locking_callback(NULL);
 524                           CRYPTO_set_id_callback     (NULL);
 525                           PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
 526                                    "Freed SSL callback.");
 527 aruran.ms        1.61     _sslLocks.reset();
 528 kumpf            1.15 }
 529                       
 530 kumpf            1.1  
 531                       //
 532                       // SSL context area
 533                       //
 534                       // For the OSs that don't have /dev/random device file,
 535                       // must enable PEGASUS_SSL_RANDOMFILE flag.
 536                       //
 537 h.sterling       1.26 SSLContextRep::SSLContextRep(
 538                                              const String& trustStore,
 539                                              const String& certPath,
 540                                              const String& keyPath,
 541 h.sterling       1.47                        const String& crlPath,
 542 h.sterling       1.26                        SSLCertificateVerifyFunction* verifyCert,
 543                                              const String& randomFile)
 544                       {
 545                           PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
 546                       
 547                           _trustStore = trustStore;
 548                       
 549                           _certPath = certPath;
 550                       
 551                           _keyPath = keyPath;
 552                       
 553 h.sterling       1.40     _crlPath = crlPath;
 554 h.sterling       1.26 
 555 h.sterling       1.47     _crlStore = NULL;
 556 h.sterling       1.26 
 557 h.sterling       1.40     _certificateVerifyFunction = verifyCert;
 558 h.sterling       1.26 
 559 h.sterling       1.28     //
 560 h.sterling       1.26     // If a truststore and/or peer verification function is specified, enable peer verification
 561 h.sterling       1.28     //
 562 h.sterling       1.26     if (trustStore != String::EMPTY || verifyCert != NULL)
 563                           {
 564                               _verifyPeer = true;
 565 david.dillard    1.59     }
 566 h.sterling       1.26     else
 567                           {
 568                               _verifyPeer = false;
 569                           }
 570 kumpf            1.15 
 571 h.sterling       1.28     //
 572 kumpf            1.15     // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.
 573 h.sterling       1.28     //
 574 a.arora          1.35     {
 575                              AutoMutex autoMut(_countRepMutex);
 576 kumpf            1.15 
 577 a.arora          1.35        Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 578 kumpf            1.15                 "Value of Countrep in constructor %d", _countRep);
 579                               if ( _countRep == 0 )
 580                               {
 581                                   init_ssl();
 582                       
 583                                   //
 584                                   // load SSL library
 585                                   //
 586                                   Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 587 mike             1.70                 "Before calling SSL_load_error_strings %d", Threads::id());
 588 kumpf            1.15 
 589                                   SSL_load_error_strings();
 590                       
 591                                   Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 592 mike             1.70                 "After calling SSL_load_error_strings %d", Threads::id());
 593 kumpf            1.15 
 594                                   Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 595 mike             1.70                 "Before calling SSL_library_init %d", Threads::id());
 596 kumpf            1.15 
 597                                   SSL_library_init();
 598                       
 599                                   Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 600 mike             1.70                 "After calling SSL_library_init %d", Threads::id());
 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