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

  1 thilo.boehm 1.1 //%LICENSE////////////////////////////////////////////////////////////////
  2                 //
  3                 // Licensed to The Open Group (TOG) under one or more contributor license
  4                 // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5                 // this work for additional information regarding copyright ownership.
  6                 // Each contributor licenses this file to you under the OpenPegasus Open
  7                 // Source License; you may not use this file except in compliance with the
  8                 // License.
  9                 //
 10                 // Permission is hereby granted, free of charge, to any person obtaining a
 11                 // copy of this software and associated documentation files (the "Software"),
 12                 // to deal in the Software without restriction, including without limitation
 13                 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14                 // and/or sell copies of the Software, and to permit persons to whom the
 15                 // Software is furnished to do so, subject to the following conditions:
 16                 //
 17                 // The above copyright notice and this permission notice shall be included
 18                 // in all copies or substantial portions of the Software.
 19                 //
 20                 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21                 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22 thilo.boehm 1.1 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23                 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24                 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25                 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26                 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27                 //
 28                 //////////////////////////////////////////////////////////////////////////
 29                 //
 30                 //%/////////////////////////////////////////////////////////////////////////////
 31                 
 32                 /////////////////////////////////////////////////////////////////////////////
 33                 //  SSLContextManager
 34                 /////////////////////////////////////////////////////////////////////////////
 35                 
 36                 #ifdef PEGASUS_HAS_SSL
 37 thilo.boehm 1.2 # include <Pegasus/Common/Network.h>
 38 thilo.boehm 1.1 # define OPENSSL_NO_KRB5 1
 39                 # include <openssl/err.h>
 40                 # include <openssl/ssl.h>
 41                 # include <openssl/rand.h>
 42                 #else
 43                 # define SSL_CTX void
 44                 #endif // end of PEGASUS_HAS_SSL
 45                 
 46                 #include <Pegasus/Common/Tracer.h>
 47                 #include <Pegasus/Common/FileSystem.h>
 48                 
 49 thilo.boehm 1.2 #include <Pegasus/Common/SSLContext.h>
 50                 #include <Pegasus/Common/SSLContextRep.h>
 51 thilo.boehm 1.1 #include "SSLContextManager.h"
 52                 
 53                 
 54                 PEGASUS_USING_STD;
 55                 
 56                 PEGASUS_NAMESPACE_BEGIN
 57                 
 58                 //
 59                 // This method along with the relevent code is moved here
 60                 // from CIMServer.cpp
 61                 //
 62                 Boolean verifyClientOptionalCallback(SSLCertificateInfo &certInfo)
 63                 {
 64                 #if defined PEGASUS_OVERRIDE_SSL_CERT_VERIFICATION_RESULT
 65                     // SSL callback for the "optional" client verification setting
 66                     // By always returning true, we allow the handshake to continue
 67                     // even if the client sent no certificate or sent an untrusted certificate.
 68                     return true;
 69                 #else
 70                     //
 71                     // Return the OpenSSL verification result
 72 thilo.boehm 1.1     //
 73                     return certInfo.getResponseCode();
 74                 #endif
 75                 }
 76                 
 77                 
 78                 
 79                 SSLContextManager::SSLContextManager()
 80                     : _sslContext(0)
 81                 {
 82                 
 83                 }
 84                 
 85                 SSLContextManager::~SSLContextManager()
 86                 {
 87                     delete _sslContext;
 88                 }
 89                 
 90                 //
 91                 // Part of this code logic comes from the CIMServer::_getSSLContext()
 92                 // and CIMServer::_getExportSSLContext() methods.
 93 thilo.boehm 1.1 //
 94                 void SSLContextManager::createSSLContext(
 95                     const String& trustStore, const String& certPath, const String& keyPath,
 96                     const String& crlStore, Boolean callback, const String& randFile)
 97                 {
 98                     PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::createSSLContext()");
 99                 
100                     if ( !_sslContext )
101                     {
102                         PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL4,
103                             "Creating the Server SSL Context.");
104                 
105                         //
106                         // Create the SSLContext object
107                         //
108                         if ( callback )
109                         {
110                             _sslContext = new SSLContext(trustStore, certPath,
111                                 keyPath, crlStore,
112                                 (SSLCertificateVerifyFunction*)verifyClientOptionalCallback,
113                                 randFile);
114 thilo.boehm 1.1         }
115                         else if ( trustStore != String::EMPTY )
116                         {
117                             _sslContext = new SSLContext(trustStore, certPath,
118                                 keyPath, crlStore, 0, randFile);
119                         }
120                         else
121                         {
122                             _sslContext = new SSLContext(String::EMPTY, certPath,
123                                 keyPath, crlStore, 0, randFile);
124                         }
125                     }
126                 
127                     PEG_METHOD_EXIT();
128                 }
129                 
130                 //
131                 // use the following methods only if SSL is available
132                 //
133                 #ifdef PEGASUS_HAS_SSL
134                 
135 thilo.boehm 1.1 /**
136                     Create a new store object and load the specified store and return
137                     a pointer to the new store object.
138                 */
139                 static X509_STORE* _getNewX509Store(const String& storePath)
140                 {
141                     PEG_METHOD_ENTER(TRC_SSL, "_getNewX509Store()");
142                 
143                     //
144                     // reload certificates from the specified store
145                     //
146                     PEG_TRACE((TRC_SSL, Tracer::LEVEL3,
147                         "Reloading certificates from the store: %s",
148                         (const char*)storePath.getCString()));
149                 
150                     X509_STORE* newStore = X509_STORE_new();
151                     if (newStore == NULL)
152                     {
153                         PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
154                             "Memory allocation error reloading the trust or crl store.");
155                         PEG_METHOD_EXIT();
156 thilo.boehm 1.1         throw PEGASUS_STD(bad_alloc)();
157                     }
158                 
159                     //
160                     // Check if there is a CA certificate file or directory specified.
161                     // If specified, load the certificates from the specified store path.
162                     //
163                     if (FileSystem::isDirectory(storePath))
164                     {
165                         X509_LOOKUP* storeLookup = X509_STORE_add_lookup(newStore,
166                                                               X509_LOOKUP_hash_dir());
167                         if (storeLookup == NULL)
168                         {
169                             X509_STORE_free(newStore);
170                 
171                             PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
172                                 "Could not reload the trust or crl store.");
173                 
174                             MessageLoaderParms parms(
175                                 "Pegasus.Common.SSLContextManager."
176                                     "COULD_NOT_RELOAD_TRUST_OR_CRL_STORE",
177 thilo.boehm 1.1                 "Could not reload the trust or certificate revocation list "
178                                     "store.");
179                             PEG_METHOD_EXIT();
180                             throw SSLException(parms);
181                         }
182                         X509_LOOKUP_add_dir(storeLookup,
183                             storePath.getCString(), X509_FILETYPE_PEM);
184                     }
185                     else if (FileSystem::exists(storePath))
186                     {
187                         X509_LOOKUP* storeLookup = X509_STORE_add_lookup(
188                             newStore, X509_LOOKUP_file());
189                         if (storeLookup == NULL)
190                         {
191                             X509_STORE_free(newStore);
192                 
193                             PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
194                                 "Could not reload the trust or crl store.");
195                 
196                             MessageLoaderParms parms(
197                                 "Pegasus.Common.SSLContextManager."
198 thilo.boehm 1.1                     "COULD_NOT_RELOAD_TRUST_OR_CRL_STORE",
199                                 "Could not reload the trust or certificate revocation list "
200                                     "store.");
201                             PEG_METHOD_EXIT();
202                             throw SSLException(parms);
203                         }
204                         X509_LOOKUP_load_file(storeLookup,
205                             storePath.getCString(), X509_FILETYPE_PEM);
206                     }
207                     else
208                     {
209                         X509_STORE_free(newStore);
210                 
211                         PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
212                             "Could not reload the trust or crl store, configured store "
213                                 "not found.");
214                 
215                         MessageLoaderParms parms(
216                             "Pegasus.Common.SSLContextManager."
217                                 "CONFIGURED_TRUST_OR_CRL_STORE_NOT_FOUND",
218                             "Could not reload the trust or certificate revocation list store. "
219 thilo.boehm 1.1                 "The configured store is not found.");
220                         PEG_METHOD_EXIT();
221                         throw SSLException(parms);
222                     }
223                 
224                     PEG_METHOD_EXIT();
225                     return newStore;
226                 }
227                 
228                 void SSLContextManager::reloadTrustStore()
229                 {
230                     PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::reloadTrustStore()");
231                 
232                     SSL_CTX* sslContext;
233                     String trustStore;
234                 
235                     if ( _sslContext )
236                     {
237                         sslContext = _sslContext->_rep->getContext();
238                         trustStore = _sslContext->getTrustStore();
239                     }
240 thilo.boehm 1.1     else
241                     {
242                         PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
243                           "Could not reload the trust store, SSL Context is not initialized.");
244                 
245                         MessageLoaderParms parms(
246                             "Pegasus.Common.SSLContextManager."
247                                 "COULD_NOT_RELOAD_TRUSTSTORE_SSL_CONTEXT_NOT_INITIALIZED",
248                             "Could not reload the trust store. The SSL context is not "
249                                 "initialized.");
250                         PEG_METHOD_EXIT();
251                         throw SSLException(parms);
252                     }
253                 
254                     if (trustStore == String::EMPTY)
255                     {
256                         PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
257                             "Could not reload the trust store, the trust store is not "
258                                 "configured.");
259                 
260                         MessageLoaderParms parms(
261 thilo.boehm 1.1             "Pegasus.Common.SSLContextManager.TRUST_STORE_NOT_CONFIGURED",
262                             "Could not reload the trust store, the trust store is not "
263                                 "configured.");
264                         PEG_METHOD_EXIT();
265                         throw SSLException(parms);
266                     }
267                 
268                     X509_STORE* newStore = _getNewX509Store(trustStore);
269                 
270                     //
271                     // acquire write lock to Context object and then overwrite the trust
272                     // store cache
273                     //
274                     WriteLock contextLock(_sslContextObjectLock);
275                     SSL_CTX_set_cert_store(sslContext, newStore);
276                 
277                     PEG_METHOD_EXIT();
278                 }
279                 
280                 void SSLContextManager::reloadCRLStore()
281                 {
282 thilo.boehm 1.1     PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::reloadCRLStore()");
283                 
284                     if (!_sslContext)
285                     {
286                         PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
287                         "Could not reload the crl store, SSL Context is not initialized.");
288                 
289                         MessageLoaderParms parms(
290                             "Pegasus.Common.SSLContextManager."
291                                 "COULD_NOT_RELOAD_CRL_STORE_SSL_CONTEXT_NOT_INITIALIZED",
292                             "Could not reload the certificate revocation list store. "
293                                 "The SSL Context is not initialized.");
294                 
295                         PEG_METHOD_EXIT();
296                         throw SSLException(parms);
297                     }
298                 
299                     String crlPath = _sslContext->getCRLPath();
300                 
301                     if (crlPath == String::EMPTY)
302                     {
303 thilo.boehm 1.1         PEG_TRACE_CSTRING(TRC_SSL, Tracer::LEVEL1,
304                             "Could not reload the crl store, the crl store is not configured.");
305                 
306                         MessageLoaderParms parms(
307                             "Pegasus.Common.SSLContextManager.CRL_STORE_NOT_CONFIGURED",
308                             "Could not reload the certificate revocation list store. "
309                                 "The certificate revocation list store is not configured.");
310                         PEG_METHOD_EXIT();
311                         throw SSLException(parms);
312                     }
313                 
314                     PEG_TRACE((TRC_SSL, Tracer::LEVEL4,
315                         "CRL store path is %s",(const char*)crlPath.getCString()));
316                 
317                     // update the CRL store
318                 
319                     {
320                         WriteLock contextLock(_sslContextObjectLock);
321                         if (_sslContext)
322                         {
323                             _sslContext->_rep->setCRLStore(_getNewX509Store(crlPath));
324 thilo.boehm 1.1         }
325                     }
326                 
327                     PEG_METHOD_EXIT();
328                 }
329                 
330                 #else    //#ifdef PEGASUS_HAS_SSL
331                 
332                 void SSLContextManager::reloadTrustStore() { }
333                 
334                 void SSLContextManager::reloadCRLStore() { }
335                 
336                 #endif   //#ifdef PEGASUS_HAS_SSL
337                 
338                 /**
339                     Get a pointer to the sslContext object.
340                  */
341                 SSLContext*  SSLContextManager::getSSLContext() const
342                 {
343                     return _sslContext;
344                 }
345 thilo.boehm 1.1 
346                 /**
347                     Get a pointer to the sslContextObjectLock.
348                  */
349                 ReadWriteSem* SSLContextManager::getSSLContextObjectLock()
350                 {
351                     return &_sslContextObjectLock;
352                 }
353                 
354                 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2