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