diff options
author | Jose <jose@zeroc.com> | 2017-01-13 09:39:17 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2017-01-13 09:39:17 +0100 |
commit | fd6e9a9f4607d8bbec226deebbd99e036c1873d9 (patch) | |
tree | 0f9aab46d22a22dddc1338cd2d8a6f4eca0f5b0b | |
parent | Added shutdown of the simulator (diff) | |
download | ice-fd6e9a9f4607d8bbec226deebbd99e036c1873d9.tar.bz2 ice-fd6e9a9f4607d8bbec226deebbd99e036c1873d9.tar.xz ice-fd6e9a9f4607d8bbec226deebbd99e036c1873d9.zip |
Fixed (ICE-7480) - Use UniqueRef to manage CoreFoundation types.
-rw-r--r-- | cpp/include/Ice/UniqueRef.h | 90 | ||||
-rw-r--r-- | cpp/include/IceSSL/Plugin.h | 17 | ||||
-rw-r--r-- | cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp | 48 | ||||
-rw-r--r-- | cpp/src/Ice/Selector.cpp | 57 | ||||
-rw-r--r-- | cpp/src/Ice/Selector.h | 7 | ||||
-rw-r--r-- | cpp/src/Ice/ios/StreamAcceptor.cpp | 19 | ||||
-rw-r--r-- | cpp/src/Ice/ios/StreamConnector.cpp | 33 | ||||
-rw-r--r-- | cpp/src/Ice/ios/StreamEndpointI.cpp | 24 | ||||
-rw-r--r-- | cpp/src/Ice/ios/StreamEndpointI.h | 3 | ||||
-rw-r--r-- | cpp/src/Ice/ios/StreamTransceiver.cpp | 110 | ||||
-rw-r--r-- | cpp/src/Ice/ios/StreamTransceiver.h | 6 | ||||
-rwxr-xr-x | cpp/src/IceSSL/Certificate.cpp | 319 | ||||
-rw-r--r-- | cpp/src/IceSSL/SSLEngine.h | 5 | ||||
-rw-r--r-- | cpp/src/IceSSL/SecureTransportEngine.cpp | 8 | ||||
-rw-r--r-- | cpp/src/IceSSL/SecureTransportTransceiverI.cpp | 61 | ||||
-rw-r--r-- | cpp/src/IceSSL/SecureTransportTransceiverI.h | 5 | ||||
-rwxr-xr-x | cpp/src/IceSSL/Util.cpp | 301 | ||||
-rw-r--r-- | cpp/src/IceSSL/Util.h | 61 | ||||
-rw-r--r-- | cpp/test/IceSSL/configuration/AllTests.cpp | 42 |
19 files changed, 547 insertions, 669 deletions
diff --git a/cpp/include/Ice/UniqueRef.h b/cpp/include/Ice/UniqueRef.h new file mode 100644 index 00000000000..0b8f045d43b --- /dev/null +++ b/cpp/include/Ice/UniqueRef.h @@ -0,0 +1,90 @@ + +#ifndef ICE_UNIQUE_REF_H +#define ICE_UNIQUE_REF_H + +#ifdef __APPLE__ + +#include <CoreFoundation/CoreFoundation.h> + +namespace IceInternal +{ + +// +// UniqueRef helper class for CoreFoundation classes, comparable to std::unique_ptr +// +template<typename R> +class UniqueRef +{ +public: + + explicit UniqueRef(R ref = 0) : + _ref(ref) + { + } + + ~UniqueRef() + { + if(_ref != 0) + { + CFRelease(_ref); + } + } + + R release() + { + R r = _ref; + _ref = 0; + return r; + } + + void reset(R ref = 0) + { + assert(ref == 0 || ref != _ref); + + if(_ref != 0) + { + CFRelease(_ref); + } + _ref = ref; + } + + void retain(R ref) + { + reset(ref ? (R)CFRetain(ref) : ref); + } + + R& get() + { + return _ref; + } + + R get() const + { + return _ref; + } + + operator bool() const + { + return _ref != 0; + } + + void swap(UniqueRef& a) + { + R tmp = a._ref; + a._ref = _ref; + _ref = tmp; + } + +private: + + UniqueRef(UniqueRef&); + UniqueRef& operator=(UniqueRef&); + + R _ref; +}; + +} + +#endif + +#endif diff --git a/cpp/include/IceSSL/Plugin.h b/cpp/include/IceSSL/Plugin.h index 9b8b63737f2..73b4015b4d0 100644 --- a/cpp/include/IceSSL/Plugin.h +++ b/cpp/include/IceSSL/Plugin.h @@ -11,6 +11,7 @@ #define ICE_SSL_PLUGIN_H #include <Ice/Plugin.h> +#include <Ice/UniqueRef.h> #include <IceSSL/Config.h> #include <IceSSL/ConnectionInfo.h> @@ -172,8 +173,9 @@ public: PublicKey(const CertificatePtr&, KeyRef); +#ifdef ICE_USE_OPENSSL ~PublicKey(); - +#endif // // Retrieve the native public key value wrapped by this object. // @@ -188,7 +190,11 @@ private: friend class Certificate; CertificatePtr _cert; +#ifdef __APPLE__ + IceInternal::UniqueRef<KeyRef> _key; +#else KeyRef _key; +#endif }; ICE_DEFINE_PTR(PublicKeyPtr, PublicKey); @@ -485,15 +491,20 @@ public: private: +#if defined(__APPLE__) + IceInternal::UniqueRef<X509CertificateRef> _cert; +#else X509CertificateRef _cert; +#endif #ifdef ICE_USE_SCHANNEL CERT_INFO* _certInfo; #endif + #if defined(__APPLE__) && TARGET_OS_IPHONE != 0 void initializeAttributes() const; - mutable CFDataRef _subject; - mutable CFDataRef _issuer; + mutable IceInternal::UniqueRef<CFDataRef> _subject; + mutable IceInternal::UniqueRef<CFDataRef> _issuer; mutable std::string _serial; mutable int _version; #endif diff --git a/cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp b/cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp index 0578309c47b..d1211b9d7a3 100644 --- a/cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp +++ b/cpp/src/Glacier2CryptPermissionsVerifier/CryptPermissionsVerifierI.cpp @@ -10,6 +10,7 @@ #include <Glacier2/PermissionsVerifier.h> #include <IceUtil/IceUtil.h> #include <Ice/Ice.h> +#include <Ice/UniqueRef.h> #include <IceUtil/FileUtil.h> #include <IceUtil/StringUtil.h> @@ -33,6 +34,7 @@ using namespace std; using namespace Ice; +using namespace IceInternal; using namespace Glacier2; namespace @@ -322,75 +324,59 @@ CryptPermissionsVerifierI::checkPermissions(const string& userId, const string& std::replace(checksum.begin(), checksum.end(), '.', '+'); checksum += paddingBytes(checksum.size()); # if defined(__APPLE__) - CFErrorRef error = 0; - SecTransformRef decoder = SecDecodeTransformCreate(kSecBase64Encoding, &error); + UniqueRef<CFErrorRef> error; + UniqueRef<SecTransformRef> decoder(SecDecodeTransformCreate(kSecBase64Encoding, &error.get())); if(error) { - CFRelease(error); return false; } - CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - reinterpret_cast<const uint8_t*>(salt.c_str()), - salt.size(), kCFAllocatorNull); + UniqueRef<CFDataRef> data(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + reinterpret_cast<const uint8_t*>(salt.c_str()), + salt.size(), kCFAllocatorNull)); - SecTransformSetAttribute(decoder, kSecTransformInputAttributeName, data, &error); + SecTransformSetAttribute(decoder.get(), kSecTransformInputAttributeName, data.get(), &error.get()); if(error) { - CFRelease(error); - CFRelease(decoder); return false; } - CFDataRef saltBuffer = static_cast<CFDataRef>(SecTransformExecute(decoder, &error)); - CFRelease(decoder); - + UniqueRef<CFDataRef> saltBuffer(static_cast<CFDataRef>(SecTransformExecute(decoder.get(), &error.get()))); if(error) { - CFRelease(error); return false; } vector<uint8_t> checksumBuffer1(checksumLength); OSStatus status = CCKeyDerivationPBKDF(kCCPBKDF2, password.c_str(), password.size(), - CFDataGetBytePtr(saltBuffer), CFDataGetLength(saltBuffer), + CFDataGetBytePtr(saltBuffer.get()), CFDataGetLength(saltBuffer.get()), algorithmId, rounds, &checksumBuffer1[0], checksumLength); - CFRelease(saltBuffer); if(status != errSecSuccess) { return false; } - decoder = SecDecodeTransformCreate(kSecBase64Encoding, &error); + decoder.reset(SecDecodeTransformCreate(kSecBase64Encoding, &error.get())); if(error) { - CFRelease(error); return false; } - data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - reinterpret_cast<const uint8_t*>(checksum.c_str()), - checksum.size(), kCFAllocatorNull); - SecTransformSetAttribute(decoder, kSecTransformInputAttributeName, data, &error); + data.reset(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + reinterpret_cast<const uint8_t*>(checksum.c_str()), + checksum.size(), kCFAllocatorNull)); + SecTransformSetAttribute(decoder.get(), kSecTransformInputAttributeName, data.get(), &error.get()); if(error) { - CFRelease(error); - CFRelease(decoder); return false; } - data = static_cast<CFDataRef>(SecTransformExecute(decoder, &error)); - CFRelease(decoder); - decoder = 0; - + data.reset(static_cast<CFDataRef>(SecTransformExecute(decoder.get(), &error.get()))); if(error) { - CFRelease(error); return false; } - vector<uint8_t> checksumBuffer2(CFDataGetBytePtr(data), CFDataGetBytePtr(data) + CFDataGetLength(data)); - CFRelease(data); - + vector<uint8_t> checksumBuffer2(CFDataGetBytePtr(data.get()), CFDataGetBytePtr(data.get()) + CFDataGetLength(data.get())); return checksumBuffer1 == checksumBuffer2; # else DWORD saltLength = static_cast<DWORD>(salt.size()); diff --git a/cpp/src/Ice/Selector.cpp b/cpp/src/Ice/Selector.cpp index e421d7271e1..c08cb559c55 100644 --- a/cpp/src/Ice/Selector.cpp +++ b/cpp/src/Ice/Selector.cpp @@ -1058,9 +1058,7 @@ EventHandlerWrapper::EventHandlerWrapper(EventHandler* handler, Selector& select _streamNativeInfo(StreamNativeInfoPtr::dynamicCast(handler->getNativeInfo())), _selector(selector), _ready(SocketOperationNone), - _finish(false), - _socket(0), - _source(0) + _finish(false) { if(_streamNativeInfo) { @@ -1070,28 +1068,23 @@ EventHandlerWrapper::EventHandlerWrapper(EventHandler* handler, Selector& select { SOCKET fd = handler->getNativeInfo()->fd(); CFSocketContext ctx = { 0, this, 0, 0, 0 }; - _socket = CFSocketCreateWithNative(kCFAllocatorDefault, - fd, - kCFSocketReadCallBack | - kCFSocketWriteCallBack | - kCFSocketConnectCallBack, - eventHandlerSocketCallback, - &ctx); + _socket.reset(CFSocketCreateWithNative(kCFAllocatorDefault, + fd, + kCFSocketReadCallBack | + kCFSocketWriteCallBack | + kCFSocketConnectCallBack, + eventHandlerSocketCallback, + &ctx)); // Disable automatic re-enabling of callbacks and closing of the native socket. - CFSocketSetSocketFlags(_socket, 0); - CFSocketDisableCallBacks(_socket, kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack); - _source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket, 0); + CFSocketSetSocketFlags(_socket.get(), 0); + CFSocketDisableCallBacks(_socket.get(), kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack); + _source.reset(CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket.get(), 0)); } } EventHandlerWrapper::~EventHandlerWrapper() { - if(_socket) - { - CFRelease(_socket); - CFRelease(_source); - } } void @@ -1102,24 +1095,24 @@ EventHandlerWrapper::updateRunLoop() if(_socket) { - CFSocketDisableCallBacks(_socket, kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack); + CFSocketDisableCallBacks(_socket.get(), kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack); if(op) { - CFSocketEnableCallBacks(_socket, toCFCallbacks(op)); + CFSocketEnableCallBacks(_socket.get(), toCFCallbacks(op)); } - if(op && !CFRunLoopContainsSource(CFRunLoopGetCurrent(), _source, kCFRunLoopDefaultMode)) + if(op && !CFRunLoopContainsSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode)) { - CFRunLoopAddSource(CFRunLoopGetCurrent(), _source, kCFRunLoopDefaultMode); + CFRunLoopAddSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode); } - else if(!op && CFRunLoopContainsSource(CFRunLoopGetCurrent(), _source, kCFRunLoopDefaultMode)) + else if(!op && CFRunLoopContainsSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode)) { - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), _source, kCFRunLoopDefaultMode); + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode); } if(_finish) { - CFSocketInvalidate(_socket); + CFSocketInvalidate(_socket.get()); } } else @@ -1239,7 +1232,7 @@ Selector::Selector(const InstancePtr& instance) : _instance(instance), _destroye memset(&ctx, 0, sizeof(CFRunLoopSourceContext)); ctx.info = this; ctx.perform = selectorInterrupt; - _source = CFRunLoopSourceCreate(0, 0, &ctx); + _source.reset(CFRunLoopSourceCreate(0, 0, &ctx)); _runLoop = 0; _thread = new SelectorHelperThread(*this); @@ -1267,12 +1260,12 @@ Selector::destroy() // streams/sockets are closed. // _destroyed = true; - CFRunLoopSourceSignal(_source); + CFRunLoopSourceSignal(_source.get()); CFRunLoopWakeUp(_runLoop); while(!_changes.empty()) { - CFRunLoopSourceSignal(_source); + CFRunLoopSourceSignal(_source.get()); CFRunLoopWakeUp(_runLoop); wait(); @@ -1283,7 +1276,7 @@ Selector::destroy() _thread = 0; Lock sync(*this); - CFRelease(_source); + _source.reset(0); //assert(_wrappers.empty()); _readyHandlers.clear(); @@ -1422,7 +1415,7 @@ Selector::select(int timeout) { while(!_changes.empty()) { - CFRunLoopSourceSignal(_source); + CFRunLoopSourceSignal(_source.get()); CFRunLoopWakeUp(_runLoop); wait(); @@ -1478,9 +1471,9 @@ Selector::run() notify(); } - CFRunLoopAddSource(CFRunLoopGetCurrent(), _source, kCFRunLoopDefaultMode); + CFRunLoopAddSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode); CFRunLoopRun(); - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), _source, kCFRunLoopDefaultMode); + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), _source.get(), kCFRunLoopDefaultMode); } void diff --git a/cpp/src/Ice/Selector.h b/cpp/src/Ice/Selector.h index 7434a240763..95f8ed432de 100644 --- a/cpp/src/Ice/Selector.h +++ b/cpp/src/Ice/Selector.h @@ -17,6 +17,7 @@ #include <Ice/Network.h> #include <Ice/InstanceF.h> #include <Ice/EventHandlerF.h> +#include <Ice/UniqueRef.h> #if defined(ICE_USE_EPOLL) # include <sys/epoll.h> @@ -255,8 +256,8 @@ private: Selector& _selector; SocketOperation _ready; bool _finish; - CFSocketRef _socket; - CFRunLoopSourceRef _source; + IceInternal::UniqueRef<CFSocketRef> _socket; + IceInternal::UniqueRef<CFRunLoopSourceRef> _source; }; typedef IceUtil::Handle<EventHandlerWrapper> EventHandlerWrapperPtr; @@ -295,7 +296,7 @@ private: InstancePtr _instance; IceUtil::ThreadPtr _thread; CFRunLoopRef _runLoop; - CFRunLoopSourceRef _source; + IceInternal::UniqueRef<CFRunLoopSourceRef> _source; bool _destroyed; std::set<EventHandlerWrapperPtr> _changes; diff --git a/cpp/src/Ice/ios/StreamAcceptor.cpp b/cpp/src/Ice/ios/StreamAcceptor.cpp index bd3e7e88a33..2bf115390fe 100644 --- a/cpp/src/Ice/ios/StreamAcceptor.cpp +++ b/cpp/src/Ice/ios/StreamAcceptor.cpp @@ -14,6 +14,7 @@ #include <IceUtil/StringUtil.h> #include <Ice/Instance.h> +#include <Ice/UniqueRef.h> #include <Ice/Network.h> #include <Ice/Exception.h> #include <Ice/Properties.h> @@ -68,13 +69,13 @@ IceObjC::StreamAcceptor::accept() // // Create the read/write streams // - CFReadStreamRef readStream = nil; - CFWriteStreamRef writeStream = nil; + UniqueRef<CFReadStreamRef> readStream; + UniqueRef<CFWriteStreamRef> writeStream; try { - CFStreamCreatePairWithSocket(ICE_NULLPTR, fd, &readStream, &writeStream); - _instance->setupStreams(readStream, writeStream, true, ""); - return new StreamTransceiver(_instance, readStream, writeStream, fd); + CFStreamCreatePairWithSocket(ICE_NULLPTR, fd, &readStream.get(), &writeStream.get()); + _instance->setupStreams(readStream.get(), writeStream.get(), true, ""); + return new StreamTransceiver(_instance, readStream.release(), writeStream.release(), fd); } catch(const Ice::LocalException& ex) { @@ -82,14 +83,6 @@ IceObjC::StreamAcceptor::accept() { closeSocketNoThrow(fd); } - if(readStream) - { - CFRelease(readStream); - } - if(writeStream) - { - CFRelease(writeStream); - } throw; } } diff --git a/cpp/src/Ice/ios/StreamConnector.cpp b/cpp/src/Ice/ios/StreamConnector.cpp index 3863e29b63a..e3a19519eca 100644 --- a/cpp/src/Ice/ios/StreamConnector.cpp +++ b/cpp/src/Ice/ios/StreamConnector.cpp @@ -12,6 +12,7 @@ #include "StreamConnector.h" #include <Ice/Network.h> +#include <Ice/UniqueRef.h> #include <Ice/Exception.h> #include <Ice/Properties.h> #include <Ice/NetworkProxy.h> @@ -25,31 +26,13 @@ using namespace IceInternal; TransceiverPtr IceObjC::StreamConnector::connect() { - CFReadStreamRef readStream = nil; - CFWriteStreamRef writeStream = nil; - try - { - CFStringRef h = CFStringCreateWithCString(ICE_NULLPTR, _host.c_str(), kCFStringEncodingUTF8); - CFHostRef host = CFHostCreateWithName(ICE_NULLPTR, h); - CFRelease(h); - CFStreamCreatePairWithSocketToCFHost(ICE_NULLPTR, host, _port, &readStream, &writeStream); - CFRelease(host); - - _instance->setupStreams(readStream, writeStream, false, _host); - return new StreamTransceiver(_instance, readStream, writeStream, _host, _port); - } - catch(const Ice::LocalException& ex) - { - if(readStream) - { - CFRelease(readStream); - } - if(writeStream) - { - CFRelease(writeStream); - } - throw; - } + UniqueRef<CFReadStreamRef> readStream; + UniqueRef<CFWriteStreamRef> writeStream; + UniqueRef<CFStringRef> h(CFStringCreateWithCString(ICE_NULLPTR, _host.c_str(), kCFStringEncodingUTF8)); + UniqueRef<CFHostRef> host(CFHostCreateWithName(ICE_NULLPTR, h.get())); + CFStreamCreatePairWithSocketToCFHost(ICE_NULLPTR, host.get(), _port, &readStream.get(), &writeStream.get()); + _instance->setupStreams(readStream.get(), writeStream.get(), false, _host); + return new StreamTransceiver(_instance, readStream.release(), writeStream.release(), _host, _port); } Short diff --git a/cpp/src/Ice/ios/StreamEndpointI.cpp b/cpp/src/Ice/ios/StreamEndpointI.cpp index 5643ee51124..33333f6fd48 100644 --- a/cpp/src/Ice/ios/StreamEndpointI.cpp +++ b/cpp/src/Ice/ios/StreamEndpointI.cpp @@ -71,29 +71,23 @@ IceObjC::Instance::Instance(const Ice::CommunicatorPtr& com, Short type, const s #if TARGET_IPHONE_SIMULATOR != 0 throw Ice::FeatureNotSupportedException(__FILE__, __LINE__, "SOCKS proxy not supported"); #endif - _proxySettings = CFDictionaryCreateMutable(0, 3, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + _proxySettings.reset(CFDictionaryCreateMutable(0, 3, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); _proxyPort = properties->getPropertyAsIntWithDefault("Ice.SOCKSProxyPort", 1080); - CFStringRef host = toCFString(_proxyHost); - CFDictionarySetValue(_proxySettings, kCFStreamPropertySOCKSProxyHost, host); - CFRelease(host); + UniqueRef<CFStringRef> host(toCFString(_proxyHost)); + CFDictionarySetValue(_proxySettings.get(), kCFStreamPropertySOCKSProxyHost, host.get()); - CFNumberRef port = CFNumberCreate(0, kCFNumberSInt32Type, &_proxyPort); - CFDictionarySetValue(_proxySettings, kCFStreamPropertySOCKSProxyPort, port); - CFRelease(port); + UniqueRef<CFNumberRef> port(CFNumberCreate(0, kCFNumberSInt32Type, &_proxyPort)); + CFDictionarySetValue(_proxySettings.get(), kCFStreamPropertySOCKSProxyPort, port.get()); - CFDictionarySetValue(_proxySettings, kCFStreamPropertySOCKSVersion, kCFStreamSocketSOCKSVersion4); + CFDictionarySetValue(_proxySettings.get(), kCFStreamPropertySOCKSVersion, kCFStreamSocketSOCKSVersion4); } } IceObjC::Instance::~Instance() { - if(_proxySettings) - { - CFRelease(_proxySettings); - } } void @@ -115,8 +109,8 @@ IceObjC::Instance::setupStreams(CFReadStreamRef readStream, if(!server && _proxySettings) { - if(!CFReadStreamSetProperty(readStream, kCFStreamPropertySOCKSProxy, _proxySettings) || - !CFWriteStreamSetProperty(writeStream, kCFStreamPropertySOCKSProxy, _proxySettings)) + if(!CFReadStreamSetProperty(readStream, kCFStreamPropertySOCKSProxy, _proxySettings.get()) || + !CFWriteStreamSetProperty(writeStream, kCFStreamPropertySOCKSProxy, _proxySettings.get())) { throw Ice::SyscallException(__FILE__, __LINE__); } diff --git a/cpp/src/Ice/ios/StreamEndpointI.h b/cpp/src/Ice/ios/StreamEndpointI.h index 974bb4b8b74..93cdd02ae04 100644 --- a/cpp/src/Ice/ios/StreamEndpointI.h +++ b/cpp/src/Ice/ios/StreamEndpointI.h @@ -15,6 +15,7 @@ #include <Ice/WSEndpoint.h> #include <Ice/EndpointFactory.h> #include <Ice/InstanceF.h> +#include <Ice/UniqueRef.h> #include <CoreFoundation/CFDictionary.h> #include <CFNetwork/CFNetwork.h> @@ -55,7 +56,7 @@ private: const bool _voip; const Ice::CommunicatorPtr _communicator; - CFMutableDictionaryRef _proxySettings; + IceInternal::UniqueRef<CFMutableDictionaryRef> _proxySettings; std::string _proxyHost; int _proxyPort; }; diff --git a/cpp/src/Ice/ios/StreamTransceiver.cpp b/cpp/src/Ice/ios/StreamTransceiver.cpp index ba367dccf74..5bc22115ea7 100644 --- a/cpp/src/Ice/ios/StreamTransceiver.cpp +++ b/cpp/src/Ice/ios/StreamTransceiver.cpp @@ -90,11 +90,11 @@ IceObjC::StreamTransceiver::initStreams(SelectorReadyCallback* callback) CFStreamClientContext ctx = { 0, callback, 0, 0, 0 }; events = kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered; - CFWriteStreamSetClient(_writeStream, events, selectorWriteCallback, &ctx); + CFWriteStreamSetClient(_writeStream.get(), events, selectorWriteCallback, &ctx); events = kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered; - CFReadStreamSetClient(_readStream, events, selectorReadCallback, &ctx); + CFReadStreamSetClient(_readStream.get(), events, selectorReadCallback, &ctx); } SocketOperation @@ -104,36 +104,36 @@ IceObjC::StreamTransceiver::registerWithRunLoop(SocketOperation op) SocketOperation readyOp = SocketOperationNone; if(op & SocketOperationConnect) { - if(CFWriteStreamGetStatus(_writeStream) != kCFStreamStatusNotOpen || - CFReadStreamGetStatus(_readStream) != kCFStreamStatusNotOpen) + if(CFWriteStreamGetStatus(_writeStream.get()) != kCFStreamStatusNotOpen || + CFReadStreamGetStatus(_readStream.get()) != kCFStreamStatusNotOpen) { return SocketOperationConnect; } _opening = true; - CFWriteStreamScheduleWithRunLoop(_writeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - CFReadStreamScheduleWithRunLoop(_readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFWriteStreamScheduleWithRunLoop(_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFReadStreamScheduleWithRunLoop(_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); _writeStreamRegistered = true; // Note: this must be set after the schedule call _readStreamRegistered = true; // Note: this must be set after the schedule call - CFReadStreamOpen(_readStream); - CFWriteStreamOpen(_writeStream); + CFReadStreamOpen(_readStream.get()); + CFWriteStreamOpen(_writeStream.get()); } else { if(op & SocketOperationWrite) { - if(CFWriteStreamCanAcceptBytes(_writeStream)) + if(CFWriteStreamCanAcceptBytes(_writeStream.get())) { readyOp = static_cast<SocketOperation>(readyOp | SocketOperationWrite); } else if(!_writeStreamRegistered) { - CFWriteStreamScheduleWithRunLoop(_writeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFWriteStreamScheduleWithRunLoop(_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); _writeStreamRegistered = true; // Note: this must be set after the schedule call - if(CFWriteStreamCanAcceptBytes(_writeStream)) + if(CFWriteStreamCanAcceptBytes(_writeStream.get())) { readyOp = static_cast<SocketOperation>(readyOp | SocketOperationWrite); } @@ -142,15 +142,15 @@ IceObjC::StreamTransceiver::registerWithRunLoop(SocketOperation op) if(op & SocketOperationRead) { - if(CFReadStreamHasBytesAvailable(_readStream)) + if(CFReadStreamHasBytesAvailable(_readStream.get())) { readyOp = static_cast<SocketOperation>(readyOp | SocketOperationRead); } else if(!_readStreamRegistered) { - CFReadStreamScheduleWithRunLoop(_readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFReadStreamScheduleWithRunLoop(_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); _readStreamRegistered = true; // Note: this must be set after the schedule call - if(CFReadStreamHasBytesAvailable(_readStream)) + if(CFReadStreamHasBytesAvailable(_readStream.get())) { readyOp = static_cast<SocketOperation>(readyOp | SocketOperationRead); } @@ -189,8 +189,8 @@ IceObjC::StreamTransceiver::unregisterFromRunLoop(SocketOperation op, bool error if(error || (!_readStreamRegistered && !_writeStreamRegistered)) { - CFWriteStreamUnscheduleFromRunLoop(_writeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - CFReadStreamUnscheduleFromRunLoop(_readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFWriteStreamUnscheduleFromRunLoop(_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFReadStreamUnscheduleFromRunLoop(_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); _opening = false; return SocketOperationConnect; } @@ -203,13 +203,13 @@ IceObjC::StreamTransceiver::unregisterFromRunLoop(SocketOperation op, bool error { if(op & SocketOperationWrite && _writeStreamRegistered) { - CFWriteStreamUnscheduleFromRunLoop(_writeStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFWriteStreamUnscheduleFromRunLoop(_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); _writeStreamRegistered = false; } if(op & SocketOperationRead && _readStreamRegistered) { - CFReadStreamUnscheduleFromRunLoop(_readStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFReadStreamUnscheduleFromRunLoop(_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); _readStreamRegistered = false; } } @@ -219,11 +219,11 @@ IceObjC::StreamTransceiver::unregisterFromRunLoop(SocketOperation op, bool error void IceObjC::StreamTransceiver::closeStreams() { - CFReadStreamSetClient(_readStream, kCFStreamEventNone, 0, 0); - CFWriteStreamSetClient(_writeStream, kCFStreamEventNone, 0, 0); + CFReadStreamSetClient(_readStream.get(), kCFStreamEventNone, 0, 0); + CFWriteStreamSetClient(_writeStream.get(), kCFStreamEventNone, 0, 0); - CFReadStreamClose(_readStream); - CFWriteStreamClose(_writeStream); + CFReadStreamClose(_readStream.get()); + CFWriteStreamClose(_writeStream.get()); } SocketOperation @@ -240,31 +240,31 @@ IceObjC::StreamTransceiver::initialize(Buffer& readBuffer, Buffer& writeBuffer) { if(_error) { - CFErrorRef err = ICE_NULLPTR; - if(CFWriteStreamGetStatus(_writeStream) == kCFStreamStatusError) + UniqueRef<CFErrorRef> err; + if(CFWriteStreamGetStatus(_writeStream.get()) == kCFStreamStatusError) { - err = CFWriteStreamCopyError(_writeStream); + err.reset(CFWriteStreamCopyError(_writeStream.get())); } - else if(CFReadStreamGetStatus(_readStream) == kCFStreamStatusError) + else if(CFReadStreamGetStatus(_readStream.get()) == kCFStreamStatusError) { - err = CFReadStreamCopyError(_readStream); + err.reset(CFReadStreamCopyError(_readStream.get())); } - checkError(err, __FILE__, __LINE__); + checkError(err.get(), __FILE__, __LINE__); } _state = StateConnected; if(_fd == INVALID_SOCKET) { - if(!CFReadStreamSetProperty(_readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse) || - !CFWriteStreamSetProperty(_writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse)) + if(!CFReadStreamSetProperty(_readStream.get(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse) || + !CFWriteStreamSetProperty(_writeStream.get(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse)) { throw Ice::SocketException(__FILE__, __LINE__, 0); } - CFDataRef d = (CFDataRef)CFReadStreamCopyProperty(_readStream, kCFStreamPropertySocketNativeHandle); - CFDataGetBytes(d, CFRangeMake(0, sizeof(SOCKET)), reinterpret_cast<UInt8*>(&_fd)); - CFRelease(d); + UniqueRef<CFDataRef> d(static_cast<CFDataRef>( + CFReadStreamCopyProperty(_readStream.get(), kCFStreamPropertySocketNativeHandle))); + CFDataGetBytes(d.get(), CFRangeMake(0, sizeof(SOCKET)), reinterpret_cast<UInt8*>(&_fd)); } ostringstream s; @@ -327,33 +327,35 @@ IceObjC::StreamTransceiver::write(Buffer& buf) IceUtil::Mutex::Lock sync(_mutex); if(_error) { - assert(CFWriteStreamGetStatus(_writeStream) == kCFStreamStatusError); - checkError(CFWriteStreamCopyError(_writeStream), __FILE__, __LINE__); + assert(CFWriteStreamGetStatus(_writeStream.get()) == kCFStreamStatusError); + UniqueRef<CFErrorRef> err(CFWriteStreamCopyError(_writeStream.get())); + checkError(err.get(), __FILE__, __LINE__); } // Its impossible for the packetSize to be more than an Int. size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i); while(buf.i != buf.b.end()) { - if(!CFWriteStreamCanAcceptBytes(_writeStream)) + if(!CFWriteStreamCanAcceptBytes(_writeStream.get())) { return SocketOperationWrite; } assert(_fd != INVALID_SOCKET); - CFIndex ret = CFWriteStreamWrite(_writeStream, reinterpret_cast<const UInt8*>(&*buf.i), packetSize); + CFIndex ret = CFWriteStreamWrite(_writeStream.get(), reinterpret_cast<const UInt8*>(&*buf.i), packetSize); if(ret == SOCKET_ERROR) { - if(CFWriteStreamGetStatus(_writeStream) == kCFStreamStatusAtEnd) + if(CFWriteStreamGetStatus(_writeStream.get()) == kCFStreamStatusAtEnd) { ConnectionLostException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; } - assert(CFWriteStreamGetStatus(_writeStream) == kCFStreamStatusError); - checkError(CFWriteStreamCopyError(_writeStream), __FILE__, __LINE__); + assert(CFWriteStreamGetStatus(_writeStream.get()) == kCFStreamStatusError); + UniqueRef<CFErrorRef> err(CFWriteStreamCopyError(_writeStream.get())); + checkError(err.get(), __FILE__, __LINE__); if(noBuffers() && packetSize > 1024) { packetSize /= 2; @@ -377,21 +379,22 @@ IceObjC::StreamTransceiver::read(Buffer& buf) IceUtil::Mutex::Lock sync(_mutex); if(_error) { - assert(CFReadStreamGetStatus(_readStream) == kCFStreamStatusError); - checkError(CFReadStreamCopyError(_readStream), __FILE__, __LINE__); + assert(CFReadStreamGetStatus(_readStream.get()) == kCFStreamStatusError); + UniqueRef<CFErrorRef> err(CFReadStreamCopyError(_readStream.get())); + checkError(err.get(), __FILE__, __LINE__); } // Its impossible for the packetSize to be more than an Int. size_t packetSize = static_cast<size_t>(buf.b.end() - buf.i); while(buf.i != buf.b.end()) { - if(!CFReadStreamHasBytesAvailable(_readStream)) + if(!CFReadStreamHasBytesAvailable(_readStream.get())) { return SocketOperationRead; } assert(_fd != INVALID_SOCKET); - CFIndex ret = CFReadStreamRead(_readStream, reinterpret_cast<UInt8*>(&*buf.i), packetSize); + CFIndex ret = CFReadStreamRead(_readStream.get(), reinterpret_cast<UInt8*>(&*buf.i), packetSize); if(ret == 0) { @@ -402,15 +405,16 @@ IceObjC::StreamTransceiver::read(Buffer& buf) if(ret == SOCKET_ERROR) { - if(CFReadStreamGetStatus(_readStream) == kCFStreamStatusAtEnd) + if(CFReadStreamGetStatus(_readStream.get()) == kCFStreamStatusAtEnd) { ConnectionLostException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; } - assert(CFReadStreamGetStatus(_readStream) == kCFStreamStatusError); - checkError(CFReadStreamCopyError(_readStream), __FILE__, __LINE__); + assert(CFReadStreamGetStatus(_readStream.get()) == kCFStreamStatusError); + UniqueRef<CFErrorRef> err(CFReadStreamCopyError(_readStream.get())); + checkError(err.get(), __FILE__, __LINE__); if(noBuffers() && packetSize > 1024) { packetSize /= 2; @@ -517,8 +521,6 @@ IceObjC::StreamTransceiver::StreamTransceiver(const InstancePtr& instance, IceObjC::StreamTransceiver::~StreamTransceiver() { assert(_fd == INVALID_SOCKET); - CFRelease(_readStream); - CFRelease(_writeStream); } void @@ -529,7 +531,6 @@ IceObjC::StreamTransceiver::checkError(CFErrorRef err, const char* file, int lin if(CFStringCompare(domain, kCFErrorDomainPOSIX, 0) == kCFCompareEqualTo) { errno = CFErrorGetCode(err); - CFRelease(err); if(interrupted() || noBuffers()) { return; @@ -567,17 +568,13 @@ IceObjC::StreamTransceiver::checkError(CFErrorRef err, const char* file, int lin int rs = 0; if(error == kCFHostErrorUnknown) { - CFDictionaryRef dict = CFErrorCopyUserInfo(err); - CFNumberRef d = (CFNumberRef)CFDictionaryGetValue(dict, kCFGetAddrInfoFailureKey); + UniqueRef<CFDictionaryRef> dict(CFErrorCopyUserInfo(err)); + CFNumberRef d = static_cast<CFNumberRef>(CFDictionaryGetValue(dict.get(), kCFGetAddrInfoFailureKey)); if(d != 0) { CFNumberGetValue(d, kCFNumberSInt32Type, &rs); } - CFRelease(dict); } - - CFRelease(err); - DNSException ex(file, line); ex.error = rs; ex.host = _host; @@ -587,6 +584,5 @@ IceObjC::StreamTransceiver::checkError(CFErrorRef err, const char* file, int lin CFNetworkException ex(file, line); ex.domain = fromCFString(domain); ex.error = CFErrorGetCode(err); - CFRelease(err); throw ex; } diff --git a/cpp/src/Ice/ios/StreamTransceiver.h b/cpp/src/Ice/ios/StreamTransceiver.h index c6ba084b64b..734823eb463 100644 --- a/cpp/src/Ice/ios/StreamTransceiver.h +++ b/cpp/src/Ice/ios/StreamTransceiver.h @@ -13,6 +13,7 @@ #include <Ice/WSTransceiver.h> #include <Ice/Network.h> #include <Ice/Selector.h> +#include <Ice/UniqueRef.h> struct __CFError; typedef struct __CFError * CFErrorRef; @@ -42,6 +43,7 @@ public: StreamTransceiver(const InstancePtr&, CFReadStreamRef, CFWriteStreamRef, const std::string&, Ice::Int); StreamTransceiver(const InstancePtr&, CFReadStreamRef, CFWriteStreamRef, SOCKET); + virtual ~StreamTransceiver(); virtual IceInternal::NativeInfoPtr getNativeInfo(); @@ -72,8 +74,8 @@ private: const InstancePtr _instance; const std::string _host; const Ice::Int _port; - CFReadStreamRef _readStream; - CFWriteStreamRef _writeStream; + IceInternal::UniqueRef<CFReadStreamRef> _readStream; + IceInternal::UniqueRef<CFWriteStreamRef> _writeStream; bool _readStreamRegistered; bool _writeStreamRegistered; bool _opening; diff --git a/cpp/src/IceSSL/Certificate.cpp b/cpp/src/IceSSL/Certificate.cpp index dd15ff928a6..d1b5a0648bc 100755 --- a/cpp/src/IceSSL/Certificate.cpp +++ b/cpp/src/IceSSL/Certificate.cpp @@ -50,6 +50,7 @@ extern "C" typedef void (*FreeFunc)(void*); using namespace std; using namespace Ice; +using namespace IceInternal; using namespace IceSSL; #ifdef ICE_OS_UWP @@ -170,19 +171,20 @@ getX509Name(SecCertificateRef cert, CFTypeRef key) { assert(key == kSecOIDX509V1IssuerName || key == kSecOIDX509V1SubjectName); list<pair<string, string> > rdnPairs; - CFDictionaryRef property = getCertificateProperty(cert, key); + UniqueRef<CFDictionaryRef> property(getCertificateProperty(cert, key)); if(property) { - CFArrayRef dn = (CFArrayRef)CFDictionaryGetValue(property, kSecPropertyKeyValue); + CFArrayRef dn = static_cast<CFArrayRef>(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); int size = CFArrayGetCount(dn); for(int i = 0; i < size; ++i) { - CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(dn, i); + CFDictionaryRef dict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(dn, i)); rdnPairs.push_front(make_pair( - certificateOIDAlias(fromCFString((CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel))), - escapeX509Name(fromCFString((CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue))))); + certificateOIDAlias( + fromCFString((static_cast<CFStringRef>(CFDictionaryGetValue(dict, kSecPropertyKeyLabel))))), + escapeX509Name( + fromCFString(static_cast<CFStringRef>(CFDictionaryGetValue(dict, kSecPropertyKeyValue)))))); } - CFRelease(property); } return DistinguishedName(rdnPairs); } @@ -191,27 +193,27 @@ vector<pair<int, string> > getX509AltName(SecCertificateRef cert, CFTypeRef key) { assert(key == kSecOIDIssuerAltName || key == kSecOIDSubjectAltName); - CFDictionaryRef property = getCertificateProperty(cert, key); + UniqueRef<CFDictionaryRef> property(getCertificateProperty(cert, key)); vector<pair<int, string> > pairs; if(property) { - CFArrayRef names = (CFArrayRef)CFDictionaryGetValue(property, kSecPropertyKeyValue); + CFArrayRef names = static_cast<CFArrayRef>(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); int size = CFArrayGetCount(names); for(int i = 0; i < size; ++i) { - CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(names, i); + CFDictionaryRef dict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(names, i)); - int type = certificateAlternativeNameType(fromCFString( - (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel))); + int type = certificateAlternativeNameType( + fromCFString(static_cast<CFStringRef>(CFDictionaryGetValue(dict, kSecPropertyKeyLabel)))); if(type != -1) { - CFTypeRef v = (CFTypeRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue); - CFStringRef t = (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyType); + CFStringRef v = static_cast<CFStringRef>(CFDictionaryGetValue(dict, kSecPropertyKeyValue)); + CFStringRef t = static_cast<CFStringRef>(CFDictionaryGetValue(dict, kSecPropertyKeyType)); if(CFEqual(t, kSecPropertyTypeString) || CFEqual(t, kSecPropertyTypeTitle)) { - pairs.push_back(make_pair(type, fromCFString((CFStringRef)v))); + pairs.push_back(make_pair(type, fromCFString(v))); } else if(CFEqual(t, kSecPropertyTypeURL)) { @@ -225,8 +227,8 @@ getX509AltName(SecCertificateRef cert, CFTypeRef key) { CFDictionaryRef d = (CFDictionaryRef)CFArrayGetValueAtIndex(section, i); - CFStringRef sectionLabel = (CFStringRef)CFDictionaryGetValue(d, kSecPropertyKeyLabel); - CFStringRef sectionValue = (CFStringRef)CFDictionaryGetValue(d, kSecPropertyKeyValue); + CFStringRef sectionLabel = static_cast<CFStringRef>(CFDictionaryGetValue(d, kSecPropertyKeyLabel)); + CFStringRef sectionValue = static_cast<CFStringRef>(CFDictionaryGetValue(d, kSecPropertyKeyValue)); os << certificateOIDAlias(fromCFString(sectionLabel)) << "=" << fromCFString(sectionValue); if(++i < count) @@ -238,7 +240,6 @@ getX509AltName(SecCertificateRef cert, CFTypeRef key) } } } - CFRelease(property); } return pairs; } @@ -251,13 +252,12 @@ IceUtil::Time getX509Date(SecCertificateRef cert, CFTypeRef key) { assert(key == kSecOIDX509V1ValidityNotAfter || key == kSecOIDX509V1ValidityNotBefore); - CFDictionaryRef property = getCertificateProperty(cert, key); + UniqueRef<CFDictionaryRef> property(getCertificateProperty(cert, key)); CFAbsoluteTime seconds = 0; if(property) { - CFNumberRef date = (CFNumberRef)CFDictionaryGetValue(property, kSecPropertyKeyValue); + CFNumberRef date = static_cast<CFNumberRef>(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); CFNumberGetValue(date, kCFNumberDoubleType, &seconds); - CFRelease(property); } IceUtil::Time time = IceUtil::Time::secondsDouble(kCFAbsoluteTimeIntervalSince1970 + seconds); @@ -273,14 +273,9 @@ string getX509String(SecCertificateRef cert, CFTypeRef key) { assert(key == kSecOIDX509V1SerialNumber || key == kSecOIDX509V1Version); - CFDictionaryRef property = getCertificateProperty(cert, key); - string value; - if(property) - { - value = fromCFString((CFStringRef)CFDictionaryGetValue(property, kSecPropertyKeyValue)); - CFRelease(property); - } - return value; + UniqueRef<CFDictionaryRef> property(getCertificateProperty(cert, key)); + return property ? + fromCFString(static_cast<CFStringRef>(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue))) : ""; } #else // IOS @@ -668,7 +663,6 @@ CertificateEncodingException::CertificateEncodingException(const char* file, int { assert(err); reason = "certificate error:\n" + errorToString(err); - CFRelease(err); } #endif @@ -1020,24 +1014,29 @@ PublicKey::PublicKey(const CertificatePtr& cert, KeyRef key) : } } +// +// With SecureTransport the key is UniqueRef and will be automatically released. +// With SChannel the key is owned by the certificate and there is no need +// for release it. +// +#ifdef ICE_USE_OPENSSL PublicKey::~PublicKey() { -#ifndef ICE_USE_SCHANNEL if(_key) { -# if defined(ICE_USE_SECURE_TRANSPORT) - CFRelease(_key); -# elif defined(ICE_USE_OPENSSL) EVP_PKEY_free(_key); -# endif } -#endif } +#endif KeyRef PublicKey::key() const { +#ifdef __APPLE__ + return _key.get(); +#else return _key; +#endif } // @@ -1070,9 +1069,6 @@ Certificate::Certificate(X509CertificateRef cert) : _cert(cert) _cert = 0; throw; } -#elif defined(ICE_USE_SECURE_TRANSPORT_IOS) - _subject = 0; - _issuer = 0; #endif } @@ -1080,19 +1076,7 @@ Certificate::~Certificate() { if(_cert) { -#if defined(ICE_USE_SECURE_TRANSPORT_IOS) - if(_subject) - { - CFRelease(_subject); - } - if(_issuer) - { - CFRelease(_issuer); - } - CFRelease(_cert); -#elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) - CFRelease(_cert); -#elif defined(ICE_USE_SCHANNEL) +#if defined(ICE_USE_SCHANNEL) LocalFree(_cert); if(_certInfo) { @@ -1149,7 +1133,7 @@ Certificate::load(const string& file) { if(HRESULT_CODE(ex->HResult) == ERROR_FILE_NOT_FOUND) { - throw CertificateReadException(__FILE__, __LINE__, "certificate file not found:\n" + file); + throw CertificateReadException(__FILE__, __LINE__, "error opening file :" + file); } else { @@ -1190,8 +1174,11 @@ Certificate::decode(const string& encoding) } return ICE_MAKE_SHARED(Certificate, cert); #elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) - CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(encoding.c_str()), - encoding.size(), kCFAllocatorNull); + UniqueRef<CFDataRef> data( + CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + reinterpret_cast<const UInt8*>(encoding.c_str()), + encoding.size(), kCFAllocatorNull)); + SecExternalFormat format = kSecFormatUnknown; SecExternalItemType type = kSecItemTypeCertificate; @@ -1199,19 +1186,17 @@ Certificate::decode(const string& encoding) memset(¶ms, 0, sizeof(params)); params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - CFArrayRef items = 0; - OSStatus err = SecItemImport(data, 0, &format, &type, 0, ¶ms, 0, &items); - CFRelease(data); + UniqueRef<CFArrayRef> items; + OSStatus err = SecItemImport(data.get(), 0, &format, &type, 0, ¶ms, 0, &items.get()); if(err) { throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); } - SecKeychainItemRef item = (SecKeychainItemRef)CFArrayGetValueAtIndex(items, 0); - CFRetain(item); - CFRelease(items); - assert(SecCertificateGetTypeID() == CFGetTypeID(item)); - return ICE_MAKE_SHARED(Certificate, (SecCertificateRef)item); + UniqueRef<SecKeychainItemRef> item; + item.retain(static_cast<SecKeychainItemRef>(const_cast<void*>(CFArrayGetValueAtIndex(items.get(), 0)))); + assert(SecCertificateGetTypeID() == CFGetTypeID(item.get())); + return ICE_MAKE_SHARED(Certificate, reinterpret_cast<SecCertificateRef>(item.get())); #elif defined(ICE_USE_SCHANNEL) CERT_SIGNED_CONTENT_INFO* cert; loadCertificate(&cert, encoding.c_str(), static_cast<DWORD>(encoding.size())); @@ -1255,7 +1240,7 @@ bool Certificate::operator==(const Certificate& other) const { #if defined(ICE_USE_SECURE_TRANSPORT) - return CFEqual(_cert, other._cert); + return CFEqual(_cert.get(), other._cert.get()); #elif defined(ICE_USE_SCHANNEL) return CertCompareCertificate(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, _certInfo, other._certInfo); #elif defined(ICE_USE_OPENSSL) @@ -1279,13 +1264,13 @@ Certificate::getPublicKey() const #if defined(ICE_USE_SECURE_TRANSPORT_IOS) return ICE_NULLPTR; // Not supported #elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) - SecKeyRef key; - OSStatus err = SecCertificateCopyPublicKey(_cert, &key); + UniqueRef<SecKeyRef> key; + OSStatus err = SecCertificateCopyPublicKey(_cert.get(), &key.get()); if(err) { throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); } - return ICE_MAKE_SHARED(PublicKey, ICE_SHARED_FROM_CONST_THIS(Certificate), key); + return ICE_MAKE_SHARED(PublicKey, ICE_SHARED_FROM_CONST_THIS(Certificate), key.release()); #elif defined(ICE_USE_SCHANNEL) return ICE_MAKE_SHARED(PublicKey, ICE_SHARED_FROM_CONST_THIS(Certificate), &_certInfo->SubjectPublicKeyInfo); #elif defined(ICE_USE_OPENSSL) @@ -1308,101 +1293,53 @@ Certificate::verify(const CertificatePtr& cert) const // bool valid = false; -#if defined(ICE_USE_SECURE_TRANSPORT_IOS) +# if defined(ICE_USE_SECURE_TRANSPORT_IOS) initializeAttributes(); cert->initializeAttributes(); - valid = CFEqual(_issuer, cert->_subject); -#else - CFDataRef issuer = 0; - CFDataRef subject = 0; - CFErrorRef error = 0; - try + valid = CFEqual(_issuer.get(), cert->_subject.get()); +# else + UniqueRef<CFErrorRef> error; + UniqueRef<CFDataRef> issuer(SecCertificateCopyNormalizedIssuerContent(_cert.get(), &error.get())); + if(error) { - issuer = SecCertificateCopyNormalizedIssuerContent(_cert, &error); - if(error) - { - throw CertificateEncodingException(__FILE__, __LINE__, error); - } - - subject = SecCertificateCopyNormalizedSubjectContent(cert->getCert(), &error); - if(error) - { - throw CertificateEncodingException(__FILE__, __LINE__, error); - } + throw CertificateEncodingException(__FILE__, __LINE__, error.get()); } - catch(...) + UniqueRef<CFDataRef> subject(SecCertificateCopyNormalizedSubjectContent(cert->getCert(), &error.get())); + if(error) { - if(issuer) - { - CFRelease(issuer); - } - - if(subject) - { - CFRelease(subject); - } - throw; + throw CertificateEncodingException(__FILE__, __LINE__, error.get()); } // // The certificate issuer must match the CA subject. // - valid = CFEqual(issuer, subject); - - CFRelease(issuer); - CFRelease(subject); -#endif + valid = CFEqual(issuer.get(), subject.get()); +# endif if(valid) { - SecPolicyRef policy = 0; - SecTrustRef trust = 0; - try + UniqueRef<SecPolicyRef> policy(SecPolicyCreateBasicX509()); + UniqueRef<SecTrustRef> trust; + OSStatus err = 0;; + if((err = SecTrustCreateWithCertificates(_cert.get(), policy.get(), &trust.get()))) { - SecPolicyRef policy = SecPolicyCreateBasicX509(); - SecTrustResultType trustResult = kSecTrustResultInvalid; - SecTrustRef trust; - OSStatus err = 0; - - if((err = SecTrustCreateWithCertificates(_cert, policy, &trust))) - { - throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); - } - - SecCertificateRef certs[1] = { cert->getCert() }; - - CFArrayRef anchorCertificates = CFArrayCreate(kCFAllocatorDefault, (const void**)&certs, 1, - &kCFTypeArrayCallBacks); - err = SecTrustSetAnchorCertificates(trust, anchorCertificates); - CFRelease(anchorCertificates); - - if(err) - { - throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); - } - - if((err = SecTrustEvaluate(trust, &trustResult))) - { - throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); - } - - valid = trustResult == kSecTrustResultUnspecified; - - CFRelease(policy); - CFRelease(trust); + throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); } - catch(...) + + SecCertificateRef certs[1] = { cert->getCert() }; + UniqueRef<CFArrayRef> anchorCertificates( + CFArrayCreate(kCFAllocatorDefault, (const void**)&certs, 1, &kCFTypeArrayCallBacks)); + if((err = SecTrustSetAnchorCertificates(trust.get(), anchorCertificates.get()))) { - if(policy) - { - CFRelease(policy); - } + throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); + } - if(trust) - { - CFRelease(trust); - } - throw; + SecTrustResultType trustResult = kSecTrustResultInvalid; + if((err = SecTrustEvaluate(trust.get(), &trustResult))) + { + throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); } + + valid = trustResult == kSecTrustResultUnspecified; } return valid; #elif defined(ICE_USE_SCHANNEL) @@ -1437,23 +1374,21 @@ string Certificate::encode() const { #if defined(ICE_USE_SECURE_TRANSPORT_IOS) - UniqueRef<CFDataRef> c(SecCertificateCopyData(_cert)); - vector<unsigned char> data(CFDataGetBytePtr(c.get()), CFDataGetBytePtr(c.get()) + CFDataGetLength(c.get())); + UniqueRef<CFDataRef> cert(SecCertificateCopyData(_cert.get())); + vector<unsigned char> data(CFDataGetBytePtr(cert.get()), CFDataGetBytePtr(cert.get()) + CFDataGetLength(cert.get())); ostringstream os; os << "-----BEGIN CERTIFICATE-----\n"; os << IceInternal::Base64::encode(data); os << "-----END CERTIFICATE-----\n"; return os.str(); #elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) - CFDataRef exported; - OSStatus err = SecItemExport(_cert, kSecFormatPEMSequence, kSecItemPemArmour, 0, &exported); + UniqueRef<CFDataRef> exported; + OSStatus err = SecItemExport(_cert.get(), kSecFormatPEMSequence, kSecItemPemArmour, 0, &exported.get()); if(err != noErr) { throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); } - string data(reinterpret_cast<const char*>(CFDataGetBytePtr(exported)), CFDataGetLength(exported)); - CFRelease(exported); - return data; + return string(reinterpret_cast<const char*>(CFDataGetBytePtr(exported.get())), CFDataGetLength(exported.get())); #elif defined(ICE_USE_SCHANNEL) string s; DWORD length = 0; @@ -1552,7 +1487,7 @@ IceUtil::Time Certificate::getNotAfter() const { #if defined(ICE_USE_SECURE_TRANSPORT) - return getX509Date(_cert, kSecOIDX509V1ValidityNotAfter); + return getX509Date(_cert.get(), kSecOIDX509V1ValidityNotAfter); #elif defined(ICE_USE_SCHANNEL) return filetimeToTime(_certInfo->NotAfter); #elif defined(ICE_USE_OPENSSL) @@ -1579,7 +1514,7 @@ IceUtil::Time Certificate::getNotBefore() const { #if defined(ICE_USE_SECURE_TRANSPORT) - return getX509Date(_cert, kSecOIDX509V1ValidityNotBefore); + return getX509Date(_cert.get(), kSecOIDX509V1ValidityNotBefore); #elif defined(ICE_USE_SCHANNEL) return filetimeToTime(_certInfo->NotBefore); #elif defined(ICE_USE_OPENSSL) @@ -1607,7 +1542,7 @@ Certificate::getSerialNumber() const initializeAttributes(); return _serial; #elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) - return getX509String(_cert, kSecOIDX509V1SerialNumber); + return getX509String(_cert.get(), kSecOIDX509V1SerialNumber); #elif defined(ICE_USE_SCHANNEL) ostringstream os; for(int i = _certInfo->SerialNumber.cbData - 1; i >= 0; --i) @@ -1649,9 +1584,9 @@ Certificate::getIssuerDN() const { #if defined(ICE_USE_SECURE_TRANSPORT_IOS) initializeAttributes(); - return _issuer ? DistinguishedName(_issuer) : DistinguishedName(""); + return _issuer ? DistinguishedName(_issuer.get()) : DistinguishedName(""); #elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) - return getX509Name(_cert, kSecOIDX509V1IssuerName); + return getX509Name(_cert.get(), kSecOIDX509V1IssuerName); #elif defined(ICE_USE_SCHANNEL) return DistinguishedName(certNameToString(&_certInfo->Issuer)); #elif defined(ICE_USE_OPENSSL) @@ -1670,7 +1605,7 @@ vector<pair<int, string> > Certificate::getIssuerAlternativeNames() { #if defined(ICE_USE_SECURE_TRANSPORT) - return getX509AltName(_cert, kSecOIDIssuerAltName); + return getX509AltName(_cert.get(), kSecOIDIssuerAltName); #elif defined(ICE_USE_SCHANNEL) return certificateAltNames(_certInfo, szOID_ISSUER_ALT_NAME2); #elif defined(ICE_USE_OPENSSL) @@ -1690,16 +1625,15 @@ Certificate::getSubjectDN() const initializeAttributes(); if(_subject) { - return DistinguishedName(_subject); + return DistinguishedName(_subject.get()); } else { - ostringstream os; - os << "CN=" << fromCFString(UniqueRef<CFStringRef>(SecCertificateCopySubjectSummary(_cert)).get()); - return DistinguishedName(os.str()); + UniqueRef<CFStringRef> subjectSummary(SecCertificateCopySubjectSummary(_cert.get())); + return DistinguishedName("CN=" + fromCFString(subjectSummary.get())); } #elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) - return getX509Name(_cert, kSecOIDX509V1SubjectName); + return getX509Name(_cert.get(), kSecOIDX509V1SubjectName); #elif defined(ICE_USE_SCHANNEL) return DistinguishedName(certNameToString(&_certInfo->Subject)); #elif defined(ICE_USE_OPENSSL) @@ -1718,7 +1652,7 @@ vector<pair<int, string> > Certificate::getSubjectAlternativeNames() { #if defined(ICE_USE_SECURE_TRANSPORT) - return getX509AltName(_cert, kSecOIDSubjectAltName); + return getX509AltName(_cert.get(), kSecOIDSubjectAltName); #elif defined(ICE_USE_SCHANNEL) return certificateAltNames(_certInfo, szOID_SUBJECT_ALT_NAME2); #elif defined(ICE_USE_OPENSSL) @@ -1738,7 +1672,7 @@ Certificate::getVersion() const initializeAttributes(); return _version; #elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) - return atoi(getX509String(_cert, kSecOIDX509V1Version).c_str()) - 1; + return atoi(getX509String(_cert.get(), kSecOIDX509V1Version).c_str()) - 1; #elif defined(ICE_USE_SCHANNEL) return _certInfo->dwVersion; #elif defined(ICE_USE_OPENSSL) @@ -1775,7 +1709,11 @@ Certificate::toString() const X509CertificateRef Certificate::getCert() const { +#ifdef __APPLE__ + return _cert.get(); +#else return _cert; +#endif } #if defined(ICE_USE_SECURE_TRANSPORT_IOS) @@ -1808,11 +1746,6 @@ Init init; void Certificate::initializeAttributes() const { - if(_subject) - { - return; - } - // // We need to temporarily add the certificate to the keychain in order to // retrieve its attributes. Unfortunately kSecMatchItemList doesn't work @@ -1820,37 +1753,41 @@ Certificate::initializeAttributes() const // IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex); - CFMutableDictionaryRef query; + if(_subject) + { + return; + } - query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(query, kSecValueRef, _cert); - CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue); - CFDictionaryRef attributes; + UniqueRef<CFMutableDictionaryRef> query( + CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecValueRef, _cert.get()); + CFDictionarySetValue(query.get(), kSecReturnAttributes, kCFBooleanTrue); + + UniqueRef<CFDictionaryRef> attributes(0); OSStatus err; - if((err = SecItemAdd(query, (CFTypeRef*)&attributes)) == errSecDuplicateItem) + if((err = SecItemAdd(query.get(), reinterpret_cast<CFTypeRef*>(&attributes.get()))) == errSecDuplicateItem) { - CFDictionarySetValue(query, kSecClass, kSecClassCertificate); - err = SecItemCopyMatching(query, (CFTypeRef*)&attributes); + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + err = SecItemCopyMatching(query.get(), reinterpret_cast<CFTypeRef*>(&attributes.get())); } else { - CFRelease(query); - query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(query, kSecClass, kSecClassCertificate); - CFDictionarySetValue(query, kSecValueRef, _cert); - err = SecItemDelete(query); + query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + CFDictionarySetValue(query.get(), kSecValueRef, _cert.get()); + err = SecItemDelete(query.get()); } - CFRelease(query); + if(err != noErr) { - _subject = 0; - _issuer = 0; + _subject.reset(0); + _issuer.reset(0); throw CertificateEncodingException(__FILE__, __LINE__, errorToString(err)); } - _subject = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrSubject); - _issuer = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrIssuer); - CFDataRef serial = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrSerialNumber); + _subject.retain(static_cast<CFDataRef>(CFDictionaryGetValue(attributes.get(), kSecAttrSubject))); + _issuer.retain(static_cast<CFDataRef>(CFDictionaryGetValue(attributes.get(), kSecAttrIssuer))); + CFDataRef serial = static_cast<CFDataRef>(CFDictionaryGetValue(attributes.get(), kSecAttrSerialNumber)); ostringstream os; for(int i = 0; i < CFDataGetLength(serial); ++i) { @@ -1864,14 +1801,10 @@ Certificate::initializeAttributes() const os << hex << c; } _serial = os.str(); - CFNumberRef version = (CFNumberRef)CFDictionaryGetValue(attributes, kSecAttrCertificateType); + CFNumberRef version = static_cast<CFNumberRef>(CFDictionaryGetValue(attributes.get(), kSecAttrCertificateType)); if(!CFNumberGetValue(version, kCFNumberIntType, &_version)) { _version = -1; } - CFRetain(_subject); - CFRetain(_issuer); - - CFRelease(attributes); } #endif diff --git a/cpp/src/IceSSL/SSLEngine.h b/cpp/src/IceSSL/SSLEngine.h index d9f1a87ca81..fddd138cc6f 100644 --- a/cpp/src/IceSSL/SSLEngine.h +++ b/cpp/src/IceSSL/SSLEngine.h @@ -19,6 +19,7 @@ #include <IceUtil/Mutex.h> #include <Ice/CommunicatorF.h> #include <Ice/Network.h> +#include <Ice/UniqueRef.h> #if defined(ICE_USE_SECURE_TRANSPORT) # include <Security/Security.h> @@ -126,8 +127,8 @@ private: void parseCiphers(const std::string&); bool _initialized; - UniqueRef<CFArrayRef> _certificateAuthorities; - UniqueRef<CFArrayRef> _chain; + IceInternal::UniqueRef<CFArrayRef> _certificateAuthorities; + IceInternal::UniqueRef<CFArrayRef> _chain; SSLProtocol _protocolVersionMax; SSLProtocol _protocolVersionMin; diff --git a/cpp/src/IceSSL/SecureTransportEngine.cpp b/cpp/src/IceSSL/SecureTransportEngine.cpp index 6dd7e82b233..cc7e80503d0 100644 --- a/cpp/src/IceSSL/SecureTransportEngine.cpp +++ b/cpp/src/IceSSL/SecureTransportEngine.cpp @@ -31,6 +31,7 @@ using namespace std; using namespace IceUtil; using namespace Ice; +using namespace IceInternal; using namespace IceSSL; namespace @@ -1192,15 +1193,14 @@ IceSSL::SecureTransportEngine::parseCiphers(const string& ciphers) // // Context used to get the cipher list // - SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType); + UniqueRef<SSLContextRef> ctx(SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType)); size_t numSupportedCiphers = 0; - SSLGetNumberSupportedCiphers(ctx, &numSupportedCiphers); + SSLGetNumberSupportedCiphers(ctx.get(), &numSupportedCiphers); vector<SSLCipherSuite> supported; supported.resize(numSupportedCiphers); - OSStatus err = SSLGetSupportedCiphers(ctx, &supported[0], &numSupportedCiphers); - CFRelease(ctx); + OSStatus err = SSLGetSupportedCiphers(ctx.get(), &supported[0], &numSupportedCiphers); if(err) { throw PluginInitializationException(__FILE__, __LINE__, diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp index e369156fcd9..fabb02eb75c 100644 --- a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp +++ b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp @@ -18,6 +18,7 @@ using namespace std; using namespace Ice; +using namespace IceInternal; using namespace IceSSL; namespace @@ -96,7 +97,7 @@ socketRead(SSLConnectionRef connection, void* data, size_t* length) } bool -checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, const InstancePtr& instance, +checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, const IceSSL::InstancePtr& instance, const string& host) { OSStatus err = noErr; @@ -123,13 +124,12 @@ checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, cons // Add SSL trust policy if we need to check the certificate name. // UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(false, toCFString(host))); - CFArrayRef policies; - if((err = SecTrustCopyPolicies(trust, &policies))) + UniqueRef<CFArrayRef> policies; + if((err = SecTrustCopyPolicies(trust, &policies.get()))) { throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err)); } - UniqueRef<CFMutableArrayRef> newPolicies(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, policies)); - CFRelease(policies); + UniqueRef<CFMutableArrayRef> newPolicies(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, policies.get())); CFArrayAppendValue(newPolicies.get(), policy.release()); if((err = SecTrustSetPolicies(trust, newPolicies.release()))) { @@ -223,14 +223,14 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B // // Initialize SSL context // - _ssl = _engine->newContext(_incoming); - if((err = SSLSetIOFuncs(_ssl, socketRead, socketWrite))) + _ssl.reset(_engine->newContext(_incoming)); + if((err = SSLSetIOFuncs(_ssl.get(), socketRead, socketWrite))) { throw SecurityException(__FILE__, __LINE__, "IceSSL: setting IO functions failed\n" + errorToString(err)); } - if((err = SSLSetConnection(_ssl, reinterpret_cast<SSLConnectionRef>(this)))) + if((err = SSLSetConnection(_ssl.get(), reinterpret_cast<SSLConnectionRef>(this)))) { throw SecurityException(__FILE__, __LINE__, "IceSSL: setting SSL connection failed\n" + errorToString(err)); @@ -238,14 +238,14 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B } SSLSessionState state; - SSLGetSessionState(_ssl, &state); + SSLGetSessionState(_ssl.get(), &state); // // SSL Handshake // while(state == kSSLHandshake || state == kSSLIdle) { - err = SSLHandshake(_ssl); + err = SSLHandshake(_ssl.get()); if(err == noErr) { break; // We're done! @@ -258,8 +258,9 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B else if(err == errSSLPeerAuthCompleted) { assert(!_trust); - err = SSLCopyPeerTrust(_ssl, &_trust); - if(_incoming && _engine->getVerifyPeer() == 1 && (err == errSSLBadCert || _trust == 0)) + err = SSLCopyPeerTrust(_ssl.get(), &_trust.get()); + + if(_incoming && _engine->getVerifyPeer() == 1 && (err == errSSLBadCert || !_trust)) { // This is expected if the client doesn't provide a certificate. With 10.10 and 10.11 errSSLBadCert // is expected, the server is configured to verify but not require the client @@ -268,7 +269,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B } if(err == noErr) { - _verified = checkTrustResult(_trust, _engine, _instance, _host); + _verified = checkTrustResult(_trust.get(), _engine, _instance, _host); continue; // Call SSLHandshake to resume the handsake. } // Let it fall through, this will raise a SecurityException with the SSLCopyPeerTrust error. @@ -292,11 +293,11 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B out << "SSL summary for " << (_incoming ? "incoming" : "outgoing") << " connection\n"; SSLProtocol protocol; - SSLGetNegotiatedProtocolVersion(_ssl, &protocol); + SSLGetNegotiatedProtocolVersion(_ssl.get(), &protocol); const string sslProtocolName = protocolName(protocol); SSLCipherSuite cipher; - SSLGetNegotiatedCipher(_ssl, &cipher); + SSLGetNegotiatedCipher(_ssl.get(), &cipher); const string sslCipherName = _engine->getCipherName(cipher); if(sslCipherName.empty()) @@ -325,18 +326,12 @@ IceSSL::TransceiverI::closing(bool initiator, const Ice::LocalException&) void IceSSL::TransceiverI::close() { - if(_trust) - { - CFRelease(_trust); - _trust = 0; - } - + _trust.reset(0); if(_ssl) { - SSLClose(_ssl); - CFRelease(_ssl); - _ssl = 0; + SSLClose(_ssl.get()); } + _ssl.reset(0); _delegate->close(); } @@ -361,8 +356,8 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf) while(buf.i != buf.b.end()) { size_t processed = 0; - OSStatus err = _buffered ? SSLWrite(_ssl, 0, 0, &processed) : - SSLWrite(_ssl, reinterpret_cast<const void*>(buf.i), packetSize, &processed); + OSStatus err = _buffered ? SSLWrite(_ssl.get(), 0, 0, &processed) : + SSLWrite(_ssl.get(), reinterpret_cast<const void*>(buf.i), packetSize, &processed); if(err) { @@ -439,7 +434,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) while(buf.i != buf.b.end()) { size_t processed = 0; - OSStatus err = SSLRead(_ssl, reinterpret_cast<void*>(buf.i), packetSize, &processed); + OSStatus err = SSLRead(_ssl.get(), reinterpret_cast<void*>(buf.i), packetSize, &processed); if(err) { if(err == errSSLWouldBlock) @@ -486,7 +481,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf) // Check if there's still buffered data to read. In this case, set the read ready status. // size_t buffered = 0; - OSStatus err = SSLGetBufferedReadSize(_ssl, &buffered); + OSStatus err = SSLGetBufferedReadSize(_ssl.get(), &buffered); if(err) { errno = err; @@ -523,9 +518,9 @@ IceSSL::TransceiverI::getInfo() const info->adapterName = _adapterName; if(_ssl) { - for(int i = 0, count = SecTrustGetCertificateCount(_trust); i < count; ++i) + for(int i = 0, count = SecTrustGetCertificateCount(_trust.get()); i < count; ++i) { - SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust, i); + SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust.get(), i); CFRetain(cert); CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cert); @@ -534,7 +529,7 @@ IceSSL::TransceiverI::getInfo() const } SSLCipherSuite cipher; - SSLGetNegotiatedCipher(_ssl, &cipher); + SSLGetNegotiatedCipher(_ssl.get(), &cipher); info->cipher = _engine->getCipherName(cipher); info->verified = _verified; } @@ -556,7 +551,7 @@ IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize) _delegate->setBufferSize(rcvSize, sndSize); } -IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, +IceSSL::TransceiverI::TransceiverI(const IceSSL::InstancePtr& instance, const IceInternal::TransceiverPtr& delegate, const string& hostOrAdapterName, bool incoming) : @@ -566,8 +561,6 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, _adapterName(incoming ? hostOrAdapterName : ""), _incoming(incoming), _delegate(delegate), - _ssl(0), - _trust(0), _connected(false), _verified(false), _buffered(0) diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.h b/cpp/src/IceSSL/SecureTransportTransceiverI.h index 59ac94b8584..1c5cd8a84e9 100644 --- a/cpp/src/IceSSL/SecureTransportTransceiverI.h +++ b/cpp/src/IceSSL/SecureTransportTransceiverI.h @@ -16,6 +16,7 @@ #include <IceSSL/Plugin.h> #include <Ice/Transceiver.h> +#include <Ice/UniqueRef.h> #include <Ice/Network.h> #ifdef ICE_USE_SECURE_TRANSPORT @@ -67,8 +68,8 @@ private: const bool _incoming; const IceInternal::TransceiverPtr _delegate; - SSLContextRef _ssl; - SecTrustRef _trust; + IceInternal::UniqueRef<SSLContextRef> _ssl; + IceInternal::UniqueRef<SecTrustRef> _trust; bool _connected; bool _verified; diff --git a/cpp/src/IceSSL/Util.cpp b/cpp/src/IceSSL/Util.cpp index 26608354fa2..f47d1e32753 100755 --- a/cpp/src/IceSSL/Util.cpp +++ b/cpp/src/IceSSL/Util.cpp @@ -33,6 +33,7 @@ using namespace std; using namespace Ice; +using namespace IceInternal; using namespace IceUtil; using namespace IceSSL; @@ -579,9 +580,8 @@ IceSSL::errorToString(CFErrorRef err) ostringstream os; if(err) { - CFStringRef s = CFErrorCopyDescription(err); - os << "(error: " << CFErrorGetCode(err) << " description: " << fromCFString(s) << ")"; - CFRelease(s); + UniqueRef<CFStringRef> s(CFErrorCopyDescription(err)); + os << "(error: " << CFErrorGetCode(err) << " description: " << fromCFString(s.get()) << ")"; } return os.str(); } @@ -592,11 +592,10 @@ IceSSL::errorToString(OSStatus status) ostringstream os; os << "(error: " << status; #if defined(ICE_USE_SECURE_TRANSPORT_MACOS) - CFStringRef s = SecCopyErrorMessageString(status, 0); + UniqueRef<CFStringRef> s(SecCopyErrorMessageString(status, 0)); if(s) { - os << " description: " << fromCFString(s); - CFRelease(s); + os << " description: " << fromCFString(s.get()); } #endif os << ")"; @@ -622,10 +621,10 @@ IceSSL::fromCFString(CFStringRef v) CFDictionaryRef IceSSL::getCertificateProperty(SecCertificateRef cert, CFTypeRef key) { - CFArrayRef keys = CFArrayCreate(ICE_NULLPTR, &key , 1, &kCFTypeArrayCallBacks); - CFErrorRef err = 0; - CFDictionaryRef values = SecCertificateCopyValues(cert, keys, &err); - CFRelease(keys); + UniqueRef<CFDictionaryRef> property; + UniqueRef<CFArrayRef> keys(CFArrayCreate(ICE_NULLPTR, &key , 1, &kCFTypeArrayCallBacks)); + UniqueRef<CFErrorRef> err; + UniqueRef<CFDictionaryRef> values(SecCertificateCopyValues(cert, keys.get(), &err.get())); if(err) { ostringstream os; @@ -634,20 +633,15 @@ IceSSL::getCertificateProperty(SecCertificateRef cert, CFTypeRef key) } assert(values); - CFDictionaryRef property = (CFDictionaryRef)CFDictionaryGetValue(values, key); - if(property) - { - CFRetain(property); - } - CFRelease(values); - return property; + property.retain(static_cast<CFDictionaryRef>(CFDictionaryGetValue(values.get(), key))); + return property.release(); } #endif namespace { -CFDataRef +CFMutableDataRef readCertFile(const string& file) { ifstream is(IceUtilInternal::streamFilename(file).c_str(), ios::in | ios::binary); @@ -660,15 +654,14 @@ readCertFile(const string& file) size_t size = is.tellg(); is.seekg(0, is.beg); - CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, size); - CFDataSetLength(data, size); - is.read(reinterpret_cast<char*>(CFDataGetMutableBytePtr(data)), size); + UniqueRef<CFMutableDataRef> data(CFDataCreateMutable(kCFAllocatorDefault, size)); + CFDataSetLength(data.get(), size); + is.read(reinterpret_cast<char*>(CFDataGetMutableBytePtr(data.get())), size); if(!is.good()) { - CFRelease(data); throw CertificateReadException(__FILE__, __LINE__, "error reading file " + file); } - return data; + return data.release(); } #if defined(ICE_USE_SECURE_TRANSPORT_MACOS) @@ -681,14 +674,14 @@ isCA(SecCertificateRef cert) UniqueRef<CFDictionaryRef> property(getCertificateProperty(cert, kSecOIDBasicConstraints)); if(property) { - CFArrayRef propertyValues = (CFArrayRef)CFDictionaryGetValue(property.get(), kSecPropertyKeyValue); + CFArrayRef propertyValues = static_cast<CFArrayRef>(CFDictionaryGetValue(property.get(), kSecPropertyKeyValue)); for(int i = 0, size = CFArrayGetCount(propertyValues); i < size; ++i) { - CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(propertyValues, i); - CFStringRef label = (CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyLabel); + CFDictionaryRef dict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(propertyValues, i)); + CFStringRef label = static_cast<CFStringRef>(CFDictionaryGetValue(dict, kSecPropertyKeyLabel)); if(CFEqual(label, CFSTR("Certificate Authority"))) { - return CFEqual((CFStringRef)CFDictionaryGetValue(dict, kSecPropertyKeyValue), CFSTR("Yes")); + return CFEqual(static_cast<CFStringRef>(CFDictionaryGetValue(dict, kSecPropertyKeyValue)), CFSTR("Yes")); } } } @@ -703,7 +696,7 @@ CFArrayRef loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef keychain, const string& passphrase, const PasswordPromptPtr& prompt, int retryMax) { - UniqueRef<CFDataRef> data(readCertFile(file)); + UniqueRef<CFMutableDataRef> data(readCertFile(file)); SecItemImportExportKeyParameters params; memset(¶ms, 0, sizeof(params)); @@ -714,17 +707,19 @@ loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef k params.passphrase = toCFString(passphrase); } - CFArrayRef items; + UniqueRef<CFArrayRef> items; SecExternalItemType importType = type; SecExternalFormat format = type == kSecItemTypeUnknown ? kSecFormatPKCS12 : kSecFormatUnknown; UniqueRef<CFStringRef> path(toCFString(file)); - OSStatus err = SecItemImport(data.get(), path.get(), &format, &importType, 0, ¶ms, keychain, &items); + OSStatus err = SecItemImport(data.get(), path.get(), &format, &importType, 0, ¶ms, keychain, &items.get()); // // If passphrase failure and no password was configured, we obtain // the password from the given prompt or configure the import to // prompt the user with an alert dialog. // + UniqueRef<CFStringRef> passphraseHolder; + UniqueRef<CFStringRef> alertPromptHolder; if(passphrase.empty() && (err == errSecPassphraseRequired || err == errSecInvalidData || err == errSecPkcs12VerifyFailure)) { @@ -733,7 +728,8 @@ loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef k params.flags |= kSecKeySecurePassphrase; ostringstream os; os << "Enter the password for\n" << file; - params.alertPrompt = toCFString(os.str()); + alertPromptHolder.reset(toCFString(os.str())); + params.alertPrompt = alertPromptHolder.get(); } int count = 0; @@ -742,25 +738,12 @@ loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef k { if(prompt) { - if(params.passphrase) - { - CFRelease(params.passphrase); - } - params.passphrase = toCFString(prompt->getPassword()); + passphraseHolder.reset(toCFString(prompt->getPassword())); + params.passphrase = passphraseHolder.get(); } - err = SecItemImport(data.get(), path.get(), &format, &importType, 0, ¶ms, keychain, &items); + err = SecItemImport(data.get(), path.get(), &format, &importType, 0, ¶ms, keychain, &items.get()); ++count; } - - if(params.alertPrompt) - { - CFRelease(params.alertPrompt); - } - } - - if(params.passphrase) - { - CFRelease(params.passphrase); } if(err != noErr) @@ -773,25 +756,24 @@ loadKeychainItems(const string& file, SecExternalItemType type, SecKeychainRef k if(type != kSecItemTypeUnknown && importType != kSecItemTypeAggregate && importType != type) { - CFRelease(items); ostringstream os; os << "IceSSL: error reading " << (type == kSecItemTypePrivateKey ? "private key" : "certificate"); os << " `" << file << "' doesn't contain the expected item"; throw CertificateReadException(__FILE__, __LINE__, os.str()); } - return items; + return items.release(); } SecKeychainRef openKeychain(const std::string& path, const std::string& keychainPassword) { string keychainPath = path; - SecKeychainRef keychain = 0; + UniqueRef<SecKeychainRef> keychain; OSStatus err = 0; if(keychainPath.empty()) { - if((err = SecKeychainCopyDefault(&keychain))) + if((err = SecKeychainCopyDefault(&keychain.get()))) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to retrieve default keychain:\n" + errorToString(err)); @@ -811,21 +793,19 @@ openKeychain(const std::string& path, const std::string& keychainPassword) } } - if((err = SecKeychainOpen(keychainPath.c_str(), &keychain))) + if((err = SecKeychainOpen(keychainPath.c_str(), &keychain.get()))) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to open keychain: `" + keychainPath + "'\n" + errorToString(err)); } } - UniqueRef<SecKeychainRef> k(keychain); - SecKeychainStatus status; - err = SecKeychainGetStatus(keychain, &status); + err = SecKeychainGetStatus(keychain.get(), &status); if(err == noErr) { const char* pass = keychainPassword.empty() ? 0 : keychainPassword.c_str(); - if((err = SecKeychainUnlock(keychain, keychainPassword.size(), pass, pass != 0))) + if((err = SecKeychainUnlock(keychain.get(), keychainPassword.size(), pass, pass != 0))) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to unlock keychain:\n" + errorToString(err)); @@ -834,12 +814,12 @@ openKeychain(const std::string& path, const std::string& keychainPassword) 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))) + keychain.reset(0); + if((err = SecKeychainCreate(keychainPath.c_str(), keychainPassword.size(), pass, pass == 0, 0, &keychain.get()))) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unable to create keychain:\n" + errorToString(err)); } - k.reset(keychain); } else { @@ -855,13 +835,13 @@ openKeychain(const std::string& path, const std::string& keychainPassword) settings.lockOnSleep = FALSE; settings.useLockInterval = FALSE; settings.lockInterval = INT_MAX; - if((err = SecKeychainSetSettings(keychain, &settings))) + if((err = SecKeychainSetSettings(keychain.get(), &settings))) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error setting keychain settings:\n" + errorToString(err)); } - return k.release(); + return keychain.release(); } // @@ -878,13 +858,14 @@ loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keycha UniqueRef<CFDictionaryRef> subjectKeyProperty(getCertificateProperty(cert, kSecOIDSubjectKeyIdentifier)); if(subjectKeyProperty) { - CFArrayRef values = (CFArrayRef)CFDictionaryGetValue(subjectKeyProperty.get(), kSecPropertyKeyValue); + CFArrayRef values = static_cast<CFArrayRef>(CFDictionaryGetValue(subjectKeyProperty.get(), + kSecPropertyKeyValue)); for(int i = 0; i < CFArrayGetCount(values); ++i) { - CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(values, i); + CFDictionaryRef dict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(values, i)); if(CFEqual(CFDictionaryGetValue(dict, kSecPropertyKeyLabel), CFSTR("Key Identifier"))) { - hash.retain(CFDictionaryGetValue(dict, kSecPropertyKeyValue)); + hash.retain(static_cast<CFDataRef>(CFDictionaryGetValue(dict, kSecPropertyKeyValue))); break; } } @@ -904,24 +885,24 @@ loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keycha CFDictionarySetValue(query.get(), kSecAttrSubjectKeyID, hash.get()); CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); - CFTypeRef value = 0; - OSStatus err = SecItemCopyMatching(query.get(), &value); - UniqueRef<SecCertificateRef> item(value); + UniqueRef<CFTypeRef> value(0); + OSStatus err = SecItemCopyMatching(query.get(), &value.get()); + UniqueRef<SecCertificateRef> item(static_cast<SecCertificateRef>(const_cast<void*>(value.release()))); if(err == noErr) { // // If the certificate has already been imported, create the // identity. The key should also have been imported. // - SecIdentityRef identity; - err = SecIdentityCreateWithCertificate(keychain, item.get(), &identity); + UniqueRef<SecIdentityRef> identity; + err = SecIdentityCreateWithCertificate(keychain, item.get(), &identity.get()); if(err != noErr) { ostringstream os; os << "IceSSL: error creating certificate identity:\n" << errorToString(err); throw CertificateReadException(__FILE__, __LINE__, os.str()); } - return identity; + return identity.release(); } else if(err != errSecItemNotFound) { @@ -939,10 +920,11 @@ loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keycha UniqueRef<SecKeyRef> key; for(int i = 0; i < count; ++i) { - SecKeychainItemRef item = (SecKeychainItemRef)CFArrayGetValueAtIndex(items.get(), 0); + SecKeychainItemRef item = + static_cast<SecKeychainItemRef>(const_cast<void*>(CFArrayGetValueAtIndex(items.get(), 0))); if(SecKeyGetTypeID() == CFGetTypeID(item)) { - key.retain(item); + key.retain(reinterpret_cast<SecKeyRef>(item)); break; } } @@ -964,16 +946,16 @@ loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keycha CFDictionarySetValue(query.get(), kSecValueRef, cert); CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); - value = 0; - err = SecItemAdd(query.get(), (CFTypeRef*)&value); - UniqueRef<CFArrayRef> added(value); + value.reset(0); + err = SecItemAdd(query.get(), static_cast<CFTypeRef*>(&value.get())); + UniqueRef<CFArrayRef> added(static_cast<CFArrayRef>(value.release())); if(err != noErr) { ostringstream os; os << "IceSSL: failure adding certificate to keychain\n" << errorToString(err); throw CertificateReadException(__FILE__, __LINE__, os.str()); } - item.retain(CFArrayGetValueAtIndex(added.get(), 0)); + item.retain(static_cast<SecCertificateRef>(const_cast<void*>(CFArrayGetValueAtIndex(added.get(), 0)))); // // Create the association between the private key and the certificate, @@ -984,7 +966,7 @@ loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keycha { SecKeychainAttribute attr; attr.tag = kSecKeyLabel; - attr.data = (void*)CFDataGetBytePtr(hash.get()); + attr.data = const_cast<UInt8*>(CFDataGetBytePtr(hash.get())); attr.length = CFDataGetLength(hash.get()); attributes.push_back(attr); } @@ -994,15 +976,13 @@ loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keycha // name. // string label; - CFStringRef commonName = 0; - if(SecCertificateCopyCommonName(item.get(), &commonName) == noErr) + UniqueRef<CFStringRef> commonName(0); + if(SecCertificateCopyCommonName(item.get(), &commonName.get()) == noErr) { - label = fromCFString(commonName); - CFRelease(commonName); - + label = fromCFString(commonName.get()); SecKeychainAttribute attr; attr.tag = kSecKeyPrintName; - attr.data = (void*)label.c_str(); + attr.data = const_cast<char*>(label.c_str()); attr.length = label.size(); attributes.push_back(attr); } @@ -1010,24 +990,24 @@ loadPrivateKey(const string& file, SecCertificateRef cert, SecKeychainRef keycha SecKeychainAttributeList attrs; attrs.attr = &attributes[0]; attrs.count = attributes.size(); - SecKeychainItemModifyAttributesAndData((SecKeychainItemRef)key.get(), &attrs, 0, 0); + SecKeychainItemModifyAttributesAndData(reinterpret_cast<SecKeychainItemRef>(key.get()), &attrs, 0, 0); - SecIdentityRef identity; - err = SecIdentityCreateWithCertificate(keychain, item.get(), &identity); + UniqueRef<SecIdentityRef> identity; + err = SecIdentityCreateWithCertificate(keychain, item.get(), &identity.get()); if(err != noErr) { ostringstream os; os << "IceSSL: error creating certificate identity:\n" << errorToString(err); throw CertificateReadException(__FILE__, __LINE__, os.str()); } - return identity; + return identity.release(); } #else CFArrayRef loadCerts(const string& file) { - UniqueRef<CFMutableArrayRef> certs(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); + UniqueRef<CFArrayRef> certs(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); if(file.find(".pem") != string::npos) { vector<char> buffer; @@ -1063,30 +1043,28 @@ loadCerts(const string& file) vector<unsigned char> data(IceInternal::Base64::decode(string(&buffer[startpos], size))); UniqueRef<CFDataRef> certdata(CFDataCreate(kCFAllocatorDefault, &data[0], data.size())); - SecCertificateRef cert = SecCertificateCreateWithData(0, certdata.get()); + UniqueRef<SecCertificateRef> cert(SecCertificateCreateWithData(0, certdata.get())); if(!cert) { InitializationException ex(__FILE__, __LINE__); ex.reason = "IceSSL: certificate " + file + " is not a valid PEM-encoded certificate"; throw ex; } - CFArrayAppendValue(certs.get(), cert); - CFRelease(cert); + CFArrayAppendValue(const_cast<CFMutableArrayRef>(certs.get()), cert.get()); first = false; } } else { UniqueRef<CFDataRef> data(readCertFile(file)); - SecCertificateRef cert = SecCertificateCreateWithData(0, data.get()); + UniqueRef<SecCertificateRef> cert(SecCertificateCreateWithData(0, data.get())); if(!cert) { InitializationException ex(__FILE__, __LINE__); ex.reason = "IceSSL: certificate " + file + " is not a valid DER-encoded certificate"; throw ex; } - CFArrayAppendValue(certs.get(), cert); - CFRelease(cert); + CFArrayAppendValue(const_cast<CFMutableArrayRef>(certs.get()), cert.get()); } return certs.release(); } @@ -1102,31 +1080,26 @@ IceSSL::loadCertificateChain(const string& file, const string& keyFile, const st const string& keychainPassword, const string& password, const PasswordPromptPtr& prompt, int retryMax) { + UniqueRef<CFArrayRef> chain; #if defined(ICE_USE_SECURE_TRANSPORT_IOS) UniqueRef<CFDataRef> cert(readCertFile(file)); - UniqueRef<CFMutableDictionaryRef> settings(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks)); - CFArrayRef items = 0; + UniqueRef<CFMutableDictionaryRef> settings(CFDictionaryCreateMutable(0, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)); + UniqueRef<CFArrayRef> items; OSStatus err; - if(password.empty() && prompt) - { - int count = 0; - do - { - UniqueRef<CFStringRef> pass(toCFString(prompt->getPassword())); - CFDictionarySetValue(settings.get(), kSecImportExportPassphrase, pass.get()); - err = SecPKCS12Import(cert.get(), settings.get(), &items); - ++count; - } - while(err == errSecAuthFailed && count < retryMax); - } - else + int count = 0; + do { - UniqueRef<CFStringRef> pass(toCFString(password)); + UniqueRef<CFStringRef> pass(toCFString(password.empty() && prompt ? prompt->getPassword() : password)); CFDictionarySetValue(settings.get(), kSecImportExportPassphrase, pass.get()); - err = SecPKCS12Import(cert.get(), settings.get(), &items); + err = SecPKCS12Import(cert.get(), settings.get(), &items.get()); + ++count; } + while(password.empty() && prompt && err == errSecAuthFailed && count < retryMax); + if(err != noErr) { ostringstream os; @@ -1134,27 +1107,30 @@ IceSSL::loadCertificateChain(const string& file, const string& keyFile, const st throw InitializationException(__FILE__, __LINE__, os.str()); } - UniqueRef<CFArrayRef> itemsHolder(items);; - for(int i = 0; i < CFArrayGetCount(items); ++i) + for(int i = 0; i < CFArrayGetCount(items.get()); ++i) { - CFDictionaryRef dict = (CFDictionaryRef)CFArrayGetValueAtIndex(items, i); - SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(dict, kSecImportItemIdentity); + CFDictionaryRef dict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(items.get(), i)); + SecIdentityRef identity = static_cast<SecIdentityRef>( + const_cast<void*>(CFDictionaryGetValue(dict, kSecImportItemIdentity))); if(identity) { - CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(dict, kSecImportItemCertChain); - CFMutableArrayRef a = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certs); - CFArraySetValueAtIndex(a, 0, identity); - return a; + CFArrayRef certs = static_cast<CFArrayRef>(CFDictionaryGetValue(dict, kSecImportItemCertChain)); + chain.reset(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certs)); + CFArraySetValueAtIndex(const_cast<CFMutableArrayRef>(chain.get()), 0, identity); } } - ostringstream os; - os << "IceSSL: couldn't find identity in file " << file; - throw InitializationException(__FILE__, __LINE__, os.str()); + + if(!chain) + { + ostringstream os; + os << "IceSSL: couldn't find identity in file " << file; + throw InitializationException(__FILE__, __LINE__, os.str()); + } #else UniqueRef<SecKeychainRef> keychain(openKeychain(keychainPath, keychainPassword)); if(keyFile.empty()) { - return loadKeychainItems(file, kSecItemTypeUnknown, keychain.get(), password, prompt, retryMax); + chain.reset(loadKeychainItems(file, kSecItemTypeUnknown, keychain.get(), password, prompt, retryMax)); } else { @@ -1163,7 +1139,8 @@ IceSSL::loadCertificateChain(const string& file, const string& keyFile, const st // might already have been imported. // UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypeCertificate, 0, password, prompt, retryMax)); - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(items.get(), 0); + SecCertificateRef cert = + static_cast<SecCertificateRef>(const_cast<void*>(CFArrayGetValueAtIndex(items.get(), 0))); if(SecCertificateGetTypeID() != CFGetTypeID(cert)) { ostringstream os; @@ -1177,28 +1154,26 @@ IceSSL::loadCertificateChain(const string& file, const string& keyFile, const st // already present in the keychain. // UniqueRef<SecIdentityRef> identity(loadPrivateKey(keyFile, cert, keychain.get(), password, prompt, retryMax)); - CFMutableArrayRef a = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, items.get()); - CFArraySetValueAtIndex(a, 0, identity.get()); - return a; + chain.reset(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, items.get())); + CFArraySetValueAtIndex(const_cast<CFMutableArrayRef>(chain.get()), 0, identity.get()); } #endif + return chain.release(); } SecCertificateRef IceSSL::loadCertificate(const string& file) { + UniqueRef<SecCertificateRef> cert; #if defined(ICE_USE_SECURE_TRANSPORT_IOS) UniqueRef<CFArrayRef> certs(loadCerts(file)); assert(CFArrayGetCount(certs.get()) > 0); - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs.get(), 0); - CFRetain(cert); - return cert; + cert.retain((SecCertificateRef)CFArrayGetValueAtIndex(certs.get(), 0)); #else UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0)); - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(items.get(), 0); - CFRetain(cert); - return cert; + cert.retain((SecCertificateRef)CFArrayGetValueAtIndex(items.get(), 0)); #endif + return cert.release(); } CFArrayRef @@ -1208,18 +1183,19 @@ IceSSL::loadCACertificates(const string& file) return loadCerts(file); #else UniqueRef<CFArrayRef> items(loadKeychainItems(file, kSecItemTypeCertificate, 0, "", 0, 0)); - CFMutableArrayRef certificateAuthorities = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + UniqueRef<CFArrayRef> certificateAuthorities(CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); int count = CFArrayGetCount(items.get()); for(CFIndex i = 0; i < count; ++i) { - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(items.get(), i); + SecCertificateRef cert = + static_cast<SecCertificateRef>(const_cast<void*>(CFArrayGetValueAtIndex(items.get(), i))); assert(SecCertificateGetTypeID() == CFGetTypeID(cert)); if(isCA(cert)) { - CFArrayAppendValue(certificateAuthorities, cert); + CFArrayAppendValue(const_cast<CFMutableArrayRef>(certificateAuthorities.get()), cert); } } - return certificateAuthorities; + return certificateAuthorities.release(); #endif } @@ -1335,22 +1311,20 @@ IceSSL::findCertificateChain(const std::string& keychainPath, const std::string& throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid value `" + value + "'"); } - SecCertificateRef cert = 0; - OSStatus err = SecItemCopyMatching(query.get(), (CFTypeRef*)&cert); + UniqueRef<SecCertificateRef> cert; + OSStatus err = SecItemCopyMatching(query.get(), (CFTypeRef*)&cert.get()); if(err != noErr) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: find certificate `" + value + "' failed:\n" + errorToString(err)); } - UniqueRef<SecCertificateRef> certHolder(cert); - // // Retrieve the certificate chain // UniqueRef<SecPolicyRef> policy(SecPolicyCreateSSL(true, 0)); SecTrustRef trust = 0; - err = SecTrustCreateWithCertificates((CFArrayRef)cert, policy.get(), &trust); + err = SecTrustCreateWithCertificates(reinterpret_cast<CFArrayRef>(cert.get()), policy.get(), &trust); if(err || !trust) { throw PluginInitializationException(__FILE__, __LINE__, @@ -1367,18 +1341,17 @@ IceSSL::findCertificateChain(const std::string& keychainPath, const std::string& } int chainLength = SecTrustGetCertificateCount(trust); - CFMutableArrayRef items = CFArrayCreateMutable(kCFAllocatorDefault, chainLength, &kCFTypeArrayCallBacks); - UniqueRef<CFMutableArrayRef> itemsHolder(items); + UniqueRef<CFArrayRef> items(CFArrayCreateMutable(kCFAllocatorDefault, chainLength, &kCFTypeArrayCallBacks)); for(int i = 0; i < chainLength; ++i) { - CFArrayAppendValue(items, SecTrustGetCertificateAtIndex(trust, i)); + CFArrayAppendValue(const_cast<CFMutableArrayRef>(items.get()), SecTrustGetCertificateAtIndex(trust, i)); } // // Replace the first certificate in the chain with the // identity. // - SecIdentityRef identity; + UniqueRef<SecIdentityRef> identity; #if defined(ICE_USE_SECURE_TRANSPORT_IOS) // @@ -1388,36 +1361,34 @@ IceSSL::findCertificateChain(const std::string& keychainPath, const std::string& // query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); - CFDictionarySetValue(query.get(), kSecValueRef, cert); + CFDictionarySetValue(query.get(), kSecValueRef, cert.get()); CFDictionarySetValue(query.get(), kSecReturnAttributes, kCFBooleanTrue); - CFDictionaryRef attributes; - err = SecItemCopyMatching(query.get(), (CFTypeRef*)&attributes); + UniqueRef<CFDictionaryRef> attributes; + err = SecItemCopyMatching(query.get(), reinterpret_cast<CFTypeRef*>(&attributes.get())); if(err != noErr) { ostringstream os; os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << errorToString(err); throw PluginInitializationException(__FILE__, __LINE__, os.str()); } - UniqueRef<CFDictionaryRef> attributesHolder(attributes); // Now lookup the identity with the label query.reset(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); CFDictionarySetValue(query.get(), kSecMatchLimit, kSecMatchLimitOne); CFDictionarySetValue(query.get(), kSecClass, kSecClassIdentity); - CFDictionarySetValue(query.get(), kSecAttrLabel, (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrLabel)); + CFDictionarySetValue(query.get(), kSecAttrLabel, (CFDataRef)CFDictionaryGetValue(attributes.get(), kSecAttrLabel)); CFDictionarySetValue(query.get(), kSecReturnRef, kCFBooleanTrue); - err = SecItemCopyMatching(query.get(), (CFTypeRef*)&identity); + err = SecItemCopyMatching(query.get(), (CFTypeRef*)&identity.get()); if(err == noErr) { - SecCertificateRef cert2 = ICE_NULLPTR; - if((err = SecIdentityCopyCertificate(identity, &cert2)) == noErr) + UniqueRef<SecCertificateRef> cert2; + if((err = SecIdentityCopyCertificate(identity.get(), &cert2.get())) == noErr) { - err = CFEqual(cert2, cert) ? noErr : errSecItemNotFound; - CFRelease(cert2); + err = CFEqual(cert2.get(), cert.get()) ? noErr : errSecItemNotFound; } } #else - err = SecIdentityCreateWithCertificate(keychain.get(), cert, &identity); + err = SecIdentityCreateWithCertificate(keychain.get(), cert.get(), &identity.get()); #endif if(err != noErr) { @@ -1425,9 +1396,8 @@ IceSSL::findCertificateChain(const std::string& keychainPath, const std::string& os << "IceSSL: couldn't create identity for certificate found in the keychain:\n" << errorToString(err); throw PluginInitializationException(__FILE__, __LINE__, os.str()); } - CFArraySetValueAtIndex(items, 0, identity); - CFRelease(identity); - return itemsHolder.release(); + CFArraySetValueAtIndex(const_cast<CFMutableArrayRef>(items.get()), 0, identity.get()); + return items.release(); } #elif defined(ICE_USE_SCHANNEL) @@ -1946,18 +1916,15 @@ bool IceSSL::checkPath(const string& path, const string& defaultDir, bool dir, string& resolved) { #if defined(ICE_USE_SECURE_TRANSPORT_IOS) - CFURLRef url = 0; CFBundleRef bundle = CFBundleGetMainBundle(); if(bundle) { - CFStringRef resourceName = toCFString(path); - CFStringRef subDirName = toCFString(defaultDir); - url = CFBundleCopyResourceURL(bundle, resourceName, 0, subDirName); - CFRelease(resourceName); - CFRelease(subDirName); + UniqueRef<CFStringRef> resourceName(toCFString(path)); + UniqueRef<CFStringRef> subDirName(toCFString(defaultDir)); + UniqueRef<CFURLRef> url(CFBundleCopyResourceURL(bundle, resourceName.get(), 0, subDirName.get())); UInt8 filePath[PATH_MAX]; - if(CFURLGetFileSystemRepresentation(url, true, filePath, sizeof(filePath))) + if(CFURLGetFileSystemRepresentation(url.get(), true, filePath, sizeof(filePath))) { string tmp = string(reinterpret_cast<char*>(filePath)); if((dir && IceUtilInternal::directoryExists(tmp)) || (!dir && IceUtilInternal::fileExists(tmp))) diff --git a/cpp/src/IceSSL/Util.h b/cpp/src/IceSSL/Util.h index 3208452366c..b52c4a524d5 100644 --- a/cpp/src/IceSSL/Util.h +++ b/cpp/src/IceSSL/Util.h @@ -14,6 +14,8 @@ #include <IceUtil/Shared.h> #include <IceUtil/Handle.h> +#include <Ice/UniqueRef.h> + #include <IceSSL/Plugin.h> #if defined(ICE_USE_OPENSSL) @@ -108,64 +110,6 @@ typedef IceUtil::Handle<DHParams> DHParamsPtr; std::string getSslErrors(bool); #elif defined(ICE_USE_SECURE_TRANSPORT) - -template<typename T> -class UniqueRef -{ -public: - - explicit UniqueRef(CFTypeRef ptr = 0) : _ptr((T)ptr) - { - } - - ~UniqueRef() - { - if(_ptr != 0) - { - CFRelease(_ptr); - } - } - - T release() - { - T r = _ptr; - _ptr = 0; - return r; - } - - void reset(CFTypeRef ptr = 0) - { - if(_ptr == ptr) - { - return; - } - if(_ptr != 0) - { - CFRelease(_ptr); - } - _ptr = (T)ptr; - } - - void retain(CFTypeRef ptr) - { - reset(ptr ? CFRetain(ptr) : ptr); - } - - T get() const - { - return _ptr; - } - - operator bool() const - { - return _ptr != 0; - } - -private: - - T _ptr; -}; - // // Helper functions to use by Secure Transport. // @@ -196,7 +140,6 @@ CFArrayRef loadCertificateChain(const std::string&, const std::string&, const st SecCertificateRef loadCertificate(const std::string&); CFArrayRef loadCACertificates(const std::string&); - CFArrayRef findCertificateChain(const std::string&, const std::string&, const std::string&); #elif defined(ICE_USE_SCHANNEL) diff --git a/cpp/test/IceSSL/configuration/AllTests.cpp b/cpp/test/IceSSL/configuration/AllTests.cpp index 573eb4ce66d..9f184817bd6 100644 --- a/cpp/test/IceSSL/configuration/AllTests.cpp +++ b/cpp/test/IceSSL/configuration/AllTests.cpp @@ -285,20 +285,19 @@ public: string resolved; if(IceSSL::checkPath(certificates[i], defaultDir, false, resolved)) { - CFArrayRef certs = IceSSL::loadCertificateChain(resolved, "", "", "", "password", 0, 0); - SecIdentityRef identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0); + IceInternal::UniqueRef<CFArrayRef> certs(IceSSL::loadCertificateChain(resolved, "", "", "", "password", 0, 0)); + SecIdentityRef identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs.get(), 0); CFRetain(identity); _identities.push_back(identity); OSStatus err; - CFMutableDictionaryRef query; + IceInternal::UniqueRef<CFMutableDictionaryRef> query; - query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(query, kSecValueRef, identity); - if((err = SecItemAdd(query, 0))) + query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecValueRef, identity); + if((err = SecItemAdd(query.get(), 0))) { cerr << "failed to add identity " << certificates[i] << ": " << err << endl; } - CFRelease(query); // query = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // CFDictionarySetValue(query, kSecClass, kSecClassCertificate); @@ -311,7 +310,6 @@ public: // { // printf("Cert %d: %s\n", i, (new IceSSL::Certificate((SecCertificateRef)CFArrayGetValueAtIndex(array, i)))->toString().c_str()); // } - // CFRelease(certs); } } // Nothing to do. @@ -324,23 +322,20 @@ public: void cleanup() { - CFMutableDictionaryRef query; + IceInternal::UniqueRef<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); + query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecClass, kSecClassIdentity); + CFDictionarySetValue(query.get(), kSecValueRef, *p); + SecItemDelete(query.get()); SecCertificateRef cert; SecIdentityCopyCertificate(*p, &cert); - query = CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(query, kSecClass, kSecClassCertificate); - CFDictionarySetValue(query, kSecValueRef, cert); - SecItemDelete(query); - CFRelease(query); - + query.reset(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFDictionarySetValue(query.get(), kSecClass, kSecClassCertificate); + CFDictionarySetValue(query.get(), kSecValueRef, cert); + SecItemDelete(query.get()); CFRelease(*p); } _identities.clear(); @@ -564,11 +559,6 @@ static Test::Properties createServerProps(const Ice::PropertiesPtr& defaultProps, bool p12, const string& cert, const string& ca) { Test::Properties d; - - // - // If no CA is specified, we don't set IceSSL.DefaultDir since - // with OpenSSL the CAs might still be found. - // d = createServerProps(defaultProps, p12); if(!ca.empty()) { @@ -685,6 +675,7 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12) Ice::PropertiesPtr defaultProps = communicator->getProperties()->clone(); defaultProps->setProperty("IceSSL.DefaultDir", defaultDir); + #ifdef _WIN32 string sep = ";"; #else @@ -880,7 +871,6 @@ allTests(const CommunicatorPtr& communicator, const string& testDir, bool p12) } fact->destroyServer(server); comm->destroy(); - // // Test IceSSL.VerifyPeer=1. Client has a certificate. // |