summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/SecureTransportTransceiverI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceSSL/SecureTransportTransceiverI.cpp')
-rw-r--r--cpp/src/IceSSL/SecureTransportTransceiverI.cpp170
1 files changed, 87 insertions, 83 deletions
diff --git a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp
index b043ef19713..f407e008913 100644
--- a/cpp/src/IceSSL/SecureTransportTransceiverI.cpp
+++ b/cpp/src/IceSSL/SecureTransportTransceiverI.cpp
@@ -96,7 +96,8 @@ 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 InstancePtr& instance,
+ const string& host)
{
OSStatus err = noErr;
SecTrustResultType trustResult = kSecTrustResultOtherError;
@@ -115,6 +116,28 @@ checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, cons
throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err));
}
+#if defined(ICE_USE_SECURE_TRANSPORT_IOS)
+ if(engine->getCheckCertName() && !host.empty())
+ {
+ //
+ // 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)))
+ {
+ throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err));
+ }
+ UniqueRef<CFMutableArrayRef> newPolicies(CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, policies));
+ CFRelease(policies);
+ CFArrayAppendValue(newPolicies.get(), policy.release());
+ if((err = SecTrustSetPolicies(trust, newPolicies.release())))
+ {
+ throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + errorToString(err));
+ }
+ }
+#endif
+
//
// Evaluate the trust
//
@@ -171,18 +194,29 @@ checkTrustResult(SecTrustRef trust, const SecureTransportEnginePtr& engine, cons
IceInternal::NativeInfoPtr
IceSSL::TransceiverI::getNativeInfo()
{
- return _stream;
+ return _delegate->getNativeInfo();
}
IceInternal::SocketOperation
IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer)
{
- IceInternal::SocketOperation status = _stream->connect(readBuffer, writeBuffer);
- if(status != IceInternal::SocketOperationNone)
+ if(!_connected)
{
- return status;
+ IceInternal::SocketOperation status = _delegate->initialize(readBuffer, writeBuffer);
+ if(status != IceInternal::SocketOperationNone)
+ {
+ return status;
+ }
+ _connected = true;
}
+ //
+ // Limit the size of packets passed to SSLWrite/SSLRead to avoid
+ // blocking and holding too much memory.
+ //
+ _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_delegate->getNativeInfo()->fd()));
+ _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_delegate->getNativeInfo()->fd()));
+
OSStatus err = 0;
if(!_ssl)
{
@@ -237,7 +271,7 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
}
if(err == noErr)
{
- _verified = checkTrustResult(_trust, _engine, _instance);
+ _verified = checkTrustResult(_trust, _engine, _instance, _host);
continue; // Call SSLHandshake to resume the handsake.
}
// Let it fall through, this will raise a SecurityException with the SSLCopyPeerTrust error.
@@ -247,18 +281,12 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B
throw ConnectionLostException(__FILE__, __LINE__, 0);
}
- IceInternal::Address remoteAddr;
- string desc = "<not available>";
- if(IceInternal::fdToRemoteAddress(_stream->fd(), remoteAddr))
- {
- desc = IceInternal::addrToString(remoteAddr);
- }
ostringstream os;
os << "IceSSL: ssl error occurred for new " << (_incoming ? "incoming" : "outgoing") << " connection:\n"
- << "remote address = " << desc << "\n" << errorToString(err);
+ << _delegate->toString() << "\n" << errorToString(err);
throw ProtocolException(__FILE__, __LINE__, os.str());
}
- _engine->verifyPeer(_stream->fd(), _host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()));
+ _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(NativeConnectionInfo, getInfo()), toString());
if(_instance->engine()->securityTraceLevel() >= 1)
{
@@ -317,15 +345,15 @@ IceSSL::TransceiverI::close()
_ssl = 0;
}
- _stream->close();
+ _delegate->close();
}
IceInternal::SocketOperation
IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(!_connected)
{
- return _stream->write(buf);
+ return _delegate->write(buf);
}
if(buf.i == buf.b.end())
@@ -402,9 +430,9 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf)
IceInternal::SocketOperation
IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
{
- if(!_stream->isConnected())
+ if(!_connected)
{
- return _stream->read(buf);
+ return _delegate->read(buf);
}
if(buf.i == buf.b.end())
@@ -412,7 +440,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
return IceInternal::SocketOperationNone;
}
- _stream->ready(IceInternal::SocketOperationRead, false);
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false);
size_t packetSize = std::min(static_cast<size_t>(buf.b.end() - buf.i), _maxRecvPacketSize);
while(buf.i != buf.b.end())
@@ -471,7 +499,7 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf)
errno = err;
throw SocketException(__FILE__, __LINE__, IceInternal::getSocketErrno());
}
- _stream->ready(IceInternal::SocketOperationRead, buffered > 0);
+ _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, buffered > 0);
return IceInternal::SocketOperationNone;
}
@@ -484,7 +512,7 @@ IceSSL::TransceiverI::protocol() const
string
IceSSL::TransceiverI::toString() const
{
- return _stream->toString();
+ return _delegate->toString();
}
string
@@ -497,16 +525,30 @@ Ice::ConnectionInfoPtr
IceSSL::TransceiverI::getInfo() const
{
NativeConnectionInfoPtr info = ICE_MAKE_SHARED(NativeConnectionInfo);
- fillConnectionInfo(info, info->nativeCerts);
- return info;
-}
+ info->underlying = _delegate->getInfo();
+ info->incoming = _incoming;
+ info->adapterName = _adapterName;
+ if(_ssl)
+ {
+ for(int i = 0, count = SecTrustGetCertificateCount(_trust); i < count; ++i)
+ {
+ SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust, i);
+ CFRetain(cert);
-Ice::ConnectionInfoPtr
-IceSSL::TransceiverI::getWSInfo(const Ice::HeaderDict& headers) const
-{
- WSSNativeConnectionInfoPtr info = ICE_MAKE_SHARED(WSSNativeConnectionInfo);
- fillConnectionInfo(info, info->nativeCerts);
- info->headers = headers;
+ CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cert);
+ info->nativeCerts.push_back(certificate);
+ info->certs.push_back(certificate->encode());
+ }
+
+ SSLCipherSuite cipher;
+ SSLGetNegotiatedCipher(_ssl, &cipher);
+ info->cipher = _engine->getCipherName(cipher);
+ info->verified = _verified;
+ }
+ else
+ {
+ info->verified = false;
+ }
return info;
}
@@ -518,11 +560,11 @@ IceSSL::TransceiverI::checkSendSize(const IceInternal::Buffer&)
void
IceSSL::TransceiverI::setBufferSize(int rcvSize, int sndSize)
{
- _stream->setBufferSize(rcvSize, sndSize);
+ _delegate->setBufferSize(rcvSize, sndSize);
}
IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance,
- const IceInternal::StreamSocketPtr& stream,
+ const IceInternal::TransceiverPtr& delegate,
const string& hostOrAdapterName,
bool incoming) :
_instance(instance),
@@ -530,61 +572,19 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance,
_host(incoming ? "" : hostOrAdapterName),
_adapterName(incoming ? hostOrAdapterName : ""),
_incoming(incoming),
- _stream(stream),
+ _delegate(delegate),
_ssl(0),
_trust(0),
+ _connected(false),
_verified(false),
_buffered(0)
{
- //
- // Limit the size of packets passed to SSLWrite/SSLRead to avoid
- // blocking and holding too much memory.
- //
- _maxSendPacketSize = std::max(512, IceInternal::getSendBufferSize(_stream->fd()));
- _maxRecvPacketSize = std::max(512, IceInternal::getRecvBufferSize(_stream->fd()));
}
IceSSL::TransceiverI::~TransceiverI()
{
}
-void
-IceSSL::TransceiverI::fillConnectionInfo(const ConnectionInfoPtr& info, std::vector<CertificatePtr>& nativeCerts) const
-{
- IceInternal::fdToAddressAndPort(_stream->fd(), info->localAddress, info->localPort, info->remoteAddress,
- info->remotePort);
- if(_stream->fd() != INVALID_SOCKET)
- {
- info->rcvSize = IceInternal::getRecvBufferSize(_stream->fd());
- info->sndSize = IceInternal::getSendBufferSize(_stream->fd());
- }
-
- if(_ssl)
- {
- for(int i = 0, count = SecTrustGetCertificateCount(_trust); i < count; ++i)
- {
- SecCertificateRef cert = SecTrustGetCertificateAtIndex(_trust, i);
- CFRetain(cert);
-
- CertificatePtr certificate = ICE_MAKE_SHARED(Certificate, cert);
- nativeCerts.push_back(certificate);
- info->certs.push_back(certificate->encode());
- }
-
- SSLCipherSuite cipher;
- SSLGetNegotiatedCipher(_ssl, &cipher);
- info->cipher = _engine->getCipherName(cipher);
- info->verified = _verified;
- }
- else
- {
- info->verified = false;
- }
-
- info->adapterName = _adapterName;
- info->incoming = _incoming;
-}
-
OSStatus
IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const
{
@@ -592,13 +592,15 @@ IceSSL::TransceiverI::writeRaw(const char* data, size_t* length) const
try
{
- ssize_t ret = _stream->write(data, *length);
- if(ret < *length)
+ IceInternal::Buffer buf(reinterpret_cast<const Ice::Byte*>(data), reinterpret_cast<const Ice::Byte*>(data) + *length);
+ IceInternal::SocketOperation op = _delegate->write(buf);
+ if(op == IceInternal::SocketOperationWrite)
{
- *length = static_cast<size_t>(ret);
+ *length = buf.i - buf.b.begin();
_flags |= SSLWantWrite;
return errSSLWouldBlock;
}
+ assert(op == IceInternal::SocketOperationNone);
}
catch(const Ice::ConnectionLostException&)
{
@@ -623,13 +625,15 @@ IceSSL::TransceiverI::readRaw(char* data, size_t* length) const
try
{
- ssize_t ret = _stream->read(data, *length);
- if(ret < *length)
+ IceInternal::Buffer buf(reinterpret_cast<Ice::Byte*>(data), reinterpret_cast<Ice::Byte*>(data) + *length);
+ IceInternal::SocketOperation op = _delegate->read(buf);
+ if(op == IceInternal::SocketOperationRead)
{
- *length = static_cast<size_t>(ret);
+ *length = buf.i - buf.b.begin();
_flags |= SSLWantRead;
return errSSLWouldBlock;
}
+ assert(op == IceInternal::SocketOperationNone);
}
catch(const Ice::ConnectionLostException&)
{