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