(file) Return to SSLContext.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2