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