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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2