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
|
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
|