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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2