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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2