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