diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/IceSSL/Certificate.cpp | 158 | ||||
-rw-r--r-- | cpp/src/IceSSL/Instance.cpp | 15 | ||||
-rw-r--r-- | cpp/src/IceSSL/Instance.h | 12 | ||||
-rw-r--r-- | cpp/src/IceSSL/OpenSSLEngine.cpp | 4 | ||||
-rw-r--r-- | cpp/src/IceSSL/PluginI.cpp | 5 | ||||
-rw-r--r-- | cpp/src/IceSSL/PluginI.h | 11 | ||||
-rw-r--r-- | cpp/src/IceSSL/SSLEngine.h | 13 | ||||
-rw-r--r-- | cpp/src/IceSSL/SecureTransportEngine.cpp | 676 | ||||
-rw-r--r-- | cpp/src/IceSSL/SecureTransportTransceiverI.cpp | 138 | ||||
-rw-r--r-- | cpp/src/IceSSL/SecureTransportTransceiverI.h | 4 | ||||
-rw-r--r-- | cpp/src/IceSSL/TransceiverI.cpp | 3 | ||||
-rw-r--r-- | cpp/src/IceSSL/Util.cpp | 105 | ||||
-rw-r--r-- | cpp/src/IceSSL/Util.h | 7 |
13 files changed, 547 insertions, 604 deletions
diff --git a/cpp/src/IceSSL/Certificate.cpp b/cpp/src/IceSSL/Certificate.cpp index 5c7f7bf08d7..ba5fa9619f3 100644 --- a/cpp/src/IceSSL/Certificate.cpp +++ b/cpp/src/IceSSL/Certificate.cpp @@ -16,7 +16,7 @@ #include <IceSSL/RFC2253.h> #include <Ice/Object.h> -#ifdef ICE_USE_OPENSSL +#if defined(ICE_USE_OPENSSL) # include <openssl/x509v3.h> # include <openssl/pem.h> #elif defined(ICE_USE_SECURE_TRANSPORT) @@ -114,7 +114,7 @@ certificateAlternativeNameType(const string& alias) } string -scapeX509Name(const string& name) +escapeX509Name(const string& name) { ostringstream os; for(string::const_iterator i = name.begin(); i != name.end(); ++i) @@ -144,61 +144,32 @@ scapeX509Name(const string& name) DistinguishedName getX509Name(SecCertificateRef cert, CFTypeRef key) { - CFErrorRef err = 0; assert(key == kSecOIDX509V1IssuerName || key == kSecOIDX509V1SubjectName); - CFArrayRef keys = CFArrayCreate(NULL, &key , 1, &kCFTypeArrayCallBacks); - CFDictionaryRef values = SecCertificateCopyValues(cert, keys, &err); - CFRelease(keys); - - if(err) - { - ostringstream os; - os << "certificate error:\n" << errorToString(err); - CFRelease(err); - - CertificateEncodingException ex(__FILE__, __LINE__, os.str()); - throw ex; - } - - assert(values); - - CFArrayRef dn = (CFArrayRef)CFDictionaryGetValue((CFDictionaryRef)CFDictionaryGetValue(values, key), kSecPropertyKeyValue); - int size = CFArrayGetCount(dn); list<pair<string, string> > rdnPairs; - for(int i = 0; i < size; ++i) + CFDictionaryRef property = getCertificateProperty(cert, key); + if(property) { - CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(dn, i); - rdnPairs.push_front(make_pair( - certificateOIDAlias(fromCFString((CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel))), - scapeX509Name(fromCFString((CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue))))); + CFArrayRef dn = (CFArrayRef)CFDictionaryGetValue(property, kSecPropertyKeyValue); + int size = CFArrayGetCount(dn); + for(int i = 0; i < size; ++i) + { + CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(dn, i); + rdnPairs.push_front(make_pair( + certificateOIDAlias(fromCFString((CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel))), + escapeX509Name(fromCFString((CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue))))); + } + CFRelease(property); } - CFRelease(values); return DistinguishedName(rdnPairs); } vector<pair<int, string> > getX509AltName(SecCertificateRef cert, CFTypeRef key) { - CFErrorRef err = 0; assert(key == kSecOIDIssuerAltName || key == kSecOIDSubjectAltName); - CFArrayRef keys = CFArrayCreate(NULL, &key , 1, &kCFTypeArrayCallBacks); - CFDictionaryRef values = SecCertificateCopyValues(cert, keys, &err); - CFRelease(keys); - - if(err) - { - ostringstream os; - os << "certificate error:\n" << errorToString(err); - CFRelease(err); - - CertificateEncodingException ex(__FILE__, __LINE__, os.str()); - throw ex; - } - - assert(values); + CFDictionaryRef property = getCertificateProperty(cert, key); vector<pair<int, string> > pairs; - CFDictionaryRef property = (CFDictionaryRef)CFDictionaryGetValue(values, key); if(property) { CFArrayRef names = (CFArrayRef)CFDictionaryGetValue(property, kSecPropertyKeyValue); @@ -233,8 +204,7 @@ getX509AltName(SecCertificateRef cert, CFTypeRef key) CFStringRef sectionLabel = (CFStringRef)CFDictionaryGetValue(d, kSecPropertyKeyLabel); CFStringRef sectionValue = (CFStringRef)CFDictionaryGetValue(d, kSecPropertyKeyValue); - os << certificateOIDAlias(fromCFString(sectionLabel)) - << "=" << fromCFString(sectionValue); + os << certificateOIDAlias(fromCFString(sectionLabel)) << "=" << fromCFString(sectionValue); if(++i < count) { os << ","; @@ -244,8 +214,8 @@ getX509AltName(SecCertificateRef cert, CFTypeRef key) } } } + CFRelease(property); } - CFRelease(values); return pairs; } @@ -253,30 +223,14 @@ IceUtil::Time getX509Date(SecCertificateRef cert, CFTypeRef key) { assert(key == kSecOIDX509V1ValidityNotAfter || key == kSecOIDX509V1ValidityNotBefore); - CFErrorRef err = 0; - const void* keyValues[] = { key }; - CFArrayRef keys = CFArrayCreate(NULL, keyValues , 1, &kCFTypeArrayCallBacks); - CFDictionaryRef values = SecCertificateCopyValues(cert, keys, &err); - CFRelease(keys); - - if(err) + CFDictionaryRef property = getCertificateProperty(cert, key); + CFAbsoluteTime seconds = 0; + if(property) { - ostringstream os; - os << "certificate error:\n" << errorToString(err); - CFRelease(err); - - CertificateEncodingException ex(__FILE__, __LINE__, os.str()); - throw ex; + CFNumberRef date = (CFNumberRef)CFDictionaryGetValue(property, kSecPropertyKeyValue); + CFNumberGetValue(date, kCFNumberDoubleType, &seconds); + CFRelease(property); } - - assert(values); - - CFNumberRef date = (CFNumberRef)CFDictionaryGetValue( - (CFDictionaryRef)CFDictionaryGetValue(values, key), kSecPropertyKeyValue); - - CFAbsoluteTime seconds; - CFNumberGetValue(date, kCFNumberDoubleType, &seconds); - CFRelease(values); return IceUtil::Time::secondsDouble(kCFAbsoluteTimeIntervalSince1970 + seconds); } @@ -284,27 +238,13 @@ string getX509String(SecCertificateRef cert, CFTypeRef key) { assert(key == kSecOIDX509V1SerialNumber || key == kSecOIDX509V1Version); - CFErrorRef err = 0; - const void* keyValues[] = { key }; - CFArrayRef keys = CFArrayCreate(NULL, keyValues , 1, &kCFTypeArrayCallBacks); - CFDictionaryRef values = SecCertificateCopyValues(cert, keys, &err); - CFRelease(keys); - - if(err) + CFDictionaryRef property = getCertificateProperty(cert, key); + string value; + if(property) { - ostringstream os; - os << "certificate error:\n" << errorToString(err); - CFRelease(err); - - CertificateEncodingException ex(__FILE__, __LINE__, os.str()); - throw ex; + value = fromCFString((CFStringRef)CFDictionaryGetValue(property, kSecPropertyKeyValue)); + CFRelease(property); } - - assert(values); - - string value = fromCFString((CFStringRef)CFDictionaryGetValue( - (CFDictionaryRef)CFDictionaryGetValue(values, key), kSecPropertyKeyValue)); - CFRelease(values); return value; } #endif @@ -339,6 +279,18 @@ CertificateReadException::ice_throw() const const char* IceSSL::CertificateEncodingException::_name = "IceSSL::CertificateEncodingException"; +#ifdef ICE_USE_SECURE_TRANSPORT +CertificateEncodingException::CertificateEncodingException(const char* file, int line, CFErrorRef err) : + Exception(file, line) +{ + assert(err); + ostringstream os; + os << "certificate error:\n" << errorToString(err); + CFRelease(err); + reason = os.str(); +} +#endif + CertificateEncodingException::CertificateEncodingException(const char* file, int line, const string& r) : Exception(file, line), reason(r) @@ -569,6 +521,14 @@ ParseException::ice_throw() const throw *this; } +#ifdef ICE_USE_OPENSSL +DistinguishedName::DistinguishedName(X509NAME* name) : + _rdns(RFC2253::parseStrict(convertX509NameToString(name))) +{ + unescape(); +} +#endif + DistinguishedName::DistinguishedName(const string& dn) : _rdns(RFC2253::parseStrict(dn)) { @@ -681,7 +641,10 @@ PublicKey::key() const Certificate::Certificate(X509CertificateRef cert) : _cert(cert) { - assert(_cert != 0); + if(!_cert) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Invalid certificate reference"); + } } Certificate::~Certificate() @@ -810,7 +773,12 @@ bool Certificate::verify(const CertificatePtr& cert) const { #ifdef ICE_USE_SECURE_TRANSPORT - + // + // We first check if the given certificate subject match + // our certificate issuer. Otherwhise when use SecTrustEvaluate + // and check a certificate against itself will always return + // that is valid. + // bool valid = false; CFErrorRef error = 0; @@ -820,20 +788,14 @@ Certificate::verify(const CertificatePtr& cert) const issuer = SecCertificateCopyNormalizedIssuerContent(_cert, &error); if(error) { - ostringstream os; - os << "certificate error:\n" << errorToString(error); - CFRelease(error); - CertificateEncodingException ex(__FILE__, __LINE__, os.str()); + CertificateEncodingException ex(__FILE__, __LINE__, error); throw ex; } subject = SecCertificateCopyNormalizedSubjectContent(cert->getCert(), &error); if(error) { - ostringstream os; - os << "certificate error:\n" << errorToString(error); - CFRelease(error); - CertificateEncodingException ex(__FILE__, __LINE__, os.str()); + CertificateEncodingException ex(__FILE__, __LINE__, error); throw ex; } diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp index 3d3f24e58d8..3e21122f26a 100644 --- a/cpp/src/IceSSL/Instance.cpp +++ b/cpp/src/IceSSL/Instance.cpp @@ -12,6 +12,7 @@ # include <winsock2.h> #endif #include <IceSSL/Instance.h> +#include <IceSSL/SSLEngine.h> #include <Ice/Properties.h> using namespace std; @@ -24,8 +25,6 @@ IceSSL::Instance::Instance(const SSLEnginePtr& engine, Short type, const string& ProtocolInstance(engine->communicator(), type, protocol), _engine(engine) { - _securityTraceLevel = properties()->getPropertyAsInt("IceSSL.Trace.Security"); - _securityTraceCategory = "Security"; } IceSSL::Instance::~Instance() @@ -37,15 +36,3 @@ IceSSL::Instance::initialized() const { return _engine->initialized(); } - -int -IceSSL::Instance::securityTraceLevel() const -{ - return _securityTraceLevel; -} - -string -IceSSL::Instance::securityTraceCategory() const -{ - return _securityTraceCategory; -} diff --git a/cpp/src/IceSSL/Instance.h b/cpp/src/IceSSL/Instance.h index ee295a6d7d1..128d9820f83 100644 --- a/cpp/src/IceSSL/Instance.h +++ b/cpp/src/IceSSL/Instance.h @@ -11,13 +11,8 @@ #define ICE_SSL_INSTANCE_H #include <IceSSL/InstanceF.h> -#include <IceSSL/UtilF.h> #include <Ice/ProtocolInstance.h> -#include <Ice/ProtocolPluginFacadeF.h> -#include <IceSSL/Plugin.h> -#include <IceSSL/SSLEngine.h> -#include <IceSSL/TrustManagerF.h> -#include <Ice/BuiltinSequences.h> +#include <IceSSL/SSLEngineF.h> namespace IceSSL { @@ -37,14 +32,9 @@ public: bool initialized() const; - int securityTraceLevel() const; - std::string securityTraceCategory() const; - private: const SSLEnginePtr _engine; - int _securityTraceLevel; - std::string _securityTraceCategory; }; } diff --git a/cpp/src/IceSSL/OpenSSLEngine.cpp b/cpp/src/IceSSL/OpenSSLEngine.cpp index c73e27da33a..e78adfe9671 100644 --- a/cpp/src/IceSSL/OpenSSLEngine.cpp +++ b/cpp/src/IceSSL/OpenSSLEngine.cpp @@ -729,7 +729,7 @@ OpenSSLEngine::initialize() } void -OpenSSLEngine::context(ContextRef context) +OpenSSLEngine::context(SSL_CTX* context) { if(initialized()) { @@ -742,7 +742,7 @@ OpenSSLEngine::context(ContextRef context) _ctx = context; } -ContextRef +SSL_CTX* OpenSSLEngine::context() const { return _ctx; diff --git a/cpp/src/IceSSL/PluginI.cpp b/cpp/src/IceSSL/PluginI.cpp index 02f9cf1a6e1..5a39e3ee93f 100644 --- a/cpp/src/IceSSL/PluginI.cpp +++ b/cpp/src/IceSSL/PluginI.cpp @@ -10,6 +10,7 @@ #include <IceSSL/PluginI.h> #include <IceSSL/Instance.h> #include <IceSSL/TransceiverI.h> +#include <IceSSL/SSLEngine.h> #include <IceSSL/EndpointI.h> #include <IceSSL/EndpointInfo.h> @@ -83,12 +84,12 @@ IceSSL::PluginI::setPasswordPrompt(const PasswordPromptPtr& prompt) #ifdef ICE_USE_OPENSSL void -IceSSL::PluginI::setContext(ContextRef context) +IceSSL::PluginI::setContext(SSL_CTX* context) { _engine->context(context); } -ContextRef +SSL_CTX* IceSSL::PluginI::getContext() { return _engine->context(); diff --git a/cpp/src/IceSSL/PluginI.h b/cpp/src/IceSSL/PluginI.h index 7d1903aa7bd..bd6447fe988 100644 --- a/cpp/src/IceSSL/PluginI.h +++ b/cpp/src/IceSSL/PluginI.h @@ -17,12 +17,7 @@ namespace IceSSL { -class PluginI : -#ifdef ICE_USE_OPENSSL - public OpenSSLPlugin -#else - public IceSSL::Plugin -#endif +class PluginI : public IceSSL::Plugin { public: @@ -41,8 +36,8 @@ public: virtual void setPasswordPrompt(const PasswordPromptPtr&); #ifdef ICE_USE_OPENSSL - virtual void setContext(ContextRef); - virtual ContextRef getContext(); + virtual void setContext(SSL_CTX*); + virtual SSL_CTX* getContext(); #endif private: diff --git a/cpp/src/IceSSL/SSLEngine.h b/cpp/src/IceSSL/SSLEngine.h index e4f1891222a..3c2cffdac22 100644 --- a/cpp/src/IceSSL/SSLEngine.h +++ b/cpp/src/IceSSL/SSLEngine.h @@ -99,7 +99,7 @@ public: virtual bool initialized() const; virtual void destroy(); - ContextRef newContext(bool); + SSLContextRef newContext(bool); CFArrayRef getCertificateAuthorities() const; std::string getCipherName(SSLCipherSuite) const; SecCertificateRef getCertificate() const; @@ -110,7 +110,7 @@ private: void parseCiphers(const std::string& ciphers); bool _initialized; - ContextRef _ctx; + SSLContextRef _ctx; CFArrayRef _certificateAuthorities; SecCertificateRef _cert; SecKeyRef _key; @@ -126,9 +126,8 @@ private: IceUtil::UniquePtr< IceUtil::ScopedArray<char> > _dhParams; size_t _dhParamsLength; - IceUtil::UniquePtr< IceUtil::ScopedArray<SSLCipherSuite> > _ciphers; + std::vector<SSLCipherSuite> _ciphers; bool _allCiphers; - size_t _numCiphers; IceUtil::Mutex _mutex; }; @@ -150,8 +149,8 @@ public: # ifndef OPENSSL_NO_DH DH* dhParams(int); # endif - ContextRef context() const; - void context(ContextRef); + SSL_CTX* context() const; + void context(SSL_CTX*); std::string sslErrors() const; private: @@ -164,7 +163,7 @@ private: bool _initOpenSSL; bool _initialized; - ContextRef _ctx; + SSL_CTX* _ctx; std::string _defaultDir; # ifndef OPENSSL_NO_DH diff --git a/cpp/src/IceSSL/SecureTransportEngine.cpp b/cpp/src/IceSSL/SecureTransportEngine.cpp index 5bf401947bd..f2ac0d7947a 100644 --- a/cpp/src/IceSSL/SecureTransportEngine.cpp +++ b/cpp/src/IceSSL/SecureTransportEngine.cpp @@ -36,6 +36,26 @@ using namespace IceSSL; namespace { +IceUtil::Mutex* staticMutex = 0; + +class Init +{ +public: + + Init() + { + staticMutex = new IceUtil::Mutex; + } + + ~Init() + { + delete staticMutex; + staticMutex = 0; + } +}; + +Init init; + vector<string> dir(const string& path) { @@ -126,224 +146,228 @@ map<string, SSLCipherSuite> CiphersHelper::_ciphers; void CiphersHelper::initialize() { - _ciphers["NULL_WITH_NULL_NULL"] = SSL_NULL_WITH_NULL_NULL; - _ciphers["RSA_WITH_NULL_MD5"] = SSL_RSA_WITH_NULL_MD5; - _ciphers["RSA_WITH_NULL_SHA"] = SSL_RSA_WITH_NULL_SHA; - _ciphers["RSA_EXPORT_WITH_RC4_40_MD5"] = SSL_RSA_EXPORT_WITH_RC4_40_MD5; - _ciphers["RSA_WITH_RC4_128_MD5"] = SSL_RSA_WITH_RC4_128_MD5; - _ciphers["RSA_WITH_RC4_128_SHA"] = SSL_RSA_WITH_RC4_128_SHA; - _ciphers["RSA_EXPORT_WITH_RC2_CBC_40_MD5"] = SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5; - _ciphers["RSA_WITH_IDEA_CBC_SHA"] = SSL_RSA_WITH_IDEA_CBC_SHA; - _ciphers["RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_RSA_EXPORT_WITH_DES40_CBC_SHA; - _ciphers["RSA_WITH_DES_CBC_SHA"] = SSL_RSA_WITH_DES_CBC_SHA; - _ciphers["RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_RSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["DH_DSS_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA; - _ciphers["DH_DSS_WITH_DES_CBC_SHA"] = SSL_DH_DSS_WITH_DES_CBC_SHA; - _ciphers["DH_DSS_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA; - _ciphers["DH_RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA; - _ciphers["DH_RSA_WITH_DES_CBC_SHA"] = SSL_DH_RSA_WITH_DES_CBC_SHA; - _ciphers["DH_RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA; - _ciphers["DHE_DSS_WITH_DES_CBC_SHA"] = SSL_DHE_DSS_WITH_DES_CBC_SHA; - _ciphers["DHE_DSS_WITH_3DES_EDE_CBC_SHA"] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA; - _ciphers["DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA; - _ciphers["DHE_RSA_WITH_DES_CBC_SHA"] = SSL_DHE_RSA_WITH_DES_CBC_SHA; - _ciphers["DHE_RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["DH_anon_EXPORT_WITH_RC4_40_MD5"] = SSL_DH_anon_EXPORT_WITH_RC4_40_MD5; - _ciphers["DH_anon_WITH_RC4_128_MD5"] = SSL_DH_anon_WITH_RC4_128_MD5; - _ciphers["DH_anon_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA; - _ciphers["DH_anon_WITH_DES_CBC_SHA"] = SSL_DH_anon_WITH_DES_CBC_SHA; - _ciphers["DH_anon_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_anon_WITH_3DES_EDE_CBC_SHA; - _ciphers["FORTEZZA_DMS_WITH_NULL_SHA"] = SSL_FORTEZZA_DMS_WITH_NULL_SHA; - _ciphers["FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"] = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA; + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(staticMutex); + if(_ciphers.empty()) + { + _ciphers["NULL_WITH_NULL_NULL"] = SSL_NULL_WITH_NULL_NULL; + _ciphers["RSA_WITH_NULL_MD5"] = SSL_RSA_WITH_NULL_MD5; + _ciphers["RSA_WITH_NULL_SHA"] = SSL_RSA_WITH_NULL_SHA; + _ciphers["RSA_EXPORT_WITH_RC4_40_MD5"] = SSL_RSA_EXPORT_WITH_RC4_40_MD5; + _ciphers["RSA_WITH_RC4_128_MD5"] = SSL_RSA_WITH_RC4_128_MD5; + _ciphers["RSA_WITH_RC4_128_SHA"] = SSL_RSA_WITH_RC4_128_SHA; + _ciphers["RSA_EXPORT_WITH_RC2_CBC_40_MD5"] = SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5; + _ciphers["RSA_WITH_IDEA_CBC_SHA"] = SSL_RSA_WITH_IDEA_CBC_SHA; + _ciphers["RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_RSA_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["RSA_WITH_DES_CBC_SHA"] = SSL_RSA_WITH_DES_CBC_SHA; + _ciphers["RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_DSS_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DH_DSS_WITH_DES_CBC_SHA"] = SSL_DH_DSS_WITH_DES_CBC_SHA; + _ciphers["DH_DSS_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DH_RSA_WITH_DES_CBC_SHA"] = SSL_DH_RSA_WITH_DES_CBC_SHA; + _ciphers["DH_RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DHE_DSS_WITH_DES_CBC_SHA"] = SSL_DHE_DSS_WITH_DES_CBC_SHA; + _ciphers["DHE_DSS_WITH_3DES_EDE_CBC_SHA"] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA; + _ciphers["DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DHE_RSA_WITH_DES_CBC_SHA"] = SSL_DHE_RSA_WITH_DES_CBC_SHA; + _ciphers["DHE_RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_anon_EXPORT_WITH_RC4_40_MD5"] = SSL_DH_anon_EXPORT_WITH_RC4_40_MD5; + _ciphers["DH_anon_WITH_RC4_128_MD5"] = SSL_DH_anon_WITH_RC4_128_MD5; + _ciphers["DH_anon_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA; + _ciphers["DH_anon_WITH_DES_CBC_SHA"] = SSL_DH_anon_WITH_DES_CBC_SHA; + _ciphers["DH_anon_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_anon_WITH_3DES_EDE_CBC_SHA; + _ciphers["FORTEZZA_DMS_WITH_NULL_SHA"] = SSL_FORTEZZA_DMS_WITH_NULL_SHA; + _ciphers["FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"] = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA; - // - // TLS addenda using AES, per RFC 3268 - // - _ciphers["RSA_WITH_AES_128_CBC_SHA"] = TLS_RSA_WITH_AES_128_CBC_SHA; - _ciphers["DH_DSS_WITH_AES_128_CBC_SHA"] = TLS_DH_DSS_WITH_AES_128_CBC_SHA; - _ciphers["DH_RSA_WITH_AES_128_CBC_SHA"] = TLS_DH_RSA_WITH_AES_128_CBC_SHA; - _ciphers["DHE_DSS_WITH_AES_128_CBC_SHA"] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA; - _ciphers["DHE_RSA_WITH_AES_128_CBC_SHA"] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA; - _ciphers["DH_anon_WITH_AES_128_CBC_SHA"] = TLS_DH_anon_WITH_AES_128_CBC_SHA; - _ciphers["RSA_WITH_AES_256_CBC_SHA"] = TLS_RSA_WITH_AES_256_CBC_SHA; - _ciphers["DH_DSS_WITH_AES_256_CBC_SHA"] = TLS_DH_DSS_WITH_AES_256_CBC_SHA; - _ciphers["DH_RSA_WITH_AES_256_CBC_SHA"] = TLS_DH_RSA_WITH_AES_256_CBC_SHA; - _ciphers["DHE_DSS_WITH_AES_256_CBC_SHA"] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA; - _ciphers["DHE_RSA_WITH_AES_256_CBC_SHA"] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; - _ciphers["DH_anon_WITH_AES_256_CBC_SHA"] = TLS_DH_anon_WITH_AES_256_CBC_SHA; + // + // TLS addenda using AES, per RFC 3268 + // + _ciphers["RSA_WITH_AES_128_CBC_SHA"] = TLS_RSA_WITH_AES_128_CBC_SHA; + _ciphers["DH_DSS_WITH_AES_128_CBC_SHA"] = TLS_DH_DSS_WITH_AES_128_CBC_SHA; + _ciphers["DH_RSA_WITH_AES_128_CBC_SHA"] = TLS_DH_RSA_WITH_AES_128_CBC_SHA; + _ciphers["DHE_DSS_WITH_AES_128_CBC_SHA"] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA; + _ciphers["DHE_RSA_WITH_AES_128_CBC_SHA"] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA; + _ciphers["DH_anon_WITH_AES_128_CBC_SHA"] = TLS_DH_anon_WITH_AES_128_CBC_SHA; + _ciphers["RSA_WITH_AES_256_CBC_SHA"] = TLS_RSA_WITH_AES_256_CBC_SHA; + _ciphers["DH_DSS_WITH_AES_256_CBC_SHA"] = TLS_DH_DSS_WITH_AES_256_CBC_SHA; + _ciphers["DH_RSA_WITH_AES_256_CBC_SHA"] = TLS_DH_RSA_WITH_AES_256_CBC_SHA; + _ciphers["DHE_DSS_WITH_AES_256_CBC_SHA"] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA; + _ciphers["DHE_RSA_WITH_AES_256_CBC_SHA"] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; + _ciphers["DH_anon_WITH_AES_256_CBC_SHA"] = TLS_DH_anon_WITH_AES_256_CBC_SHA; - // - // ECDSA addenda, RFC 4492 - // - _ciphers["ECDH_ECDSA_WITH_NULL_SHA"] = TLS_ECDH_ECDSA_WITH_NULL_SHA; - _ciphers["ECDH_ECDSA_WITH_RC4_128_SHA"] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA; - _ciphers["ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["ECDH_ECDSA_WITH_AES_128_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA; - _ciphers["ECDH_ECDSA_WITH_AES_256_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA; - _ciphers["ECDHE_ECDSA_WITH_NULL_SHA"] = TLS_ECDHE_ECDSA_WITH_NULL_SHA; - _ciphers["ECDHE_ECDSA_WITH_RC4_128_SHA"] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA; - _ciphers["ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["ECDHE_ECDSA_WITH_AES_128_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA; - _ciphers["ECDHE_ECDSA_WITH_AES_256_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA; - _ciphers["ECDH_RSA_WITH_NULL_SHA"] = TLS_ECDH_RSA_WITH_NULL_SHA; - _ciphers["ECDH_RSA_WITH_RC4_128_SHA"] = TLS_ECDH_RSA_WITH_RC4_128_SHA; - _ciphers["ECDH_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["ECDH_RSA_WITH_AES_128_CBC_SHA"] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA; - _ciphers["ECDH_RSA_WITH_AES_256_CBC_SHA"] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA; - _ciphers["ECDHE_RSA_WITH_NULL_SHA"] = TLS_ECDHE_RSA_WITH_NULL_SHA; - _ciphers["ECDHE_RSA_WITH_RC4_128_SHA"] = TLS_ECDHE_RSA_WITH_RC4_128_SHA; - _ciphers["ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["ECDHE_RSA_WITH_AES_128_CBC_SHA"] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA; - _ciphers["ECDHE_RSA_WITH_AES_256_CBC_SHA"] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA; - _ciphers["ECDH_anon_WITH_NULL_SHA"] = TLS_ECDH_anon_WITH_NULL_SHA; - _ciphers["ECDH_anon_WITH_RC4_128_SHA"] = TLS_ECDH_anon_WITH_RC4_128_SHA; - _ciphers["ECDH_anon_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA; - _ciphers["ECDH_anon_WITH_AES_128_CBC_SHA"] = TLS_ECDH_anon_WITH_AES_128_CBC_SHA; - _ciphers["ECDH_anon_WITH_AES_256_CBC_SHA"] = TLS_ECDH_anon_WITH_AES_256_CBC_SHA; + // + // ECDSA addenda, RFC 4492 + // + _ciphers["ECDH_ECDSA_WITH_NULL_SHA"] = TLS_ECDH_ECDSA_WITH_NULL_SHA; + _ciphers["ECDH_ECDSA_WITH_RC4_128_SHA"] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA; + _ciphers["ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDH_ECDSA_WITH_AES_128_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA; + _ciphers["ECDH_ECDSA_WITH_AES_256_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA; + _ciphers["ECDHE_ECDSA_WITH_NULL_SHA"] = TLS_ECDHE_ECDSA_WITH_NULL_SHA; + _ciphers["ECDHE_ECDSA_WITH_RC4_128_SHA"] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA; + _ciphers["ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDHE_ECDSA_WITH_AES_128_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA; + _ciphers["ECDHE_ECDSA_WITH_AES_256_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA; + _ciphers["ECDH_RSA_WITH_NULL_SHA"] = TLS_ECDH_RSA_WITH_NULL_SHA; + _ciphers["ECDH_RSA_WITH_RC4_128_SHA"] = TLS_ECDH_RSA_WITH_RC4_128_SHA; + _ciphers["ECDH_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDH_RSA_WITH_AES_128_CBC_SHA"] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA; + _ciphers["ECDH_RSA_WITH_AES_256_CBC_SHA"] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA; + _ciphers["ECDHE_RSA_WITH_NULL_SHA"] = TLS_ECDHE_RSA_WITH_NULL_SHA; + _ciphers["ECDHE_RSA_WITH_RC4_128_SHA"] = TLS_ECDHE_RSA_WITH_RC4_128_SHA; + _ciphers["ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDHE_RSA_WITH_AES_128_CBC_SHA"] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA; + _ciphers["ECDHE_RSA_WITH_AES_256_CBC_SHA"] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA; + _ciphers["ECDH_anon_WITH_NULL_SHA"] = TLS_ECDH_anon_WITH_NULL_SHA; + _ciphers["ECDH_anon_WITH_RC4_128_SHA"] = TLS_ECDH_anon_WITH_RC4_128_SHA; + _ciphers["ECDH_anon_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA; + _ciphers["ECDH_anon_WITH_AES_128_CBC_SHA"] = TLS_ECDH_anon_WITH_AES_128_CBC_SHA; + _ciphers["ECDH_anon_WITH_AES_256_CBC_SHA"] = TLS_ECDH_anon_WITH_AES_256_CBC_SHA; - // - // TLS 1.2 addenda, RFC 5246 - // - //_ciphers["NULL_WITH_NULL_NULL"] = TLS_NULL_WITH_NULL_NULL; + // + // TLS 1.2 addenda, RFC 5246 + // + //_ciphers["NULL_WITH_NULL_NULL"] = TLS_NULL_WITH_NULL_NULL; - // - // Server provided RSA certificate for key exchange. - // - //_ciphers["RSA_WITH_NULL_MD5"] = TLS_RSA_WITH_NULL_MD5; - //_ciphers["RSA_WITH_NULL_SHA"] = TLS_RSA_WITH_NULL_SHA; - //_ciphers["RSA_WITH_RC4_128_MD5"] = TLS_RSA_WITH_RC4_128_MD5; - //_ciphers["RSA_WITH_RC4_128_SHA"] = TLS_RSA_WITH_RC4_128_SHA; - //_ciphers["RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_RSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["RSA_WITH_NULL_SHA256"] = TLS_RSA_WITH_NULL_SHA256; - _ciphers["RSA_WITH_AES_128_CBC_SHA256"] = TLS_RSA_WITH_AES_128_CBC_SHA256; - _ciphers["RSA_WITH_AES_256_CBC_SHA256"] = TLS_RSA_WITH_AES_256_CBC_SHA256; + // + // Server provided RSA certificate for key exchange. + // + //_ciphers["RSA_WITH_NULL_MD5"] = TLS_RSA_WITH_NULL_MD5; + //_ciphers["RSA_WITH_NULL_SHA"] = TLS_RSA_WITH_NULL_SHA; + //_ciphers["RSA_WITH_RC4_128_MD5"] = TLS_RSA_WITH_RC4_128_MD5; + //_ciphers["RSA_WITH_RC4_128_SHA"] = TLS_RSA_WITH_RC4_128_SHA; + //_ciphers["RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["RSA_WITH_NULL_SHA256"] = TLS_RSA_WITH_NULL_SHA256; + _ciphers["RSA_WITH_AES_128_CBC_SHA256"] = TLS_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["RSA_WITH_AES_256_CBC_SHA256"] = TLS_RSA_WITH_AES_256_CBC_SHA256; - // - // Server-authenticated (and optionally client-authenticated) Diffie-Hellman. - // - //_ciphers["DH_DSS_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA; - //_ciphers["DH_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA; - //_ciphers["DHE_DSS_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA; - //_ciphers["DHE_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA; - _ciphers["DH_DSS_WITH_AES_128_CBC_SHA256"] = TLS_DH_DSS_WITH_AES_128_CBC_SHA256; - _ciphers["DH_RSA_WITH_AES_128_CBC_SHA256"] = TLS_DH_RSA_WITH_AES_128_CBC_SHA256; - _ciphers["DHE_DSS_WITH_AES_128_CBC_SHA256"] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA256; - _ciphers["DHE_RSA_WITH_AES_128_CBC_SHA256"] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256; - _ciphers["DH_DSS_WITH_AES_256_CBC_SHA256"] = TLS_DH_DSS_WITH_AES_256_CBC_SHA256; - _ciphers["DH_RSA_WITH_AES_256_CBC_SHA256"] = TLS_DH_RSA_WITH_AES_256_CBC_SHA256; - _ciphers["DHE_DSS_WITH_AES_256_CBC_SHA256"] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA256; - _ciphers["DHE_RSA_WITH_AES_256_CBC_SHA256"] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256; + // + // Server-authenticated (and optionally client-authenticated) Diffie-Hellman. + // + //_ciphers["DH_DSS_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA; + //_ciphers["DH_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA; + //_ciphers["DHE_DSS_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA; + //_ciphers["DHE_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_DSS_WITH_AES_128_CBC_SHA256"] = TLS_DH_DSS_WITH_AES_128_CBC_SHA256; + _ciphers["DH_RSA_WITH_AES_128_CBC_SHA256"] = TLS_DH_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["DHE_DSS_WITH_AES_128_CBC_SHA256"] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA256; + _ciphers["DHE_RSA_WITH_AES_128_CBC_SHA256"] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["DH_DSS_WITH_AES_256_CBC_SHA256"] = TLS_DH_DSS_WITH_AES_256_CBC_SHA256; + _ciphers["DH_RSA_WITH_AES_256_CBC_SHA256"] = TLS_DH_RSA_WITH_AES_256_CBC_SHA256; + _ciphers["DHE_DSS_WITH_AES_256_CBC_SHA256"] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA256; + _ciphers["DHE_RSA_WITH_AES_256_CBC_SHA256"] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256; - // - // Completely anonymous Diffie-Hellman - // - //_ciphers["DH_anon_WITH_RC4_128_MD5"] = TLS_DH_anon_WITH_RC4_128_MD5; - //_ciphers["DH_anon_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA; - _ciphers["DH_anon_WITH_AES_128_CBC_SHA256"] = TLS_DH_anon_WITH_AES_128_CBC_SHA256; - _ciphers["DH_anon_WITH_AES_256_CBC_SHA256"] = TLS_DH_anon_WITH_AES_256_CBC_SHA256; - - // - // Addendum from RFC 4279, TLS PSK - // - _ciphers["PSK_WITH_RC4_128_SHA"] = TLS_PSK_WITH_RC4_128_SHA; - _ciphers["PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_PSK_WITH_3DES_EDE_CBC_SHA; - _ciphers["PSK_WITH_AES_128_CBC_SHA"] = TLS_PSK_WITH_AES_128_CBC_SHA; - _ciphers["PSK_WITH_AES_256_CBC_SHA"] = TLS_PSK_WITH_AES_256_CBC_SHA; - _ciphers["DHE_PSK_WITH_RC4_128_SHA"] = TLS_DHE_PSK_WITH_RC4_128_SHA; - _ciphers["DHE_PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA; - _ciphers["DHE_PSK_WITH_AES_128_CBC_SHA"] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA; - _ciphers["DHE_PSK_WITH_AES_256_CBC_SHA"] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA; - _ciphers["RSA_PSK_WITH_RC4_128_SHA"] = TLS_RSA_PSK_WITH_RC4_128_SHA; - _ciphers["RSA_PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA; - _ciphers["RSA_PSK_WITH_AES_128_CBC_SHA"] = TLS_RSA_PSK_WITH_AES_128_CBC_SHA; - _ciphers["RSA_PSK_WITH_AES_256_CBC_SHA"] = TLS_RSA_PSK_WITH_AES_256_CBC_SHA; + // + // Completely anonymous Diffie-Hellman + // + //_ciphers["DH_anon_WITH_RC4_128_MD5"] = TLS_DH_anon_WITH_RC4_128_MD5; + //_ciphers["DH_anon_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA; + _ciphers["DH_anon_WITH_AES_128_CBC_SHA256"] = TLS_DH_anon_WITH_AES_128_CBC_SHA256; + _ciphers["DH_anon_WITH_AES_256_CBC_SHA256"] = TLS_DH_anon_WITH_AES_256_CBC_SHA256; + + // + // Addendum from RFC 4279, TLS PSK + // + _ciphers["PSK_WITH_RC4_128_SHA"] = TLS_PSK_WITH_RC4_128_SHA; + _ciphers["PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_PSK_WITH_3DES_EDE_CBC_SHA; + _ciphers["PSK_WITH_AES_128_CBC_SHA"] = TLS_PSK_WITH_AES_128_CBC_SHA; + _ciphers["PSK_WITH_AES_256_CBC_SHA"] = TLS_PSK_WITH_AES_256_CBC_SHA; + _ciphers["DHE_PSK_WITH_RC4_128_SHA"] = TLS_DHE_PSK_WITH_RC4_128_SHA; + _ciphers["DHE_PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA; + _ciphers["DHE_PSK_WITH_AES_128_CBC_SHA"] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA; + _ciphers["DHE_PSK_WITH_AES_256_CBC_SHA"] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA; + _ciphers["RSA_PSK_WITH_RC4_128_SHA"] = TLS_RSA_PSK_WITH_RC4_128_SHA; + _ciphers["RSA_PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA; + _ciphers["RSA_PSK_WITH_AES_128_CBC_SHA"] = TLS_RSA_PSK_WITH_AES_128_CBC_SHA; + _ciphers["RSA_PSK_WITH_AES_256_CBC_SHA"] = TLS_RSA_PSK_WITH_AES_256_CBC_SHA; - // - // RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption - // - _ciphers["PSK_WITH_NULL_SHA"] = TLS_PSK_WITH_NULL_SHA; - _ciphers["DHE_PSK_WITH_NULL_SHA"] = TLS_DHE_PSK_WITH_NULL_SHA; - _ciphers["RSA_PSK_WITH_NULL_SHA"] = TLS_RSA_PSK_WITH_NULL_SHA; + // + // RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption + // + _ciphers["PSK_WITH_NULL_SHA"] = TLS_PSK_WITH_NULL_SHA; + _ciphers["DHE_PSK_WITH_NULL_SHA"] = TLS_DHE_PSK_WITH_NULL_SHA; + _ciphers["RSA_PSK_WITH_NULL_SHA"] = TLS_RSA_PSK_WITH_NULL_SHA; - // - // Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites for TLS. - // - _ciphers["RSA_WITH_AES_128_GCM_SHA256"] = TLS_RSA_WITH_AES_128_GCM_SHA256; - _ciphers["RSA_WITH_AES_256_GCM_SHA384"] = TLS_RSA_WITH_AES_256_GCM_SHA384; - _ciphers["DHE_RSA_WITH_AES_128_GCM_SHA256"] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256; - _ciphers["DHE_RSA_WITH_AES_256_GCM_SHA384"] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384; - _ciphers["DH_RSA_WITH_AES_128_GCM_SHA256"] = TLS_DH_RSA_WITH_AES_128_GCM_SHA256; - _ciphers["DH_RSA_WITH_AES_256_GCM_SHA384"] = TLS_DH_RSA_WITH_AES_256_GCM_SHA384; - _ciphers["DHE_DSS_WITH_AES_128_GCM_SHA256"] = TLS_DHE_DSS_WITH_AES_128_GCM_SHA256; - _ciphers["DHE_DSS_WITH_AES_256_GCM_SHA384"] = TLS_DHE_DSS_WITH_AES_256_GCM_SHA384; - _ciphers["DH_DSS_WITH_AES_128_GCM_SHA256"] = TLS_DH_DSS_WITH_AES_128_GCM_SHA256; - _ciphers["DH_DSS_WITH_AES_256_GCM_SHA384"] = TLS_DH_DSS_WITH_AES_256_GCM_SHA384; - _ciphers["DH_anon_WITH_AES_128_GCM_SHA256"] = TLS_DH_anon_WITH_AES_128_GCM_SHA256; - _ciphers["DH_anon_WITH_AES_256_GCM_SHA384"] = TLS_DH_anon_WITH_AES_256_GCM_SHA384; + // + // Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites for TLS. + // + _ciphers["RSA_WITH_AES_128_GCM_SHA256"] = TLS_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["RSA_WITH_AES_256_GCM_SHA384"] = TLS_RSA_WITH_AES_256_GCM_SHA384; + _ciphers["DHE_RSA_WITH_AES_128_GCM_SHA256"] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["DHE_RSA_WITH_AES_256_GCM_SHA384"] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384; + _ciphers["DH_RSA_WITH_AES_128_GCM_SHA256"] = TLS_DH_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["DH_RSA_WITH_AES_256_GCM_SHA384"] = TLS_DH_RSA_WITH_AES_256_GCM_SHA384; + _ciphers["DHE_DSS_WITH_AES_128_GCM_SHA256"] = TLS_DHE_DSS_WITH_AES_128_GCM_SHA256; + _ciphers["DHE_DSS_WITH_AES_256_GCM_SHA384"] = TLS_DHE_DSS_WITH_AES_256_GCM_SHA384; + _ciphers["DH_DSS_WITH_AES_128_GCM_SHA256"] = TLS_DH_DSS_WITH_AES_128_GCM_SHA256; + _ciphers["DH_DSS_WITH_AES_256_GCM_SHA384"] = TLS_DH_DSS_WITH_AES_256_GCM_SHA384; + _ciphers["DH_anon_WITH_AES_128_GCM_SHA256"] = TLS_DH_anon_WITH_AES_128_GCM_SHA256; + _ciphers["DH_anon_WITH_AES_256_GCM_SHA384"] = TLS_DH_anon_WITH_AES_256_GCM_SHA384; - // - // RFC 5487 - PSK with SHA-256/384 and AES GCM - // - _ciphers["PSK_WITH_AES_128_GCM_SHA256"] = TLS_PSK_WITH_AES_128_GCM_SHA256; - _ciphers["PSK_WITH_AES_256_GCM_SHA384"] = TLS_PSK_WITH_AES_256_GCM_SHA384; - _ciphers["DHE_PSK_WITH_AES_128_GCM_SHA256"] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256; - _ciphers["DHE_PSK_WITH_AES_256_GCM_SHA384"] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384; - _ciphers["RSA_PSK_WITH_AES_128_GCM_SHA256"] = TLS_RSA_PSK_WITH_AES_128_GCM_SHA256; - _ciphers["RSA_PSK_WITH_AES_256_GCM_SHA384"] = TLS_RSA_PSK_WITH_AES_256_GCM_SHA384; - - _ciphers["PSK_WITH_AES_128_CBC_SHA256"] = TLS_PSK_WITH_AES_128_CBC_SHA256; - _ciphers["PSK_WITH_AES_256_CBC_SHA384"] = TLS_PSK_WITH_AES_256_CBC_SHA384; - _ciphers["PSK_WITH_NULL_SHA256"] = TLS_PSK_WITH_NULL_SHA256; - _ciphers["PSK_WITH_NULL_SHA384"] = TLS_PSK_WITH_NULL_SHA384; - - _ciphers["DHE_PSK_WITH_AES_128_CBC_SHA256"] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256; - _ciphers["DHE_PSK_WITH_AES_256_CBC_SHA384"] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384; - _ciphers["DHE_PSK_WITH_NULL_SHA256"] = TLS_DHE_PSK_WITH_NULL_SHA256; - _ciphers["DHE_PSK_WITH_NULL_SHA384"] = TLS_DHE_PSK_WITH_NULL_SHA384; - - _ciphers["RSA_PSK_WITH_AES_128_CBC_SHA256"] = TLS_RSA_PSK_WITH_AES_128_CBC_SHA256; - _ciphers["RSA_PSK_WITH_AES_256_CBC_SHA384"] = TLS_RSA_PSK_WITH_AES_256_CBC_SHA384; - _ciphers["RSA_PSK_WITH_NULL_SHA256"] = TLS_RSA_PSK_WITH_NULL_SHA256; - _ciphers["RSA_PSK_WITH_NULL_SHA384"] = TLS_RSA_PSK_WITH_NULL_SHA384; + // + // RFC 5487 - PSK with SHA-256/384 and AES GCM + // + _ciphers["PSK_WITH_AES_128_GCM_SHA256"] = TLS_PSK_WITH_AES_128_GCM_SHA256; + _ciphers["PSK_WITH_AES_256_GCM_SHA384"] = TLS_PSK_WITH_AES_256_GCM_SHA384; + _ciphers["DHE_PSK_WITH_AES_128_GCM_SHA256"] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256; + _ciphers["DHE_PSK_WITH_AES_256_GCM_SHA384"] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384; + _ciphers["RSA_PSK_WITH_AES_128_GCM_SHA256"] = TLS_RSA_PSK_WITH_AES_128_GCM_SHA256; + _ciphers["RSA_PSK_WITH_AES_256_GCM_SHA384"] = TLS_RSA_PSK_WITH_AES_256_GCM_SHA384; + + _ciphers["PSK_WITH_AES_128_CBC_SHA256"] = TLS_PSK_WITH_AES_128_CBC_SHA256; + _ciphers["PSK_WITH_AES_256_CBC_SHA384"] = TLS_PSK_WITH_AES_256_CBC_SHA384; + _ciphers["PSK_WITH_NULL_SHA256"] = TLS_PSK_WITH_NULL_SHA256; + _ciphers["PSK_WITH_NULL_SHA384"] = TLS_PSK_WITH_NULL_SHA384; + + _ciphers["DHE_PSK_WITH_AES_128_CBC_SHA256"] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256; + _ciphers["DHE_PSK_WITH_AES_256_CBC_SHA384"] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384; + _ciphers["DHE_PSK_WITH_NULL_SHA256"] = TLS_DHE_PSK_WITH_NULL_SHA256; + _ciphers["DHE_PSK_WITH_NULL_SHA384"] = TLS_DHE_PSK_WITH_NULL_SHA384; + + _ciphers["RSA_PSK_WITH_AES_128_CBC_SHA256"] = TLS_RSA_PSK_WITH_AES_128_CBC_SHA256; + _ciphers["RSA_PSK_WITH_AES_256_CBC_SHA384"] = TLS_RSA_PSK_WITH_AES_256_CBC_SHA384; + _ciphers["RSA_PSK_WITH_NULL_SHA256"] = TLS_RSA_PSK_WITH_NULL_SHA256; + _ciphers["RSA_PSK_WITH_NULL_SHA384"] = TLS_RSA_PSK_WITH_NULL_SHA384; - // - // Addenda from rfc 5289 Elliptic Curve Cipher Suites with HMAC SHA-256/384. - // - _ciphers["ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256; - _ciphers["ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384; - _ciphers["ECDH_ECDSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256; - _ciphers["ECDH_ECDSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384; - _ciphers["ECDHE_RSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256; - _ciphers["ECDHE_RSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384; - _ciphers["ECDH_RSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256; - _ciphers["ECDH_RSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384; + // + // Addenda from rfc 5289 Elliptic Curve Cipher Suites with HMAC SHA-256/384. + // + _ciphers["ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256; + _ciphers["ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384; + _ciphers["ECDH_ECDSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256; + _ciphers["ECDH_ECDSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384; + _ciphers["ECDHE_RSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["ECDHE_RSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384; + _ciphers["ECDH_RSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256; + _ciphers["ECDH_RSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384; - // - // Addenda from rfc 5289 Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM) - // - _ciphers["ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; - _ciphers["ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384; - _ciphers["ECDH_ECDSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256; - _ciphers["ECDH_ECDSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384; - _ciphers["ECDHE_RSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; - _ciphers["ECDHE_RSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384; - _ciphers["ECDH_RSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256; - _ciphers["ECDH_RSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384; + // + // Addenda from rfc 5289 Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM) + // + _ciphers["ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; + _ciphers["ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384; + _ciphers["ECDH_ECDSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256; + _ciphers["ECDH_ECDSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384; + _ciphers["ECDHE_RSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["ECDHE_RSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384; + _ciphers["ECDH_RSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256; + _ciphers["ECDH_RSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384; - // - // RFC 5746 - Secure Renegotiation - // - _ciphers["EMPTY_RENEGOTIATION_INFO_SCSV"] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV; + // + // RFC 5746 - Secure Renegotiation + // + _ciphers["EMPTY_RENEGOTIATION_INFO_SCSV"] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV; - // - // Tags for SSL 2 cipher kinds that are not specified for SSL 3. - // - _ciphers["RSA_WITH_RC2_CBC_MD5"] = SSL_RSA_WITH_RC2_CBC_MD5; - _ciphers["RSA_WITH_IDEA_CBC_MD5"] = SSL_RSA_WITH_IDEA_CBC_MD5; - _ciphers["RSA_WITH_DES_CBC_MD5"] = SSL_RSA_WITH_DES_CBC_MD5; - _ciphers["RSA_WITH_3DES_EDE_CBC_MD5"] = SSL_RSA_WITH_3DES_EDE_CBC_MD5; - _ciphers["NO_SUCH_CIPHERSUITE"] = SSL_NO_SUCH_CIPHERSUITE; + // + // Tags for SSL 2 cipher kinds that are not specified for SSL 3. + // + _ciphers["RSA_WITH_RC2_CBC_MD5"] = SSL_RSA_WITH_RC2_CBC_MD5; + _ciphers["RSA_WITH_IDEA_CBC_MD5"] = SSL_RSA_WITH_IDEA_CBC_MD5; + _ciphers["RSA_WITH_DES_CBC_MD5"] = SSL_RSA_WITH_DES_CBC_MD5; + _ciphers["RSA_WITH_3DES_EDE_CBC_MD5"] = SSL_RSA_WITH_3DES_EDE_CBC_MD5; + _ciphers["NO_SUCH_CIPHERSUITE"] = SSL_NO_SUCH_CIPHERSUITE; + } } SSLCipherSuite @@ -797,9 +821,7 @@ IceSSL::SecureTransportEngine::SecureTransportEngine(const Ice::CommunicatorPtr& _protocolVersionMin(kSSLProtocolUnknown), _dhParams(0), _dhParamsLength(0), - _ciphers(new ScopedArray<SSLCipherSuite>()), - _allCiphers(false), - _numCiphers(-1) + _allCiphers(false) { } @@ -838,15 +860,25 @@ IceSSL::SecureTransportEngine::initialize() string keychainPath = properties->getProperty("IceSSL.Keychain"); string keychainPassword = properties->getProperty("IceSSL.KeychainPassword"); - // - // KeyChain path is relative to the current working directory. - // + bool usePassword = !keychainPassword.empty(); + size_t size = keychainPassword.size(); + const char* password = usePassword ? keychainPassword.c_str() : 0; + OSStatus err = noErr; if(keychainPath.empty()) { - keychainPath = "login.keychain"; + err = SecKeychainCopyDefault(&_keychain); + if(err != noErr) + { + ostringstream os; + os << "IceSSL: unable to retrieve default keychain:\n" << errorToString(err); + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } } else { + // + // KeyChain path is relative to the current working directory. + // if(!IceUtilInternal::isAbsolutePath(keychainPath)) { string cwd; @@ -855,18 +887,14 @@ IceSSL::SecureTransportEngine::initialize() keychainPath = string(cwd) + '/' + keychainPath; } } - } - - bool usePassword = !keychainPassword.empty(); - size_t size = keychainPassword.size(); - const char* password = usePassword ? keychainPassword.c_str() : 0; - OSStatus err = SecKeychainOpen(keychainPath.c_str(), &_keychain); - if(err != noErr) - { - ostringstream os; - os << "IceSSL: unable to open keychain: `" << keychainPath << "'\n" << errorToString(err); - throw PluginInitializationException(__FILE__, __LINE__, os.str()); + err = SecKeychainOpen(keychainPath.c_str(), &_keychain); + if(err != noErr) + { + ostringstream os; + os << "IceSSL: unable to open keychain: `" << keychainPath << "'\n" << errorToString(err); + throw PluginInitializationException(__FILE__, __LINE__, os.str()); + } } SecKeychainStatus status; @@ -878,7 +906,7 @@ IceSSL::SecureTransportEngine::initialize() if(err != noErr) { ostringstream os; - os << "IceSSL: unable to unlock keychain: `" << keychainPath << "'\n" << errorToString(err); + os << "IceSSL: unable to unlock keychain:\n" << errorToString(err); throw PluginInitializationException(__FILE__, __LINE__, os.str()); } } @@ -888,19 +916,20 @@ IceSSL::SecureTransportEngine::initialize() if(err != noErr) { ostringstream os; - os << "IceSSL: unable to create keychain: `" << keychainPath << "'\n" << errorToString(err); + os << "IceSSL: unable to create keychain:\n" << errorToString(err); throw PluginInitializationException(__FILE__, __LINE__, os.str()); } } else { ostringstream os; - os << "IceSSL: unable to open keychain: `" << keychainPath << "'\n" << errorToString(err); + os << "IceSSL: unable to open keychain:\n" << errorToString(err); throw PluginInitializationException(__FILE__, __LINE__, os.str()); } int passwordRetryMax = properties->getPropertyAsIntWithDefault(propPrefix + "PasswordRetryMax", 3); PasswordPromptPtr passwordPrompt = getPasswordPrompt(); + // // Load the CA certificates used to authenticate peers into // _certificateAuthorities array. @@ -925,6 +954,11 @@ IceSSL::SecureTransportEngine::initialize() PluginInitializationException ex(__FILE__, __LINE__, ce.reason); throw ex; } + catch(const CertificateEncodingException& ce) + { + PluginInitializationException ex(__FILE__, __LINE__, ce.reason); + throw ex; + } string caDir = properties->getPropertyWithDefault(propPrefix + "CertAuthDir", defaultDir); if(!caDir.empty()) @@ -956,6 +990,12 @@ IceSSL::SecureTransportEngine::initialize() // Some files in CertAuthDir might not be certificates, we just ignore those files. // } + catch(const CertificateEncodingException&) + { + // + // Some files in CertAuthDir might not be certificates, we just ignore those files. + // + } } _certificateAuthorities = certificateAuthorities; } @@ -974,80 +1014,91 @@ IceSSL::SecureTransportEngine::initialize() if(!certFile.empty()) { - try + vector<string> files; + if(!IceUtilInternal::splitString(certFile, IceUtilInternal::pathsep, files) || files.size() > 2) { - vector<string> files; - if(!IceUtilInternal::splitString(certFile, IceUtilInternal::pathsep, files) || files.size() > 2) + PluginInitializationException ex(__FILE__, __LINE__); + ex.reason = "IceSSL: invalid value for " + propPrefix + "CertFile:\n" + certFile; + throw ex; + } + numCerts = files.size(); + for(vector<string>::iterator p = files.begin(); p != files.end();) + { + string file = *p; + if(!checkPath(file, defaultDir, false)) { PluginInitializationException ex(__FILE__, __LINE__); - ex.reason = "IceSSL: invalid value for " + propPrefix + "CertFile:\n" + certFile; + ex.reason = "IceSSL: certificate file not found:\n" + file; throw ex; } - numCerts = files.size(); - for(vector<string>::iterator p = files.begin(); p != files.end(); ++p) + + try { - string file = *p; - if(!checkPath(file, defaultDir, false)) - { - PluginInitializationException ex(__FILE__, __LINE__); - ex.reason = "IceSSL: certificate file not found:\n" + file; - throw ex; - } - loadCertificate(&_cert, &hash, keyFile.empty() ? &_key : 0, _keychain, file, properties->getProperty(propPrefix + "Password"), passwordPrompt, passwordRetryMax); break; } - } - catch(const CertificateReadException& ce) - { - PluginInitializationException ex(__FILE__, __LINE__, ce.reason); - throw ex; + catch(const CertificateReadException& ce) + { + // + // If this is the last certificate rethrow the exception as PluginInitializationException, + // otherwise try the next certificate. + // + if(++p == files.end()) + { + PluginInitializationException ex(__FILE__, __LINE__, ce.reason); + throw ex; + } + } } } if(!keyFile.empty()) { - try + vector<string> files; + if(!IceUtilInternal::splitString(keyFile, IceUtilInternal::pathsep, files) || files.size() > 2) { - vector<string> files; - if(!IceUtilInternal::splitString(keyFile, IceUtilInternal::pathsep, files) || files.size() > 2) + PluginInitializationException ex(__FILE__, __LINE__); + ex.reason = "IceSSL: invalid value for " + propPrefix + "KeyFile:\n" + keyFile; + throw ex; + } + if(files.size() != numCerts) + { + PluginInitializationException ex(__FILE__, __LINE__); + ex.reason = "IceSSL: " + propPrefix + "KeyFile does not agree with " + propPrefix + "CertFile"; + throw ex; + } + for(vector<string>::iterator p = files.begin(); p != files.end();) + { + string file = *p; + if(!checkPath(file, defaultDir, false)) { PluginInitializationException ex(__FILE__, __LINE__); - ex.reason = "IceSSL: invalid value for " + propPrefix + "KeyFile:\n" + keyFile; + ex.reason = "IceSSL: key file not found:\n" + file; throw ex; } - if(files.size() != numCerts) + + try { - PluginInitializationException ex(__FILE__, __LINE__); - ex.reason = "IceSSL: " + propPrefix + "KeyFile does not agree with " + propPrefix + "CertFile"; - throw ex; + loadPrivateKey(&_key, keyLabel(_cert), hash, _keychain, file, + properties->getProperty(propPrefix + "Password"), + passwordPrompt, passwordRetryMax); + break; } - for(vector<string>::iterator p = files.begin(); p != files.end(); ++p) + catch(const CertificateReadException& ce) { - string file = *p; - if(!checkPath(file, defaultDir, false)) + // + // If this is the last key rethrow the exception as PluginInitializationException, + // otherwise try the next certificate. + // + if(++p == files.end()) { - PluginInitializationException ex(__FILE__, __LINE__); - ex.reason = "IceSSL: key file not found:\n" + file; + PluginInitializationException ex(__FILE__, __LINE__, ce.reason); throw ex; } - // - // The private key may be stored in an encrypted file, so handle - // password retries. - // - loadPrivateKey(&_key, keyLabel(_cert), hash, _keychain, file, - properties->getProperty(propPrefix + "Password"), - passwordPrompt, passwordRetryMax); - break; } } - catch(const CertificateReadException& ce) - { - PluginInitializationException ex(__FILE__, __LINE__, ce.reason); - throw ex; - } } if(_cert) @@ -1162,10 +1213,10 @@ IceSSL::SecureTransportEngine::destroy() } } -ContextRef +SSLContextRef IceSSL::SecureTransportEngine::newContext(bool incoming) { - ContextRef ssl = SSLCreateContext(kCFAllocatorDefault, incoming ? kSSLServerSide : kSSLClientSide, kSSLStreamType); + SSLContextRef ssl = SSLCreateContext(kCFAllocatorDefault, incoming ? kSSLServerSide : kSSLClientSide, kSSLStreamType); if(!ssl) { PluginInitializationException ex(__FILE__, __LINE__, "IceSSL: unable to create SSL context"); @@ -1217,16 +1268,17 @@ IceSSL::SecureTransportEngine::newContext(bool incoming) // // Retrieve the certificate chain // - SecPolicyRef policy = SecPolicyCreateSSL(true, 0); + SecPolicyRef policy = SecPolicyCreateSSL(incoming, 0); SecTrustRef trust; err = SecTrustCreateWithCertificates((CFArrayRef)_cert, policy, &trust); + CFRelease(policy); if(err != noErr || !trust) { ostringstream os; os << "IceSSL: unable to create the trust object"; if(err != noErr) { - os << '\n' << errorToString(err); + os << ":\n" << errorToString(err); } PluginInitializationException ex(__FILE__, __LINE__, os.str()); throw ex; @@ -1236,7 +1288,7 @@ IceSSL::SecureTransportEngine::newContext(bool incoming) if(err != noErr) { ostringstream os; - os << "IceSSL: unable to establish the anchor certificates\n" << errorToString(err); + os << "IceSSL: unable to establish the anchor certificates:\n" << errorToString(err); PluginInitializationException ex(__FILE__, __LINE__, os.str()); throw ex; } @@ -1274,9 +1326,9 @@ IceSSL::SecureTransportEngine::newContext(bool incoming) } - if(_numCiphers != -1) + if(!_ciphers.empty()) { - err = SSLSetEnabledCiphers(ssl, _ciphers->get(), _numCiphers); + err = SSLSetEnabledCiphers(ssl, reinterpret_cast<SSLCipherSuite*>(&_ciphers[0]), _ciphers.size()); if(err != noErr) { ostringstream os; @@ -1356,6 +1408,16 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) } _allCiphers = true; } + else if(token == "NONE") + { + if(i != tokens.begin()) + { + ostringstream os; + os << "IceSSL: `NONE' must be first in cipher list `" << ciphers << "'"; + PluginInitializationException ex(__FILE__, __LINE__, os.str()); + throw ex; + } + } else { CipherExpression ce; @@ -1374,6 +1436,10 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) throw ex; } } + else + { + ce.negation = false; + } if(token.find('(') == 0) { @@ -1405,28 +1471,28 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) cipherExpressions.push_back(ce); } } + size_t numSupportedCiphers = 0; SSLGetNumberSupportedCiphers(_ctx, &numSupportedCiphers); - ScopedArray<SSLCipherSuite> buffer(new SSLCipherSuite[numSupportedCiphers]); + vector<SSLCipherSuite> supported; + supported.resize(numSupportedCiphers); - OSStatus err; - if((err = SSLGetSupportedCiphers(_ctx, buffer.get(), &numSupportedCiphers)) != noErr) + OSStatus err = SSLGetSupportedCiphers(_ctx, + reinterpret_cast<SSLCipherSuite*>(&supported[0]), + &numSupportedCiphers); + if(err != noErr) { ostringstream os; - os << "IceSSL: unable to get supported ciphers list (error = " << err << ")"; + os << "IceSSL: unable to get supported ciphers list:\n" << errorToString(err); PluginInitializationException ex(__FILE__, __LINE__, os.str()); throw ex; } - SSLCipherSuite* supported = buffer.get(); - vector<SSLCipherSuite> allCiphers; + vector<SSLCipherSuite> enabled; if(_allCiphers) { - for(int i = 0; i < numSupportedCiphers; ++i) - { - allCiphers.push_back(supported[i]); - } + enabled = supported; } for(vector<CipherExpression>::const_iterator i = cipherExpressions.begin(); i != cipherExpressions.end(); ++i) @@ -1434,7 +1500,7 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) CipherExpression ce = *i; if(ce.negation) { - for(vector<SSLCipherSuite>::iterator j = allCiphers.begin(); j != allCiphers.end();) + for(vector<SSLCipherSuite>::iterator j = enabled.begin(); j != enabled.end();) { SSLCipherSuite cipher = *j; string name = CiphersHelper::cipherName(cipher); @@ -1443,7 +1509,7 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) { if(ce.re->match(name)) { - j = allCiphers.erase(j); + j = enabled.erase(j); continue; } } @@ -1451,7 +1517,7 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) { if(ce.cipher == name) { - j = allCiphers.erase(j); + j = enabled.erase(j); continue; } } @@ -1462,16 +1528,16 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) { if(ce.cipher.empty()) { - for(int i = 0; i < numSupportedCiphers; ++i) + for(vector<SSLCipherSuite>::const_iterator j = supported.begin(); j != supported.end(); ++j) { - SSLCipherSuite cipher = supported[i]; + SSLCipherSuite cipher = *j; string name = CiphersHelper::cipherName(cipher); if(ce.re->match(name)) { - vector<SSLCipherSuite>::const_iterator k = find(allCiphers.begin(), allCiphers.end(), cipher); - if(k == allCiphers.end()) + vector<SSLCipherSuite>::const_iterator k = find(enabled.begin(), enabled.end(), cipher); + if(k == enabled.end()) { - allCiphers.push_back(cipher); + enabled.push_back(cipher); } } } @@ -1479,25 +1545,15 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) else { SSLCipherSuite cipher = CiphersHelper::cipherForName(ce.cipher); - vector<SSLCipherSuite>::const_iterator k = find(allCiphers.begin(), allCiphers.end(), cipher); - if(k == allCiphers.end()) + vector<SSLCipherSuite>::const_iterator k = find(enabled.begin(), enabled.end(), cipher); + if(k == enabled.end()) { - allCiphers.push_back(cipher); + enabled.push_back(cipher); } } } } - - if(!allCiphers.empty()) - { - _ciphers.reset(new ScopedArray<SSLCipherSuite>(new SSLCipherSuite[allCiphers.size()])); - SSLCipherSuite* enabled = _ciphers->get(); - for(vector<SSLCipherSuite>::const_iterator i = allCiphers.begin(); i != allCiphers.end(); ++i) - { - *(enabled++) = *i; - } - } - _numCiphers = allCiphers.size(); + _ciphers = enabled; } SecCertificateRef diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp index 38572c5ba65..bd25cf57c08 100644 --- a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp +++ b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp @@ -14,6 +14,7 @@ #include <IceSSL/ConnectionInfo.h> #include <IceSSL/Instance.h> +#include <IceSSL/SSLEngine.h> #include <IceSSL/Util.h> #include <Ice/Communicator.h> #include <Ice/LoggerUtil.h> @@ -36,23 +37,20 @@ trustResultDescription(SecTrustResultType result) { case kSecTrustResultInvalid: { - return "Invalid setting or result."; + return "Invalid setting or result"; } case kSecTrustResultDeny: { - return "The user specified that the certificate should not be trusted."; + return "The user specified that the certificate should not be trusted"; } case kSecTrustResultRecoverableTrustFailure: - { - return "Trust denied; retry after changing settings."; - } case kSecTrustResultFatalTrustFailure: { - return "Trust denied; no simple fix is available."; + return "Trust denied; no simple fix is available"; } case kSecTrustResultOtherError: { - return "A failure other than that of trust evaluation."; + return "Other error internal error"; } default: { @@ -393,9 +391,30 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B } } - if(_instance->securityTraceLevel() >= 1) + if(_instance->engine()->securityTraceLevel() >= 1) { - traceConnection(); + assert(_ssl); + Trace out(_instance->logger(), _instance->traceCategory()); + out << "SSL summary for " << (_incoming ? "incoming" : "outgoing") << " connection\n"; + + SSLProtocol protocol; + SSLGetNegotiatedProtocolVersion(_ssl, &protocol); + const string sslProtocolName = protocolName(protocol); + + SSLCipherSuite cipher; + SSLGetNegotiatedCipher(_ssl, &cipher); + const string sslCipherName = _engine->getCipherName(cipher); + + if(sslCipherName.empty()) + { + out << "unknown cipher\n"; + } + else + { + out << "cipher = " << sslCipherName << "\n"; + out << "protocol = " << sslProtocolName << "\n"; + } + out << IceInternal::fdToString(_fd); } return IceInternal::SocketOperationNone; @@ -479,7 +498,7 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf) // // It's impossible for packetSize to be more than an Int. // - size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i); + size_t packetSize = buf.b.end() - buf.i; packetSize = std::min(packetSize, _maxSendPacketSize); while(buf.i != buf.b.end()) { @@ -539,7 +558,7 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf) if(packetSize > buf.b.end() - buf.i) { - packetSize = static_cast<int>(buf.b.end() - buf.i); + packetSize = buf.b.end() - buf.i; } } @@ -564,7 +583,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf, bool&) // // It's impossible for packetSize to be more than an Int. // - size_t packetSize = static_cast<int>(buf.b.end() - buf.i); + size_t packetSize = buf.b.end() - buf.i; size_t processed = 0; packetSize = std::min(packetSize, _maxReceivePacketSize); @@ -632,7 +651,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf, bool&) if(packetSize > buf.b.end() - buf.i) { - packetSize = static_cast<int>(buf.b.end() - buf.i); + packetSize = buf.b.end() - buf.i; } } return IceInternal::SocketOperationNone; @@ -665,18 +684,6 @@ IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer& buf, size_t messa } } -SecTrustRef -IceSSL::TransceiverI::trust() const -{ - return _trust; -} - -ContextRef -IceSSL::TransceiverI::context() const -{ - return _ssl; -} - IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, SOCKET fd, const IceInternal::NetworkProxyPtr& proxy, const string& host, const IceInternal::Address& addr) : IceInternal::NativeInfo(fd), @@ -712,11 +719,11 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, SOCKET fd, const } // - // Limit the size of packet pass to SSLWrite/SSLRead to avoid blocking and + // Limit the size of packet passed to SSLWrite/SSLRead to avoid blocking and // holding too much memory. // - _maxSendPacketSize = std::min(512, IceInternal::getSendBufferSize(fd)); - _maxReceivePacketSize = std::min(512, IceInternal::getRecvBufferSize(fd)); + _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(fd)); + _maxReceivePacketSize = std::max(512, IceInternal::getRecvBufferSize(fd)); } IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, SOCKET fd, const string& adapterName) : @@ -737,11 +744,11 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, SOCKET fd, const IceInternal::setTcpBufSize(fd, _instance->properties(), _instance->logger()); // - // Limit the size of packet pass to SSLWrite/SSLRead to avoid blocking and + // Limit the size of packet passed to SSLWrite/SSLRead to avoid blocking and // holding too much memory. // - _maxSendPacketSize = std::min(512, IceInternal::getSendBufferSize(fd)); - _maxReceivePacketSize = std::min(512, IceInternal::getRecvBufferSize(fd)); + _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(fd)); + _maxReceivePacketSize = std::max(512, IceInternal::getRecvBufferSize(fd)); } IceSSL::TransceiverI::~TransceiverI() @@ -780,10 +787,7 @@ IceSSL::TransceiverI::getNativeConnectionInfo() const bool IceSSL::TransceiverI::writeRaw(IceInternal::Buffer& buf) { - // - // It's impossible for packetSize to be more than an Int. - // - int packetSize = static_cast<int>(buf.b.end() - buf.i); + int packetSize = buf.b.end() - buf.i; while(buf.i != buf.b.end()) { assert(_fd != INVALID_SOCKET); @@ -838,7 +842,7 @@ IceSSL::TransceiverI::writeRaw(IceInternal::Buffer& buf) if(packetSize > buf.b.end() - buf.i) { - packetSize = static_cast<int>(buf.b.end() - buf.i); + packetSize = buf.b.end() - buf.i; } } @@ -848,10 +852,7 @@ IceSSL::TransceiverI::writeRaw(IceInternal::Buffer& buf) bool IceSSL::TransceiverI::readRaw(IceInternal::Buffer& buf) { - // - // It's impossible for packetSize to be more than an Int. - // - int packetSize = static_cast<int>(buf.b.end() - buf.i); + int packetSize = buf.b.end() - buf.i; while(buf.i != buf.b.end()) { assert(_fd != INVALID_SOCKET); @@ -903,43 +904,12 @@ IceSSL::TransceiverI::readRaw(IceInternal::Buffer& buf) } buf.i += ret; - - packetSize = static_cast<int>(buf.b.end() - buf.i); + packetSize = buf.b.end() - buf.i; } return true; } -// -// Trace connection -// -void -IceSSL::TransceiverI::traceConnection() -{ - assert(_ssl); - Trace out(_instance->logger(), _instance->traceCategory()); - out << "SSL summary for " << (_incoming ? "incoming" : "outgoing") << " connection\n"; - - SSLProtocol protocol; - SSLGetNegotiatedProtocolVersion(_ssl, &protocol); - const string sslProtocolName = protocolName(protocol); - - SSLCipherSuite cipher; - SSLGetNegotiatedCipher(_ssl, &cipher); - const string sslCipherName = _engine->getCipherName(cipher); - - if(sslCipherName.empty()) - { - out << "unknown cipher\n"; - } - else - { - out << "cipher = " << sslCipherName << "\n"; - out << "protocol = " << sslProtocolName << "\n"; - } - out << IceInternal::fdToString(_fd); -} - OSStatus IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const { @@ -974,7 +944,7 @@ IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const if(IceInternal::wouldBlock()) { - *length = static_cast<int>(i - data); + *length = i - data; _flags |= SSLWantWrite; return errSSLWouldBlock; } @@ -982,18 +952,13 @@ IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const } i += ret; - if(_instance->traceLevel() >= 3) - { - Trace out(_instance->logger(), _instance->traceCategory()); - out << "sent " << ret << " of " << packetSize << " bytes via " << protocol() << "\n" << toString(); - } if(packetSize > end - i) { - packetSize = static_cast<int>(end - i); + packetSize = end - i; } } - *length = static_cast<int>(i - data); + *length = i - data; return noErr; } @@ -1030,7 +995,7 @@ IceSSL::TransceiverI::readRaw(char* data, size_t* length) const if(IceInternal::wouldBlock()) { - *length = static_cast<int>(i - data); + *length = i - data; _flags |= SSLWantRead; return errSSLWouldBlock; } @@ -1038,17 +1003,10 @@ IceSSL::TransceiverI::readRaw(char* data, size_t* length) const } i += ret; - - if(_instance->traceLevel() >= 3) - { - Trace out(_instance->logger(), _instance->traceCategory()); - out << "received " << ret << " of " << packetSize << " bytes via " << protocol() << "\n" << toString(); - } - - packetSize = static_cast<int>(end - i); + packetSize = end - i; } - *length = static_cast<int>(i - data); + *length = i - data; return noErr; } diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.h b/cpp/src/IceSSL/SecureTransportTransceiverI.h index c38c8d26b4c..bef04b5c8c0 100644 --- a/cpp/src/IceSSL/SecureTransportTransceiverI.h +++ b/cpp/src/IceSSL/SecureTransportTransceiverI.h @@ -56,8 +56,6 @@ public: virtual Ice::ConnectionInfoPtr getInfo() const; virtual void checkSendSize(const IceInternal::Buffer&, size_t); - ContextRef context() const; - SecTrustRef trust() const; OSStatus writeRaw(const char*, size_t*) const; OSStatus readRaw(char*, size_t*) const; @@ -88,7 +86,7 @@ private: const std::string _adapterName; const bool _incoming; - ContextRef _ssl; + SSLContextRef _ssl; SecTrustRef _trust; size_t _buffered; diff --git a/cpp/src/IceSSL/TransceiverI.cpp b/cpp/src/IceSSL/TransceiverI.cpp index d749cdf9651..597faa8e923 100644 --- a/cpp/src/IceSSL/TransceiverI.cpp +++ b/cpp/src/IceSSL/TransceiverI.cpp @@ -14,6 +14,7 @@ #include <IceSSL/ConnectionInfo.h> #include <IceSSL/Instance.h> +#include <IceSSL/SSLEngine.h> #include <IceSSL/Util.h> #include <Ice/Communicator.h> #include <Ice/LoggerUtil.h> @@ -405,7 +406,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B } } - if(_instance->securityTraceLevel() >= 1) + if(_instance->engine()->securityTraceLevel() >= 1) { traceConnection(); } diff --git a/cpp/src/IceSSL/Util.cpp b/cpp/src/IceSSL/Util.cpp index 518fd9f5d67..27fd312c3d6 100644 --- a/cpp/src/IceSSL/Util.cpp +++ b/cpp/src/IceSSL/Util.cpp @@ -401,6 +401,30 @@ IceSSL::readFile(const string& file, ScopedArray<char>& buffer) return length; } +CFDictionaryRef +IceSSL::getCertificateProperty(SecCertificateRef cert, CFTypeRef key) +{ + CFArrayRef keys = CFArrayCreate(NULL, &key , 1, &kCFTypeArrayCallBacks); + CFErrorRef err = 0; + CFDictionaryRef values = SecCertificateCopyValues(cert, keys, &err); + CFRelease(keys); + + if(err) + { + CertificateEncodingException ex(__FILE__, __LINE__, err); + throw ex; + } + + assert(values); + CFDictionaryRef property = (CFDictionaryRef)CFDictionaryGetValue(values, key); + if(property) + { + CFRetain(property); + } + CFRelease(values); + return property; +} + namespace { @@ -412,39 +436,22 @@ CFDataRef getSubjectKeyIdentifier(SecCertificateRef cert) { CFDataRef data = 0; - CFErrorRef err = 0; - CFArrayRef keys = CFArrayCreate(NULL, &kSecOIDSubjectKeyIdentifier , 1, &kCFTypeArrayCallBacks); - CFDictionaryRef values = SecCertificateCopyValues(cert, keys, &err); - CFRelease(keys); - - if(err) - { - ostringstream os; - os << "Failed to copy certificate subject key identifier\n" << errorToString(err); - CFRelease(err); - CertificateReadException ex(__FILE__, __LINE__, os.str()); - throw ex; - } - - if(values) + CFDictionaryRef property = getCertificateProperty(cert, kSecOIDSubjectKeyIdentifier); + if(property) { - CFDictionaryRef ski = (CFDictionaryRef)CFDictionaryGetValue(values, kSecOIDSubjectKeyIdentifier); - if(ski) + CFArrayRef propertyValues = (CFArrayRef)CFDictionaryGetValue(property, kSecPropertyKeyValue); + for(int i = 0, length = CFArrayGetCount(propertyValues); i < length; ++i) { - CFArrayRef propertyValues = (CFArrayRef)CFDictionaryGetValue(ski, kSecPropertyKeyValue); - for(int i = 0, length = CFArrayGetCount(propertyValues); i < length; ++i) + CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(propertyValues, i); + CFStringRef label = (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel); + if(CFEqual(label, CFSTR("Key Identifier"))) { - CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(propertyValues, i); - CFStringRef label = (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel); - if(CFEqual(label, CFSTR("Key Identifier"))) - { - data = (CFDataRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue); - CFRetain(data); - break; - } + data = (CFDataRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue); + CFRetain(data); + break; } } - CFRelease(values); + CFRelease(property); } return data; } @@ -456,43 +463,25 @@ bool isCA(SecCertificateRef cert) { bool ca = false; - CFErrorRef err = 0; - CFArrayRef keys = CFArrayCreate(NULL, &kSecOIDBasicConstraints, 1, &kCFTypeArrayCallBacks); - CFDictionaryRef values = SecCertificateCopyValues(cert, keys, &err); - CFRelease(keys); - - if(err) - { - ostringstream os; - os << "Failed to copy certificate basic constraints\n" << errorToString(err); - CFRelease(err); - CertificateReadException ex(__FILE__, __LINE__, os.str()); - throw ex; - } - - if(values) + CFDictionaryRef property = getCertificateProperty(cert, kSecOIDBasicConstraints); + if(property) { - CFDictionaryRef basicConstraints = (CFDictionaryRef)CFDictionaryGetValue(values, kSecOIDBasicConstraints); - if(basicConstraints) + CFArrayRef propertyValues = (CFArrayRef)CFDictionaryGetValue(property, kSecPropertyKeyValue); + for(int i = 0, size = CFArrayGetCount(propertyValues); i < size; ++i) { - CFArrayRef propertyValues = (CFArrayRef)CFDictionaryGetValue(basicConstraints, kSecPropertyKeyValue); - int size = CFArrayGetCount(propertyValues); - for(int i = 0; i < size; ++i) + CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(propertyValues, i); + CFStringRef label = (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel); + if(CFEqual(label, CFSTR("Certificate Authority"))) { - CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(propertyValues, i); - CFStringRef label = (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel); - if(CFEqual(label, CFSTR("Certificate Authority"))) + CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue); + if(CFEqual(value, CFSTR("Yes"))) { - CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue); - if(CFEqual(value, CFSTR("Yes"))) - { - ca = true; - } - break; + ca = true; } + break; } - CFRelease(values); } + CFRelease(property); } return ca; } diff --git a/cpp/src/IceSSL/Util.h b/cpp/src/IceSSL/Util.h index 0224f978a86..5b8784e29e5 100644 --- a/cpp/src/IceSSL/Util.h +++ b/cpp/src/IceSSL/Util.h @@ -89,6 +89,13 @@ std::string errorToString(OSStatus); int readFile(const std::string&, IceUtil::ScopedArray<char>&); +// +// Retrieve a certificate property +// +CFDictionaryRef +getCertificateProperty(SecCertificateRef, CFTypeRef); + + std::string keyLabel(SecCertificateRef); // |