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