summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2015-10-02 09:31:00 +0200
committerBenoit Foucher <benoit@zeroc.com>2015-10-02 09:31:00 +0200
commit228f3051c1a78f9749f848fd1a3411eee3d35827 (patch)
tree701d2031cb29c9f02b3eb8107ac7b90022e70451 /cpp
parentICE-6767 Better handling of server start failure by test controller (diff)
downloadice-228f3051c1a78f9749f848fd1a3411eee3d35827.tar.bz2
ice-228f3051c1a78f9749f848fd1a3411eee3d35827.tar.xz
ice-228f3051c1a78f9749f848fd1a3411eee3d35827.zip
Fixed ICE-6829 - open keychain only if needed
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/IceSSL/SSLEngine.h1
-rw-r--r--cpp/src/IceSSL/SecureTransportEngine.cpp179
2 files changed, 96 insertions, 84 deletions
diff --git a/cpp/src/IceSSL/SSLEngine.h b/cpp/src/IceSSL/SSLEngine.h
index f460135e785..aa3fd99e0a8 100644
--- a/cpp/src/IceSSL/SSLEngine.h
+++ b/cpp/src/IceSSL/SSLEngine.h
@@ -120,6 +120,7 @@ public:
private:
void parseCiphers(const std::string&);
+ SecKeychainRef openKeychain();
bool _initialized;
UniqueRef<CFArrayRef> _certificateAuthorities;
diff --git a/cpp/src/IceSSL/SecureTransportEngine.cpp b/cpp/src/IceSSL/SecureTransportEngine.cpp
index d9537ffedc2..250430c53ac 100644
--- a/cpp/src/IceSSL/SecureTransportEngine.cpp
+++ b/cpp/src/IceSSL/SecureTransportEngine.cpp
@@ -820,86 +820,6 @@ IceSSL::SecureTransportEngine::initialize()
const string defaultDir = properties->getProperty("IceSSL.DefaultDir");
//
- // Open the application KeyChain or create it if the keychain doesn't exists
- //
- string keychainPath = properties->getProperty("IceSSL.Keychain");
- string keychainPassword = properties->getProperty("IceSSL.KeychainPassword");
-
- SecKeychainRef keychain = 0;
- OSStatus err = 0;
- if(keychainPath.empty())
- {
- if((err = SecKeychainCopyDefault(&keychain)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unable to retrieve default keychain:\n" + errorToString(err));
- }
- }
- else
- {
- //
- // KeyChain path is relative to the current working directory.
- //
- if(!IceUtilInternal::isAbsolutePath(keychainPath))
- {
- string cwd;
- if(IceUtilInternal::getcwd(cwd) == 0)
- {
- keychainPath = string(cwd) + '/' + keychainPath;
- }
- }
-
- if((err = SecKeychainOpen(keychainPath.c_str(), &keychain)))
- {
- throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to open keychain: `" +
- keychainPath + "'\n" + errorToString(err));
- }
- }
-
- UniqueRef<SecKeychainRef> k(keychain);
-
- SecKeychainStatus status;
- err = SecKeychainGetStatus(keychain, &status);
- if(err == noErr)
- {
- const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str();
- if((err = SecKeychainUnlock(keychain, keychainPassword.size(), pass, pass != 0)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unable to unlock keychain:\n" + errorToString(err));
- }
- }
- else if(err == errSecNoSuchKeychain)
- {
- const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str();
- if((err = SecKeychainCreate(keychainPath.c_str(), keychainPassword.size(), pass, pass == 0, 0, &keychain)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unable to create keychain:\n" + errorToString(err));
- }
- k.reset(keychain);
- }
- else
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: unable to open keychain:\n" + errorToString(err));
- }
-
- //
- // Set keychain settings to avoid keychain lock.
- //
- SecKeychainSettings settings;
- settings.version = SEC_KEYCHAIN_SETTINGS_VERS1;
- settings.lockOnSleep = FALSE;
- settings.useLockInterval = FALSE;
- settings.lockInterval = INT_MAX;
- if((err = SecKeychainSetSettings(keychain, &settings)))
- {
- throw PluginInitializationException(__FILE__, __LINE__,
- "IceSSL: error setting keychain settings:\n" + errorToString(err));
- }
-
- //
// Load the CA certificates used to authenticate peers into
// _certificateAuthorities array.
//
@@ -983,9 +903,10 @@ IceSSL::SecureTransportEngine::initialize()
keyFile = resolved;
}
+ UniqueRef<SecKeychainRef> kc(openKeychain());
try
{
- _chain.reset(loadCertificateChain(file, keyFile, keychain, password, passwordPrompt, passwordRetryMax));
+ _chain.reset(loadCertificateChain(file, keyFile, kc.get(), password, passwordPrompt, passwordRetryMax));
break;
}
catch(const CertificateReadException& ce)
@@ -1003,14 +924,15 @@ IceSSL::SecureTransportEngine::initialize()
}
else if(!findCert.empty())
{
- UniqueRef<SecCertificateRef> cert(findCertificate(keychain, findCert));
+ UniqueRef<SecKeychainRef> kc(openKeychain());
+ UniqueRef<SecCertificateRef> cert(findCertificate(kc.get(), findCert));
//
// Retrieve the certificate chain
//
UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(true, 0));
SecTrustRef trust = 0;
- err = SecTrustCreateWithCertificates((CFArrayRef)cert.get(), policy.get(), &trust);
+ OSStatus err = SecTrustCreateWithCertificates((CFArrayRef)cert.get(), policy.get(), &trust);
if(err || !trust)
{
throw PluginInitializationException(__FILE__, __LINE__,
@@ -1038,7 +960,7 @@ IceSSL::SecureTransportEngine::initialize()
// identity.
//
SecIdentityRef identity;
- err = SecIdentityCreateWithCertificate(keychain, cert.get(), &identity);
+ err = SecIdentityCreateWithCertificate(kc.get(), cert.get(), &identity);
if(err != noErr)
{
ostringstream os;
@@ -1395,4 +1317,93 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers)
"\nThe result cipher list does not contain any entries");
}
}
+
+SecKeychainRef
+SecureTransportEngine::openKeychain()
+{
+ const PropertiesPtr properties = communicator()->getProperties();
+
+ //
+ // Open the application KeyChain or create it if the keychain doesn't exists
+ //
+ string keychainPath = properties->getProperty("IceSSL.Keychain");
+ string keychainPassword = properties->getProperty("IceSSL.KeychainPassword");
+
+ SecKeychainRef keychain = 0;
+ OSStatus err = 0;
+ if(keychainPath.empty())
+ {
+ if((err = SecKeychainCopyDefault(&keychain)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: unable to retrieve default keychain:\n" + errorToString(err));
+ }
+ }
+ else
+ {
+ //
+ // KeyChain path is relative to the current working directory.
+ //
+ if(!IceUtilInternal::isAbsolutePath(keychainPath))
+ {
+ string cwd;
+ if(IceUtilInternal::getcwd(cwd) == 0)
+ {
+ keychainPath = string(cwd) + '/' + keychainPath;
+ }
+ }
+
+ if((err = SecKeychainOpen(keychainPath.c_str(), &keychain)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to open keychain: `" +
+ keychainPath + "'\n" + errorToString(err));
+ }
+ }
+
+ UniqueRef<SecKeychainRef> k(keychain);
+
+ SecKeychainStatus status;
+ err = SecKeychainGetStatus(keychain, &status);
+ if(err == noErr)
+ {
+ const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str();
+ if((err = SecKeychainUnlock(keychain, keychainPassword.size(), pass, pass != 0)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: unable to unlock keychain:\n" + errorToString(err));
+ }
+ }
+ else if(err == errSecNoSuchKeychain)
+ {
+ const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str();
+ if((err = SecKeychainCreate(keychainPath.c_str(), keychainPassword.size(), pass, pass == 0, 0, &keychain)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: unable to create keychain:\n" + errorToString(err));
+ }
+ k.reset(keychain);
+ }
+ else
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: unable to open keychain:\n" + errorToString(err));
+ }
+
+ //
+ // Set keychain settings to avoid keychain lock.
+ //
+ SecKeychainSettings settings;
+ settings.version = SEC_KEYCHAIN_SETTINGS_VERS1;
+ settings.lockOnSleep = FALSE;
+ settings.useLockInterval = FALSE;
+ settings.lockInterval = INT_MAX;
+ if((err = SecKeychainSetSettings(keychain, &settings)))
+ {
+ throw PluginInitializationException(__FILE__, __LINE__,
+ "IceSSL: error setting keychain settings:\n" + errorToString(err));
+ }
+
+ return k.release();
+}
+
#endif