Why does SChannel TLS limit a message to 32kb - c

I am working on using SChannel to build a client/server program. One of the things I would like to do is have file sharing. I found some example code of a client program using Schannel to communicate and I am wondering why the max size of a message is 32kb. Here is the example function that does the receiving
int tls_handshake(tls_ctx *c, tls_session *s) {
DWORD flags_in, flags_out;
SecBuffer ib[2], ob[1];
SecBufferDesc in, out;
int len;
// send initial hello
if (!tls_hello(c, s)) {
return 0;
}
flags_in = ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONFIDENTIALITY |
ISC_RET_EXTENDED_ERROR |
ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_MANUAL_CRED_VALIDATION;
c->ss = SEC_I_CONTINUE_NEEDED;
s->buflen = 0;
while (c->ss == SEC_I_CONTINUE_NEEDED ||
c->ss == SEC_E_INCOMPLETE_MESSAGE ||
c->ss == SEC_I_INCOMPLETE_CREDENTIALS)
{
if (c->ss == SEC_E_INCOMPLETE_MESSAGE)
{
// receive data from server
len = recv(s->sck, &s->buf[s->buflen], s->maxlen - s->buflen, 0);
// socket error?
if (len == SOCKET_ERROR) {
c->ss = SEC_E_INTERNAL_ERROR;
break;
// server disconnected?
} else if (len==0) {
c->ss = SEC_E_INTERNAL_ERROR;
break;
}
// increase buffer position
s->buflen += len;
}
// inspect what we've received
//tls_hex_dump(s->buf, s->buflen);
// input data
ib[0].pvBuffer = s->buf;
ib[0].cbBuffer = s->buflen;
ib[0].BufferType = SECBUFFER_TOKEN;
// empty buffer
ib[1].pvBuffer = NULL;
ib[1].cbBuffer = 0;
ib[1].BufferType = SECBUFFER_VERSION;
in.cBuffers = 2;
in.pBuffers = ib;
in.ulVersion = SECBUFFER_VERSION;
// output from schannel
ob[0].pvBuffer = NULL;
ob[0].cbBuffer = 0;
ob[0].BufferType = SECBUFFER_VERSION;
out.cBuffers = 1;
out.pBuffers = ob;
out.ulVersion = SECBUFFER_VERSION;
c->ss = c->sspi->
InitializeSecurityContextA(
&s->cc, &s->ctx, NULL, flags_in, 0,
SECURITY_NATIVE_DREP, &in, 0, NULL,
&out, &flags_out, NULL);
// what have we got so far?
if (c->ss == SEC_E_OK ||
c->ss == SEC_I_CONTINUE_NEEDED ||
(FAILED(c->ss) && (flags_out & ISC_RET_EXTENDED_ERROR)))
{
// response for server?
if (ob[0].cbBuffer != 0 && ob[0].pvBuffer) {
// send response
tls_send(s->sck, ob[0].pvBuffer, ob[0].cbBuffer);
// free response
c->sspi->FreeContextBuffer(ob[0].pvBuffer);
ob[0].pvBuffer = NULL;
}
}
// incomplete message? continue reading
if (c->ss==SEC_E_INCOMPLETE_MESSAGE) continue;
// completed handshake?
if (c->ss==SEC_E_OK) {
s->established = 1;
// If the "extra" buffer contains data, this is encrypted application
// protocol layer stuff and needs to be saved. The application layer
// will decrypt it later with DecryptMessage.
if (ib[1].BufferType == SECBUFFER_EXTRA) {
DEBUG_PRINT(" [ we have extra data after handshake.\n");
memmove(s->pExtra.pvBuffer,
&s->buf[(s->buflen - ib[1].cbBuffer)], ib[1].cbBuffer);
s->pExtra.cbBuffer = ib[1].cbBuffer;
s->pExtra.BufferType = SECBUFFER_TOKEN;
} else {
// no extra data encountered
s->pExtra.pvBuffer = NULL;
s->pExtra.cbBuffer = 0;
s->pExtra.BufferType = SECBUFFER_EMPTY;
}
break;
}
// some other error
if(FAILED(c->ss)) break;
// Copy any leftover data from the "extra" buffer, and go around again.
if(ib[1].BufferType == SECBUFFER_EXTRA) {
memmove(s->buf, &s->buf[(s->buflen - ib[1].cbBuffer)], ib[1].cbBuffer);
s->buflen = ib[1].cbBuffer;
DEBUG_PRINT(" [ we have %i bytes of extra data.\n", s->buflen);
tls_hex_dump(s->buf, s->buflen);
} else {
s->buflen = 0;
}
}
return c->ss==SEC_E_OK ? 1 : 0;
}
The code comes from a Github I found here: https://github.com/odzhan/shells/blob/master/s6/tls.c
Inside one of his header files he defines
#define TLS_MAX_BUFSIZ 32768
I have also read in other places that this is a limit with TLS. Is it possible to increase that limit? What happens if I need to receive more then that? Like a large file?

Related

Ble data sending with nrf52

I am working with nrf52 and I made a custom service for 17 bytes data array and I want to send it but it gives fatal error while in data update (sending) function and resets the program.
Here's my custom service data update function:
uint32_t ble_cus_mydata_update(ble_cus_t * p_cus, uint8_array_t mydata, uint16_t conn_handle)
{
if (p_cus->conn_handle != BLE_CONN_HANDLE_INVALID)
{
ble_gatts_hvx_params_t params;
memset(&params, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_cus->mydata_char_handles.value_handle;
params.p_data = &mydata;
params.p_len = 17;
return sd_ble_gatts_hvx(conn_handle, &params);
}}
and i send data with timeout_handler
static void mydata_timeout_handler(void * p_context)
{
ret_code_t err_code;
UNUSED_PARAMETER(p_context);
bsp_board_led_on(2);
nrf_delay_ms(100);
bsp_board_led_off(2);
uint8_array_t mydata_value [17] = {0x55,0x10,0x01,0x23,0x99,0xFF,0xFF,0xCC,0xBB,0x00,0x00,0x00,0x00,0x00,0x24,0x24,0x20};
err_code = ble_cus_mydata_update(&m_cus, *mydata_value , m_conn_handle);
if ((err_code != NRF_SUCCESS) &&
(err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != NRF_ERROR_RESOURCES) &&
(err_code != NRF_ERROR_BUSY) &&
(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
)
{
APP_ERROR_HANDLER(err_code);
}
}
And here is my service char add
uint8_array_t mydata_char_init_value [17] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
memset(&add_char_params, 0, sizeof(add_char_params));
add_char_params.uuid = MYDATA_CHAR_UUID;
add_char_params.uuid_type = p_cus->uuid_type;
add_char_params.init_len = 17;
add_char_params.max_len = 17;
add_char_params.p_init_value = mydata_char_init_value;
add_char_params.char_props.read = 1;
add_char_params.char_props.notify = 1;
add_char_params.read_access = SEC_OPEN;
add_char_params.cccd_write_access = SEC_OPEN;
err_code = characteristic_add(p_cus->service_handle,
&add_char_params,
&p_cus->mydata_char_handles);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
I get an error:
nrf error_code= 0x2000310c
There is no info about this error message; it throws this fatal error and goes to nrf_breakpoint_cond after error handler and resets itself.
Please help me; I tried everything I know and I can't move forward. Thanks in advance to whomever tries to help me.
i solved it and wanted to help others who might need it its a little different this code is for sending 4 bytes of data you need to do a little changes for 17 bytes but its not that much the other codes are same you just need to change update function to something like this
uint32_t ble_cus_pres_level_update(ble_cus_t * p_cus, uint32_t presvalue)
{
// NRF_LOG_INFO("In ble_cus_presvalue_update. \r\n");
if (p_cus == NULL)
{
return NRF_ERROR_NULL;
}
uint32_t err_code = NRF_SUCCESS;
ble_gatts_value_t gatts_value;
// Initialize value struct.
memset(&gatts_value, 0, sizeof(gatts_value));
gatts_value.len = sizeof(uint32_t);
gatts_value.offset = 0;
gatts_value.p_value = &presvalue;
// Update database.
err_code = sd_ble_gatts_value_set(p_cus->conn_handle,
p_cus->bme280_presvalue_char_handles.value_handle,
&gatts_value);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// Send value if connected and notifying.
if (p_cus->conn_handle != BLE_CONN_HANDLE_INVALID)
{
ble_gatts_hvx_params_t params;
memset(&params, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_cus->bme280_presvalue_char_handles.value_handle;
params.offset = gatts_value.offset;
params.p_data = gatts_value.p_value;
params.p_len = &gatts_value.len;
err_code = sd_ble_gatts_hvx(p_cus->conn_handle, &params);
// NRF_LOG_INFO("sd_ble_gatts_hvx result: %x. \r\n", err_code);
}
else
{
err_code = NRF_ERROR_INVALID_STATE;
// NRF_LOG_INFO("sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE. \r\n");
}
return err_code;
}
Shouldn't err_code = ble_cus_mydata_update(&m_cus, *mydata_value , m_conn_handle); be err_code = ble_cus_mydata_update(&m_cus, mydata_value , m_conn_handle);?

Sending a string with 000 at beginning in C

I posted this problem a couple of hours ago, but unfortunately, the details was not clear. i've added the code and some explanation.
i have a string like this to send through socket: "000f45546874684498765" as you see the first 3 numbers are zero, when the C compiler comes to this 000 it thinks these zeros are the finishing of the string. any suggestion?
proc_socketgps(s32 TaskId)
while (1)
{
Ql_Sleep(socket_timer);
if (is_socket_success == TRUE)
{
APP_DEBUG("start socket connect\r\n");
APP_DEBUG("m_tcp_state :%d\r\n", m_tcp_state);
APP_DEBUG("STATE_SOC_SEND :%d\r\n", STATE_SOC_SEND);
APP_DEBUG("m_socketid :%d\r\n", m_socketid);
proc_handle("\x00\x11\x22", sizeof("\x00\x11\x22"));
}
static void proc_handle(unsigned char *pData, s32 len)
char *p = NULL;
s32 iret;
u8 srvport[10];
//command: Set_APN_Param=<APN>,<username>,<password>
p = Ql_strstr(pData, "Set_APN_Param=");
if (p)
{
Ql_memset(m_apn, 0, 10);
if (Analyse_Command(pData, 1, '>', m_apn))
{
APP_DEBUG("<--APN Parameter Error.-->\r\n");
return;
}
Ql_memset(m_userid, 0, 10);
if (Analyse_Command(pData, 2, '>', m_userid))
{
APP_DEBUG("<--APN Username Parameter Error.-->\r\n");
return;
}
Ql_memset(m_passwd, 0, 10);
if (Analyse_Command(pData, 3, '>', m_passwd))
{
APP_DEBUG("<--APN Password Parameter Error.-->\r\n");
return;
}
APP_DEBUG("<--Set APN Parameter Successfully<%s>,<%s>,<%s>.-->\r\n", m_apn, m_userid, m_passwd);
return;
}
//command: Set_Srv_Param=<srv ip>,<srv port>
p = Ql_strstr(pData, "Set_Srv_Param=");
if (p)
{
Ql_memset(m_SrvADDR, 0, SRVADDR_BUFFER_LEN);
if (Analyse_Command(pData, 1, '>', m_SrvADDR))
{
APP_DEBUG("<--Server Address Parameter Error.-->\r\n");
return;
}
Ql_memset(srvport, 0, 10);
if (Analyse_Command(pData, 2, '>', srvport))
{
APP_DEBUG("<--Server Port Parameter Error.-->\r\n");
return;
}
m_SrvPort = Ql_atoi(srvport);
APP_DEBUG("<--Set TCP Server Parameter Successfully<%s>,<%d>.-->\r\n", m_SrvADDR, m_SrvPort);
m_tcp_state = STATE_NW_GET_SIMSTATE;
APP_DEBUG("<--Restart the TCP connection process.-->\r\n");
return;
}
//if not command,send it to server
m_pCurrentPos = m_send_buf;
Ql_strcpy(m_pCurrentPos + m_remain_len, pData);
m_remain_len = Ql_strlen(m_pCurrentPos);
if (!Ql_strlen(m_send_buf)) //no data need to send
break;
m_tcp_state = STATE_SOC_SENDING;
do
{
ret = Ql_SOC_Send(m_socketid, m_pCurrentPos, m_remain_len);
APP_DEBUG("Message Data :%s", m_pCurrentPos);
APP_DEBUG("<--Send data,socketid=%d,number of bytes sent=%d-->\r\n", m_socketid, ret);
if (ret == m_remain_len) //send compelete
{
m_remain_len = 0;
m_pCurrentPos = NULL;
m_nSentLen += ret;
m_tcp_state = STATE_SOC_ACK;
break;
}
else if ((ret <= 0) && (ret == SOC_WOULDBLOCK))
{
//waiting CallBack_socket_write, then send data;
break;
}
else if (ret <= 0)
{
APP_DEBUG("<--Send data failure,ret=%d.-->\r\n", ret);
APP_DEBUG("<-- Close socket.-->\r\n");
Ql_SOC_Close(m_socketid); //error , Ql_SOC_Close
m_socketid = -1;
m_remain_len = 0;
m_pCurrentPos = NULL;
if (ret == SOC_BEARER_FAIL)
{
m_tcp_state = STATE_GPRS_DEACTIVATE;
}
else
{
m_tcp_state = STATE_GPRS_GET_DNSADDRESS;
}
break;
}
else if (ret < m_remain_len) //continue send, do not send all data
{
m_remain_len -= ret;
m_pCurrentPos += ret;
m_nSentLen += ret;
}
} while (1);
break;
the code has been added to the question. firs socket gets open and gets connected to the server. this function >> proc_handle("\x00\x11\x22", sizeof("\x00\x11\x22")); sends hexadecimal string, however i think c consider this part "\x00" as end of the string ! and the data won't be sent ! I already tested that if I remove "\x00" from the row above it works like a charm !

Circular Buffer Reader, I'm stuck

I am trying to implement a circular buffer, I'm writing to it just fine, all the received data is there, but something about my function to read from it doesn't work. No data gets saved into MtoHSdata.
The data I'm trying to read has a Start (>) and End (<) symbol, and is supposed to be sent via USART1.
Read data function:
void MtoHS(struct remoteM *Buff)
{
BYTE k = 0;
static BYTE st = 1;
switch (st)
{
case 1:
{
if ((*Buff).wr != (*Buff).re)
{
(*Buff).re = ((*Buff).re + 1) % (*Buff).max;
if ((*Buff).Buffer[(*Buff).re] == '>') // > == Start Symbol
{
k = 0;
MtoHSdata[k] = (*Buff).Buffer[(*Buff).re];
}
else if ((*Buff).Buffer[(*Buff).re] == '<') // < == End Symbol
{
MtoHSdata[k] = (*Buff).Buffer[(*Buff).re];
st = 5;
}
else
{
MtoHSdata[k] = (*Buff).Buffer[(*Buff).re]; // Data
k++;
}
}
}
break;
/* When End Symbol was read, send data to M */
case 5:
{
BYTE i = 0;
while (MtoHSdata[i] != '<')
{
USART_SendData(USART1, MtoHSdata[i]);
i++;
}
}
break;
default:
{
st = 1;
}
}
return;
}
Write data function (interrupt):
void USART1_IRQHandler(void)
{
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
{
uint16_t byteM = 0;
USART_GetITStatus(USART1, USART_IT_ORE);
byteM = USART_ReceiveData(USART1);
pRXD5->Buffer[pRXD5->wr] = byteM;
pRXD5->wr = (pRXD5->wr + 1) % pRXD5->max;
}
return;
}
I'm calling MtoHS function with the parameter 'pRXD5'.
Could anyone please tell me what I'm doing wrong?

libavcodec transcoding - setting pts and dts

I'm trying to transcode video files into a standard format. This is the main loop I have:
for(frame_count = 0; av_read_frame(input_ctx, &in_packet) >= 0; frame_count++) {
if(in_packet.stream_index == video_stream_index) {
decodedPacket = 0;
rc = avcodec_decode_video2(video_in_codec, inputFrame, &decodedPacket, &in_packet);
if(decodedPacket) {
out_frames++;
rc = sws_scale(sws_ctx, inputFrame->data, inputFrame->linesize, 0, video_out_codec->height, outputFrame->data, outputFrame->linesize);
if(rc != video_out_codec->height) {
puts("scaling error");
}
outputFrame->pts = (1.0 / 30.0) * 90.0 * video_out_codec->frame_number;
rc = avcodec_encode_video2(video_out_codec, &out_packet, outputFrame, &encodedPacket);
if(rc != 0) {
puts("encoding error");
}
if(encodedPacket) {
if (video_out_stream->codec->coded_frame->key_frame) { // deprecated, what to use instead
out_packet.flags |= AV_PKT_FLAG_KEY;
}
out_packet.stream_index = 0;
rc = av_interleaved_write_frame(output_ctx, &out_packet);
if(rc != 0) {
puts("frame write error");
}
av_free_packet(&out_packet);
memset(&out_packet, 0, sizeof(AVPacket));
packet_count++;
}
av_free_packet(&in_packet);
}
}
...
When I run this I get strange values for tbr/tbn/tbc reported by ffprobe and the video is a mess.
I've tried adding code as per this answer e.g.
if (out_packet.pts != AV_NOPTS_VALUE) {
out_packet.pts = av_rescale_q(out_packet.pts, video_out_stream->codec->time_base, video_out_stream->time_base);
}
if (out_packet.pts != AV_NOPTS_VALUE) {
out_packet.dts = av_rescale_q(out_packet.dts, video_out_stream->codec->time_base, video_out_stream->time_base);
}
...but then I get errors such as this is the debug output:
[mp4 # 0x1038aba00] Delay between the first packet and last packet in the muxing queue is 10100000 > 10000000: forcing output
I'm setting the timebase correctly (I think)...
video_out_stream = avformat_new_stream(output_ctx, videoEncoder);
video_out_stream->id = 0;
video_out_stream->time_base.den = 30;
video_out_stream->time_base.num = 1;
video_out_codec = video_out_stream->codec;
avcodec_get_context_defaults3(video_out_codec, videoEncoder);
video_out_codec->codec_id = AV_CODEC_ID_H264;
video_out_codec->bit_rate = 2048;
video_out_codec->width = 854;
video_out_codec->height = 480;
video_out_codec->time_base.den = 30;
video_out_codec->time_base.num = 1;
video_out_codec->gop_size = 30;
video_out_codec->pix_fmt = AV_PIX_FMT_YUV420P;
Any thoughts about how I can calculate the correct output frame pts and encoded packet dts/pts? I'm clearly doing something wrong.

STM32F103 - PC communication via USB

I am trying to use the found-bits project to communicate with my STM32F103 via USB from a Windows application with no success.
The program keeps returning an error code 31 at the WinUsb_ControlTransfer function call.
I made some changes that solved the problem for receiving the data from the default end point but the issue remains when trying to send data to it.
How can I get my windows application to send and receive data from the STM32?
P.S.: I created .inf and .cat files for my device and installed the driver
BOOL SendDatatoDefaultEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, BYTE byWinUSBCommControl, BYTE *pbyData = NULL, WORD wNumBytesCount = 0)
{
if (hDeviceHandle==INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bResult = TRUE;
WINUSB_SETUP_PACKET SetupPacket;
ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
ULONG cbSent = 0;
//Create the setup packet
SetupPacket.RequestType = (BMREQUEST_HOST_TO_DEVICE << 7)/* | (BMREQUEST_VENDOR << 5) | BMREQUEST_TO_INTERFACE*/;
//SetupPacket.Request = byWinUSBCommControl;
//SetupPacket.Value = 0;
SetupPacket.Index = 0; // specify WinUSBComm interface
//SetupPacket.Length = wNumBytesCount;
SetupPacket.Request = USB_REQUEST_GET_DESCRIPTOR;
SetupPacket.Value = USB_DEVICE_DESCRIPTOR_TYPE << 8;
SetupPacket.Length = sizeof(USB_DEVICE_DESCRIPTOR);
bResult = WinUsb_ControlTransfer(hDeviceHandle, SetupPacket, pbyData, wNumBytesCount, &cbSent, 0);
if(!bResult)
{
printf("Error WinUsb_ControlTransfer: %d.\n", GetLastError());
goto done;
}
PTRACE("Data sent: %d \nActual data transferred: %d.\n", wNumBytesCount, cbSent);
done:
return bResult;
}
BOOL GetDataFromDefaultEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, BYTE byWinUSBCommControl, BYTE *pbyData, WORD wNumBytesCount)
{
if ( 0 == wNumBytesCount )
{
return TRUE;
}
if ( NULL == pbyData )
{
return FALSE;
}
if (hDeviceHandle==INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bResult = TRUE;
WINUSB_SETUP_PACKET SetupPacket;
ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
ULONG cbSent = 0;
//Create the setup packet
SetupPacket.RequestType = (BMREQUEST_DEVICE_TO_HOST << 7)/* | (BMREQUEST_VENDOR << 5) | BMREQUEST_TO_DEVICE*/;
//SetupPacket.Request = byWinUSBCommControl;
//SetupPacket.Value = 0;
SetupPacket.Index = 0; // specify WinUSBComm interface
//SetupPacket.Length = wNumBytesCount;
SetupPacket.Request = USB_REQUEST_GET_DESCRIPTOR;
SetupPacket.Value = USB_DEVICE_DESCRIPTOR_TYPE << 8;
SetupPacket.Length = sizeof(USB_DEVICE_DESCRIPTOR);
bResult = WinUsb_ControlTransfer(hDeviceHandle, SetupPacket, pbyData, wNumBytesCount, &cbSent, 0);
if(!bResult)
{
printf("Error WinUsb_ControlTransfer: %d.\n", GetLastError());
goto done;
}
PTRACE("Data get : %d \nActual data transferred: %d.\n", wNumBytesCount, cbSent);
done:
return bResult;
}

Resources