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

Diff for /pegasus/src/Pegasus/Common/SSLContext.cpp between version 1.27 and 1.28

version 1.27, 2004/05/21 20:57:00 version 1.28, 2004/06/09 20:49:35
Line 74 
Line 74 
 // //
 #ifdef PEGASUS_HAS_SSL #ifdef PEGASUS_HAS_SSL
  
 //  
 // certificate handling routine  
 //  
   
 // ATTN-RK-20020905: This global variable is unsafe with multiple SSL contexts  
 SSLCertificateVerifyFunction* verify_certificate;  
   
 // Mutex for SSL locks. // Mutex for SSL locks.
 Mutex* SSLContextRep::_sslLocks = 0; Mutex* SSLContextRep::_sslLocks = 0;
  
Line 168 
Line 161 
  
     char   buf[256];     char   buf[256];
     X509   *currentCert;     X509   *currentCert;
       SSL    *ssl;
     int    verifyError = X509_V_OK;     int    verifyError = X509_V_OK;
  
       //
       // get the verification callback info specific to each SSL connection
       //
       ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
       SSLCallbackInfo* exData = (SSLCallbackInfo*) SSL_get_ex_data(ssl, SSL_CALLBACK_INDEX);
   
       //
     // If the SSLContext does not have an additional callback     // If the SSLContext does not have an additional callback
     // simply return the preverification error.     // simply return the preverification error.
     // We do not need to go through the additional steps.     // We do not need to go through the additional steps.
     if (verify_certificate == NULL)      //
       if (exData->verifyCertificateCallback == NULL)
     {     {
         return (preVerifyOk);         return (preVerifyOk);
     }     }
Line 193 
Line 195 
     //     //
     int depth = X509_STORE_CTX_get_error_depth(ctx);     int depth = X509_STORE_CTX_get_error_depth(ctx);
  
     //FUTURE: Not sure what to do with these...?  
     //ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());  
     //mydata = SSL_get_ex_data(ssl, mydata_index);  
   
     //     //
     // get the version on the certificate     // get the version on the certificate
     //     //
Line 247 
Line 245 
     }     }
     String issuerName = String(buf);     String issuerName = String(buf);
  
     //  //    SSLCertificateInfo certInfo(subjectName, issuerName, version, serialNumber,
     // Call the verify_certificate() application callback  //        notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk);
     //  
     SSLCertificateInfo certInfo(subjectName, issuerName, version, serialNumber,      exData->_peerCertificate = new SSLCertificateInfo(subjectName, issuerName, version, serialNumber,
         notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk);         notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk);
  
     if (verify_certificate(certInfo))      //
       // Call the application callback.
       // Note that the verification result does not automatically get set to X509_V_OK if the callback is successful.
       // This is because OpenSSL retains the original default error in case we want to use it later.
       // To set the error, we could use X509_STORE_CTX_set_error(ctx, verifyError); but there is no real benefit to doing that here.
       //
       if (exData->verifyCertificateCallback(*exData->_peerCertificate))//certInfo))
     {     {
 #ifndef PEGASUS_USE_SSL_CLIENT_VERIFICATION  
         verifyError = X509_V_OK;  
 #endif  
         preVerifyOk = 1;  
         Tracer::trace(TRC_SSL, Tracer::LEVEL4,         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
             "--> SSL: verify_certificate() returned X509_V_OK");              "--> SSL: verifyCertificateCallback() returned X509_V_OK");
   
           PEG_METHOD_EXIT();
           return 1;
     }     }
     else      else // verification failed, handshake will be immediately terminated
     {     {
 #ifndef PEGASUS_USE_SSL_CLIENT_VERIFICATION  
         verifyError = certInfo.getErrorCode();  
 #endif  
         preVerifyOk = 0;  
         Tracer::trace(TRC_SSL, Tracer::LEVEL4,         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
             "--> SSL: verify_certificate() returned error %d", verifyError);              "--> SSL: verifyCertificateCallback() returned error %d", exData->_peerCertificate->getErrorCode());
     }  
   
     // We need a way for the server to retain the verification result,  
     // so that in 'optional' settings, we can still continue the connection.  
     // We can then give the verification result to a consumer and let them  
     // decide whether to accept or reject the request.  
     //  
     // The problem is that if we don't reset the error, the server verification  
     // gets messed up on the client side.  
     //  
     // If SSL client verification is disabled, do things the old way,  
     // since the server will never even use the callback.  
     //  
     // If SSL client verification is enabled, do not set the error code explicitly.  
     // Instead, require the client to set the error code within its callback.  
     // i.e.  
     // Boolean verifyCertificate(SSLCertificateInfo cert)  
     // {  
     //    cert.setErrorCode(SSLCertificateInfo::V_OK);  
     //    return true;  
     // }  
     //  
     // If clients do not do this w/ PEGASUS_USE_SSL_CLIENT_VERIFICATION enabled,  
     // the server verification will fail because the error code will be the original result.  
     // This is sort of a kluge, but I cannot figure out a better way to do this w/o  
     // some storage tactic.  
     //  
     // This will definitely be fixed in 2.4.  For 2.3.2, it shouldn't matter since we  
     // are not using server verification.  
   
 #ifdef PEGASUS_USE_SSL_CLIENT_VERIFICATION  
     X509_STORE_CTX_set_error(ctx, certInfo.getErrorCode());  
 #else  
     X509_STORE_CTX_set_error(ctx, verifyError);  
 #endif  
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
           return 0;
     return(preVerifyOk);      }
 } }
  
 // //
Line 391 
Line 355 
  
     _keyPath = keyPath;     _keyPath = keyPath;
  
         //ATTN: This cannot be global now that there are multiple SSLContexts.      _certificateVerifyFunction = verifyCert;
     verify_certificate = verifyCert;  
  
         _trustStoreAutoUpdate = false;         _trustStoreAutoUpdate = false;
  
         _trustStoreUserName = String::EMPTY;         _trustStoreUserName = String::EMPTY;
  
       //
     // If a truststore and/or peer verification function is specified, enable peer verification     // If a truststore and/or peer verification function is specified, enable peer verification
       //
     if (trustStore != String::EMPTY || verifyCert != NULL)     if (trustStore != String::EMPTY || verifyCert != NULL)
     {     {
         _verifyPeer = true;         _verifyPeer = true;
Line 408 
Line 373 
         _verifyPeer = false;         _verifyPeer = false;
     }     }
  
     // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.      //
       // Initialize SSL callbacks and increment the SSLContextRep object _counter.
       //
     _countRepMutex.lock(pegasus_thread_self());     _countRepMutex.lock(pegasus_thread_self());
  
     try     try
Line 473 
Line 440 
  
     _keyPath = keyPath;     _keyPath = keyPath;
  
         //ATTN: This cannot be global now that there are multiple SSLContexts.      _certificateVerifyFunction = verifyCert;
     verify_certificate = verifyCert;  
  
     _trustStoreAutoUpdate = trustStoreAutoUpdate;     _trustStoreAutoUpdate = trustStoreAutoUpdate;
  
         _trustStoreUserName = trustStoreUserName;         _trustStoreUserName = trustStoreUserName;
  
       //
     // If a truststore and/or peer verification function is specified, enable peer verification     // If a truststore and/or peer verification function is specified, enable peer verification
       //
     if (trustStore != String::EMPTY || verifyCert != NULL)     if (trustStore != String::EMPTY || verifyCert != NULL)
     {     {
         _verifyPeer = true;         _verifyPeer = true;
Line 490 
Line 458 
         _verifyPeer = false;         _verifyPeer = false;
     }     }
  
       //
     // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.     // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.
       //
     _countRepMutex.lock(pegasus_thread_self());     _countRepMutex.lock(pegasus_thread_self());
  
     try     try
Line 548 
Line 518 
     _verifyPeer = sslContextRep._verifyPeer;     _verifyPeer = sslContextRep._verifyPeer;
     _trustStoreAutoUpdate = sslContextRep._trustStoreAutoUpdate;     _trustStoreAutoUpdate = sslContextRep._trustStoreAutoUpdate;
         _trustStoreUserName = sslContextRep._trustStoreUserName;         _trustStoreUserName = sslContextRep._trustStoreUserName;
       _certificateVerifyFunction = sslContextRep._certificateVerifyFunction;
     // ATTN: verify_certificate is set implicitly in global variable  
     _randomFile = sslContextRep._randomFile;     _randomFile = sslContextRep._randomFile;
  
     // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.     // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.
Line 805 
Line 774 
         // callback function is not called in this case; the handshake is simply terminated.         // callback function is not called in this case; the handshake is simply terminated.
         // This value has NO effect in from a client perspective         // This value has NO effect in from a client perspective
  
         if (verify_certificate != NULL)          if (_certificateVerifyFunction != NULL)
         {         {
             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
                 "---> SSL: certificate verification callback specified");                 "---> SSL: certificate verification callback specified");
Line 1042 
Line 1011 
         return _trustStoreUserName;         return _trustStoreUserName;
 } }
  
   SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const
   {
       return _certificateVerifyFunction;
   }
   
 #else #else
  
 // //
Line 1087 
Line 1061 
  
 String SSLContextRep::getTrustStoreUserName() const { return String::EMPTY; } String SSLContextRep::getTrustStoreUserName() const { return String::EMPTY; }
  
   SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const { return NULL; }
   
 void SSLContextRep::init_ssl() {} void SSLContextRep::init_ssl() {}
  
 void SSLContextRep::free_ssl() {} void SSLContextRep::free_ssl() {}
Line 1214 
Line 1190 
         return (_rep->getTrustStoreUserName());         return (_rep->getTrustStoreUserName());
 } }
  
   SSLCertificateVerifyFunction* SSLContext::getSSLCertificateVerifyFunction() const
   {
       return (_rep->getSSLCertificateVerifyFunction());
   }
   
 /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
 // //
 // SSLCertificateInfo // SSLCertificateInfo
Line 1405 
Line 1386 
     _rep->respCode = respCode;     _rep->respCode = respCode;
 } }
  
   String SSLCertificateInfo::toString() const
   {
       char buf[1024];
   
       String s;
   
       s.append("Subject Name:\n\t");
       s.append(_rep->subjectName);
       s.append("\n");
   
       s.append("Issuer Name:\n\t");
       s.append(_rep->issuerName);
       s.append("\n");
   
       sprintf(buf, "Depth: %d\n", _rep->depth);
       s.append(buf);
   
       sprintf(buf, "Error code: %d\n", _rep->errorCode);
       s.append(buf);
   
       sprintf(buf, "Response (preverify) code: %d\n", _rep->respCode);
       s.append(buf);
   
       s.append("Error string: ");
       s.append(_rep->errorString);
       s.append("\n");
   
       sprintf(buf, "Version number: %d\n", _rep->versionNumber);
       s.append(buf);
   
       sprintf(buf, "Serial number: %ld\n", _rep->serialNumber);
       s.append(buf);
   
       s.append("Not before date: ");
       s.append((_rep->notBefore).toString());
       s.append("\n");
   
       s.append("Not after date: ");
       s.append((_rep->notAfter).toString());
       s.append("\n");
   
       return s;
   }
   
   SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert)
   {
       verifyCertificateCallback = verifyCert;
       _peerCertificate = NULL;
   }
   
   SSLCallbackInfo::~SSLCallbackInfo()
   {
       if (_peerCertificate)
       {
           delete _peerCertificate;
       }
   }
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END
  


Legend:
Removed from v.1.27  
changed lines
  Added in v.1.28

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2