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

Diff for /pegasus/src/Pegasus/Common/SSLContext.cpp between version 1.11 and 1.84

version 1.11, 2002/09/06 02:52:42 version 1.84, 2007/08/06 09:46:20
Line 1 
Line 1 
 //%/////////////////////////////////////////////////////////////////////////////  //%2006////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,  // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // The Open Group, Tivoli Systems  // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   // IBM Corp.; EMC Corporation, The Open Group.
   // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; Symantec Corporation; The Open Group.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
Line 21 
Line 29 
 // //
 //============================================================================== //==============================================================================
 // //
 // Author: Markus Mueller (sedgewick_de@yahoo.de)  
 //  
 // Modified By: Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)  
 //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)  
 //  
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #ifdef PEGASUS_HAS_SSL #ifdef PEGASUS_HAS_SSL
   # include <Pegasus/Common/Config.h>
   # include <Pegasus/Common/Executor.h>
   # include <Pegasus/Common/Network.h>
   # define OPENSSL_NO_KRB5 1
 #include <openssl/err.h> #include <openssl/err.h>
 #include <openssl/ssl.h> #include <openssl/ssl.h>
 #include <openssl/rand.h> #include <openssl/rand.h>
 #else #else
 #define SSL_CTX void #define SSL_CTX void
 #endif // end of PEGASUS_HAS_SSL #endif // end of PEGASUS_HAS_SSL
 #include <Pegasus/Common/Destroyer.h>  
   #include <time.h>
 #include <Pegasus/Common/Socket.h> #include <Pegasus/Common/Socket.h>
 #include <Pegasus/Common/Tracer.h> #include <Pegasus/Common/Tracer.h>
   #include <Pegasus/Common/FileSystem.h>
   #include <Pegasus/Common/MessageLoader.h>
   #include <Pegasus/Common/AuditLogger.h>
  
 #include "SSLContext.h" #include "SSLContext.h"
 #include "SSLContextRep.h" #include "SSLContextRep.h"
  
   #ifdef PEGASUS_OS_PASE
   # include <ILEWrapper/ILEUtilities.h>
   #endif
   //
   // Typedef's for OpenSSL callback functions.
   //
   extern "C"
   {
       typedef void (* CRYPTO_SET_LOCKING_CALLBACK)(int, int, const char *, int);
       typedef unsigned long (* CRYPTO_SET_ID_CALLBACK)(void);
   };
   
   typedef struct x509_store_ctx_st X509_STORE_CTX;
   
   typedef struct Timestamp
   {
       char year[4];
       char month[2];
       char day[2];
       char hour[2];
       char minutes[2];
       char seconds[2];
       char dot;
       char microSeconds[6];
       char plusOrMinus;
       char utcOffset[3];
       char padding[3];
   } Timestamp_t;
   
 PEGASUS_USING_STD; PEGASUS_USING_STD;
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
 // switch on if 'server needs certified client'  const int SSLCallbackInfo::SSL_CALLBACK_INDEX = 0;
 //#define CLIENT_CERTIFY  
  
 // //
 // use the following definitions only if SSL is available // use the following definitions only if SSL is available
 // //
 #ifdef PEGASUS_HAS_SSL #ifdef PEGASUS_HAS_SSL
  
   // Mutex for SSL locks which will get initialized by AutoArrayPtr constructor.
   AutoArrayPtr<Mutex> SSLContextRep::_sslLocks;
   
   // Mutex for _countRep.
   Mutex SSLContextRep::_countRepMutex;
   
   // Initialise _count for SSLContextRep objects.
   int SSLContextRep::_countRep = 0;
   
   
 // //
 // certificate handling routine  // Convert ASN1_UTCTIME to CIMDateTime
 // //
   CIMDateTime getDateTime(const ASN1_UTCTIME *utcTime)
   {
       struct tm time;
       int offset;
       Timestamp_t timeStamp;
       char tempString[80];
       char plusOrMinus = '+';
       unsigned char* utcTimeData = utcTime->data;
  
 // ATTN-RK-20020905: This global variable is unsafe with multiple SSL contexts      memset(&time, '\0', sizeof(time));
 SSLCertificateVerifyFunction* verify_certificate;  
  
 static int cert_verify(SSL_CTX *ctx, const char *cert_file, const char *key_file)  #define g2(p) ( ( (p)[0] - '0' ) * 10 + (p)[1] - '0' )
   
       if (utcTime->type == V_ASN1_GENERALIZEDTIME)
       {
           time.tm_year = g2(utcTimeData) * 100;
           utcTimeData += 2;  // Remaining data is equivalent to ASN1_UTCTIME type
           time.tm_year += g2(utcTimeData);
       }
       else
       {
           time.tm_year = g2(utcTimeData);
           if (time.tm_year < 50)
           {
               time.tm_year += 2000;
           }
           else
 { {
     PEG_METHOD_ENTER(TRC_SSL, "cert_verify()");              time.tm_year += 1900;
           }
       }
  
     if (cert_file != NULL)      time.tm_mon = g2(utcTimeData + 2) - 1;
       time.tm_mday = g2(utcTimeData + 4);
       time.tm_hour = g2(utcTimeData + 6);
       time.tm_min = g2(utcTimeData + 8);
       time.tm_sec = g2(utcTimeData + 10);
   
       if (utcTimeData[12] == 'Z')
     {     {
         if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <=0)          offset = 0;
       }
       else
         {         {
             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,          offset = g2(utcTimeData + 13) * 60 + g2(utcTimeData + 15);
                 "---> SSL: no certificate found in " + String(cert_file));          if (utcTimeData[12] == '-')
           {
               plusOrMinus = '-';
           }
       }
   #undef g2
   
       memset((void *)&timeStamp, 0, sizeof(Timestamp_t));
   
       // Format the date.
       sprintf((char *) &timeStamp,"%04d%02d%02d%02d%02d%02d.%06d%04d",
               time.tm_year,
               time.tm_mon + 1,
               time.tm_mday,
               time.tm_hour,
               time.tm_min,
               time.tm_sec,
               0,
               offset);
   
       timeStamp.plusOrMinus = plusOrMinus;
   
       CIMDateTime dateTime;
   
       dateTime.clear();
       strcpy(tempString, (char *)&timeStamp);
       dateTime.set(tempString);
   
       return dateTime;
   }
   
   //
   // Static class used to define C++ callback functions for OpenSSL.
   //
   class SSLCallback
   {
   
   public:
       static int verificationCallback(
           int preVerifyOk,
           X509_STORE_CTX* ctx);
       static int verificationCRLCallback(
           int ok,
           X509_STORE_CTX* ctx,
           X509_STORE* sslCRLStore);
   };
   
   //
   // Callback function that is called by the OpenSSL library. This function
   // checks whether the certificate is listed in any of the CRL's
   //
   // return 1 if revoked, 0 otherwise
   //
   int SSLCallback::verificationCRLCallback(
       int ok,
       X509_STORE_CTX* ctx,
       X509_STORE* sslCRLStore)
   {
       PEG_METHOD_ENTER(TRC_SSL, "SSLCallback::verificationCRLCallback");
   
       char buf[1024];
   
       //check whether a CRL store was specified
       if (sslCRLStore == NULL)
       {
           PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
               "---> SSL: CRL store is NULL");
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             return 0;             return 0;
         }         }
         if (key_file == NULL) key_file=cert_file;  
         if (SSL_CTX_use_PrivateKey_file(ctx,key_file,SSL_FILETYPE_PEM) <= 0)      //get the current certificate info
       X509* currentCert;
       X509_NAME* issuerName;
       X509_NAME* subjectName;
       ASN1_INTEGER* serialNumber;
   
       currentCert = X509_STORE_CTX_get_current_cert(ctx);
       subjectName = X509_get_subject_name(currentCert);
       issuerName = X509_get_issuer_name(currentCert);
       serialNumber = X509_get_serialNumber(currentCert);
   
       //log certificate information
       //this is information in the "public" key, so it does no harm to log it
       X509_NAME_oneline(issuerName, buf, sizeof(buf));
       PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
           "---> SSL: Certificate Data: Issuer/Subject");
       PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, buf);
       X509_NAME_oneline(subjectName, buf, sizeof(buf));
       PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, buf);
   
       //initialize the CRL store
       X509_STORE_CTX crlStoreCtx;
       X509_STORE_CTX_init(&crlStoreCtx, sslCRLStore, NULL, NULL);
   
       PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
           "---> SSL: Initialized CRL store");
   
       //attempt to get a CRL issued by the certificate's issuer
       X509_OBJECT obj;
       if (X509_STORE_get_by_subject(
               &crlStoreCtx, X509_LU_CRL, issuerName, &obj) <= 0)
         {         {
             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
                 "---> SSL: no private key found in " + String(key_file));              "---> SSL: No CRL by that issuer");
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             return 0;             return 0;
         }         }
       X509_STORE_CTX_cleanup(&crlStoreCtx);
  
         if (!SSL_CTX_check_private_key(ctx))      //get CRL
       X509_CRL* crl = obj.data.crl;
       if (crl == NULL)
         {         {
             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL is null");
                 "---> SSL: Private and public key do not match");  
             PEG_METHOD_EXIT();             PEG_METHOD_EXIT();
             return 0;             return 0;
         }         }
       else
       {
           PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
               "---> SSL: Found CRL by that issuer");
       }
   
       //get revoked certificates
       STACK_OF(X509_REVOKED)* revokedCerts = NULL;
       revokedCerts = X509_CRL_get_REVOKED(crl);
       int numRevoked = sk_X509_REVOKED_num(revokedCerts);
       PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
           "---> SSL: Number of certificates revoked by the issuer %d\n",
           numRevoked));
   
       //check whether the subject's certificate is revoked
       X509_REVOKED* revokedCert = NULL;
       for (int i = 0; i < sk_X509_REVOKED_num(revokedCerts); i++)
       {
           revokedCert = (X509_REVOKED *)sk_value(X509_CRL_get_REVOKED(crl), i);
   
           //a matching serial number indicates revocation
           if (ASN1_INTEGER_cmp(revokedCert->serialNumber, serialNumber) == 0)
           {
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL2,
                   "---> SSL: Certificate is revoked");
               X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
               PEG_METHOD_EXIT();
               return 1;
           }
     }     }
   
       PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
           "---> SSL: Certificate is not revoked at this level");
   
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     return -1;      return 0;
 } }
  
 static int prepareForCallback(int preverifyOk, X509_STORE_CTX *ctx)  //
   // Callback function that is called by the OpenSSL library. This function
   // extracts X509 certficate information and pass that on to client application
   // callback function.
   // We HAVE to build the certificate in all cases since it's needed to get
   // the associated username out of the repository later in the transaction.
   //
   int SSLCallback::verificationCallback(int preVerifyOk, X509_STORE_CTX* ctx)
 { {
     PEG_METHOD_ENTER(TRC_SSL, "prepareForCallback()");      PEG_METHOD_ENTER(TRC_SSL, "SSLCallback::callback()");
  
     char   buf[256];     char   buf[256];
     X509   *err_cert;      X509   *currentCert;
     int    err;      SSL    *ssl;
     int    depth;      int    verifyError = X509_V_OK;
     String subjectName;      int    revoked = -1;
     String issuerName;  
     int    verify_depth = 0;  
     int    verify_error = X509_V_OK;  
   
     err_cert = X509_STORE_CTX_get_current_cert(ctx);  
     err = X509_STORE_CTX_get_error(ctx);  
  
     depth = X509_STORE_CTX_get_error_depth(ctx);      PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
           "--->SSL: Preverify Error %d", verifyError));
  
     //FUTURE: Not sure what to do with these...?      //
     //ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());      // get the verification callback info specific to each SSL connection
     //mydata = SSL_get_ex_data(ssl, mydata_index);      //
       ssl = (SSL*) X509_STORE_CTX_get_ex_data(
           ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
       SSLCallbackInfo* exData = (SSLCallbackInfo*) SSL_get_ex_data(
           ssl, SSLCallbackInfo::SSL_CALLBACK_INDEX);
  
     X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);  #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
     subjectName = String(buf);      //
       // Check to see if a CRL path is defined
       //
       if (exData->_rep->crlStore != NULL)
       {
           revoked = verificationCRLCallback(
               preVerifyOk,ctx,exData->_rep->crlStore);
           PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
               "---> SSL: CRL callback returned %d", revoked));
  
     if (verify_depth >= depth)          if (revoked) //with the SSL callbacks '0' indicates failure
     {     {
         preverifyOk = 1;              PEG_METHOD_EXIT();
         verify_error = X509_V_OK;              return 0;
     }     }
     else      }
   
       PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
           "---> SSL: CRL callback returned %d", revoked));
   #endif
   
       //
       // get the current certificate
       //
       currentCert = X509_STORE_CTX_get_current_cert(ctx);
   
       //
       // get the default verification error code
       //
       int errorCode = X509_STORE_CTX_get_error(ctx);
   
       //
       // get the depth of certificate chain
       //
       int depth = X509_STORE_CTX_get_error_depth(ctx);
   
       //
       // get the version on the certificate
       //
       long version = X509_get_version(currentCert);
   
       //
       // get the serial number of the certificate
       //
       long serialNumber = ASN1_INTEGER_get(X509_get_serialNumber(currentCert));
       char serialNumberString[32];
       sprintf(serialNumberString, "%lu", serialNumber);
   
       //
       // get the validity of the certificate
       //
       CIMDateTime notBefore = getDateTime(X509_get_notBefore(currentCert));
   
       CIMDateTime notAfter = getDateTime(X509_get_notAfter(currentCert));
   
       //
       // get the subject name on the certificate
       //
       X509_NAME_oneline(X509_get_subject_name(currentCert), buf, 256);
       String subjectName = String(buf);
   
       //
       // get the default verification error string
       //
       String errorStr = String(X509_verify_cert_error_string(errorCode));
   
       //
       // log the error string if the default verification was failed
       //
       if (!preVerifyOk)
     {     {
         preverifyOk = 0;          PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
         verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;              "---> SSL: certificate default verification error: %s",
         X509_STORE_CTX_set_error(ctx, verify_error);              (const char*)errorStr.getCString()));
     }     }
  
     if (!preverifyOk)      //
       // get the issuer name on the certificate
       //
       X509_NAME_oneline(X509_get_issuer_name(currentCert), buf, 256);
       String issuerName = String(buf);
   
       //
       // Create the certificate object
       //
   
       // insert at the beginning of the array so that the peer certificate is
       // first and the root CA is last
       exData->_rep->peerCertificate.insert(0, new SSLCertificateInfo(
           subjectName, issuerName, version, serialNumber,
           notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk));
   
       PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3, "Created SSLCertificateInfo");
   
       // NOT_YET_VALID checks do not work correctly on subsequent tries --
       // Bugzilla#4283
       // call this prior to calling the user-specified callback in case they
       // want to override it
       if (errorCode == X509_V_OK &&
           (CIMDateTime::getDifference(
                CIMDateTime::getCurrentDateTime(), notBefore) > 0))
     {     {
         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,          PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
             "---> SSL: verify error: " + String(X509_verify_cert_error_string(err)));              "Certificate was not yet valid.");
   
           X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_NOT_YET_VALID);
   
           PEG_AUDIT_LOG(logCertificateBasedAuthentication(
               issuerName,
               subjectName,
               serialNumberString,
               exData->_rep->ipAddress,
               false));
     }     }
  
     if (!preverifyOk && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))      //
       // Call the user-specified application callback if it is specified.
       // If it is null, return OpenSSL's verification code.
       // Note that the verification result does not automatically get set
       // to X509_V_OK if the callback is successful.
       // This is because OpenSSL retains the original default error in case
       // we want to use it later.
       // To set the error, we could use X509_STORE_CTX_set_error(ctx,
       // verifyError); but there is no real benefit to doing that here.
       //
       if (exData->_rep->verifyCertificateCallback == NULL)
     {     {
         X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);          PEG_AUDIT_LOG(logCertificateBasedAuthentication(
         issuerName = String(buf);              issuerName,
               subjectName,
               serialNumberString,
               exData->_rep->ipAddress,
               preVerifyOk));
   
           return preVerifyOk;
     }     }
     else     else
     {     {
         X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, 256);          if (exData->_rep->verifyCertificateCallback(
         issuerName = String(buf);                  *exData->_rep->peerCertificate[0]))
           {
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
                   "--> SSL: _rep->verifyCertificateCallback() returned "
                       "X509_V_OK");
   
               PEG_AUDIT_LOG(logCertificateBasedAuthentication(
                    issuerName,
                    subjectName,
                    serialNumberString,
                    exData->_rep->ipAddress,
                    true));
   
               PEG_METHOD_EXIT();
               return 1;
           }
           else // verification failed, handshake will be immediately terminated
           {
               PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
                   "--> SSL: _rep->verifyCertificateCallback() returned error %d",
                   exData->_rep->peerCertificate[0]->getErrorCode()));
   
               PEG_AUDIT_LOG(logCertificateBasedAuthentication(
                    issuerName,
                    subjectName,
                    serialNumberString,
                    exData->_rep->ipAddress,
                    false));
   
               PEG_METHOD_EXIT();
               return 0;
           }
       }
     }     }
  
     //     //
     // Call the verify_certificate() callback  // Callback function called by OpenSSL.  This request is merely forwarded
   // to the static function SSLCallback::callback().  The SSLCallback class
   // is a friend class of the Pegasus SSL related classes needed to complete
   // the callback.
     //     //
     SSLCertificateInfo certInfo(subjectName, issuerName, depth, err);  extern "C" int prepareForCallback(int preVerifyOk, X509_STORE_CTX *ctx)
   
     if (verify_certificate(certInfo))  
     {     {
         preverifyOk = 1;      return SSLCallback::verificationCallback(preVerifyOk, ctx);
     }     }
  
     //delete certInfo;  //
   // Implement OpenSSL locking callback.
   //
   void pegasus_locking_callback(
       int mode,
       int type,
       const char* file,
       int line)
   {
       // Check whether the mode is lock or unlock.
   
       if ( mode & CRYPTO_LOCK )
       {
           /*PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
                   "Now locking for type %d", type));*/
           SSLContextRep::_sslLocks.get()[type].lock( );
       }
       else
       {
           /*PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
                   "Now unlocking for type %d", type));*/
           SSLContextRep::_sslLocks.get()[type].unlock( );
       }
   }
  
     // ATTN-NB-03-05102002: Overriding the default verification result, may  //
     // need to be changed to make it more generic.  // Initialize OpenSSL Locking and id callbacks.
     if (preverifyOk)  //
   void SSLContextRep::init_ssl()
     {     {
         X509_STORE_CTX_set_error(ctx, verify_error);       // Allocate Memory for _sslLocks. SSL locks needs to be able to handle
        // up to CRYPTO_num_locks() different mutex locks.
        PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
              "Initialized SSL callback.");
   
        _sslLocks.reset(new Mutex[CRYPTO_num_locks()]);
   
   #if defined(PEGASUS_HAVE_PTHREADS) && !defined(PEGASUS_OS_VMS)
        // Set the ID callback. The ID callback returns a thread ID.
        CRYPTO_set_id_callback((CRYPTO_SET_ID_CALLBACK) pthread_self);
   #endif
   
        // Set the locking callback to pegasus_locking_callback.
   
        CRYPTO_set_locking_callback(
            (CRYPTO_SET_LOCKING_CALLBACK) pegasus_locking_callback);
   
     }     }
  
     PEG_METHOD_EXIT();  // Free OpenSSL Locking and id callbacks.
     return(preverifyOk);  void SSLContextRep::free_ssl()
   {
       // Cleanup _sslLocks and set locking & id callback to NULL.
   
       CRYPTO_set_locking_callback(NULL);
       CRYPTO_set_id_callback     (NULL);
       PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
                "Freed SSL callback.");
       _sslLocks.reset();
 } }
  
  
Line 179 
Line 589 
 // For the OSs that don't have /dev/random device file, // For the OSs that don't have /dev/random device file,
 // must enable PEGASUS_SSL_RANDOMFILE flag. // must enable PEGASUS_SSL_RANDOMFILE flag.
 // //
 // CIM clients must specify a SSL random file and also  SSLContextRep::SSLContextRep(
 // set isCIMClient to true. However, CIMserver does not      const String& trustStore,
 // seem to care the Random seed and /dev/random.      const String& certPath,
 //      const String& keyPath,
 //      const String& crlPath,
 SSLContextRep::SSLContextRep(const String& certPath,  
                        SSLCertificateVerifyFunction* verifyCert,                        SSLCertificateVerifyFunction* verifyCert,
                        const String& randomFile,      const String& randomFile)
                        Boolean isCIMClient)  
 { {
     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
  
     _certPath = certPath.getCString();      _trustStore = trustStore;
  
     verify_certificate = verifyCert;      _certPath = certPath;
  
     //      _keyPath = keyPath;
     // load SSL library  
     //      _crlPath = crlPath;
     SSL_load_error_strings();  
     SSL_library_init();  
  
 #ifdef PEGASUS_SSL_RANDOMFILE      _crlStore = NULL;
   
       _certificateVerifyFunction = verifyCert;
  
     //     //
     // We will only need SSL Random Seed for CIM Clients      // If a truststore and/or peer verification function is specified,
       // enable peer verification
     //     //
     if (isCIMClient)      if (trustStore != String::EMPTY || verifyCert != NULL)
     {     {
        long  seedNumber;          _verifyPeer = true;
       }
       else
       {
           _verifyPeer = false;
       }
   
        //        //
        // Initialise OpenSSL 0.9.5 random number generator.      // Initialize SSL callbacks and increment the SSLContextRep object _counter.
        //        //
        if ( randomFile != String::EMPTY )  
        {        {
           int ret = RAND_load_file(randomFile.getCString(), -1);         AutoMutex autoMut(_countRepMutex);
           if ( ret < 0 )  
          PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
                   "Value of Countrep in constructor %d", _countRep));
           if ( _countRep == 0 )
           {           {
             PEG_METHOD_EXIT();              init_ssl();
             throw( SSLException("RAND_load_file - failed"));  
           }  
  
           //           //
           // Will do more seeding              // load SSL library
           //           //
           srandom((unsigned int)time(NULL)); // Initialize              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
           seedNumber = random();                  "Before calling SSL_load_error_strings");
           RAND_seed((unsigned char *) &seedNumber, sizeof(seedNumber));  
  
           int  seedRet = RAND_status();              SSL_load_error_strings();
           if ( seedRet == 0 )  
           {              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
               PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,                  "After calling SSL_load_error_strings");
                   "Not enough data , RAND_status = " + seedRet );  
               PEG_METHOD_EXIT();              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
               throw( SSLException("RAND_seed - Not enough seed data "));                  "Before calling SSL_library_init");
           }  
        }              SSL_library_init();
        else  
        {  
            PEG_METHOD_EXIT();  
            throw( SSLException("Random seed file required"));  
        }  
  
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
                   "After calling SSL_library_init");
      }      }
  
 #endif // end of PEGASUS_SSL_RANDOMFILE          _countRep++;
       }  // mutex unlocks here
   
       _randomInit(randomFile);
  
     _sslContext = _makeSSLContext();     _sslContext = _makeSSLContext();
  
Line 256 
Line 670 
 { {
     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
  
       _trustStore = sslContextRep._trustStore;
     _certPath = sslContextRep._certPath;     _certPath = sslContextRep._certPath;
     // ATTN: verify_certificate is set implicitly in global variable      _keyPath = sslContextRep._keyPath;
       _crlPath = sslContextRep._crlPath;
       _crlStore = sslContextRep._crlStore;
       _verifyPeer = sslContextRep._verifyPeer;
       _certificateVerifyFunction = sslContextRep._certificateVerifyFunction;
     _randomFile = sslContextRep._randomFile;     _randomFile = sslContextRep._randomFile;
     _isCIMClient = sslContextRep._isCIMClient;  
     _sslContext = _makeSSLContext();  
  
     PEG_METHOD_EXIT();      // Initialize SSL callbacks and increment the SSLContextRep object _counter.
       {
           AutoMutex autoMut(_countRepMutex);
           PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
               "Value of Countrep in copy constructor %d", _countRep));
           if ( _countRep == 0 )
           {
               init_ssl();
 } }
  
 // Dummy constructor made private to disallow default construction          _countRep++;
 SSLContextRep::SSLContextRep()      }  // mutex unlocks here
 {  
       _sslContext = _makeSSLContext();
       PEG_METHOD_EXIT();
 } }
  
 // //
Line 280 
Line 706 
  
     SSL_CTX_free(_sslContext);     SSL_CTX_free(_sslContext);
  
     PEG_METHOD_EXIT();      // Decrement the SSLContextRep object _counter.
 }      {
           AutoMutex autoMut(_countRepMutex);
           _countRep--;
           // Free SSL locks if no instances of SSLContextRep exist.
  
 SSL_CTX * SSLContextRep::_makeSSLContext()          PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
               "Value of Countrep in destructor %d", _countRep));
           if ( _countRep == 0 )
 { {
     PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()");              free_ssl();
           }
  
     SSL_CTX * sslContext = 0;      }
       PEG_METHOD_EXIT();
   }
  
     //     //
     // create SSL Context Area  // initialize OpenSSL's PRNG
     //     //
   void SSLContextRep::_randomInit(const String& randomFile)
     if (!( sslContext = SSL_CTX_new(SSLv23_method()) ))  
     {     {
         PEG_METHOD_EXIT();      PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_randomInit()");
         throw( SSLException("Could not get SSL CTX"));  
     }  
  
 #ifdef PEGASUS_OS_HPUX      Boolean ret;
     if (!(SSL_CTX_set_cipher_list(sslContext, SSL_TXT_EXP40)))      int retVal = 0;
         throw( SSLException("Could not set the cipher list"));  
 #endif  
  
   #if defined(PEGASUS_SSL_RANDOMFILE) && !defined(PEGASUS_OS_PASE)
       if ( RAND_status() == 0 )
       {
     //     //
     // set overall SSL Context flags          // Initialise OpenSSL random number generator.
     //     //
           if ( randomFile == String::EMPTY )
     SSL_CTX_set_quiet_shutdown(sslContext, 1);  
     SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);  
     SSL_CTX_set_options(sslContext,SSL_OP_ALL);  
   
 #ifdef CLIENT_CERTIFY  
     SSL_CTX_set_verify(sslContext, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,  
         prepareForCallback);  
 #else  
     if (verify_certificate != NULL)  
     {     {
         SSL_CTX_set_verify(sslContext,              PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
             SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, prepareForCallback);                  "Random seed file is required.");
               PEG_METHOD_EXIT();
               MessageLoaderParms parms(
                   "Common.SSLContext.RANDOM_SEED_FILE_REQUIRED",
                   "Random seed file required");
               throw SSLException(parms);
     }     }
 #endif  
  
     //     //
     // check certificate given to me          // Try the given random seed file
     //     //
           ret = FileSystem::exists(randomFile);
     if (!cert_verify(sslContext, _certPath, _certPath))          if (ret)
     {     {
               retVal = RAND_load_file(randomFile.getCString(), -1);
               if ( retVal < 0 )
               {
                   PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
                       String("Not enough seed data in seed file: ") + randomFile);
         PEG_METHOD_EXIT();         PEG_METHOD_EXIT();
         throw( SSLException("Could not get certificate and/or private key"));                  // do not put in $0 in default message, but pass in filename
                   // for bundle message
                   MessageLoaderParms parms(
                       "Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
                       "Not enough seed data in random seed file.",
                       randomFile);
                   throw SSLException(parms);
     }     }
   
     PEG_METHOD_EXIT();  
     return sslContext;  
 } }
           else
 SSL_CTX * SSLContextRep::getContext() const  
 { {
     return _sslContext;              PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
                   String("seed file - " + randomFile + " does not exist."));
               PEG_METHOD_EXIT();
               MessageLoaderParms parms(
                   "Common.SSLContext.SEED_FILE_DOES_NOT_EXIST",
                   "Seed file '$0' does not exist.",
                   randomFile);
               throw SSLException(parms);
 } }
 #else  
  
           if ( RAND_status() == 0 )
           {
 // //
 // these definitions are used if ssl is not available              // Try to do more seeding
 // //
               long seedNumber;
           #if defined(PEGASUS_COMPILER_MSVC)
               srand((unsigned int)time(NULL)); // Initialize
               seedNumber = rand();
           #else
               srandom((unsigned int)time(NULL)); // Initialize
               seedNumber = random();
           #endif
               RAND_seed((unsigned char *) &seedNumber, sizeof(seedNumber));
   
               int  seedRet = RAND_status();
               if ( seedRet == 0 )
               {
                   PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
                       "Not enough seed data in random seed file, "
                           "RAND_status = %d",
                       seedRet));
                   PEG_METHOD_EXIT();
                   // do not put in $0 in default message, but pass in filename
                   // for bundle message
                   MessageLoaderParms parms(
                       "Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
                       "Not enough seed data in random seed file.",
                       randomFile);
                   throw SSLException(parms);
               }
           }
       }
   #endif  /* PEGASUS_SSL_RANDOMFILE */
   
       int seedRet = RAND_status();
       if (seedRet == 0)
       {
   // pase for different logic
   #ifdef PEGASUS_OS_PASE
           unsigned char prn[1024];
   
           umeGenerateRandomNumber(prn);
   
           RAND_seed(prn, 1024);
   
           if (RAND_status() == 0)
           {
   #endif
           PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
               "Not enough seed data, RAND_status = %d",
               seedRet));
           PEG_METHOD_EXIT();
           MessageLoaderParms parms(
               "Common.SSLContext.NOT_ENOUGH_SEED_DATA",
               "Not enough seed data.");
           throw SSLException(parms);
   #ifdef PEGASUS_OS_PASE
           }
   #endif
       }
   
       PEG_METHOD_EXIT();
   }
   
   SSL_CTX* SSLContextRep::_makeSSLContext()
   {
       PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()");
   
       SSL_CTX * sslContext = 0;
   
       //
       // create SSL Context Area
       //
   
       if (!(sslContext = SSL_CTX_new(SSLv23_method())))
       {
           PEG_METHOD_EXIT();
           MessageLoaderParms parms(
               "Common.SSLContext.COULD_NOT_GET",
               "Could not get SSL CTX");
           throw SSLException(parms);
       }
   
   #ifdef PEGASUS_SSL_WEAKENCRYPTION
       if (!(SSL_CTX_set_cipher_list(sslContext, SSL_TXT_EXP40)))
       {
           MessageLoaderParms parms(
               "Common.SSLContext.COULD_NOT_SET_CIPHER_LIST",
               "Could not set the cipher list");
           throw SSLException(parms);
       }
   #endif
   
       //
       // set overall SSL Context flags
       //
   
       SSL_CTX_set_quiet_shutdown(sslContext, 1);
       SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);
       SSL_CTX_set_mode(sslContext, SSL_MODE_ENABLE_PARTIAL_WRITE);
       SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
   
       int options = SSL_OP_ALL;
   #ifndef PEGASUS_ENABLE_SSLV2 //SSLv2 is disabled by default
       options |= SSL_OP_NO_SSLv2;
   #endif
       SSL_CTX_set_options(sslContext, options);
   
       if (_verifyPeer)
       {
           // ATTN: We might still need a flag to specify
           // SSL_VERIFY_FAIL_IF_NO_PEER_CERT
           // If SSL_VERIFY_FAIL_IF_NO_PEER_CERT is ON, SSL will immediately be
           // terminated if the client sends no certificate or sends an
           // untrusted certificate.  The callback function is not called in
           // this case; the handshake is simply terminated.
           // This value has NO effect in from a client perspective
   
           if (_certificateVerifyFunction != NULL)
           {
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
                   "---> SSL: certificate verification callback specified");
               SSL_CTX_set_verify(sslContext,
                   SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, prepareForCallback);
           }
           else
           {
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
                   "---> SSL: Trust Store specified");
               SSL_CTX_set_verify(sslContext,
                   SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE |
                       SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
                   prepareForCallback);
           }
       }
       else
       {
           PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
               "---> SSL: Trust Store and certificate verification callback "
                   "are NOT specified");
           SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
       }
   
       //
       // Check if there is CA certificate file or directory specified. If
       // specified, and is not empty, load the certificates from the Trust store.
       //
       if (_trustStore != String::EMPTY)
       {
           //
           // The truststore may be a single file of CA certificates OR
           // a directory containing multiple CA certificates.
           // Check which one it is, and call the load_verify_locations function
           // with the appropriate parameter.  Note: It is possible to have both
           // options, in which case the CA file takes precedence over the CA path.
           // However, since there is currently only one trust parameter to the
           // SSL functions, only allow one choice here.
           //
           if (FileSystem::isDirectory(_trustStore))
           {
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
                               "---> SSL: Truststore is a directory");
               //
               // load certificates from the trust store
               //
               PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
                   String("---> SSL: Loading certificates from the trust store: " +
                       _trustStore));
   
               if ((!SSL_CTX_load_verify_locations(
                        sslContext, NULL, _trustStore.getCString())) ||
                   (!SSL_CTX_set_default_verify_paths(sslContext)))
               {
                   PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
                       String("---> SSL: Could not load certificates from the "
                           "trust store: " + _trustStore));
                   MessageLoaderParms parms(
                       "Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
                       "Could not load certificates in to trust store.");
                   PEG_METHOD_EXIT();
                   throw SSLException(parms);
               }
   
           }
           else if (FileSystem::exists(_trustStore))
           {
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
                   "---> SSL: Truststore is a file");
               //
               // Get size of the trust store file:
               //
               Uint32 fileSize = 0;
   
               FileSystem::getFileSize(_trustStore, fileSize);
   
               if (fileSize > 0)
               {
                   //
                   // load certificates from the trust store
                   //
                   PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
                       String("---> SSL: Loading certificates from the trust "
                           "store: " + _trustStore));
   
                   if ((!SSL_CTX_load_verify_locations(
                            sslContext, _trustStore.getCString(), NULL)) ||
                       (!SSL_CTX_set_default_verify_paths(sslContext)))
                   {
                       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
                           String("---> SSL: Could not load certificates from the "
                               "trust store: " + _trustStore));
                       MessageLoaderParms parms(
                           "Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
                           "Could not load certificates in to trust store.");
                       PEG_METHOD_EXIT();
                       throw SSLException(parms);
                   }
               }
               else
               {
                   //
                   // no certificates found in the trust store
                   //
                   PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
                       String("---> SSL: No certificates to load from the trust "
                           "store: " + _trustStore));
               }
           }
       }
   
       if (_crlPath != String::EMPTY)
       {
           // need to save this -- can we make it static since there's only
           // one CRL for cimserver?
           X509_LOOKUP* pLookup;
   
           _crlStore = X509_STORE_new();
   
           // the validity of the crlstore was checked in ConfigManager
           // during server startup
           if (FileSystem::isDirectory(_crlPath))
           {
               PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
                   "---> SSL: CRL store is a directory in %s",
                   (const char*)_crlPath.getCString()));
   
               if ((pLookup = X509_STORE_add_lookup(
                        _crlStore, X509_LOOKUP_hash_dir())) == NULL)
               {
                   MessageLoaderParms parms(
                       "Common.SSLContext.COULD_NOT_LOAD_CRLS",
                       "Could not load certificate revocation list.");
                   X509_STORE_free(_crlStore);
                   PEG_METHOD_EXIT();
                   throw SSLException(parms);
               }
   
               X509_LOOKUP_add_dir(
                   pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
   
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
                   "---> SSL: Successfully configured CRL directory");
           }
           else
           {
               PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
                   "---> SSL: CRL store is the file %s",
                   (const char*)_crlPath.getCString()));
   
               if ((pLookup = X509_STORE_add_lookup(
                      _crlStore, X509_LOOKUP_file())) == NULL)
               {
                   MessageLoaderParms parms(
                       "Common.SSLContext.COULD_NOT_LOAD_CRLS",
                       "Could not load certificate revocation list.");
                   X509_STORE_free(_crlStore);
                   PEG_METHOD_EXIT();
                   throw SSLException(parms);
               }
   
               X509_LOOKUP_load_file(
                   pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
   
               PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL3,
                   "---> SSL: Successfully configured CRL file");
           }
       }
   
       Boolean keyLoaded = false;
   
       //
       // Check if there is a certificate file (file containing server
       // certificate) specified. If specified, validate and load the
       // certificate.
       //
       if (_certPath != String::EMPTY)
       {
           //
           // load the specified server certificates
           //
           PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
               String("---> SSL: Loading server certificate from: " + _certPath));
   
           if (SSL_CTX_use_certificate_file(sslContext,
               _certPath.getCString(), SSL_FILETYPE_PEM) <=0)
           {
               PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
                   String("---> SSL: No server certificate found in " +
                       _certPath));
               MessageLoaderParms parms(
                   "Common.SSLContext.COULD_NOT_GET_SERVER_CERTIFICATE",
                   "Could not get server certificate.");
               PEG_METHOD_EXIT();
               throw SSLException(parms);
           }
   
           //
           // If there is no key file (file containing server
           // private key) specified, then try loading the key from the
           // certificate file.
           // As of 2.4, if a keyfile is specified, its location is verified
           // during server startup and will throw an error if the path is invalid.
           //
           if (_keyPath == String::EMPTY)
           {
               PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
                   String("---> SSL: loading private key from: " + _certPath));
               //
               // load the private key and check for validity
               //
               if (!_verifyPrivateKey(sslContext, _certPath))
               {
                   MessageLoaderParms parms(
                       "Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
                       "Could not get private key.");
                   PEG_METHOD_EXIT();
                   throw SSLException(parms);
               }
               keyLoaded = true;
           }
       }
   
       //
       // Check if there is a key file (file containing server
       // private key) specified and the key was not already loaded.
       // If specified, validate and load the key.
       //
       if (_keyPath != String::EMPTY && !keyLoaded)
       {
           PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
               String("---> SSL: loading private key from: " + _keyPath));
           //
           // load given private key and check for validity
           //
           if (!_verifyPrivateKey(sslContext, _keyPath))
           {
               MessageLoaderParms parms(
                   "Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
                   "Could not get private key.");
               PEG_METHOD_EXIT();
               throw SSLException(parms);
           }
           keyLoaded = true;
       }
   
       PEG_METHOD_EXIT();
       return sslContext;
   }
   
   Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx, const String& keyPath)
   {
       PEG_METHOD_ENTER(TRC_SSL, "_verifyPrivateKey()");
   
       // Open the private key file.
   
       FILE* is = Executor::openFile(keyPath.getCString(), 'r');
   
       if (!is)
       {
           PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
               String("failed to open private key file: " + keyPath));
           return false;
       }
   
       // Read the private key from the input stream.
   
       EVP_PKEY* pkey;
       pkey = PEM_read_PrivateKey(is, NULL, NULL, NULL);
   
       if (!pkey)
       {
           PEG_TRACE_CSTRING(
               TRC_SSL, Tracer::LEVEL2, "failed to create private key");
           return false;
       }
   
       // Close the input stream.
   
       fclose(is);
   
       // Associate the new private key with the SSL context object.
   
       if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0)
       {
           PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
               String("---> SSL: no private key found in " + keyPath));
           PEG_METHOD_EXIT();
           return false;
       }
   
       // Check private key for validity.
   
       if (!SSL_CTX_check_private_key(ctx))
       {
           PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL2,
               "---> SSL: Private and public key do not match");
           PEG_METHOD_EXIT();
           return false;
       }
   
       PEG_METHOD_EXIT();
       return true;
   }
   
   SSL_CTX* SSLContextRep::getContext() const
   {
       return _sslContext;
   }
   
   String SSLContextRep::getTrustStore() const
   {
       return _trustStore;
   }
   
   String SSLContextRep::getCertPath() const
   {
       return _certPath;
   }
   
   String SSLContextRep::getKeyPath() const
   {
       return _keyPath;
   }
   
   #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
   String SSLContextRep::getTrustStoreUserName() const
   {
       return String::EMPTY;
   }
   #endif
   
   String SSLContextRep::getCRLPath() const
   {
       return _crlPath;
   }
   
   X509_STORE* SSLContextRep::getCRLStore() const
   {
       return _crlStore;
   }
   
   void SSLContextRep::setCRLStore(X509_STORE* store)
   {
       _crlStore = store;
   }
   
   Boolean SSLContextRep::isPeerVerificationEnabled() const
   {
       return _verifyPeer;
   }
   
   SSLCertificateVerifyFunction*
       SSLContextRep::getSSLCertificateVerifyFunction() const
   {
       return _certificateVerifyFunction;
   }
   
   #else
   
   //
   // these definitions are used if ssl is not available
   //
   
   SSLContextRep::SSLContextRep(
       const String& trustStore,
       const String& certPath,
       const String& keyPath,
       const String& crlPath,
       SSLCertificateVerifyFunction* verifyCert,
       const String& randomFile)
   {
   }
  
 SSLContextRep::SSLContextRep(const String& certPath,  
                        SSLCertificateVerifyFunction* verifyCert,  
                        const String& randomFile,  
                        Boolean isCIMClient) {}  
   
 SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep) {} SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep) {}
  
 SSLContextRep::~SSLContextRep() {} SSLContextRep::~SSLContextRep() {}
  
 SSL_CTX * SSLContextRep::_makeSSLContext() { return 0; } SSL_CTX * SSLContextRep::_makeSSLContext() { return 0; }
  
   Boolean SSLContextRep::_verifyPrivateKey(
       SSL_CTX *ctx,
       const String& keyPath)
   {
       return false;
   }
   
 SSL_CTX * SSLContextRep::getContext() const { return 0; } SSL_CTX * SSLContextRep::getContext() const { return 0; }
  
   String SSLContextRep::getTrustStore() const { return String::EMPTY; }
   
   String SSLContextRep::getCertPath() const { return String::EMPTY; }
   
   String SSLContextRep::getKeyPath() const { return String::EMPTY; }
   
   #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
   String SSLContextRep::getTrustStoreUserName() const { return String::EMPTY; }
   #endif
   
   String SSLContextRep::getCRLPath() const { return String::EMPTY; }
   
   X509_STORE* SSLContextRep::getCRLStore() const { return NULL; }
   
   void SSLContextRep::setCRLStore(X509_STORE* store) { }
   
   Boolean SSLContextRep::isPeerVerificationEnabled() const { return false; }
   
   SSLCertificateVerifyFunction*
       SSLContextRep::getSSLCertificateVerifyFunction() const
   {
       return NULL;
   }
   
   void SSLContextRep::init_ssl() {}
   
   void SSLContextRep::free_ssl() {}
   
 #endif // end of PEGASUS_HAS_SSL #endif // end of PEGASUS_HAS_SSL
  
 /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
Line 370 
Line 1330 
  
  
 SSLContext::SSLContext( SSLContext::SSLContext(
       const String& trustStore,
       SSLCertificateVerifyFunction* verifyCert,
       const String& randomFile)
   {
       _rep = new SSLContextRep(
           trustStore,
           String::EMPTY,
           String::EMPTY,
           String::EMPTY,
           verifyCert,
           randomFile);
   }
   
   SSLContext::SSLContext(
       const String& trustStore,
       const String& certPath,
       const String& keyPath,
       SSLCertificateVerifyFunction* verifyCert,
       const String& randomFile)
   {
       _rep = new SSLContextRep(
           trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
   }
   
   //PEP187
   SSLContext::SSLContext(
           const String& trustStore,
           const String& certPath,
           const String& keyPath,
           const String& crlPath,
           SSLCertificateVerifyFunction* verifyCert,
           const String& randomFile)
   {
   #ifndef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
       if (crlPath.size() > 0)
       {
           MessageLoaderParms parms(
               "Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
               "SSL CRL verification is not enabled.");
           throw Exception(parms);
       }
   #endif
       _rep = new SSLContextRep(
           trustStore, certPath, keyPath, crlPath, verifyCert, randomFile);
   }
   
   #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
   SSLContext::SSLContext(
       const String& trustStore,
     const String& certPath,     const String& certPath,
       const String& keyPath,
     SSLCertificateVerifyFunction* verifyCert,     SSLCertificateVerifyFunction* verifyCert,
     const String& randomFile,      String trustStoreUserName,
     Boolean isCIMClient)      const String& randomFile)
 { {
     _rep = new SSLContextRep(certPath, verifyCert, randomFile, isCIMClient);      _rep = new SSLContextRep(
           trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
 } }
   #endif
  
 SSLContext::SSLContext(const SSLContext& sslContext) SSLContext::SSLContext(const SSLContext& sslContext)
 { {
     _rep = new SSLContextRep(*sslContext._rep);     _rep = new SSLContextRep(*sslContext._rep);
 } }
  
   // Dummy constructor made private to disallow default construction
   SSLContext::SSLContext()
   {
   }
   
 SSLContext::~SSLContext() SSLContext::~SSLContext()
 { {
     delete _rep;     delete _rep;
 } }
  
   String SSLContext::getTrustStore() const
   {
       return _rep->getTrustStore();
   }
   
   String SSLContext::getCertPath() const
   {
       return _rep->getCertPath();
   }
   
   String SSLContext::getKeyPath() const
   {
       return _rep->getKeyPath();
   }
   
   String SSLContext::getCRLPath() const
   {
   #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
       return _rep->getCRLPath();
   #else
       MessageLoaderParms parms(
           "Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
           "SSL CRL verification is not enabled.");
       throw Exception(parms);
       PEGASUS_UNREACHABLE(return String::EMPTY;)
   #endif
   }
   
   X509_STORE* SSLContext::getCRLStore() const
   {
   #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
       return _rep->getCRLStore();
   #else
       MessageLoaderParms parms(
           "Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
           "SSL CRL verification is not enabled.");
       throw Exception(parms);
       PEGASUS_UNREACHABLE(return 0;)
   #endif
   }
   
   Boolean SSLContext::isPeerVerificationEnabled() const
   {
       return _rep->isPeerVerificationEnabled();
   }
   
   #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
   String SSLContext::getTrustStoreUserName() const
   {
       return _rep->getTrustStoreUserName();
   }
   #endif
   
   SSLCertificateVerifyFunction*
       SSLContext::getSSLCertificateVerifyFunction() const
   {
       return _rep->getSSLCertificateVerifyFunction();
   }
  
 /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
 // //
 // SSLCertificateInfo // SSLCertificateInfo
 // //
 /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
   //
   // Certificate validation result codes.
   //
   const int    SSLCertificateInfo::V_OK                                      = 0;
   
   const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT           = 2;
   const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_CRL                   = 3;
   const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE    = 4;
   const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE     = 5;
   const int    SSLCertificateInfo::V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY  = 6;
   const int    SSLCertificateInfo::V_ERR_CERT_SIGNATURE_FAILURE              = 7;
   const int    SSLCertificateInfo::V_ERR_CRL_SIGNATURE_FAILURE               = 8;
   const int    SSLCertificateInfo::V_ERR_CERT_NOT_YET_VALID                  = 9;
   const int    SSLCertificateInfo::V_ERR_CERT_HAS_EXPIRED                    = 10;
   const int    SSLCertificateInfo::V_ERR_CRL_NOT_YET_VALID                   = 11;
   const int    SSLCertificateInfo::V_ERR_CRL_HAS_EXPIRED                     = 12;
   const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD      = 13;
   const int    SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD       = 14;
   const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD      = 15;
   const int    SSLCertificateInfo::V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD      = 16;
   const int    SSLCertificateInfo::V_ERR_OUT_OF_MEM                          = 17;
   const int    SSLCertificateInfo::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT         = 18;
   const int    SSLCertificateInfo::V_ERR_SELF_SIGNED_CERT_IN_CHAIN           = 19;
   const int    SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY   = 20;
   const int    SSLCertificateInfo::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE     = 21;
   const int    SSLCertificateInfo::V_ERR_CERT_CHAIN_TOO_LONG                 = 22;
   const int    SSLCertificateInfo::V_ERR_CERT_REVOKED                        = 23;
   const int    SSLCertificateInfo::V_ERR_INVALID_CA                          = 24;
   const int    SSLCertificateInfo::V_ERR_PATH_LENGTH_EXCEEDED                = 25;
   const int    SSLCertificateInfo::V_ERR_INVALID_PURPOSE                     = 26;
   const int    SSLCertificateInfo::V_ERR_CERT_UNTRUSTED                      = 27;
   const int    SSLCertificateInfo::V_ERR_CERT_REJECTED                       = 28;
   const int    SSLCertificateInfo::V_ERR_SUBJECT_ISSUER_MISMATCH             = 29;
   const int    SSLCertificateInfo::V_ERR_AKID_SKID_MISMATCH                  = 30;
   const int    SSLCertificateInfo::V_ERR_AKID_ISSUER_SERIAL_MISMATCH         = 31;
   const int    SSLCertificateInfo::V_ERR_KEYUSAGE_NO_CERTSIGN                = 32;
   
   const int    SSLCertificateInfo::V_ERR_APPLICATION_VERIFICATION            = 50;
  
 class SSLCertificateInfoRep class SSLCertificateInfoRep
 { {
 public: public:
     String subjectName;     String subjectName;
     String issuerName;     String issuerName;
     int    errorDepth;      Uint32    depth;
     int    errorCode;      Uint32    errorCode;
     int    respCode;      Uint32    respCode;
       String    errorString;
       Uint32    versionNumber;
       long      serialNumber;
       CIMDateTime    notBefore;
       CIMDateTime    notAfter;
 }; };
  
  
Line 410 
Line 1528 
     const String subjectName,     const String subjectName,
     const String issuerName,     const String issuerName,
     const int errorDepth,     const int errorDepth,
     const int errorCode)      const int errorCode,
       const int respCode)
 { {
     _rep = new SSLCertificateInfoRep();     _rep = new SSLCertificateInfoRep();
     _rep->subjectName = subjectName;     _rep->subjectName = subjectName;
     _rep->issuerName = issuerName;     _rep->issuerName = issuerName;
     _rep->errorDepth = errorDepth;      _rep->versionNumber = 0;
       _rep->serialNumber = 0;
       _rep->notBefore = CIMDateTime();
       _rep->notAfter = CIMDateTime();
       _rep->depth = errorDepth;
     _rep->errorCode = errorCode;     _rep->errorCode = errorCode;
     _rep->respCode = 0;      _rep->errorString = String::EMPTY;
       _rep->respCode = respCode;
   }
   
   SSLCertificateInfo::SSLCertificateInfo(
       const String subjectName,
       const String issuerName,
       const Uint32 versionNumber,
       const long serialNumber,
       const CIMDateTime notBefore,
       const CIMDateTime notAfter,
       const Uint32 depth,
       const Uint32 errorCode,
       const String errorString,
       const Uint32 respCode)
   {
       _rep = new SSLCertificateInfoRep();
       _rep->subjectName = subjectName;
       _rep->issuerName = issuerName;
       _rep->versionNumber = versionNumber;
       _rep->serialNumber = serialNumber;
       _rep->notBefore = notBefore;
       _rep->notAfter = notAfter;
       _rep->depth = depth;
       _rep->errorCode = errorCode;
       _rep->errorString = errorString;
       _rep->respCode = respCode;
 } }
  
 SSLCertificateInfo::SSLCertificateInfo( SSLCertificateInfo::SSLCertificateInfo(
Line 426 
Line 1575 
     _rep = new SSLCertificateInfoRep();     _rep = new SSLCertificateInfoRep();
     _rep->subjectName = certificateInfo._rep->subjectName;     _rep->subjectName = certificateInfo._rep->subjectName;
     _rep->issuerName = certificateInfo._rep->issuerName;     _rep->issuerName = certificateInfo._rep->issuerName;
     _rep->errorDepth = certificateInfo._rep->errorDepth;      _rep->versionNumber = certificateInfo._rep->versionNumber;
       _rep->serialNumber = certificateInfo._rep->serialNumber;
       _rep->notBefore = certificateInfo._rep->notBefore;
       _rep->notAfter = certificateInfo._rep->notAfter;
       _rep->depth = certificateInfo._rep->depth;
     _rep->errorCode = certificateInfo._rep->errorCode;     _rep->errorCode = certificateInfo._rep->errorCode;
       _rep->errorString = certificateInfo._rep->errorString;
     _rep->respCode = certificateInfo._rep->respCode;     _rep->respCode = certificateInfo._rep->respCode;
 } }
  
Line 443 
Line 1597 
  
 String SSLCertificateInfo::getSubjectName() const String SSLCertificateInfo::getSubjectName() const
 { {
     return (_rep->subjectName);      return _rep->subjectName;
 } }
  
 String SSLCertificateInfo::getIssuerName() const String SSLCertificateInfo::getIssuerName() const
 { {
     return (_rep->issuerName);      return _rep->issuerName;
   }
   
   Uint32 SSLCertificateInfo::getVersionNumber() const
   {
       return _rep->versionNumber;
   }
   
   long SSLCertificateInfo::getSerialNumber() const
   {
       return _rep->serialNumber;
   }
   
   CIMDateTime SSLCertificateInfo::getNotBefore() const
   {
       return _rep->notBefore;
   }
   
   CIMDateTime SSLCertificateInfo::getNotAfter() const
   {
       return _rep->notAfter;
 } }
  
 int SSLCertificateInfo::getErrorDepth() const  Uint32 SSLCertificateInfo::getErrorDepth() const
 { {
     return (_rep->errorDepth);      return _rep->depth;
 } }
  
 int SSLCertificateInfo::getErrorCode() const  Uint32 SSLCertificateInfo::getErrorCode()  const
 { {
     return (_rep->errorCode);      return _rep->errorCode;
   }
   
   void SSLCertificateInfo::setErrorCode(const int errorCode)
   {
       _rep->errorCode = errorCode;
   }
   
   String SSLCertificateInfo::getErrorString() const
   {
       return _rep->errorString;
   }
   
   Uint32 SSLCertificateInfo::getResponseCode()  const
   {
       return _rep->respCode;
 } }
  
 void SSLCertificateInfo::setResponseCode(const int respCode) void SSLCertificateInfo::setResponseCode(const int respCode)
Line 466 
Line 1655 
     _rep->respCode = respCode;     _rep->respCode = respCode;
 } }
  
   String SSLCertificateInfo::toString() const
   {
       char buf[1024];
   
       String s;
   
       s.append("Subject Name:\n\t");
       s.append(_rep->subjectName);
       s.append("\n");
   
       s.append("Issuer Name:\n\t");
       s.append(_rep->issuerName);
       s.append("\n");
   
       sprintf(buf, "Depth: %d\n", _rep->depth);
       s.append(buf);
   
       sprintf(buf, "Error code: %d\n", _rep->errorCode);
       s.append(buf);
   
       sprintf(buf, "Response (preverify) code: %d\n", _rep->respCode);
       s.append(buf);
   
       s.append("Error string: ");
       s.append(_rep->errorString);
       s.append("\n");
   
       sprintf(buf, "Version number: %d\n", _rep->versionNumber);
       s.append(buf);
   
       sprintf(buf, "Serial number: %lu\n", _rep->serialNumber);
       s.append(buf);
   
       s.append("Not before date: ");
       s.append((_rep->notBefore).toString());
       s.append("\n");
   
       s.append("Not after date: ");
       s.append((_rep->notAfter).toString());
       s.append("\n");
   
       return s;
   }
   
   ///////////////////////////////////////////////////////////////////////////////
   //
   // SSLCallbackInfo
   //
   ///////////////////////////////////////////////////////////////////////////////
   
   SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert)
   {
       _rep = new SSLCallbackInfoRep();
       _rep->verifyCertificateCallback = verifyCert;
       _rep->crlStore = NULL;
   }
   
   SSLCallbackInfo::SSLCallbackInfo(
       SSLCertificateVerifyFunction* verifyCert,
       X509_STORE* crlStore)
   {
       _rep = new SSLCallbackInfoRep();
       _rep->verifyCertificateCallback = verifyCert;
       _rep->crlStore = crlStore;
   }
   
   SSLCallbackInfo::SSLCallbackInfo(
       SSLCertificateVerifyFunction* verifyCert,
       X509_STORE* crlStore,
       String ipAddress)
   {
       _rep = new SSLCallbackInfoRep();
       _rep->verifyCertificateCallback = verifyCert;
       _rep->crlStore = crlStore;
       _rep->ipAddress = ipAddress;
   }
   
   SSLCallbackInfo::~SSLCallbackInfo()
   {
       PEG_METHOD_ENTER(TRC_SSL, "SSLCallbackInfo::~SSLCallbackInfo");
       for (Uint32 i = 0; i < _rep->peerCertificate.size(); i++)
       {
           delete _rep->peerCertificate[i];
       }
       delete _rep;
       PEG_METHOD_EXIT();
   }
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END
  


Legend:
Removed from v.1.11  
changed lines
  Added in v.1.84

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2