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