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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2