(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                        if (exData->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 h.sterling    1.47         if (exData->_crlStore != NULL) 
 335                            {
 336                                revoked = verificationCRLCallback(preVerifyOk,ctx,exData->_crlStore);
 337                                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                        if (exData->_crlStore != NULL) 
 351                        {
 352 h.sterling    1.40         revoked = verificationCRLCallback(preVerifyOk,ctx,exData->_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 h.sterling    1.54     if (exData->_peerCertificate != NULL)
 433                        {
 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                            delete exData->_peerCertificate;
 439                            exData->_peerCertificate = NULL;
 440                        } 	
 441                    
 442 h.sterling    1.28     exData->_peerCertificate = new SSLCertificateInfo(subjectName, issuerName, version, serialNumber,
 443                            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 h.sterling    1.40     if (exData->verifyCertificateCallback(*exData->_peerCertificate)) 
 452 kumpf         1.1      {
 453 kumpf         1.16         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
 454 h.sterling    1.28             "--> SSL: verifyCertificateCallback() returned X509_V_OK");
 455                    
 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 h.sterling    1.28             "--> SSL: verifyCertificateCallback() returned error %d", exData->_peerCertificate->getErrorCode());
 463                          
 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 h.sterling    1.40 String SSLContextRep::getCRLPath() const
1119 h.sterling    1.26 {
1120 h.sterling    1.40     return _crlPath;
1121 h.sterling    1.26 }
1122                    
1123 h.sterling    1.40 X509_STORE* SSLContextRep::getCRLStore() const
1124 h.sterling    1.26 {
1125 h.sterling    1.40     return _crlStore;
1126 h.sterling    1.26 }
1127                    
1128 h.sterling    1.50 void SSLContextRep::setCRLStore(X509_STORE* store)
1129                    {
1130                        _crlStore = store;
1131                    }
1132                    
1133 h.sterling    1.40 Boolean SSLContextRep::isPeerVerificationEnabled() const
1134 h.sterling    1.26 {
1135 h.sterling    1.40     return _verifyPeer;
1136 h.sterling    1.26 }
1137                    
1138 h.sterling    1.28 SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const
1139                    {
1140                        return _certificateVerifyFunction;
1141                    }
1142                    
1143 kumpf         1.1  #else 
1144                    
1145                    //
1146 kumpf         1.9  // these definitions are used if ssl is not available
1147 kumpf         1.1  //
1148                    
1149 h.sterling    1.26 SSLContextRep::SSLContextRep(const String& trustStore,
1150 kumpf         1.16                        const String& certPath,
1151                                           const String& keyPath,
1152 h.sterling    1.41                        const String& crlPath,
1153 kumpf         1.9                         SSLCertificateVerifyFunction* verifyCert,
1154 h.sterling    1.41                        const String& randomFile)
1155                    {}
1156 h.sterling    1.26 
1157 kumpf         1.9  SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep) {}
1158                    
1159 kumpf         1.1  SSLContextRep::~SSLContextRep() {}
1160                    
1161 kumpf         1.9  SSL_CTX * SSLContextRep::_makeSSLContext() { return 0; }
1162                    
1163 kumpf         1.27 Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx, 
1164                                                             const String& keyPath) { return false; }
1165 kumpf         1.14 
1166 kumpf         1.9  SSL_CTX * SSLContextRep::getContext() const { return 0; }
1167 kumpf         1.15 
1168 h.sterling    1.26 String SSLContextRep::getTrustStore() const { return String::EMPTY; }
1169                    
1170                    String SSLContextRep::getCertPath() const { return String::EMPTY; }
1171                    
1172                    String SSLContextRep::getKeyPath() const { return String::EMPTY; }
1173                    
1174 h.sterling    1.40 String SSLContextRep::getCRLPath() const { return String::EMPTY; }
1175 h.sterling    1.26 
1176 h.sterling    1.40 X509_STORE* SSLContextRep::getCRLStore() const { return NULL; }
1177 h.sterling    1.26 
1178 h.sterling    1.50 void SSLContextRep::setCRLStore(X509_STORE* store) { }
1179                    
1180 h.sterling    1.40 Boolean SSLContextRep::isPeerVerificationEnabled() const { return false; }
1181 h.sterling    1.26 
1182 h.sterling    1.28 SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const { return NULL; }
1183                    
1184 kumpf         1.15 void SSLContextRep::init_ssl() {}
1185                    
1186                    void SSLContextRep::free_ssl() {}
1187 kumpf         1.1  
1188                    #endif // end of PEGASUS_HAS_SSL
1189                    
1190                    ///////////////////////////////////////////////////////////////////////////////
1191                    //
1192                    // SSLContext
1193                    //
1194                    ///////////////////////////////////////////////////////////////////////////////
1195                    
1196                    
1197                    SSLContext::SSLContext(
1198 h.sterling    1.26     const String& trustStore,
1199 kumpf         1.9      SSLCertificateVerifyFunction* verifyCert,
1200 kumpf         1.13     const String& randomFile)
1201                    {
1202 h.sterling    1.40     _rep = new SSLContextRep(trustStore, String::EMPTY, String::EMPTY, String::EMPTY, verifyCert, randomFile);
1203 kumpf         1.13 }
1204                    
1205 kumpf         1.14 SSLContext::SSLContext(
1206 h.sterling    1.26     const String& trustStore,
1207 kumpf         1.14     const String& certPath,
1208 kumpf         1.16     const String& keyPath,
1209 kumpf         1.14     SSLCertificateVerifyFunction* verifyCert,
1210                        const String& randomFile)
1211                    {
1212 h.sterling    1.40     _rep = new SSLContextRep(trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
1213 h.sterling    1.30 }
1214                    
1215 h.sterling    1.40 //PEP187
1216 h.sterling    1.26 SSLContext::SSLContext(
1217                            const String& trustStore,
1218                            const String& certPath,
1219                            const String& keyPath,
1220 h.sterling    1.47         const String& crlPath,
1221 h.sterling    1.26         SSLCertificateVerifyFunction* verifyCert,
1222                            const String& randomFile)
1223                    {
1224 h.sterling    1.40     _rep = new SSLContextRep(trustStore, certPath, keyPath, crlPath, verifyCert, randomFile);
1225 kumpf         1.14 }
1226                    
1227 kumpf         1.9  SSLContext::SSLContext(const SSLContext& sslContext)
1228                    {
1229                        _rep = new SSLContextRep(*sslContext._rep);
1230 kumpf         1.12 }
1231                    
1232                    // Dummy constructor made private to disallow default construction
1233                    SSLContext::SSLContext()
1234                    {
1235 kumpf         1.9  }
1236                    
1237 kumpf         1.1  SSLContext::~SSLContext() 
1238                    {
1239                        delete _rep;
1240                    }
1241                    
1242 h.sterling    1.26 String SSLContext::getTrustStore() const
1243                    {
1244                        return (_rep->getTrustStore());
1245                    }
1246                    
1247                    String SSLContext::getCertPath() const
1248                    {
1249                        return (_rep->getCertPath());
1250                    }
1251                    
1252                    String SSLContext::getKeyPath() const
1253                    {
1254                        return (_rep->getKeyPath()); 
1255                    }
1256                    
1257 h.sterling    1.40 String SSLContext::getCRLPath() const
1258 h.sterling    1.26 {
1259 h.sterling    1.40     return (_rep->getCRLPath()); 
1260 h.sterling    1.26 }
1261                    
1262 h.sterling    1.40 X509_STORE* SSLContext::getCRLStore() const
1263 h.sterling    1.26 {
1264 h.sterling    1.40     return (_rep->getCRLStore()); 
1265 h.sterling    1.26 }
1266                    
1267 h.sterling    1.40 Boolean SSLContext::isPeerVerificationEnabled() const
1268 h.sterling    1.26 {
1269 h.sterling    1.40     return (_rep->isPeerVerificationEnabled());
1270 h.sterling    1.26 }
1271 kumpf         1.1  
1272 h.sterling    1.28 SSLCertificateVerifyFunction* SSLContext::getSSLCertificateVerifyFunction() const
1273                    {
1274                        return (_rep->getSSLCertificateVerifyFunction());
1275                    }
1276                    
1277 kumpf         1.1  ///////////////////////////////////////////////////////////////////////////////
1278                    //
1279 kumpf         1.9  // SSLCertificateInfo
1280 kumpf         1.1  //
1281                    ///////////////////////////////////////////////////////////////////////////////
1282 kumpf         1.16 //
1283                    // Certificate validation result codes.
1284                    //
1285                    const int    SSLCertificateInfo::V_OK                                       = 0;
1286                    
1287                    const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT            = 2;
1288                    const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_CRL                    = 3;
1289                    const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     = 4;
1290                    const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      = 5;
1291                    const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   = 6;
1292                    const int    SSLCertificateInfo::V_ERR_CERT_SIGNATURE_FAILURE               = 7;
1293                    const int    SSLCertificateInfo::V_ERR_CRL_SIGNATURE_FAILURE                = 8;
1294                    const int    SSLCertificateInfo::V_ERR_CERT_NOT_YET_VALID                   = 9;
1295                    const int    SSLCertificateInfo::V_ERR_CERT_HAS_EXPIRED                     = 10;
1296                    const int    SSLCertificateInfo::V_ERR_CRL_NOT_YET_VALID                    = 11;
1297                    const int    SSLCertificateInfo::V_ERR_CRL_HAS_EXPIRED                      = 12;
1298                    const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       = 13;
1299                    const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        = 14;
1300                    const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       = 15;
1301                    const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       = 16;
1302                    const int    SSLCertificateInfo::V_ERR_OUT_OF_MEM                           = 17;
1303 kumpf         1.16 const int    SSLCertificateInfo::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          = 18;
1304                    const int    SSLCertificateInfo::V_ERR_SELF_SIGNED_CERT_IN_CHAIN            = 19;
1305                    const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    = 20;
1306                    const int    SSLCertificateInfo::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      = 21;
1307                    const int    SSLCertificateInfo::V_ERR_CERT_CHAIN_TOO_LONG                  = 22;
1308                    const int    SSLCertificateInfo::V_ERR_CERT_REVOKED                         = 23;
1309                    const int    SSLCertificateInfo::V_ERR_INVALID_CA                           = 24;
1310                    const int    SSLCertificateInfo::V_ERR_PATH_LENGTH_EXCEEDED                 = 25;
1311                    const int    SSLCertificateInfo::V_ERR_INVALID_PURPOSE                      = 26;
1312                    const int    SSLCertificateInfo::V_ERR_CERT_UNTRUSTED                       = 27;
1313                    const int    SSLCertificateInfo::V_ERR_CERT_REJECTED                        = 28;
1314                    const int    SSLCertificateInfo::V_ERR_SUBJECT_ISSUER_MISMATCH              = 29;
1315                    const int    SSLCertificateInfo::V_ERR_AKID_SKID_MISMATCH                   = 30;
1316                    const int    SSLCertificateInfo::V_ERR_AKID_ISSUER_SERIAL_MISMATCH          = 31;
1317                    const int    SSLCertificateInfo::V_ERR_KEYUSAGE_NO_CERTSIGN                 = 32;
1318                    
1319                    const int    SSLCertificateInfo::V_ERR_APPLICATION_VERIFICATION             = 50;
1320 kumpf         1.1  
1321 kumpf         1.9  class SSLCertificateInfoRep
1322                    {
1323                    public:
1324 kumpf         1.16     String    subjectName;
1325                        String    issuerName;
1326                        Uint32    depth;
1327                        Uint32    errorCode;
1328                        Uint32    respCode;
1329                        String    errorString;
1330                        Uint32    versionNumber;
1331                        long      serialNumber;
1332                        CIMDateTime    notBefore;
1333                        CIMDateTime    notAfter;
1334 kumpf         1.9  };
1335                    
1336                    
1337                    SSLCertificateInfo::SSLCertificateInfo(
1338 kumpf         1.1      const String subjectName,
1339                        const String issuerName,
1340                        const int errorDepth,
1341 kumpf         1.14     const int errorCode,
1342                        const int respCode)
1343 kumpf         1.1  {
1344 kumpf         1.9      _rep = new SSLCertificateInfoRep();
1345                        _rep->subjectName = subjectName;
1346                        _rep->issuerName = issuerName;
1347 kumpf         1.16     _rep->versionNumber = 0;
1348                        _rep->serialNumber = 0;
1349 h.sterling    1.26     _rep->notBefore = CIMDateTime();
1350                        _rep->notAfter = CIMDateTime();
1351 kumpf         1.16     _rep->depth = errorDepth;
1352 kumpf         1.9      _rep->errorCode = errorCode;
1353 kumpf         1.16     _rep->errorString = String::EMPTY;
1354                        _rep->respCode = respCode;
1355                    }
1356                    
1357                    SSLCertificateInfo::SSLCertificateInfo(
1358                        const String subjectName,
1359                        const String issuerName,
1360                        const Uint32 versionNumber,
1361                        const long serialNumber,
1362                        const CIMDateTime notBefore,
1363                        const CIMDateTime notAfter,
1364                        const Uint32 depth,
1365                        const Uint32 errorCode,
1366                        const String errorString,
1367                        const Uint32 respCode)
1368                    {
1369                        _rep = new SSLCertificateInfoRep();
1370                        _rep->subjectName = subjectName;
1371                        _rep->issuerName = issuerName;
1372                        _rep->versionNumber = versionNumber;
1373                        _rep->serialNumber = serialNumber;
1374 kumpf         1.16     _rep->notBefore = notBefore;
1375                        _rep->notAfter = notAfter;
1376                        _rep->depth = depth;
1377                        _rep->errorCode = errorCode;
1378                        _rep->errorString = errorString;
1379 kumpf         1.14     _rep->respCode = respCode;
1380 kumpf         1.9  }
1381                    
1382                    SSLCertificateInfo::SSLCertificateInfo(
1383                        const SSLCertificateInfo& certificateInfo)
1384                    {
1385                        _rep = new SSLCertificateInfoRep();
1386                        _rep->subjectName = certificateInfo._rep->subjectName;
1387                        _rep->issuerName = certificateInfo._rep->issuerName;
1388 kumpf         1.16     _rep->versionNumber = certificateInfo._rep->versionNumber;
1389                        _rep->serialNumber = certificateInfo._rep->serialNumber;
1390                        _rep->notBefore = certificateInfo._rep->notBefore;
1391                        _rep->notAfter = certificateInfo._rep->notAfter;
1392                        _rep->depth = certificateInfo._rep->depth;
1393 kumpf         1.9      _rep->errorCode = certificateInfo._rep->errorCode;
1394 kumpf         1.16     _rep->errorString = certificateInfo._rep->errorString;
1395 kumpf         1.9      _rep->respCode = certificateInfo._rep->respCode;
1396 kumpf         1.11 }
1397                    
1398                    // Dummy constructor made private to disallow default construction
1399                    SSLCertificateInfo::SSLCertificateInfo()
1400                    {
1401 kumpf         1.1  }
1402                    
1403 kumpf         1.9  SSLCertificateInfo::~SSLCertificateInfo()
1404 kumpf         1.1  {
1405 kumpf         1.9      delete _rep;
1406 kumpf         1.1  }
1407                    
1408 kumpf         1.9  String SSLCertificateInfo::getSubjectName() const
1409 kumpf         1.1  {
1410 kumpf         1.9      return (_rep->subjectName);
1411 kumpf         1.1  }
1412                    
1413 kumpf         1.9  String SSLCertificateInfo::getIssuerName() const
1414 kumpf         1.1  {
1415 kumpf         1.9      return (_rep->issuerName);
1416 kumpf         1.1  }
1417                    
1418 kumpf         1.16 Uint32 SSLCertificateInfo::getVersionNumber() const
1419                    {
1420                        return (_rep->versionNumber);
1421                    }
1422                    
1423                    long SSLCertificateInfo::getSerialNumber() const
1424 kumpf         1.1  {
1425 kumpf         1.16     return (_rep->serialNumber);
1426 kumpf         1.1  }
1427                    
1428 kumpf         1.16 CIMDateTime SSLCertificateInfo::getNotBefore() const
1429                    {
1430                        return (_rep->notBefore);
1431                    }
1432                    
1433                    CIMDateTime SSLCertificateInfo::getNotAfter() const 
1434                    {
1435                        return (_rep->notAfter);
1436                    }
1437                    
1438                    Uint32 SSLCertificateInfo::getErrorDepth() const
1439                    {
1440                        return (_rep->depth);
1441                    }
1442                    
1443                    Uint32 SSLCertificateInfo::getErrorCode()  const
1444 kumpf         1.1  {
1445 kumpf         1.9      return (_rep->errorCode);
1446 kumpf         1.14 }
1447                    
1448 kumpf         1.16 void SSLCertificateInfo::setErrorCode(const int errorCode)
1449                    {
1450                        _rep->errorCode = errorCode;
1451                    }
1452                    
1453                    String SSLCertificateInfo::getErrorString() const
1454                    {
1455                        return (_rep->errorString);
1456                    }
1457                    
1458                    Uint32 SSLCertificateInfo::getResponseCode()  const
1459 kumpf         1.14 {
1460                        return (_rep->respCode);
1461 kumpf         1.1  }
1462                    
1463 kumpf         1.9  void SSLCertificateInfo::setResponseCode(const int respCode)
1464 kumpf         1.1  {
1465 kumpf         1.9      _rep->respCode = respCode;
1466 kumpf         1.1  }
1467                    
1468 h.sterling    1.28 String SSLCertificateInfo::toString() const
1469                    {
1470                        char buf[1024];
1471                        
1472                        String s;
1473                    
1474                        s.append("Subject Name:\n\t");
1475                        s.append(_rep->subjectName);
1476                        s.append("\n");
1477                        
1478                        s.append("Issuer Name:\n\t");
1479                        s.append(_rep->issuerName);
1480                        s.append("\n");
1481                        
1482                        sprintf(buf, "Depth: %d\n", _rep->depth);
1483                        s.append(buf);
1484                        
1485                        sprintf(buf, "Error code: %d\n", _rep->errorCode);
1486                        s.append(buf);
1487                        
1488                        sprintf(buf, "Response (preverify) code: %d\n", _rep->respCode);
1489 h.sterling    1.28     s.append(buf);
1490                    
1491                        s.append("Error string: ");
1492                        s.append(_rep->errorString);
1493                        s.append("\n");
1494                        
1495                        sprintf(buf, "Version number: %d\n", _rep->versionNumber);
1496                        s.append(buf);
1497                    
1498                        sprintf(buf, "Serial number: %ld\n", _rep->serialNumber);
1499                        s.append(buf);
1500                        
1501                        s.append("Not before date: ");
1502                        s.append((_rep->notBefore).toString());
1503                        s.append("\n");
1504                    
1505                        s.append("Not after date: ");
1506                        s.append((_rep->notAfter).toString());
1507                        s.append("\n");
1508                    
1509                        return s;
1510 h.sterling    1.28 }
1511                    
1512 h.sterling    1.40 SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert, X509_STORE* crlStore)
1513 h.sterling    1.28 {
1514                        verifyCertificateCallback = verifyCert;
1515 h.sterling    1.47     _crlStore = crlStore;
1516 h.sterling    1.28     _peerCertificate = NULL;  
1517                    }
1518                    
1519                    SSLCallbackInfo::~SSLCallbackInfo()
1520                    {
1521                        if (_peerCertificate) 
1522                        {
1523                            delete _peerCertificate;
1524                        }
1525                    }
1526                    
1527 kumpf         1.1  PEGASUS_NAMESPACE_END
1528                    

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2