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