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