SECURITY_STATUS schannel_openssl_decrypt_message(SCHANNEL_OPENSSL* context, PSecBufferDesc pMessage) { int status; int length; BYTE* buffer; int ssl_error; PSecBuffer pBuffer; pBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_DATA); if (!pBuffer) return SEC_E_INVALID_TOKEN; status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer); status = SSL_read(context->ssl, pBuffer->pvBuffer, pBuffer->cbBuffer); if (status < 0) { ssl_error = SSL_get_error(context->ssl, status); WLog_ERR(TAG, "SSL_read: %s", openssl_get_ssl_error_string(ssl_error)); } length = status; buffer = pBuffer->pvBuffer; pMessage->pBuffers[0].BufferType = SECBUFFER_STREAM_HEADER; pMessage->pBuffers[0].cbBuffer = 5; pMessage->pBuffers[1].BufferType = SECBUFFER_DATA; pMessage->pBuffers[1].pvBuffer = buffer; pMessage->pBuffers[1].cbBuffer = length; pMessage->pBuffers[2].BufferType = SECBUFFER_STREAM_TRAILER; pMessage->pBuffers[2].cbBuffer = 36; pMessage->pBuffers[3].BufferType = SECBUFFER_EMPTY; pMessage->pBuffers[3].cbBuffer = 0; return SEC_E_OK; }
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput) { int status; int ssl_error; PSecBuffer pBuffer; if (!context->connected) { if (pInput) { if (pInput->cBuffers < 1) return SEC_E_INVALID_TOKEN; pBuffer = sspi_FindSecBuffer(pInput, SECBUFFER_TOKEN); if (!pBuffer) return SEC_E_INVALID_TOKEN; status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer); } status = SSL_connect(context->ssl); if (status < 0) { ssl_error = SSL_get_error(context->ssl, status); WLog_ERR(TAG, "SSL_connect error: %s", openssl_get_ssl_error_string(ssl_error)); } if (status == 1) context->connected = TRUE; status = BIO_read(context->bioWrite, context->ReadBuffer, SCHANNEL_CB_MAX_TOKEN); if (pOutput->cBuffers < 1) return SEC_E_INVALID_TOKEN; pBuffer = sspi_FindSecBuffer(pOutput, SECBUFFER_TOKEN); if (!pBuffer) return SEC_E_INVALID_TOKEN; if (status > 0) { if (pBuffer->cbBuffer < (unsigned long) status) return SEC_E_INSUFFICIENT_MEMORY; CopyMemory(pBuffer->pvBuffer, context->ReadBuffer, status); pBuffer->cbBuffer = status; return (context->connected) ? SEC_E_OK : SEC_I_CONTINUE_NEEDED; } else { pBuffer->cbBuffer = 0; return (context->connected) ? SEC_E_OK : SEC_I_CONTINUE_NEEDED; } } return SEC_E_OK; }
SECURITY_STATUS schannel_openssl_client_process_tokens(SCHANNEL_OPENSSL* context, PSecBufferDesc pInput, PSecBufferDesc pOutput) { int status; int ssl_error; PSecBuffer pBuffer; if (!context->connected) { if (pInput) { if (pInput->cBuffers < 1) return SEC_E_INVALID_TOKEN; pBuffer = &pInput->pBuffers[0]; if (pBuffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; status = BIO_write(context->bioRead, pBuffer->pvBuffer, pBuffer->cbBuffer); } status = SSL_connect(context->ssl); if (status < 0) { ssl_error = SSL_get_error(context->ssl, status); printf("SSL_connect error: %s\n", openssl_get_ssl_error_string(ssl_error)); } status = BIO_read(context->bioWrite, context->ReadBuffer, SCHANNEL_CB_MAX_TOKEN); if (status >= 0) { winpr_HexDump(context->ReadBuffer, status); } if (pOutput->cBuffers < 1) return SEC_E_INVALID_TOKEN; pBuffer = &pOutput->pBuffers[0]; if (pBuffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; if (pBuffer->cbBuffer < status) return SEC_E_INSUFFICIENT_MEMORY; CopyMemory(pBuffer->pvBuffer, context->ReadBuffer, status); pBuffer->cbBuffer = status; return SEC_I_CONTINUE_NEEDED; } return SEC_E_OK; }
SECURITY_STATUS schannel_openssl_encrypt_message(SCHANNEL_OPENSSL* context, PSecBufferDesc pMessage) { int status; int length; int offset; int ssl_error; PSecBuffer pStreamBodyBuffer; PSecBuffer pStreamHeaderBuffer; PSecBuffer pStreamTrailerBuffer; pStreamHeaderBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_STREAM_HEADER); pStreamBodyBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_DATA); pStreamTrailerBuffer = sspi_FindSecBuffer(pMessage, SECBUFFER_STREAM_TRAILER); if ((!pStreamHeaderBuffer) || (!pStreamBodyBuffer) || (!pStreamTrailerBuffer)) return SEC_E_INVALID_TOKEN; status = SSL_write(context->ssl, pStreamBodyBuffer->pvBuffer, pStreamBodyBuffer->cbBuffer); if (status < 0) { ssl_error = SSL_get_error(context->ssl, status); WLog_ERR(TAG, "SSL_write: %s", openssl_get_ssl_error_string(ssl_error)); } status = BIO_read(context->bioWrite, context->ReadBuffer, SCHANNEL_CB_MAX_TOKEN); if (status > 0) { offset = 0; length = (pStreamHeaderBuffer->cbBuffer > (unsigned long) status) ? status : pStreamHeaderBuffer->cbBuffer; CopyMemory(pStreamHeaderBuffer->pvBuffer, &context->ReadBuffer[offset], length); status -= length; offset += length; length = (pStreamBodyBuffer->cbBuffer > (unsigned long) status) ? status : pStreamBodyBuffer->cbBuffer; CopyMemory(pStreamBodyBuffer->pvBuffer, &context->ReadBuffer[offset], length); status -= length; offset += length; length = (pStreamTrailerBuffer->cbBuffer > (unsigned long) status) ? status : pStreamTrailerBuffer->cbBuffer; CopyMemory(pStreamTrailerBuffer->pvBuffer, &context->ReadBuffer[offset], length); } return SEC_E_OK; }