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