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.58 // Call the user-specified application callback if it is specified. If it is null, return OpenSSL's verification code.
|
447 h.sterling 1.28 // 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 h.sterling 1.58 if (exData->_rep->verifyCertificateCallback == NULL)
|
452 kumpf 1.1 {
|
453 h.sterling 1.58 return preVerifyOk;
|
454 h.sterling 1.28
|
455 h.sterling 1.58 } else
|
456 kumpf 1.16 {
|
457 h.sterling 1.58 if (exData->_rep->verifyCertificateCallback(*exData->_rep->peerCertificate))
458 {
459 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
460 "--> SSL: _rep->verifyCertificateCallback() returned X509_V_OK");
461
462 PEG_METHOD_EXIT();
463 return 1;
464 }
465 else // verification failed, handshake will be immediately terminated
466 {
467 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
468 "--> SSL: _rep->verifyCertificateCallback() returned error %d", exData->_rep->peerCertificate->getErrorCode());
469
470 PEG_METHOD_EXIT();
471 return 0;
472 }
|
473 kumpf 1.1 }
474 }
475
|
476 kumpf 1.15 //
|
477 david.dillard 1.38 // Callback function called by OpenSSL. This request is merely forwarded to the static
478 // function SSLCallback::callback(). The SSLCallback class is a friend class of the
479 // Pegasus SSL related classes needed to complete the callback.
480 //
481 extern "C" int prepareForCallback(int preVerifyOk, X509_STORE_CTX *ctx)
482 {
|
483 h.sterling 1.40 return SSLCallback::verificationCallback(preVerifyOk, ctx);
|
484 david.dillard 1.38 }
485
486 //
|
487 kumpf 1.15 // Implement OpenSSL locking callback.
488 //
|
489 h.sterling 1.47 void pegasus_locking_callback( int mode,
490 int type,
491 const char* file,
492 int line)
|
493 kumpf 1.15 {
494 // Check whether the mode is lock or unlock.
495
496 if ( mode & CRYPTO_LOCK )
497 {
|
498 h.sterling 1.26 /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,
499 "Now locking for %d", pegasus_thread_self());*/
|
500 kumpf 1.15 SSLContextRep::_sslLocks[type].lock( pegasus_thread_self() );
501 }
502 else
503 {
|
504 h.sterling 1.26 /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,
505 "Now unlocking for %d", pegasus_thread_self());*/
|
506 kumpf 1.15 SSLContextRep::_sslLocks[type].unlock( );
507 }
508 }
509
510 //
511 // Initialize OpenSSL Locking and id callbacks.
512 //
513 void SSLContextRep::init_ssl()
514 {
515 // Allocate Memory for _sslLocks. SSL locks needs to be able to handle
516 // up to CRYPTO_num_locks() different mutex locks.
517 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
518 "Initialized SSL callback.");
519
|
520 chuck 1.53 #ifdef PEGASUS_OS_OS400
521 // Load the OpenSSL library and get the exports
522 SSL_OS400_Init();
523 #endif
524
|
525 kumpf 1.15 _sslLocks= new Mutex[CRYPTO_num_locks()];
526
527 // Set the ID callback. The ID callback returns a thread ID.
528
|
529 david.dillard 1.38 CRYPTO_set_id_callback((CRYPTO_SET_ID_CALLBACK) pegasus_thread_self);
|
530 kumpf 1.15
531 // Set the locking callback to pegasus_locking_callback.
532
|
533 david.dillard 1.38 CRYPTO_set_locking_callback((CRYPTO_SET_LOCKING_CALLBACK) pegasus_locking_callback);
|
534 kumpf 1.15
535 }
536
537 // Free OpenSSL Locking and id callbacks.
538 void SSLContextRep::free_ssl()
539 {
540 // Cleanup _sslLocks and set locking & id callback to NULL.
541
542 CRYPTO_set_locking_callback(NULL);
543 CRYPTO_set_id_callback (NULL);
544 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
545 "Freed SSL callback.");
546
547 delete []_sslLocks;
548 }
549
|
550 kumpf 1.1
551 //
552 // SSL context area
553 //
554 // For the OSs that don't have /dev/random device file,
555 // must enable PEGASUS_SSL_RANDOMFILE flag.
556 //
|
557 h.sterling 1.26 SSLContextRep::SSLContextRep(
558 const String& trustStore,
559 const String& certPath,
560 const String& keyPath,
|
561 h.sterling 1.47 const String& crlPath,
|
562 h.sterling 1.26 SSLCertificateVerifyFunction* verifyCert,
563 const String& randomFile)
564 {
565 PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
566
567 _trustStore = trustStore;
568
569 _certPath = certPath;
570
571 _keyPath = keyPath;
572
|
573 h.sterling 1.40 _crlPath = crlPath;
|
574 h.sterling 1.26
|
575 h.sterling 1.47 _crlStore = NULL;
|
576 h.sterling 1.26
|
577 h.sterling 1.40 _certificateVerifyFunction = verifyCert;
|
578 h.sterling 1.26
|
579 h.sterling 1.28 //
|
580 h.sterling 1.26 // If a truststore and/or peer verification function is specified, enable peer verification
|
581 h.sterling 1.28 //
|
582 h.sterling 1.26 if (trustStore != String::EMPTY || verifyCert != NULL)
583 {
584 _verifyPeer = true;
585 }
586 else
587 {
588 _verifyPeer = false;
589 }
|
590 kumpf 1.15
|
591 h.sterling 1.28 //
|
592 kumpf 1.15 // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.
|
593 h.sterling 1.28 //
|
594 a.arora 1.35 {
595 AutoMutex autoMut(_countRepMutex);
|
596 kumpf 1.15
|
597 a.arora 1.35 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
|
598 kumpf 1.15 "Value of Countrep in constructor %d", _countRep);
599 if ( _countRep == 0 )
600 {
601 init_ssl();
602
603 //
604 // load SSL library
605 //
606 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
607 "Before calling SSL_load_error_strings %d", pegasus_thread_self());
608
609 SSL_load_error_strings();
610
611 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
612 "After calling SSL_load_error_strings %d", pegasus_thread_self());
613
614 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
615 "Before calling SSL_library_init %d", pegasus_thread_self());
616
617 SSL_library_init();
618
619 kumpf 1.15 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
620 "After calling SSL_library_init %d", pegasus_thread_self());
621
622 }
|
623 h.sterling 1.40
|
624 kumpf 1.15 _countRep++;
|
625 a.arora 1.35 } // mutex unlocks here
|
626 kumpf 1.1
|
627 kumpf 1.14 _randomInit(randomFile);
|
628 kumpf 1.1
|
629 kumpf 1.9 _sslContext = _makeSSLContext();
630
631 PEG_METHOD_EXIT();
632 }
633
634 SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep)
635 {
636 PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()");
637
|
638 h.sterling 1.26 _trustStore = sslContextRep._trustStore;
|
639 kumpf 1.9 _certPath = sslContextRep._certPath;
|
640 kumpf 1.16 _keyPath = sslContextRep._keyPath;
|
641 h.sterling 1.47 _crlPath = sslContextRep._crlPath;
|
642 h.sterling 1.50 _crlStore = sslContextRep._crlStore;
|
643 h.sterling 1.26 _verifyPeer = sslContextRep._verifyPeer;
|
644 h.sterling 1.28 _certificateVerifyFunction = sslContextRep._certificateVerifyFunction;
|
645 kumpf 1.9 _randomFile = sslContextRep._randomFile;
|
646 kumpf 1.15
647 // Initialiaze SSL callbacks and increment the SSLContextRep object _counter.
648 {
|
649 a.arora 1.35 AutoMutex autoMut(_countRepMutex);
|
650 kumpf 1.15 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
651 "Value of Countrep in copy constructor %d", _countRep);
652 if ( _countRep == 0 )
653 {
654 init_ssl();
655 }
|
656 h.sterling 1.40
|
657 kumpf 1.15 _countRep++;
|
658 a.arora 1.35 } // mutex unlocks here
|
659 kumpf 1.15
|
660 kumpf 1.9 _sslContext = _makeSSLContext();
661 PEG_METHOD_EXIT();
662 }
|
663 kumpf 1.11
|
664 kumpf 1.9 //
665 // Destructor
666 //
667
668 SSLContextRep::~SSLContextRep()
669 {
670 PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::~SSLContextRep()");
671
672 SSL_CTX_free(_sslContext);
673
|
674 kumpf 1.15 // Decrement the SSLContextRep object _counter.
675 {
|
676 a.arora 1.35 AutoMutex autoMut(_countRepMutex);
677 _countRep--;
678 // Free SSL locks if no instances of SSLContextRep exist.
679
|
680 kumpf 1.15 Tracer::trace(TRC_SSL, Tracer::LEVEL4,
681 "Value of Countrep in destructor %d", _countRep);
682 if ( _countRep == 0 )
683 {
684 free_ssl();
685 }
|
686 alagaraja 1.36
|
687 kumpf 1.15 }
|
688 kumpf 1.9 PEG_METHOD_EXIT();
689 }
690
|
691 kumpf 1.14 //
692 // initialize OpenSSL's PRNG
693 //
694 void SSLContextRep::_randomInit(const String& randomFile)
695 {
696 PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_randomInit()");
697
698 Boolean ret;
699 int retVal = 0;
700
701 #ifdef PEGASUS_SSL_RANDOMFILE
702 if ( RAND_status() == 0 )
703 {
704 //
705 // Initialise OpenSSL random number generator.
706 //
707 if ( randomFile == String::EMPTY )
708 {
709 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
710 "Random seed file is required.");
711 PEG_METHOD_EXIT();
|
712 humberto 1.18 //l10n
713 //throw( SSLException("Random seed file required"));
714 MessageLoaderParms parms("Common.SSLContext.RANDOM_SEED_FILE_REQUIRED",
|
715 h.sterling 1.47 "Random seed file required");
716 throw SSLException(parms);
|
717 kumpf 1.14 }
718
719 //
720 // Try the given random seed file
721 //
722 ret = FileSystem::exists(randomFile);
723 if( ret )
724 {
|
725 kumpf 1.15 retVal = RAND_load_file(randomFile.getCString(), -1);
|
726 kumpf 1.14 if ( retVal < 0 )
727 {
728 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
729 "Not enough seed data in seed file: " + randomFile);
730 PEG_METHOD_EXIT();
|
731 humberto 1.18 //l10n
|
732 h.sterling 1.47 // do not put in $0 in default message, but pass in filename for bundle message
|
733 humberto 1.18 //throw( SSLException("Not enough seed data in random seed file."));
734 MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
|
735 h.sterling 1.47 "Not enough seed data in random seed file.",
736 randomFile);
737 throw SSLException(parms);
|
738 kumpf 1.14 }
739 }
|
740 kumpf 1.16 else
741 {
742 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
743 "seed file - " + randomFile + " does not exist.");
744 PEG_METHOD_EXIT();
|
745 humberto 1.18 //l10n
746 //throw( SSLException("Seed file '" + randomFile + "' does not exist."));
747 MessageLoaderParms parms("Common.SSLContext.SEED_FILE_DOES_NOT_EXIST",
|
748 h.sterling 1.47 "Seed file '$0' does not exist.",
749 randomFile);
|
750 tony 1.24 throw SSLException(parms);
|
751 kumpf 1.16 }
|
752 kumpf 1.14
753 if ( RAND_status() == 0 )
754 {
755 //
756 // Try to do more seeding
757 //
758 long seedNumber;
|
759 tony 1.24 #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC)
760 srand((unsigned int)time(NULL)); // Initialize
761 seedNumber = rand();
762 #else
|
763 kumpf 1.14 srandom((unsigned int)time(NULL)); // Initialize
764 seedNumber = random();
|
765 tony 1.24 #endif
|
766 kumpf 1.14 RAND_seed((unsigned char *) &seedNumber, sizeof(seedNumber));
767
768 int seedRet = RAND_status();
769 if ( seedRet == 0 )
770 {
771 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
|
772 kumpf 1.15 "Not enough seed data in random seed file, RAND_status = " +
773 seedRet);
|
774 kumpf 1.14 PEG_METHOD_EXIT();
|
775 humberto 1.22 //l10n 485
|
776 h.sterling 1.47 // do not put in $0 in default message, but pass in filename for bundle message
|
777 humberto 1.18 //throw( SSLException("Not enough seed data in random seed file."));
778 MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE",
|
779 h.sterling 1.47 "Not enough seed data in random seed file.",
780 randomFile);
781 throw SSLException(parms);
|
782 kumpf 1.14 }
783 }
784 }
785 #endif /* PEGASUS_SSL_RANDOMFILE */
786
787 int seedRet = RAND_status();
788 if ( seedRet == 0 )
789 {
790 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
791 "Not enough seed data , RAND_status = " + seedRet );
792 PEG_METHOD_EXIT();
|
793 humberto 1.18 //l10n
794 //throw( SSLException("Not enough seed data."));
795 MessageLoaderParms parms("Common.SSLContext.NOT_ENOUGH_SEED_DATA",
|
796 h.sterling 1.47 "Not enough seed data.");
|
797 tony 1.24 throw SSLException(parms);
|
798 kumpf 1.14 }
799
800 PEG_METHOD_EXIT();
801 }
802
|
803 kumpf 1.9 SSL_CTX * SSLContextRep::_makeSSLContext()
804 {
805 PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()");
806
807 SSL_CTX * sslContext = 0;
808
|
809 kumpf 1.1 //
810 // create SSL Context Area
811 //
812
|
813 kumpf 1.9 if (!( sslContext = SSL_CTX_new(SSLv23_method()) ))
|
814 kumpf 1.3 {
815 PEG_METHOD_EXIT();
|
816 humberto 1.18 //l10n
817 //throw( SSLException("Could not get SSL CTX"));
818 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET",
|
819 h.sterling 1.47 "Could not get SSL CTX");
|
820 tony 1.24 throw SSLException(parms);
|
821 kumpf 1.3 }
822
|
823 kumpf 1.14 #ifdef PEGASUS_SSL_WEAKENCRYPTION
|
824 humberto 1.18 if (!(SSL_CTX_set_cipher_list(sslContext, SSL_TXT_EXP40))){
|
825 h.sterling 1.47 //l10n
|
826 humberto 1.18 //throw( SSLException("Could not set the cipher list"));
827 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_SET_CIPHER_LIST",
|
828 h.sterling 1.47 "Could not set the cipher list");
|
829 tony 1.24 throw SSLException(parms);
|
830 humberto 1.18 }
|
831 kumpf 1.3 #endif
|
832 kumpf 1.1
833 //
834 // set overall SSL Context flags
835 //
836
|
837 kumpf 1.9 SSL_CTX_set_quiet_shutdown(sslContext, 1);
838 SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);
|
839 kumpf 1.14 SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
|
840 kumpf 1.1
|
841 h.sterling 1.50 int options = SSL_OP_ALL;
|
842 h.sterling 1.49 #ifndef PEGASUS_ENABLE_SSLV2 //SSLv2 is disabled by default
|
843 h.sterling 1.50 options |= SSL_OP_NO_SSLv2;
|
844 h.sterling 1.49 #endif
|
845 h.sterling 1.50 SSL_CTX_set_options(sslContext, options);
|
846 h.sterling 1.49
|
847 h.sterling 1.26 if (_verifyPeer)
|
848 kumpf 1.1 {
|
849 h.sterling 1.26 //ATTN: We might still need a flag to specify SSL_VERIFY_FAIL_IF_NO_PEER_CERT
|
850 kumpf 1.27 // If SSL_VERIFY_FAIL_IF_NO_PEER_CERT is ON, SSL will immediately be terminated
851 // if the client sends no certificate or sends an untrusted certificate. The
852 // callback function is not called in this case; the handshake is simply terminated.
|
853 h.sterling 1.26 // This value has NO effect in from a client perspective
854
|
855 h.sterling 1.28 if (_certificateVerifyFunction != NULL)
|
856 h.sterling 1.26 {
|
857 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
858 "---> SSL: certificate verification callback specified");
859 SSL_CTX_set_verify(sslContext,
860 SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, prepareForCallback);
861 }
|
862 h.sterling 1.26 else
863 {
|
864 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: Trust Store specified");
865 SSL_CTX_set_verify(sslContext,
866 SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
867 prepareForCallback);
|
868 h.sterling 1.26 }
|
869 kumpf 1.1 }
|
870 kumpf 1.14 else
871 {
|
872 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
873 "---> SSL: Trust Store and certificate verification callback are NOT specified");
874 SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
|
875 kumpf 1.14 }
|
876 kumpf 1.1
877 //
|
878 kumpf 1.27 // Check if there is CA certificate file or directory specified. If specified,
879 // and is not empty, load the certificates from the Trust store.
|
880 h.sterling 1.26 //
|
881 kumpf 1.27 if (_trustStore != String::EMPTY)
|
882 kumpf 1.14 {
883 //
|
884 h.sterling 1.26 // The truststore may be a single file of CA certificates OR
885 // a directory containing multiple CA certificates.
886 // Check which one it is, and call the load_verify_locations function
887 // with the appropriate parameter. Note: It is possible to have both
|
888 kumpf 1.27 // options, in which case the CA file takes precedence over the CA path.
|
889 h.sterling 1.26 // However, since there is currently only one trust parameter to the
890 // SSL functions, only allow one choice here.
|
891 kumpf 1.27 //
892 if (FileSystem::isDirectory(_trustStore))
893 {
894 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
895 "---> SSL: Truststore is a directory");
896 //
897 // load certificates from the trust store
898 //
899 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
900 "---> SSL: Loading certificates from the trust store: " + _trustStore);
901
902 if ((!SSL_CTX_load_verify_locations(sslContext, NULL, _trustStore.getCString())) ||
903 (!SSL_CTX_set_default_verify_paths(sslContext)))
904 {
905 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
906 "---> SSL: Could not load certificates from the trust store: " + _trustStore);
907 //l10n
908 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
909 "Could not load certificates in to trust store.");
910 PEG_METHOD_EXIT();
911 throw SSLException(parms);
912 kumpf 1.27 }
|
913 h.sterling 1.26
|
914 kumpf 1.27 }
915 else if (FileSystem::exists(_trustStore))
|
916 h.sterling 1.26 {
|
917 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
918 "---> SSL: Truststore is a file");
919 //
920 // Get size of the trust store file:
921 //
922 Uint32 fileSize = 0;
|
923 h.sterling 1.26
|
924 kumpf 1.27 FileSystem::getFileSize(_trustStore, fileSize);
|
925 h.sterling 1.26
|
926 kumpf 1.27 if (fileSize > 0)
927 {
928 //
929 // load certificates from the trust store
930 //
931 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
932 "---> SSL: Loading certificates from the trust store: " + _trustStore);
933
934 if ((!SSL_CTX_load_verify_locations(sslContext, _trustStore.getCString(), NULL)) ||
935 (!SSL_CTX_set_default_verify_paths(sslContext)))
936 {
937 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
938 "---> SSL: Could not load certificates from the trust store: " + _trustStore);
939 //l10n
940 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CERTIFICATES",
941 "Could not load certificates in to trust store.");
942 PEG_METHOD_EXIT();
943 throw SSLException(parms);
944 }
945 }
946 else
947 kumpf 1.27 {
948 //
949 // no certificates found in the trust store
950 //
951 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
952 "---> SSL: No certificates to load from the trust store: " + _trustStore);
953 }
|
954 kumpf 1.14 }
955 }
956
|
957 h.sterling 1.47 if (_crlPath != String::EMPTY)
958 {
|
959 h.sterling 1.40 //need to save this -- can we make it static since there's only one CRL for cimserver?
|
960 h.sterling 1.47 X509_LOOKUP* pLookup;
961
962 _crlStore = X509_STORE_new();
|
963 h.sterling 1.40
|
964 h.sterling 1.47 //the validity of the crlstore was checked in ConfigManager during server startup
965 if (FileSystem::isDirectory(_crlPath))
|
966 h.sterling 1.40 {
967 Tracer::trace(TRC_SSL, Tracer::LEVEL3,
|
968 h.sterling 1.47 "---> SSL: CRL store is a directory in %s", (const char*)_crlPath.getCString());
|
969 h.sterling 1.40
970 if ((pLookup = X509_STORE_add_lookup(_crlStore, X509_LOOKUP_hash_dir())) == NULL)
|
971 h.sterling 1.47 {
972 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CRLS",
973 "Could not load certificate revocation list.");
974 X509_STORE_free(_crlStore);
|
975 h.sterling 1.40 PEG_METHOD_EXIT();
976 throw SSLException(parms);
|
977 h.sterling 1.47 }
|
978 h.sterling 1.40
979 X509_LOOKUP_add_dir(pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
980
981 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
982 "---> SSL: Successfully configured CRL directory");
983
|
984 h.sterling 1.47 } else
985 {
|
986 h.sterling 1.40 Tracer::trace(TRC_SSL, Tracer::LEVEL3,
|
987 h.sterling 1.47 "---> SSL: CRL store is the file %s", (const char*)_crlPath.getCString());
|
988 h.sterling 1.40
989 if ((pLookup = X509_STORE_add_lookup(_crlStore, X509_LOOKUP_file())) == NULL)
|
990 h.sterling 1.47 {
|
991 h.sterling 1.40 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_LOAD_CRLS",
|
992 h.sterling 1.47 "Could not load certificate revocation list.");
993 X509_STORE_free(_crlStore);
|
994 h.sterling 1.40 PEG_METHOD_EXIT();
995 throw SSLException(parms);
|
996 h.sterling 1.47 }
|
997 h.sterling 1.40
|
998 h.sterling 1.47 X509_LOOKUP_load_file(pLookup, (const char*)_crlPath.getCString(), X509_FILETYPE_PEM);
999
1000 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3,
1001 "---> SSL: Successfully configured CRL file");
1002 }
1003 }
|
1004 h.sterling 1.40
|
1005 kumpf 1.17 Boolean keyLoaded = false;
|
1006 kumpf 1.27
|
1007 kumpf 1.1 //
|
1008 kumpf 1.16 // Check if there is a certificate file (file containing server
1009 // certificate) specified. If specified, validate and load the
1010 // certificate.
|
1011 kumpf 1.14 //
|
1012 kumpf 1.27 if (_certPath != String::EMPTY)
|
1013 kumpf 1.14 {
1014 //
1015 // load the specified server certificates
1016 //
|
1017 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1018 "---> SSL: Loading server certificate from: " + _certPath);
|
1019 kumpf 1.1
|
1020 kumpf 1.27 if (SSL_CTX_use_certificate_file(sslContext,
1021 _certPath.getCString(), SSL_FILETYPE_PEM) <=0)
|
1022 kumpf 1.14 {
|
1023 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1024 "---> SSL: No server certificate found in " + _certPath);
|
1025 humberto 1.18 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_SERVER_CERTIFICATE",
|
1026 h.sterling 1.47 "Could not get server certificate.");
|
1027 kumpf 1.27 PEG_METHOD_EXIT();
|
1028 tony 1.24 throw SSLException(parms);
|
1029 kumpf 1.14 }
|
1030 kumpf 1.17
|
1031 kumpf 1.16 //
1032 // If there is no key file (file containing server
|
1033 h.sterling 1.26 // private key) specified, then try loading the key from the certificate file.
|
1034 kumpf 1.27 // As of 2.4, if a keyfile is specified, its location is verified during server
1035 // startup and will throw an error if the path is invalid.
|
1036 kumpf 1.16 //
|
1037 kumpf 1.27 if (_keyPath == String::EMPTY)
|
1038 kumpf 1.16 {
|
1039 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1040 "---> SSL: loading private key from: " + _certPath);
|
1041 kumpf 1.16 //
1042 // load the private key and check for validity
1043 //
|
1044 kumpf 1.27 if (!_verifyPrivateKey(sslContext, _certPath))
|
1045 kumpf 1.16 {
|
1046 humberto 1.18 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
|
1047 h.sterling 1.47 "Could not get private key.");
|
1048 kumpf 1.27 PEG_METHOD_EXIT();
|
1049 h.sterling 1.47 throw SSLException(parms);
|
1050 kumpf 1.16 }
|
1051 kumpf 1.17 keyLoaded = true;
|
1052 kumpf 1.16 }
1053 }
|
1054 kumpf 1.14
|
1055 kumpf 1.16 //
|
1056 kumpf 1.17 // Check if there is a key file (file containing server
1057 // private key) specified and the key was not already loaded.
1058 // If specified, validate and load the key.
|
1059 kumpf 1.16 //
|
1060 kumpf 1.27 if (_keyPath != String::EMPTY && !keyLoaded)
|
1061 kumpf 1.16 {
|
1062 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
1063 "---> SSL: loading private key from: " + _keyPath);
|
1064 kumpf 1.14 //
1065 // load given private key and check for validity
1066 //
|
1067 kumpf 1.27 if (!_verifyPrivateKey(sslContext, _keyPath))
|
1068 kumpf 1.14 {
|
1069 humberto 1.18 MessageLoaderParms parms("Common.SSLContext.COULD_NOT_GET_PRIVATE_KEY",
|
1070 h.sterling 1.47 "Could not get private key.");
|
1071 kumpf 1.27 PEG_METHOD_EXIT();
|
1072 tony 1.24 throw SSLException(parms);
|
1073 kumpf 1.14 }
|
1074 kumpf 1.17 keyLoaded = true;
|
1075 kumpf 1.14 }
1076
1077 PEG_METHOD_EXIT();
1078 return sslContext;
1079 }
1080
|
1081 kumpf 1.27 Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx, const String& keyPath)
|
1082 kumpf 1.14 {
1083 PEG_METHOD_ENTER(TRC_SSL, "_verifyPrivateKey()");
1084
|
1085 kumpf 1.27 if (SSL_CTX_use_PrivateKey_file(ctx, keyPath.getCString(), SSL_FILETYPE_PEM) <= 0)
|
1086 kumpf 1.3 {
|
1087 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
|
1088 kumpf 1.16 "---> SSL: no private key found in " + String(keyPath));
|
1089 kumpf 1.3 PEG_METHOD_EXIT();
|
1090 kumpf 1.14 return false;
1091 }
1092
1093 if (!SSL_CTX_check_private_key(ctx))
1094 {
|
1095 kumpf 1.27 PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2,
|
1096 kumpf 1.14 "---> SSL: Private and public key do not match");
1097 PEG_METHOD_EXIT();
1098 return false;
|
1099 kumpf 1.3 }
|
1100 kumpf 1.1
|
1101 kumpf 1.3 PEG_METHOD_EXIT();
|
1102 kumpf 1.14 return true;
|
1103 kumpf 1.1 }
1104
1105 SSL_CTX * SSLContextRep::getContext() const
1106 {
|
1107 kumpf 1.9 return _sslContext;
|
1108 kumpf 1.1 }
|
1109 h.sterling 1.26
1110 String SSLContextRep::getTrustStore() const
1111 {
1112 return _trustStore;
1113 }
1114
1115 String SSLContextRep::getCertPath() const
1116 {
1117 return _certPath;
1118 }
1119
1120 String SSLContextRep::getKeyPath() const
1121 {
1122 return _keyPath;
1123 }
1124
|
1125 dave.sudlik 1.55 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1126 String SSLContextRep::getTrustStoreUserName() const
1127 {
1128 return String::EMPTY;
1129 }
1130 #endif
1131
|
1132 h.sterling 1.40 String SSLContextRep::getCRLPath() const
|
1133 h.sterling 1.26 {
|
1134 h.sterling 1.40 return _crlPath;
|
1135 h.sterling 1.26 }
1136
|
1137 h.sterling 1.40 X509_STORE* SSLContextRep::getCRLStore() const
|
1138 h.sterling 1.26 {
|
1139 h.sterling 1.40 return _crlStore;
|
1140 h.sterling 1.26 }
1141
|
1142 h.sterling 1.50 void SSLContextRep::setCRLStore(X509_STORE* store)
1143 {
1144 _crlStore = store;
1145 }
1146
|
1147 h.sterling 1.40 Boolean SSLContextRep::isPeerVerificationEnabled() const
|
1148 h.sterling 1.26 {
|
1149 h.sterling 1.40 return _verifyPeer;
|
1150 h.sterling 1.26 }
1151
|
1152 h.sterling 1.28 SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const
1153 {
1154 return _certificateVerifyFunction;
1155 }
1156
|
1157 kumpf 1.1 #else
1158
1159 //
|
1160 kumpf 1.9 // these definitions are used if ssl is not available
|
1161 kumpf 1.1 //
1162
|
1163 h.sterling 1.26 SSLContextRep::SSLContextRep(const String& trustStore,
|
1164 kumpf 1.16 const String& certPath,
1165 const String& keyPath,
|
1166 h.sterling 1.41 const String& crlPath,
|
1167 kumpf 1.9 SSLCertificateVerifyFunction* verifyCert,
|
1168 h.sterling 1.41 const String& randomFile)
1169 {}
|
1170 h.sterling 1.26
|
1171 kumpf 1.9 SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep) {}
1172
|
1173 kumpf 1.1 SSLContextRep::~SSLContextRep() {}
1174
|
1175 kumpf 1.9 SSL_CTX * SSLContextRep::_makeSSLContext() { return 0; }
1176
|
1177 kumpf 1.27 Boolean SSLContextRep::_verifyPrivateKey(SSL_CTX *ctx,
1178 const String& keyPath) { return false; }
|
1179 kumpf 1.14
|
1180 kumpf 1.9 SSL_CTX * SSLContextRep::getContext() const { return 0; }
|
1181 kumpf 1.15
|
1182 h.sterling 1.26 String SSLContextRep::getTrustStore() const { return String::EMPTY; }
1183
1184 String SSLContextRep::getCertPath() const { return String::EMPTY; }
1185
1186 String SSLContextRep::getKeyPath() const { return String::EMPTY; }
1187
|
1188 dave.sudlik 1.55 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1189 String SSLContextRep::getTrustStoreUserName() const { return String::EMPTY; }
1190 #endif
1191
|
1192 h.sterling 1.40 String SSLContextRep::getCRLPath() const { return String::EMPTY; }
|
1193 h.sterling 1.26
|
1194 h.sterling 1.40 X509_STORE* SSLContextRep::getCRLStore() const { return NULL; }
|
1195 h.sterling 1.26
|
1196 h.sterling 1.50 void SSLContextRep::setCRLStore(X509_STORE* store) { }
1197
|
1198 h.sterling 1.40 Boolean SSLContextRep::isPeerVerificationEnabled() const { return false; }
|
1199 h.sterling 1.26
|
1200 h.sterling 1.28 SSLCertificateVerifyFunction* SSLContextRep::getSSLCertificateVerifyFunction() const { return NULL; }
1201
|
1202 kumpf 1.15 void SSLContextRep::init_ssl() {}
1203
1204 void SSLContextRep::free_ssl() {}
|
1205 kumpf 1.1
1206 #endif // end of PEGASUS_HAS_SSL
1207
1208 ///////////////////////////////////////////////////////////////////////////////
1209 //
1210 // SSLContext
1211 //
1212 ///////////////////////////////////////////////////////////////////////////////
1213
1214
1215 SSLContext::SSLContext(
|
1216 h.sterling 1.26 const String& trustStore,
|
1217 kumpf 1.9 SSLCertificateVerifyFunction* verifyCert,
|
1218 kumpf 1.13 const String& randomFile)
1219 {
|
1220 h.sterling 1.40 _rep = new SSLContextRep(trustStore, String::EMPTY, String::EMPTY, String::EMPTY, verifyCert, randomFile);
|
1221 kumpf 1.13 }
1222
|
1223 kumpf 1.14 SSLContext::SSLContext(
|
1224 h.sterling 1.26 const String& trustStore,
|
1225 kumpf 1.14 const String& certPath,
|
1226 kumpf 1.16 const String& keyPath,
|
1227 kumpf 1.14 SSLCertificateVerifyFunction* verifyCert,
1228 const String& randomFile)
1229 {
|
1230 h.sterling 1.40 _rep = new SSLContextRep(trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
|
1231 h.sterling 1.30 }
1232
|
1233 h.sterling 1.40 //PEP187
|
1234 h.sterling 1.26 SSLContext::SSLContext(
1235 const String& trustStore,
1236 const String& certPath,
1237 const String& keyPath,
|
1238 h.sterling 1.47 const String& crlPath,
|
1239 h.sterling 1.26 SSLCertificateVerifyFunction* verifyCert,
1240 const String& randomFile)
1241 {
|
1242 h.sterling 1.40 _rep = new SSLContextRep(trustStore, certPath, keyPath, crlPath, verifyCert, randomFile);
|
1243 kumpf 1.14 }
1244
|
1245 dave.sudlik 1.55 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1246 SSLContext::SSLContext(
1247 const String& trustStore,
1248 const String& certPath,
1249 const String& keyPath,
1250 SSLCertificateVerifyFunction* verifyCert,
1251 String trustStoreUserName,
1252 const String& randomFile)
1253 {
1254 _rep = new SSLContextRep(trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
1255 }
1256 #endif
1257
|
1258 kumpf 1.9 SSLContext::SSLContext(const SSLContext& sslContext)
1259 {
1260 _rep = new SSLContextRep(*sslContext._rep);
|
1261 kumpf 1.12 }
1262
1263 // Dummy constructor made private to disallow default construction
1264 SSLContext::SSLContext()
1265 {
|
1266 kumpf 1.9 }
1267
|
1268 kumpf 1.1 SSLContext::~SSLContext()
1269 {
1270 delete _rep;
1271 }
1272
|
1273 h.sterling 1.26 String SSLContext::getTrustStore() const
1274 {
1275 return (_rep->getTrustStore());
1276 }
1277
1278 String SSLContext::getCertPath() const
1279 {
1280 return (_rep->getCertPath());
1281 }
1282
1283 String SSLContext::getKeyPath() const
1284 {
1285 return (_rep->getKeyPath());
1286 }
1287
|
1288 h.sterling 1.40 String SSLContext::getCRLPath() const
|
1289 h.sterling 1.26 {
|
1290 h.sterling 1.40 return (_rep->getCRLPath());
|
1291 h.sterling 1.26 }
1292
|
1293 h.sterling 1.40 X509_STORE* SSLContext::getCRLStore() const
|
1294 h.sterling 1.26 {
|
1295 h.sterling 1.40 return (_rep->getCRLStore());
|
1296 h.sterling 1.26 }
1297
|
1298 h.sterling 1.40 Boolean SSLContext::isPeerVerificationEnabled() const
|
1299 h.sterling 1.26 {
|
1300 h.sterling 1.40 return (_rep->isPeerVerificationEnabled());
|
1301 h.sterling 1.26 }
|
1302 kumpf 1.1
|
1303 dave.sudlik 1.55 #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
1304 String SSLContext::getTrustStoreUserName() const
1305 {
1306 return (_rep->getTrustStoreUserName());
1307 }
1308 #endif
1309
|
1310 h.sterling 1.28 SSLCertificateVerifyFunction* SSLContext::getSSLCertificateVerifyFunction() const
1311 {
1312 return (_rep->getSSLCertificateVerifyFunction());
1313 }
1314
|
1315 kumpf 1.1 ///////////////////////////////////////////////////////////////////////////////
1316 //
|
1317 kumpf 1.9 // SSLCertificateInfo
|
1318 kumpf 1.1 //
1319 ///////////////////////////////////////////////////////////////////////////////
|
1320 kumpf 1.16 //
1321 // Certificate validation result codes.
1322 //
1323 const int SSLCertificateInfo::V_OK = 0;
1324
1325 const int SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2;
1326 const int SSLCertificateInfo::V_ERR_UNABLE_TO_GET_CRL = 3;
1327 const int SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = 4;
1328 const int SSLCertificateInfo::V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = 5;
1329 const int SSLCertificateInfo::V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = 6;
1330 const int SSLCertificateInfo::V_ERR_CERT_SIGNATURE_FAILURE = 7;
1331 const int SSLCertificateInfo::V_ERR_CRL_SIGNATURE_FAILURE = 8;
1332 const int SSLCertificateInfo::V_ERR_CERT_NOT_YET_VALID = 9;
1333 const int SSLCertificateInfo::V_ERR_CERT_HAS_EXPIRED = 10;
1334 const int SSLCertificateInfo::V_ERR_CRL_NOT_YET_VALID = 11;
1335 const int SSLCertificateInfo::V_ERR_CRL_HAS_EXPIRED = 12;
1336 const int SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 13;
1337 const int SSLCertificateInfo::V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 14;
1338 const int SSLCertificateInfo::V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD = 15;
1339 const int SSLCertificateInfo::V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 16;
1340 const int SSLCertificateInfo::V_ERR_OUT_OF_MEM = 17;
1341 kumpf 1.16 const int SSLCertificateInfo::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18;
1342 const int SSLCertificateInfo::V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 19;
1343 const int SSLCertificateInfo::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 20;
1344 const int SSLCertificateInfo::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21;
1345 const int SSLCertificateInfo::V_ERR_CERT_CHAIN_TOO_LONG = 22;
1346 const int SSLCertificateInfo::V_ERR_CERT_REVOKED = 23;
1347 const int SSLCertificateInfo::V_ERR_INVALID_CA = 24;
1348 const int SSLCertificateInfo::V_ERR_PATH_LENGTH_EXCEEDED = 25;
1349 const int SSLCertificateInfo::V_ERR_INVALID_PURPOSE = 26;
1350 const int SSLCertificateInfo::V_ERR_CERT_UNTRUSTED = 27;
1351 const int SSLCertificateInfo::V_ERR_CERT_REJECTED = 28;
1352 const int SSLCertificateInfo::V_ERR_SUBJECT_ISSUER_MISMATCH = 29;
1353 const int SSLCertificateInfo::V_ERR_AKID_SKID_MISMATCH = 30;
1354 const int SSLCertificateInfo::V_ERR_AKID_ISSUER_SERIAL_MISMATCH = 31;
1355 const int SSLCertificateInfo::V_ERR_KEYUSAGE_NO_CERTSIGN = 32;
1356
1357 const int SSLCertificateInfo::V_ERR_APPLICATION_VERIFICATION = 50;
|
1358 kumpf 1.1
|
1359 kumpf 1.9 class SSLCertificateInfoRep
1360 {
1361 public:
|
1362 kumpf 1.16 String subjectName;
1363 String issuerName;
1364 Uint32 depth;
1365 Uint32 errorCode;
1366 Uint32 respCode;
1367 String errorString;
1368 Uint32 versionNumber;
1369 long serialNumber;
1370 CIMDateTime notBefore;
1371 CIMDateTime notAfter;
|
1372 kumpf 1.9 };
1373
1374
1375 SSLCertificateInfo::SSLCertificateInfo(
|
1376 kumpf 1.1 const String subjectName,
1377 const String issuerName,
1378 const int errorDepth,
|
1379 kumpf 1.14 const int errorCode,
1380 const int respCode)
|
1381 kumpf 1.1 {
|
1382 kumpf 1.9 _rep = new SSLCertificateInfoRep();
1383 _rep->subjectName = subjectName;
1384 _rep->issuerName = issuerName;
|
1385 kumpf 1.16 _rep->versionNumber = 0;
1386 _rep->serialNumber = 0;
|
1387 h.sterling 1.26 _rep->notBefore = CIMDateTime();
1388 _rep->notAfter = CIMDateTime();
|
1389 kumpf 1.16 _rep->depth = errorDepth;
|
1390 kumpf 1.9 _rep->errorCode = errorCode;
|
1391 kumpf 1.16 _rep->errorString = String::EMPTY;
1392 _rep->respCode = respCode;
1393 }
1394
1395 SSLCertificateInfo::SSLCertificateInfo(
1396 const String subjectName,
1397 const String issuerName,
1398 const Uint32 versionNumber,
1399 const long serialNumber,
1400 const CIMDateTime notBefore,
1401 const CIMDateTime notAfter,
1402 const Uint32 depth,
1403 const Uint32 errorCode,
1404 const String errorString,
1405 const Uint32 respCode)
1406 {
1407 _rep = new SSLCertificateInfoRep();
1408 _rep->subjectName = subjectName;
1409 _rep->issuerName = issuerName;
1410 _rep->versionNumber = versionNumber;
1411 _rep->serialNumber = serialNumber;
1412 kumpf 1.16 _rep->notBefore = notBefore;
1413 _rep->notAfter = notAfter;
1414 _rep->depth = depth;
1415 _rep->errorCode = errorCode;
1416 _rep->errorString = errorString;
|
1417 kumpf 1.14 _rep->respCode = respCode;
|
1418 kumpf 1.9 }
1419
1420 SSLCertificateInfo::SSLCertificateInfo(
1421 const SSLCertificateInfo& certificateInfo)
1422 {
1423 _rep = new SSLCertificateInfoRep();
1424 _rep->subjectName = certificateInfo._rep->subjectName;
1425 _rep->issuerName = certificateInfo._rep->issuerName;
|
1426 kumpf 1.16 _rep->versionNumber = certificateInfo._rep->versionNumber;
1427 _rep->serialNumber = certificateInfo._rep->serialNumber;
1428 _rep->notBefore = certificateInfo._rep->notBefore;
1429 _rep->notAfter = certificateInfo._rep->notAfter;
1430 _rep->depth = certificateInfo._rep->depth;
|
1431 kumpf 1.9 _rep->errorCode = certificateInfo._rep->errorCode;
|
1432 kumpf 1.16 _rep->errorString = certificateInfo._rep->errorString;
|
1433 kumpf 1.9 _rep->respCode = certificateInfo._rep->respCode;
|
1434 kumpf 1.11 }
1435
1436 // Dummy constructor made private to disallow default construction
1437 SSLCertificateInfo::SSLCertificateInfo()
1438 {
|
1439 kumpf 1.1 }
1440
|
1441 kumpf 1.9 SSLCertificateInfo::~SSLCertificateInfo()
|
1442 kumpf 1.1 {
|
1443 kumpf 1.9 delete _rep;
|
1444 kumpf 1.1 }
1445
|
1446 kumpf 1.9 String SSLCertificateInfo::getSubjectName() const
|
1447 kumpf 1.1 {
|
1448 kumpf 1.9 return (_rep->subjectName);
|
1449 kumpf 1.1 }
1450
|
1451 kumpf 1.9 String SSLCertificateInfo::getIssuerName() const
|
1452 kumpf 1.1 {
|
1453 kumpf 1.9 return (_rep->issuerName);
|
1454 kumpf 1.1 }
1455
|
1456 kumpf 1.16 Uint32 SSLCertificateInfo::getVersionNumber() const
1457 {
1458 return (_rep->versionNumber);
1459 }
1460
1461 long SSLCertificateInfo::getSerialNumber() const
|
1462 kumpf 1.1 {
|
1463 kumpf 1.16 return (_rep->serialNumber);
|
1464 kumpf 1.1 }
1465
|
1466 kumpf 1.16 CIMDateTime SSLCertificateInfo::getNotBefore() const
1467 {
1468 return (_rep->notBefore);
1469 }
1470
1471 CIMDateTime SSLCertificateInfo::getNotAfter() const
1472 {
1473 return (_rep->notAfter);
1474 }
1475
1476 Uint32 SSLCertificateInfo::getErrorDepth() const
1477 {
1478 return (_rep->depth);
1479 }
1480
1481 Uint32 SSLCertificateInfo::getErrorCode() const
|
1482 kumpf 1.1 {
|
1483 kumpf 1.9 return (_rep->errorCode);
|
1484 kumpf 1.14 }
1485
|
1486 kumpf 1.16 void SSLCertificateInfo::setErrorCode(const int errorCode)
1487 {
1488 _rep->errorCode = errorCode;
1489 }
1490
1491 String SSLCertificateInfo::getErrorString() const
1492 {
1493 return (_rep->errorString);
1494 }
1495
1496 Uint32 SSLCertificateInfo::getResponseCode() const
|
1497 kumpf 1.14 {
1498 return (_rep->respCode);
|
1499 kumpf 1.1 }
1500
|
1501 kumpf 1.9 void SSLCertificateInfo::setResponseCode(const int respCode)
|
1502 kumpf 1.1 {
|
1503 kumpf 1.9 _rep->respCode = respCode;
|
1504 kumpf 1.1 }
1505
|
1506 h.sterling 1.28 String SSLCertificateInfo::toString() const
1507 {
1508 char buf[1024];
1509
1510 String s;
1511
1512 s.append("Subject Name:\n\t");
1513 s.append(_rep->subjectName);
1514 s.append("\n");
1515
1516 s.append("Issuer Name:\n\t");
1517 s.append(_rep->issuerName);
1518 s.append("\n");
1519
1520 sprintf(buf, "Depth: %d\n", _rep->depth);
1521 s.append(buf);
1522
1523 sprintf(buf, "Error code: %d\n", _rep->errorCode);
1524 s.append(buf);
1525
1526 sprintf(buf, "Response (preverify) code: %d\n", _rep->respCode);
1527 h.sterling 1.28 s.append(buf);
1528
1529 s.append("Error string: ");
1530 s.append(_rep->errorString);
1531 s.append("\n");
1532
1533 sprintf(buf, "Version number: %d\n", _rep->versionNumber);
1534 s.append(buf);
1535
|
1536 h.sterling 1.57 sprintf(buf, "Serial number: %lu\n", _rep->serialNumber);
|
1537 h.sterling 1.28 s.append(buf);
1538
1539 s.append("Not before date: ");
1540 s.append((_rep->notBefore).toString());
1541 s.append("\n");
1542
1543 s.append("Not after date: ");
1544 s.append((_rep->notAfter).toString());
1545 s.append("\n");
1546
1547 return s;
1548 }
1549
|
1550 dave.sudlik 1.55 ///////////////////////////////////////////////////////////////////////////////
1551 //
1552 // SSLCallbackInfo
1553 //
1554 ///////////////////////////////////////////////////////////////////////////////
1555
1556 SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert)
1557 {
1558 _rep = new SSLCallbackInfoRep();
1559 _rep->verifyCertificateCallback = verifyCert;
1560 _rep->crlStore = NULL;
1561 _rep->peerCertificate = NULL;
1562 }
1563
|
1564 h.sterling 1.40 SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert, X509_STORE* crlStore)
|
1565 h.sterling 1.28 {
|
1566 dave.sudlik 1.55 _rep = new SSLCallbackInfoRep();
1567 _rep->verifyCertificateCallback = verifyCert;
1568 _rep->crlStore = crlStore;
1569 _rep->peerCertificate = NULL;
|
1570 h.sterling 1.28 }
1571
1572 SSLCallbackInfo::~SSLCallbackInfo()
1573 {
|
1574 dave.sudlik 1.55 if (_rep->peerCertificate)
|
1575 h.sterling 1.28 {
|
1576 dave.sudlik 1.55 delete _rep->peerCertificate;
|
1577 h.sterling 1.28 }
|
1578 dave.sudlik 1.55 delete _rep;
|
1579 h.sterling 1.28 }
1580
|
1581 kumpf 1.1 PEGASUS_NAMESPACE_END
1582
|