1 karl 1.7 //%2006////////////////////////////////////////////////////////////////////////
|
2 nag.boranna 1.1 //
3 // 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 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.7 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 nag.boranna 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // 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 // 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.7 //
|
21 nag.boranna 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // 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 // 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 // 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 /////////////////////////////////////////////////////////////////////////////
35 // SSLContextManager
36 /////////////////////////////////////////////////////////////////////////////
37
38 #ifdef PEGASUS_HAS_SSL
39
|
40 mike 1.9 #include "Network.h"
|
41 nag.boranna 1.1
42 #define OPENSSL_NO_KRB5 1
43 #include <openssl/err.h>
44 #include <openssl/ssl.h>
45 #include <openssl/rand.h>
46 #else
47 #define SSL_CTX void
48 #define X509_STORE void
49
50 #endif // end of PEGASUS_HAS_SSL
51
52 #include <Pegasus/Common/Tracer.h>
53 #include <Pegasus/Common/FileSystem.h>
54
55 #include "SSLContext.h"
56 #include "SSLContextRep.h"
57 #include "SSLContextManager.h"
58
59
60 PEGASUS_USING_STD;
61
62 nag.boranna 1.1 PEGASUS_NAMESPACE_BEGIN
63
64 //
65 // This method along with the relevent code is moved here
66 // from CIMServer.cpp
67 //
68 Boolean verifyClientOptionalCallback(SSLCertificateInfo &certInfo)
69 {
|
70 sushma.fernandes 1.6 #if defined PEGASUS_OVERRIDE_SSL_CERT_VERIFICATION_RESULT
|
71 nag.boranna 1.1 // SSL callback for the "optional" client verification setting
72 // By always returning true, we allow the handshake to continue
73 // even if the client sent no certificate or sent an untrusted certificate.
74 return true;
|
75 sushma.fernandes 1.6 #else
76 //
77 // Return the OpenSSL verification result
78 //
79 return certInfo.getResponseCode();
80 #endif
|
81 nag.boranna 1.1 }
82
83
84
85 SSLContextManager::SSLContextManager()
|
86 sushma.fernandes 1.10 : _sslContext(0)
|
87 nag.boranna 1.1 {
88
89 }
90
91 SSLContextManager::~SSLContextManager()
92 {
|
93 kumpf 1.8 delete _sslContext;
|
94 nag.boranna 1.1 }
95
96 //
97 // Part of this code logic comes from the CIMServer::_getSSLContext()
98 // and CIMServer::_getExportSSLContext() methods.
99 //
|
100 sushma.fernandes 1.10 void SSLContextManager::createSSLContext(
|
101 david.dillard 1.5 const String& trustStore, const String& certPath, const String& keyPath,
|
102 nag.boranna 1.1 const String& crlStore, Boolean callback, const String& randFile)
103 {
104 PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::createSSLContext()");
105
|
106 sushma.fernandes 1.10 if ( !_sslContext )
|
107 nag.boranna 1.1 {
108 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
109 "Creating the Server SSL Context.");
110
111 //
112 // Create the SSLContext object
113 //
114 if ( callback )
115 {
|
116 david.dillard 1.5 _sslContext = new SSLContext(trustStore, certPath,
117 keyPath, crlStore,
|
118 nag.boranna 1.1 (SSLCertificateVerifyFunction*)verifyClientOptionalCallback,
119 randFile);
120 }
121 else if ( trustStore != String::EMPTY )
122 {
|
123 david.dillard 1.5 _sslContext = new SSLContext(trustStore, certPath,
|
124 nag.boranna 1.1 keyPath, crlStore, 0, randFile);
125 }
|
126 david.dillard 1.5 else
|
127 nag.boranna 1.1 {
|
128 david.dillard 1.5 _sslContext = new SSLContext(String::EMPTY, certPath,
|
129 nag.boranna 1.1 keyPath, crlStore, 0, randFile);
130 }
131 }
132
133 PEG_METHOD_EXIT();
134 }
135
136 //
137 // use the following methods only if SSL is available
138 //
139 #ifdef PEGASUS_HAS_SSL
140
|
141 sushma.fernandes 1.10 void SSLContextManager::reloadTrustStore()
|
142 nag.boranna 1.1 {
143 PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::reloadTrustStore()");
144
145 SSL_CTX* sslContext;
146 String trustStore = String::EMPTY;
147
|
148 sushma.fernandes 1.10 if ( _sslContext )
|
149 nag.boranna 1.1 {
150 sslContext = _sslContext->_rep->getContext();
151 trustStore = _sslContext->getTrustStore();
152 }
153 else
154 {
155 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
156 "Could not reload the trust store, SSL Context is not initialized.");
157
158 MessageLoaderParms parms(
|
159 kumpf 1.11 "Pegasus.Common.SSLContextManager."
160 "COULD_NOT_RELOAD_TRUSTSTORE_SSL_CONTEXT_NOT_INITIALIZED",
161 "Could not reload the trust store, SSL Context is not "
162 "initialized.");
|
163 nag.boranna 1.1 PEG_METHOD_EXIT();
164 throw SSLException(parms);
165 }
166
167 if (trustStore == String::EMPTY)
168 {
169 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
|
170 kumpf 1.11 "Could not reload the trust store, the trust store is not "
171 "configured.");
|
172 nag.boranna 1.1
173 MessageLoaderParms parms(
174 "Pegasus.Common.SSLContextManager.TRUST_STORE_NOT_CONFIGURED",
|
175 kumpf 1.11 "Could not reload the trust store, the trust store is not "
176 "configured.");
|
177 nag.boranna 1.1 PEG_METHOD_EXIT();
178 throw SSLException(parms);
179 }
180
181 X509_STORE* newStore = _getNewX509Store(trustStore);
182
183 //
|
184 david.dillard 1.5 // acquire write lock to Context object and then overwrite the trust
|
185 nag.boranna 1.1 // store cache
186 //
|
187 sushma.fernandes 1.10 WriteLock contextLock(_sslContextObjectLock);
188 SSL_CTX_set_cert_store(sslContext, newStore);
189
|
190 nag.boranna 1.1 PEG_METHOD_EXIT();
191 }
192
193 void SSLContextManager::reloadCRLStore()
194 {
195 PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::reloadCRLStore()");
196
|
197 sushma.fernandes 1.10 if (!_sslContext)
|
198 nag.boranna 1.1 {
199 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
200 "Could not reload the crl store, SSL Context is not initialized.");
201
202 MessageLoaderParms parms(
|
203 kumpf 1.11 "Pegasus.Common.SSLContextManager."
204 "COULD_NOT_RELOAD_CRL_STORE_SSL_CONTEXT_NOT_INITIALIZED",
205 "Could not reload the crl store, SSL Context is not initialized.");
|
206 nag.boranna 1.1
207 PEG_METHOD_EXIT();
208 throw SSLException(parms);
209 }
210
|
211 h.sterling 1.3 String crlPath = _sslContext->getCRLPath();
|
212 nag.boranna 1.1
|
213 h.sterling 1.3 if (crlPath == String::EMPTY)
|
214 nag.boranna 1.1 {
215 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
216 "Could not reload the crl store, the crl store is not configured.");
217
218 MessageLoaderParms parms(
219 "Pegasus.Common.SSLContextManager.CRL_STORE_NOT_CONFIGURED",
220 "Could not reload the crl store, the crl store is not configured.");
221 PEG_METHOD_EXIT();
222 throw SSLException(parms);
223 }
224
|
225 h.sterling 1.3 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "CRL store path is " + crlPath);
|
226 nag.boranna 1.1
|
227 kumpf 1.11 // update the CRL store for both the server and the export server since
228 // they share the same CRL store
|
229 h.sterling 1.3 X509_STORE* crlStore;
|
230 david.dillard 1.5
|
231 nag.boranna 1.1 {
232 WriteLock contextLock(_sslContextObjectLock);
233 if (_sslContext)
234 {
|
235 kumpf 1.4 _sslContext->_rep->setCRLStore(_getNewX509Store(crlPath));
|
236 nag.boranna 1.1 }
237 }
238
239 PEG_METHOD_EXIT();
240 }
241
|
242 sushma.fernandes 1.10
|
243 nag.boranna 1.1 X509_STORE* SSLContextManager::_getNewX509Store(const String& storePath)
244 {
245 PEG_METHOD_ENTER(TRC_SSL, "SSLContextManager::_getNewX509Store()");
246
247 //
248 // reload certificates from the specified store
249 //
250 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
251 "Reloading certificates from the store: " + storePath);
252
|
253 david.dillard 1.5 X509_STORE* newStore = X509_STORE_new();
|
254 nag.boranna 1.1
255 //
|
256 david.dillard 1.5 // Check if there is a CA certificate file or directory specified.
|
257 nag.boranna 1.1 // If specified, load the certificates from the specified store path.
258 //
259 if (FileSystem::isDirectory(storePath))
260 {
|
261 david.dillard 1.5 X509_LOOKUP* storeLookup = X509_STORE_add_lookup(newStore,
262 X509_LOOKUP_hash_dir());
|
263 nag.boranna 1.1 if (storeLookup == NULL)
264 {
265 X509_STORE_free(newStore);
266
267 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
268 "Could not reload the trust or crl store.");
269
270 MessageLoaderParms parms(
|
271 kumpf 1.11 "Pegasus.Common.SSLContextManager."
272 "COULD_NOT_RELOAD_TRUST_OR_CRL_STORE",
273 "Could not reload the trust or crl store.");
|
274 nag.boranna 1.1 PEG_METHOD_EXIT();
275 throw SSLException(parms);
276 }
|
277 david.dillard 1.5 X509_LOOKUP_add_dir(storeLookup,
278 storePath.getCString(), X509_FILETYPE_PEM);
|
279 nag.boranna 1.1 }
280 else if (FileSystem::exists(storePath))
281 {
|
282 kumpf 1.11 X509_LOOKUP* storeLookup = X509_STORE_add_lookup(
283 newStore, X509_LOOKUP_file());
|
284 nag.boranna 1.1 if (storeLookup == NULL)
285 {
286 X509_STORE_free(newStore);
287
288 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
289 "Could not reload the trust or crl store.");
290
291 MessageLoaderParms parms(
|
292 kumpf 1.11 "Pegasus.Common.SSLContextManager."
293 "COULD_NOT_RELOAD_TRUST_OR_CRL_STORE",
294 "Could not reload the trust or crl store.");
|
295 nag.boranna 1.1 PEG_METHOD_EXIT();
296 throw SSLException(parms);
297 }
|
298 david.dillard 1.5 X509_LOOKUP_load_file(storeLookup,
299 storePath.getCString(), X509_FILETYPE_PEM);
|
300 nag.boranna 1.1 }
301 else
302 {
303 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
|
304 kumpf 1.11 "Could not reload the trust or crl store, configured store "
305 "not found.");
|
306 nag.boranna 1.1
307 MessageLoaderParms parms(
|
308 kumpf 1.11 "Pegasus.Common.SSLContextManager."
309 "CONFIGURED_TRUST_OR_CRL_STORE_NOT_FOUND",
310 "Could not reload the trust or crl store, configured store "
311 "not found.");
|
312 nag.boranna 1.1 PEG_METHOD_EXIT();
313 throw SSLException(parms);
314 }
315
316 PEG_METHOD_EXIT();
317 return newStore;
318 }
319
320 #else //#ifdef PEGASUS_HAS_SSL
321
|
322 sushma.fernandes 1.10 void SSLContextManager::reloadTrustStore() { }
|
323 nag.boranna 1.1
324 void SSLContextManager::reloadCRLStore() { }
325
|
326 kumpf 1.11 X509_STORE* SSLContextManager::_getNewX509Store(
327 const String& storePath)
328 {
329 return NULL;
330 }
|
331 nag.boranna 1.1
332 #endif //#ifdef PEGASUS_HAS_SSL
333
334 /**
335 Get a pointer to the sslContext object.
336 */
|
337 sushma.fernandes 1.10 SSLContext* SSLContextManager::getSSLContext() const
|
338 nag.boranna 1.1 {
|
339 sushma.fernandes 1.10 return _sslContext;
|
340 nag.boranna 1.1 }
341
342 /**
343 Get a pointer to the sslContextObjectLock.
344 */
345 ReadWriteSem* SSLContextManager::getSSLContextObjectLock()
346 {
347 return &_sslContextObjectLock;
348 }
349
350 PEGASUS_NAMESPACE_END
|