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