void OpenSSLContext::sendPendingDataToApplication() { SafeByteArray data; data.resize(SSL_READ_BUFFERSIZE); int ret = SSL_read(handle_, vecptr(data), data.size()); while (ret > 0) { data.resize(ret); onDataForApplication(data); data.resize(SSL_READ_BUFFERSIZE); ret = SSL_read(handle_, vecptr(data), data.size()); } if (ret < 0 && SSL_get_error(handle_, ret) != SSL_ERROR_WANT_READ) { state_ = Error; onError(boost::make_shared<TLSError>()); } }
void OpenSSLContext::sendPendingDataToNetwork() { int size = BIO_pending(writeBIO_); if (size > 0) { SafeByteArray data; data.resize(size); BIO_read(writeBIO_, vecptr(data), size); onDataForNetwork(data); } }
SafeByteArray ZLibCodecompressor::process(const SafeByteArray& input) { SafeByteArray output; p->stream.avail_in = static_cast<unsigned int>(input.size()); p->stream.next_in = reinterpret_cast<Bytef*>(const_cast<unsigned char*>(vecptr(input))); size_t outputPosition = 0; do { output.resize(outputPosition + CHUNK_SIZE); p->stream.avail_out = CHUNK_SIZE; p->stream.next_out = reinterpret_cast<Bytef*>(vecptr(output) + outputPosition); int result = processZStream(); if (result != Z_OK && result != Z_BUF_ERROR) { throw ZLibException(/* p->stream.msg */); } outputPosition += CHUNK_SIZE; } while (p->stream.avail_out == 0); if (p->stream.avail_in != 0) { throw ZLibException(); } output.resize(outputPosition - p->stream.avail_out); return output; }
void SchannelContext::encryptAndSendData(const SafeByteArray& data) { if (m_streamSizes.cbMaximumMessage == 0) return; SecBuffer outBuffers[4] = {0}; // Calculate the largest required size of the send buffer size_t messageBufferSize = (data.size() > m_streamSizes.cbMaximumMessage) ? m_streamSizes.cbMaximumMessage : data.size(); // Allocate a packet for the encrypted data SafeByteArray sendBuffer; sendBuffer.resize(m_streamSizes.cbHeader + messageBufferSize + m_streamSizes.cbTrailer); size_t bytesSent = 0; do { size_t bytesLeftToSend = data.size() - bytesSent; // Calculate how much of the send buffer we'll be using for this chunk size_t bytesToSend = (bytesLeftToSend > m_streamSizes.cbMaximumMessage) ? m_streamSizes.cbMaximumMessage : bytesLeftToSend; // Copy the plain text data into the send buffer memcpy(&sendBuffer[0] + m_streamSizes.cbHeader, &data[0] + bytesSent, bytesToSend); outBuffers[0].pvBuffer = &sendBuffer[0]; outBuffers[0].cbBuffer = m_streamSizes.cbHeader; outBuffers[0].BufferType = SECBUFFER_STREAM_HEADER; outBuffers[1].pvBuffer = &sendBuffer[0] + m_streamSizes.cbHeader; outBuffers[1].cbBuffer = (unsigned long)bytesToSend; outBuffers[1].BufferType = SECBUFFER_DATA; outBuffers[2].pvBuffer = &sendBuffer[0] + m_streamSizes.cbHeader + bytesToSend; outBuffers[2].cbBuffer = m_streamSizes.cbTrailer; outBuffers[2].BufferType = SECBUFFER_STREAM_TRAILER; outBuffers[3].pvBuffer = 0; outBuffers[3].cbBuffer = 0; outBuffers[3].BufferType = SECBUFFER_EMPTY; SecBufferDesc outBufferDesc = {0}; outBufferDesc.cBuffers = 4; outBufferDesc.pBuffers = outBuffers; outBufferDesc.ulVersion = SECBUFFER_VERSION; SECURITY_STATUS status = EncryptMessage(m_ctxtHandle, 0, &outBufferDesc, 0); if (status != SEC_E_OK) { indicateError(); return; } sendDataOnNetwork(&sendBuffer[0], outBuffers[0].cbBuffer + outBuffers[1].cbBuffer + outBuffers[2].cbBuffer); bytesSent += bytesToSend; } while (bytesSent < data.size()); }