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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2