diff options
author | Benoit Foucher <benoit@zeroc.com> | 2016-06-27 17:54:30 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2016-06-27 17:54:30 +0200 |
commit | c56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7 (patch) | |
tree | 5cb64dfe155e5d2349efb6c7dc4b0f5b5284d44a /cpp/test/IceSSL/configuration | |
parent | Fix Windows php build to restore nuget packages (diff) | |
download | ice-c56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7.tar.bz2 ice-c56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7.tar.xz ice-c56f8ab6ca6ca0bdb9536fcce1ef24f1ef40ddc7.zip |
Refactored SSL and iAP transports, support for running SSL on top
of TCP/iAP/Bluetooth.
Diffstat (limited to 'cpp/test/IceSSL/configuration')
-rw-r--r-- | cpp/test/IceSSL/configuration/AllTests.cpp | 154 | ||||
-rw-r--r-- | cpp/test/IceSSL/configuration/Client.cpp | 37 | ||||
-rw-r--r-- | cpp/test/IceSSL/configuration/Makefile.mk | 4 | ||||
-rw-r--r-- | cpp/test/IceSSL/configuration/Server.cpp | 7 | ||||
-rw-r--r-- | cpp/test/IceSSL/configuration/TestI.cpp | 3 |
5 files changed, 176 insertions, 29 deletions
diff --git a/cpp/test/IceSSL/configuration/AllTests.cpp b/cpp/test/IceSSL/configuration/AllTests.cpp index 3313424859a..65d4d031640 100644 --- a/cpp/test/IceSSL/configuration/AllTests.cpp +++ b/cpp/test/IceSSL/configuration/AllTests.cpp @@ -2,7 +2,7 @@ // // Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. // -// This copy of Ice is licensed to you under the terms described in the +// This copy of Ice is licensed to you under the terms dribed in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** @@ -15,6 +15,9 @@ #ifdef __APPLE__ # include <sys/sysctl.h> +#if TARGET_OS_IPHONE != 0 +#include <IceSSL/Util.h> // For loadCertificateChain +#endif #endif #ifdef ICE_CPP11_MAPPING @@ -141,6 +144,83 @@ private: vector<PCCERT_CONTEXT> _certs; }; +#elif defined(__APPLE__) && TARGET_OS_IPHONE != 0 +class ImportCerts +{ +public: + + ImportCerts(const string& defaultDir, const char* certificates[]) + { + for(int i = 0; certificates[i] != 0; ++i) + { + string resolved; + if(IceSSL::checkPath(certificates[i], defaultDir, false, resolved)) + { + CFArrayRef certs = IceSSL::loadCertificateChain(resolved, "", "", "", "password", 0, 0); + SecIdentityRef identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0); + CFRetain(identity); + _identities.push_back(identity); + OSStatus err; + CFMutableDictionaryRef query; + + query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecValueRef, identity); + if((err = SecItemAdd(query, 0))) + { + cerr << "failed to add identity " << certificates[i] << ": " << err << endl; + } + CFRelease(query); + + // query = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + // CFDictionarySetValue(query, kSecClass, kSecClassCertificate); + // CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue); + // CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll); + // CFArrayRef array = 0; + // err = SecItemCopyMatching(query, (CFTypeRef*)&array); + // printf("Certificates\n"); + // for(int i = 0; i < CFArrayGetCount(array); ++i) + // { + // printf("Cert %d: %s\n", i, (new IceSSL::Certificate((SecCertificateRef)CFArrayGetValueAtIndex(array, i)))->toString().c_str()); + // } + // CFRelease(certs); + } + } + // Nothing to do. + } + + ~ImportCerts() + { + cleanup(); + } + + void cleanup() + { + CFMutableDictionaryRef query; + for(vector<SecIdentityRef>::const_iterator p = _identities.begin(); p != _identities.end(); ++p) + { + query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecClass, kSecClassIdentity); + CFDictionarySetValue(query, kSecValueRef, *p); + SecItemDelete(query); + CFRelease(query); + + SecCertificateRef cert; + SecIdentityCopyCertificate(*p, &cert); + query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(query, kSecClass, kSecClassCertificate); + CFDictionarySetValue(query, kSecValueRef, cert); + SecItemDelete(query); + CFRelease(query); + + CFRelease(*p); + } + _identities.clear(); + } + +private: + + vector<SecIdentityRef> _identities; +}; #else class ImportCerts { @@ -197,6 +277,7 @@ public: { if(info->nativeCerts.size() > 0) { +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 // // Subject alternative name // @@ -243,6 +324,7 @@ public: test(find(ipAddresses.begin(), ipAddresses.end(), "127.0.0.1") != ipAddresses.end()); test(find(emailAddresses.begin(), emailAddresses.end(), "issuer@zeroc.com") != emailAddresses.end()); } +#endif } _hadCert = info->nativeCerts.size() != 0; @@ -306,7 +388,8 @@ createClientProps(const Ice::PropertiesPtr& defaultProps, const string& defaultD { result->setProperty("IceSSL.Password", "password"); } - //result->setProperty("IceSSL.Trace.Security", "1"); +// result->setProperty("IceSSL.Trace.Security", "1"); +// result->setProperty("Ice.Trace.Network", "1"); #ifdef ICE_USE_SECURE_TRANSPORT ostringstream keychainName; keychainName << "../certs/keychain/client" << keychainN++ << ".keychain"; @@ -338,7 +421,8 @@ createServerProps(const Ice::PropertiesPtr& defaultProps, const string& defaultD { result["IceSSL.Password"] = "password"; } - //result["IceSSL.Trace.Security"] = "1"; +// result["Ice.Trace.Network"] = "1"; +// result["IceSSL.Trace.Security"] = "1"; #ifdef ICE_USE_SECURE_TRANSPORT ostringstream keychainName; keychainName << "../certs/keychain/server" << keychainN << ".keychain"; @@ -420,8 +504,8 @@ void verify(const IceSSL::CertificatePtr& cert, const IceSSL::CertificatePtr& ca cerr << endl; } -void -allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, bool shutdown) +Test::ServerFactoryPrxPtr +allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12) { bool elCapitanUpdate2OrLower = false; #ifdef __APPLE__ @@ -441,14 +525,19 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b } } #endif - - string factoryRef = "factory:tcp -p 12010"; + string endpt = getTestEndpoint(communicator, 0); + string factoryRef = "factory:" + endpt; ObjectPrxPtr base = communicator->stringToProxy(factoryRef); test(base); Test::ServerFactoryPrxPtr factory = ICE_CHECKED_CAST(Test::ServerFactoryPrx, base); string defaultHost = communicator->getProperties()->getProperty("Ice.Default.Host"); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 string defaultDir = testDir + "/../certs"; +#else + string defaultDir = "certs"; +#endif + Ice::PropertiesPtr defaultProps = communicator->getProperties(); #ifdef _WIN32 string sep = ";"; @@ -484,7 +573,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b // // Anonymous cipher are not supported with SChannel // -#ifndef ICE_USE_SCHANNEL +#if !defined(ICE_USE_SCHANNEL) { InitializationData initData; initData.properties = createClientProps(defaultProps, defaultDir, defaultHost, p12); @@ -647,16 +736,22 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b IceSSL::CertificatePtr serverCert = IceSSL::Certificate::load(defaultDir + "/s_rsa_ca1_pub.pem"); test(ICE_TARGET_EQUALS(IceSSL::Certificate::decode(serverCert->encode()), serverCert)); test(ICE_TARGET_EQUALS(serverCert, serverCert)); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 test(serverCert->checkValidity()); test(!serverCert->checkValidity(IceUtil::Time::seconds(0))); +#endif IceSSL::CertificatePtr caCert = IceSSL::Certificate::load(defaultDir + "/cacert1.pem"); + IceSSL::CertificatePtr caCert2 = IceSSL::Certificate::load(defaultDir + "/cacert2.pem"); test(ICE_TARGET_EQUALS(caCert, caCert)); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 test(caCert->checkValidity()); test(!caCert->checkValidity(IceUtil::Time::seconds(0))); +#endif test(!serverCert->verify(serverCert)); test(serverCert->verify(caCert)); + test(!serverCert->verify(caCert2)); test(caCert->verify(caCert)); info = ICE_DYNAMIC_CAST(IceSSL::NativeConnectionInfo, server->ice_getConnection()->getInfo()); @@ -669,9 +764,11 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b test(!(ICE_TARGET_EQUALS(serverCert, info->nativeCerts[1]))); test(!(ICE_TARGET_EQUALS(caCert, info->nativeCerts[0]))); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 test(info->nativeCerts[0]->checkValidity() && info->nativeCerts[1]->checkValidity()); test(!info->nativeCerts[0]->checkValidity(IceUtil::Time::seconds(0)) && !info->nativeCerts[1]->checkValidity(IceUtil::Time::seconds(0))); +#endif test(info->nativeCerts[0]->verify(info->nativeCerts[1])); test(info->nativeCerts.size() == 2 && info->nativeCerts[0]->getSubjectDN() == serverCert->getSubjectDN() && @@ -874,8 +971,9 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b { server->ice_ping(); } - catch(const LocalException&) + catch(const LocalException& ex) { + cerr << ex << endl; test(false); } fact->destroyServer(server); @@ -1589,10 +1687,12 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b // // This should fail because the server's certificate is expired. // +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 { IceSSL::CertificatePtr cert = IceSSL::Certificate::load(defaultDir + "/s_rsa_ca1_exp_pub.pem"); test(!cert->checkValidity()); } +#endif InitializationData initData; initData.properties = createClientProps(defaultProps, defaultDir, defaultHost, p12, "c_rsa_ca1", "cacert1"); @@ -1621,10 +1721,12 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b // // This should fail because the client's certificate is expired. // +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 { IceSSL::CertificatePtr cert = IceSSL::Certificate::load(defaultDir + "/c_rsa_ca1_exp_pub.pem"); test(!cert->checkValidity()); } +#endif initData.properties = createClientProps(defaultProps, defaultDir, defaultHost, p12, "c_rsa_ca1_exp", "cacert1"); comm = initialize(initData); @@ -2193,9 +2295,14 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b cout << "ok" << endl; cout << "testing IceSSL.TrustOnly... " << flush; + // + // iOS support only provides access to the CN of the certificate so we + // can't check for other attributes + // { InitializationData initData; initData.properties = createClientProps(defaultProps, defaultDir, defaultHost, p12, "c_rsa_ca1", "cacert1"); + initData.properties->setProperty("IceSSL.TrustOnly", "CN=Server"); initData.properties->setProperty("IceSSL.TrustOnly", "C=US, ST=Florida, O=ZeroC\\, Inc.," "OU=Ice, emailAddress=info@zeroc.com, CN=Server"); CommunicatorPtr comm = initialize(initData); @@ -2568,7 +2675,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b test(fact); Test::Properties d = createServerProps(defaultProps, defaultDir, defaultHost, p12, "s_rsa_ca1", "cacert1"); d["IceSSL.VerifyPeer"] = "0"; - d["IceSSL.TrustOnly"] = "C=US, ST=Florida, O=ZeroC\\, Inc.,OU=Ice, emailAddress=info@zeroc.com, CN=Client"; + d["IceSSL.TrustOnly"] = "CN=Client"; Test::ServerPrxPtr server = fact->createServer(d); try { @@ -2593,7 +2700,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b Test::ServerFactoryPrxPtr fact = ICE_CHECKED_CAST(Test::ServerFactoryPrx, comm->stringToProxy(factoryRef)); test(fact); Test::Properties d = createServerProps(defaultProps, defaultDir, defaultHost, p12, "s_rsa_ca1", "cacert1"); - d["IceSSL.TrustOnly"] = "!C=US, ST=Florida, O=ZeroC\\, Inc.,OU=Ice, emailAddress=info@zeroc.com, CN=Client"; + d["IceSSL.TrustOnly"] = "!CN=Client"; d["IceSSL.VerifyPeer"] = "0"; Test::ServerPrxPtr server = fact->createServer(d); try @@ -3116,7 +3223,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b cout << "testing IceSSL.FindCert... " << flush; const char* clientFindCertProperties[] = { - "SUBJECT:Client", +// "SUBJECT:Client", "LABEL:'Client'", "SUBJECTKEYID:'FC 5D 4F AB F0 6C 03 11 B8 F3 68 CF 89 54 92 3F F9 79 2A 06'", "SERIAL:02", @@ -3126,7 +3233,10 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b const char* serverFindCertProperties[] = { +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + // iOS match on Subject DN isn't supported by SecItemCopyMatch "SUBJECT:Server", +#endif "LABEL:'Server'", "SUBJECTKEYID:'47 84 AE F9 F2 85 3D 99 30 6A 03 38 41 1A B9 EB C3 9C B5 4D'", "SERIAL:01", @@ -3139,7 +3249,10 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b "nolabel", "unknownlabel:foo", "LABEL:", +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + // iOS match on Subject DN isn't supported by SecItemCopyMatch "SUBJECT:ServerX", +#endif "LABEL:'ServerX'", "SUBJECTKEYID:'a6 42 aa 17 04 41 86 56 67 e4 04 64 59 34 30 c7 4c 6b ef ff'", "SERIAL:04", @@ -3147,6 +3260,9 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b 0 }; + const char* certificates[] = {"/s_rsa_ca1.p12", "/c_rsa_ca1.p12", 0}; + ImportCerts import(defaultDir, certificates); + for(int i = 0; clientFindCertProperties[i] != 0; i++) { InitializationData initData; @@ -3169,6 +3285,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b d["IceSSL.Keychain"] = "../certs/Find.keychain"; d["IceSSL.KeychainPassword"] = "password"; d["IceSSL.FindCert"] = serverFindCertProperties[i]; + // // Use TrustOnly to ensure the peer has pick the expected certificate. // @@ -3198,6 +3315,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b try { CommunicatorPtr comm = initialize(initData); + printf("failed %s", failFindCertProperties[i]); test(false); } catch(const PluginInitializationException&) @@ -3247,11 +3365,11 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b comm = initialize(initData); p = comm->stringToProxy("dummy:wss -h demo.zeroc.com -p 5064"); - IceSSL::WSSConnectionInfoPtr info; try { - info = ICE_DYNAMIC_CAST(IceSSL::WSSConnectionInfo, p->ice_getConnection()->getInfo()); - test(info->verified); + Ice::WSConnectionInfoPtr info = ICE_DYNAMIC_CAST(Ice::WSConnectionInfo, p->ice_getConnection()->getInfo()); + IceSSL::ConnectionInfoPtr sslInfo = ICE_DYNAMIC_CAST(IceSSL::ConnectionInfo, info->underlying); + test(sslInfo->verified); } catch(const Ice::LocalException& ex) { @@ -3261,9 +3379,5 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12, b } cout << "ok" << endl; #endif - - if(shutdown) - { - factory->shutdown(); - } + return factory; } diff --git a/cpp/test/IceSSL/configuration/Client.cpp b/cpp/test/IceSSL/configuration/Client.cpp index 14538e7beac..68d3ad936e1 100644 --- a/cpp/test/IceSSL/configuration/Client.cpp +++ b/cpp/test/IceSSL/configuration/Client.cpp @@ -9,26 +9,51 @@ #include <Ice/Ice.h> #include <IceSSL/IceSSL.h> +#include <TestCommon.h> +#include <Test.h> + +DEFINE_TEST("client") using namespace std; int run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator) { + string testdir; +#if TARGET_OS_IPHONE == 0 if(argc < 2) { cerr << "Usage: " << argv[0] << " testdir" << endl; return 1; } + testdir = argv[1]; +#endif - void allTests(const Ice::CommunicatorPtr&, const string&, bool, bool); - - cerr << "testing with PKCS12 certificates..." << endl; - allTests(communicator, argv[1], true, false); - cerr << "testing with PEM certificates..." << endl; - allTests(communicator, argv[1], false, true); + Test::ServerFactoryPrxPtr allTests(const Ice::CommunicatorPtr&, const string&, bool); + try + { + cerr << "testing with PKCS12 certificates..." << endl; + Test::ServerFactoryPrxPtr factory = allTests(communicator, testdir, true); +#if !defined(__APPLE__) || TARGET_OS_IPHONE == 0 + cerr << "testing with PEM certificates..." << endl; + factory = allTests(communicator, testdir, false); +#endif + if(factory) + { + factory->shutdown(); + } + } + catch(const IceSSL::CertificateReadException& ex) + { + cout << "couldn't read certificate: " << ex.reason << endl; + } + catch(const std::exception& ex) + { + cout << "unexpected exception: " << ex.what() << endl; + } return EXIT_SUCCESS; + } int diff --git a/cpp/test/IceSSL/configuration/Makefile.mk b/cpp/test/IceSSL/configuration/Makefile.mk index 92098e429b6..9eb4e1b4c75 100644 --- a/cpp/test/IceSSL/configuration/Makefile.mk +++ b/cpp/test/IceSSL/configuration/Makefile.mk @@ -9,4 +9,8 @@ $(test)_dependencies = IceSSL Ice TestCommon +# Need to load certificates with functions from src/IceSSL/Util.h +$(test)[iphoneos]_cppflags := -Isrc +$(test)[iphonesimulator]_cppflags := -Isrc + tests += $(test) diff --git a/cpp/test/IceSSL/configuration/Server.cpp b/cpp/test/IceSSL/configuration/Server.cpp index 5ed1e401b15..6a1f98614dd 100644 --- a/cpp/test/IceSSL/configuration/Server.cpp +++ b/cpp/test/IceSSL/configuration/Server.cpp @@ -9,18 +9,21 @@ #include <Ice/Ice.h> #include <TestI.h> +#include <TestCommon.h> + +DEFINE_TEST("server") using namespace std; int run(int, char**, const Ice::CommunicatorPtr& communicator) { - communicator->getProperties()->setProperty("TestAdapter.Endpoints", "tcp -p 12010"); + communicator->getProperties()->setProperty("TestAdapter.Endpoints", getTestEndpoint(communicator, 0)); Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("TestAdapter"); Ice::Identity id = communicator->stringToIdentity("factory"); adapter->add(ICE_MAKE_SHARED(ServerFactoryI), id); adapter->activate(); - + TEST_READY communicator->waitForShutdown(); return EXIT_SUCCESS; } diff --git a/cpp/test/IceSSL/configuration/TestI.cpp b/cpp/test/IceSSL/configuration/TestI.cpp index 7723da865b3..39b78d02712 100644 --- a/cpp/test/IceSSL/configuration/TestI.cpp +++ b/cpp/test/IceSSL/configuration/TestI.cpp @@ -45,7 +45,8 @@ ServerI::checkCert(ICE_IN(string) subjectDN, ICE_IN(string) issuerDN, const Ice: test(info->verified); test(info->nativeCerts.size() == 2 && info->nativeCerts[0]->getSubjectDN() == IceSSL::DistinguishedName(subjectDN) && - info->nativeCerts[0]->getIssuerDN() == IceSSL::DistinguishedName(issuerDN)); + info->nativeCerts[0]->getIssuerDN() == IceSSL::DistinguishedName(issuerDN) + ); } catch(const Ice::LocalException&) { |