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; }
std::pair<SafeByteArray, size_t> BOSHConnection::createHTTPRequest(const SafeByteArray& data, bool streamRestart, bool terminate, unsigned long long rid, const std::string& sid, const URL& boshURL) { size_t size; std::stringstream content; SafeByteArray contentTail = createSafeByteArray("</body>"); std::stringstream header; content << "<body rid='" << rid << "' sid='" << sid << "'"; if (streamRestart) { content << " xmpp:restart='true' xmlns:xmpp='urn:xmpp:xbosh'"; } if (terminate) { content << " type='terminate'"; } content << " xmlns='http://jabber.org/protocol/httpbind'>"; SafeByteArray safeContent = createSafeByteArray(content.str()); safeContent.insert(safeContent.end(), data.begin(), data.end()); safeContent.insert(safeContent.end(), contentTail.begin(), contentTail.end()); size = safeContent.size(); header << "POST " << boshURL.getPath() << " HTTP/1.1\r\n" << "Host: " << boshURL.getHost(); if (boshURL.getPort()) { header << ":" << *boshURL.getPort(); } header << "\r\n" // << "Accept-Encoding: deflate\r\n" << "Content-Type: text/xml; charset=utf-8\r\n" << "Content-Length: " << size << "\r\n\r\n"; SafeByteArray safeHeader = createSafeByteArray(header.str()); safeHeader.insert(safeHeader.end(), safeContent.begin(), safeContent.end()); return std::pair<SafeByteArray, size_t>(safeHeader, size); }
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()); }
void SchannelContext::appendNewData(const SafeByteArray& data) { size_t originalSize = m_receivedData.size(); m_receivedData.resize( originalSize + data.size() ); memcpy( &m_receivedData[0] + originalSize, &data[0], data.size() ); }
bool WindowsGSSAPIClientAuthenticator::setChallenge(const boost::optional<ByteArray>& challengeData) { /* Following http://tools.ietf.org/html/rfc4752, https://msdn.microsoft.com/en-us/library/windows/desktop/aa380496%28v=vs.85%29.aspx */ if (step_ == BuildingSecurityContext) { buildSecurityContext(challengeData); } else if (step_ == SecurityLayerNegotiation) { if (!challengeData) { SWIFT_LOG(debug) << "Empty message received from the server" << std::endl; error_ = true; return false; } SafeByteArray challenge; errorCode_ = decryptMessage(&contextHandle_, challengeData.get(), challenge); if (isError()) { return false; } if (challenge.size() != 4) { SWIFT_LOG(debug) << "Token received from the server of incorrect length: " << challenge.size() << std::endl; error_ = true; return false; } unsigned char* challengePointer = vecptr(challenge); unsigned char serverSecurityLayer = challengePointer[0]; if (serverSecurityLayer == 0) { SWIFT_LOG(debug) << "Server supports unknown security layer, assuming no security layer" << std::endl; serverSecurityLayer = SECURITY_LAYER_NONE; } else if (serverSecurityLayer == SECURITY_LAYER_NONE) { SWIFT_LOG(debug) << "Server supports no security layer" << std::endl; } else { SWIFT_LOG(debug) << "Server supports security layer" << std::endl; } unsigned int serverMaximumBuffer = (challengePointer[1] << 16) | (challengePointer[2] << 8) | (challengePointer[3] << 0); if ((serverSecurityLayer == SECURITY_LAYER_NONE) && (serverMaximumBuffer != 0)) { SWIFT_LOG(debug) << "Server supports no security layer but has maximum buffer size" << serverMaximumBuffer << std::endl; error_ = true; return false; } SafeByteArray message(4); /* Commenting this out as streamSizes was not obtained before if (message.size() > streamSizes_.cbMaximumMessage) { error_ = true; return false; } */ unsigned char* messagePointer = vecptr(message); messagePointer[0] = SECURITY_LAYER_NONE; /* The next 3 bytes indicate the client's maximum size buffer which is set to 0 as we do not support a security layer */ messagePointer[1] = 0; messagePointer[2] = 0; messagePointer[3] = 0; /* The authorization identity is omitted as it is the same as the authentication identity */ errorCode_ = encryptMessage(&contextHandle_, sizes_, message, response_); if (isError()) { return false; } step_ = ServerAuthenticated; } if (isError()) { return false; } return true; }