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