6531E platform HTTPS interface debug

 Platform SSL protocol

 First, part of the agreement

 

 

 

 

SSL_AsyncRegCallback register callback

http_SecurityRecvDataCllback encryption success callback

http_SecuritySendDataCllback decryption success callback

http_SecurityPostMessageCllback handshake callback

http_SecurityShowCertInfoCllback certificate error correction

 

Second, workflow analysis

It can be sent by the protocol on the map, before receiving the data, must first inform SSL layer. After a successful longer follow the normal process of Socket transceiver

For example, data transmission process (reception Similarly)

Soket treated in my article Spreadtrum socket 6531 platform is described in detail in, here we only said part of the difference, according to analysis of the first part of the SSL process. Before sending and receiving data requires notification to call SSL encryption and decryption. And performing transmission and reception by the SSL cipher text callback. Process is as follows

1, after the establishment of SSL sci_sock_connect: SSL_Create (source in HTTP_SslInit), and to the upper SSL registered callback SSL_AsyncRegCallback (source in httpHandshaking)

2, in the event of a thread monitor the arrival of socket

socket write: SSL_EncryptPasser encrypted data, after SSL encryption successful call our registered callback http_SecuritySendDataCllback, after processing logic directly sci_sock_send me here, and inform SSL: SSL_AsyncMessageProc (((HX_SALE_SSL_INSTANCE *) httpmachine_ptr) -> hSSl, SSL_RECV_MESSAGE_SEND_SUCC, data_len); I sent successful, releasing resources occupied it

socket read: After sci_sock_recv, at this time the state data or cipher text, you need to call SSL decryption of data interfaces: After SSL_DecryptPasser, SSL decryption is successful calls the callback: http_SecurityRecvDataCllback, data received after that operation, I was content directly parse data then SSL_AsyncMessageProc (((HX_SALE_SSL_INSTANCE *) httpmachine_ptr) -> hSSl, SSL_RECV_MESSAGE_RECV_SUCC, data_len) ;, inform SSL release resources.

So far, SSL processing flow is completed. SSL mere addition process on the basis of HTTP, HTTPS can call up the data interface transceiver

SSL_EncryptPasser(SslInstance->hSSl, buf, strlen(buf));
                |
                |

http_SecuritySendDataCllback
                |
                |
http_Sending
                |
                |
sci_sock_send
                |
                |
SSL_AsyncMessageProc(((HX_SALE_SSL_INSTANCE *)httpmachine_ptr)->hSSl, SSL_RECV_MESSAGE_SEND_SUCC, data_len);//发送成功之后,需要向SSL发送异步消息。通知SSL释放占用的资源

 

 

 

 

 

Third, the source

Source partially achieved as follows: 

 

/*****************************************************************************/
//  Description : 封装JSON格式的数据
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: HX_SALE_SEND_DATA_TYPE
/*****************************************************************************/

LOCAL uint8 * MMISALE_CreateJSONpack(HX_SALE_SEND_DATA_TYPE CustomData)
{
	cJSON *root = PNULL;
	char *ret_ptr = PNULL;

	char plmn_info_data[8] = {0};

	SCI_TRACE_LOW("MMISALE_CreateJSONpack ...entry...");

	root=cJSON_CreateObject();	

	cJSON_AddItemToObject(root, "IMEI1", 			cJSON_CreateString(CustomData.imei1));
	cJSON_AddItemToObject(root, "IMEI2", 			cJSON_CreateString(CustomData.imei2));
	cJSON_AddItemToObject(root, "model", 			cJSON_CreateString(CustomData.model));
	cJSON_AddItemToObject(root, "modelDetail", 		cJSON_CreateString(CustomData.modelDetail));
	cJSON_AddItemToObject(root, "currentVersion", 	cJSON_CreateString(CustomData.currentVersion));
	cJSON_AddItemToObject(root, "serialNumber", 	cJSON_CreateString(CustomData.serialNumber));
	
	sprintf(plmn_info_data, 	"%d%02d", 			CustomData.sim1plmn.mcc, CustomData.sim1plmn.mnc);
	cJSON_AddItemToObject(root, "operator", 		cJSON_CreateString(plmn_info_data));
	memset(plmn_info_data, 0, sizeof(plmn_info_data));
	sprintf(plmn_info_data, 	"%d%02d", 			CustomData.sim2plmn.mcc, CustomData.sim2plmn.mnc);
	cJSON_AddItemToObject(root, "operator2", 		cJSON_CreateString(plmn_info_data));
	cJSON_AddItemToObject(root, "language", 		cJSON_CreateString(CustomData.language));

	ret_ptr = cJSON_Print(root);
	cJSON_Delete(root);
	//free(root);

	SCI_TRACE_LOW("MMISALE_CreateJSONpack ...out...");
	
	return ret_ptr;
	
}

/*****************************************************************************/
//  Description : 解析服务器返回的数据
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
LOCAL BOOLEAN HxSaleParseDataInfo(char* CustomData)
{
	char* b = PNULL;
	char* e = PNULL;
	char RecvData[8] = {0};

	SCI_TRACE_LOW("HxSaleParseDataInfo Entry !");
	
	if(PNULL == CustomData)
	{
		SCI_TRACE_LOW("HxSaleParseDataInfo  CustomData == PNULL!");
		return FALSE;
	}
	if( MMIAPICOM_Stristr(CustomData," 200") == NULL)   //不是返回的200,那说明是错误的
	{
	    SCI_TRACE_LOW("HxSaleParseDataInfo  (server data:HTTP/1.1 200)  no data");
		return FALSE;
	}

#if defined(TP_LINK_SALES_STATISTICS)&&defined(WIN32)//激活次数统计
    Sales_start_flag_add();
	if(TP_LINK_Sales_Start_Flag_Times()<5)
	{
        MMIDefault_StartSalesTimer();
		return FALSE;
	}
#endif


	//成功的标志是{"type":"success"}
	e = b = MMIAPICOM_Stristr(CustomData,"{\"type\":\"") + strlen("{\"type\":\""); //到前一个分号
	e = MMIAPICOM_Stristr(b, "\"");   //到后一个分号,e跟b之间就是返回的数据

	strncpy(RecvData, b, e - b);

	SCI_TRACE_LOW("HxSaleParseDataInfo RecvData=:%s", RecvData);

	if((strlen(RecvData) != 0) && (0 == strncmp("success", RecvData, strlen(RecvData))))  // 表示成功,服务器已接收请求
	{
		//清除销量统计的NV
	  #if defined(TP_LINK_SALES_STATISTICS)
        sales_statistics_send_success();
        MMIIDefault_StopSalesTimer();
	  #endif
		SCI_TRACE_LOW("HxSaleParseDataInfo parse custom data success !");
		return TRUE;
	}
	
}

/*****************************************************************************/
//  Description : 向socket线程发送信号(socket打开过程中遇到错误)
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
LOCAL BOOLEAN HxSaleSendSignal(void)
{
	xSignalHeaderRec *sig_ptr = 0;

	SCI_TRACE_LOW("HxSaleSendSignal");

	sig_ptr = (xSignalHeaderRec *)SCI_ALLOCA(sizeof(xSignalHeaderRec));
	SCI_ASSERT(sig_ptr);/*assert verified*/

	sig_ptr->SignalCode = MSG_SALE_SOCKET_ERROR;
	sig_ptr->SignalSize = sizeof(xSignalHeaderRec);
	sig_ptr->Sender = SCI_IdentifyThread();

	SCI_SendSignal((xSignalHeader)sig_ptr, s_sale_task_id);
}

/*****************************************************************************/
//  Description :销量统计条件达到,调用此函数执行网络端发送,本模块实现,外部模块调用 
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: HX_SALE_SEND_DATA_TYPE
/*****************************************************************************/
PUBLIC BOOLEAN MMISALE_RunSendInfor(void)
{
#if defined(TP_LINK_SALES_STATISTICS)
   if(TP_LINK_Sales_Start_Flag_Times()<5)
#endif   
   {
    #ifdef WIN32
	char testbuf[]="HTTP/1.1 200 Date: Tue, 19 Feb 2019 10:28:54 GMT Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Connection: close Server: nginx/1.12.1 12 {\"type\":\"success\"}";
	HxSaleParseDataInfo(testbuf);
    #else
	MMIAPIPDP_Deactive(MMI_MODULE_SALE);
	HxSaleActivePDP();
    #endif
   }    
}

#ifdef HTTPS_SUPPORT
/*****************************************************************************/
//  Description : 加密数据成功的回调
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: httpmachine_ptr SSL句柄  data_ptr加密后的数据  data_len加密后的数据长度
/*****************************************************************************/
int32 http_SecuritySendDataCllback( void *httpmachine_ptr, uint8 *data_ptr, uint32 data_len)
{

	SCI_TRACE_LOW("http_SecuritySendDataCllback is run!");
	
	if((PNULL == httpmachine_ptr) || (PNULL == data_ptr) || (0 == data_len))
	{
		SCI_TRACE_LOW("http_SecuritySendData  parameters fail!");
		return 0;
	}
#if 0
	BackBuf = SCI_MALLOC(uint8 *, data_len * sizeof(uint8));
	SCI_MEMCPY(BackBuf, data_ptr, data_len);

	//获取数据
	HTTP_SslGetRequestData(buf);

	
	//SSL_DecryptPasser((HX_SALE_SSL_INSTANCE *)httpmachine_ptr->hSSL, buf, strlen(buf));
	//加密
	SSL_EncryptPasser((HX_SALE_SSL_INSTANCE *)httpmachine_ptr->hSSL, buf, strlen(buf));

	return_ret = sci_sock_send((HX_SALE_SSL_INSTANCE *)httpmachine_ptr->fd, buf, strlen(buf), 0);

	SCI_TRACE_LOW("http_SecuritySendData send ret = :%d", return_ret);
#endif
	//加密成功了就调用发送接口
	http_Sending(httpmachine_ptr, data_ptr, data_len);
	//SSL_AsyncMessageProc((HX_SALE_SSL_INSTANCE *)httpmachine_ptr->hSSL, SSL_RECV_MESSAGE_SEND_SUCC);
		
}

/*****************************************************************************/
//  Description : 解密数据成功的回调
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: httpmachine_ptr SSL句柄  data_ptr解密后的数据  data_len解密后的数据长度
/*****************************************************************************/
void http_SecurityRecvDataCllback(void  *httpmachine_ptr, uint8 *data_ptr, uint32 data_len)
{

	SCI_TRACE_LOW("http_SecurityRecvDataCllback is run!");
	
	if((PNULL == httpmachine_ptr) || (PNULL == data_ptr) || (0 == data_len))
	{
		SCI_TRACE_LOW("http_SecurityRecvData  parameters fail!");
		return ;
	}

	
	http_Receiveing(httpmachine_ptr, data_ptr, data_len);
	
}

/*****************************************************************************/
//  Description : 传递加密解密数据以及握手过程中可能出现的问题
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: void *httpmachine_ptr句柄,  uint32 message_id消息ID
/*****************************************************************************/
void http_SecurityPostMessageCllback(void *httpmachine_ptr,  uint32 message_id)
{
	SCI_TRACE_LOW("http_SecurityPostMessageCllback is run!");
	
	if(PNULL == httpmachine_ptr)
	{
		SCI_TRACE_LOW("http_SecurityPostMessage parameters fail");
		return ;
	}

	switch (message_id)
	{
		//case SECURITY_HANDSHAKE_SUCC:
		case SSL_SEND_MESSAGE_HANDSHAKE_SUCC:  // 握手成功
			{
			 	//http handle this case according to its state
			 	SCI_TRACE_LOW("http_SecurityPostMessage SSL_SEND_MESSAGE_HANDSHAKE_SUCC");
			}
			break;
			
		case SSL_SEND_MESSAGE_FAIL:      //发送失败
			{
				//http handle this case according to its state
				SCI_TRACE_LOW("http_SecurityPostMessage SSL_SEND_MESSAGE_FAIL");
			}
			break;
			
		//case SSL_RECV_MESSAGE_SEND_SUCC:
			//SSL_EncryptPasser(SSL_HANDLE ssl_handle, uint8 * data_ptr, uint32 len)
			//break;

		//case SSL_RECV_MESSAGE_RECV_SUCC:  //接收成功
			//SSL_DecryptPasser((HX_SALE_SSL_INSTANCE *)httpmachine_ptr->hSSL, RecvBuf, RecvDateLenn);
			//break;
			
	    case SSL_SEND_MESSAGE_CLOSE_BY_SERVER:   //服务器发送关闭
			{
				SCI_TRACE_LOW("http_SecurityPostMessage SSL_SEND_MESSAGE_CLOSE_BY_SERVER");
			}
			break;
			
		case SSL_SEND_MESSAGE_CANCLED_BY_USER: // 证书出现问题
			{
				//http handle this case according to its state
				SCI_TRACE_LOW("http_SecurityPostMessage SSL_SEND_MESSAGE_CANCLED_BY_USER");
			}
			break;
			
		default:
			SCI_TRACE_LOW("http_SecurityPostMessage default");
			break;
	}

}

/*****************************************************************************/
//  Description : 当证书无法验证时,需要将将需要确认的消息传递给应用协议
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
void http_SecurityShowCertInfoCllback(void *machine_ptr, uint8 *title_ptr, uint8 *info_ptr)
{
	SCI_TRACE_LOW("http_SecurityShowCertInfoCllback is run!");
	if((PNULL == machine_ptr) || (PNULL == title_ptr) || (PNULL == info_ptr))
	{
		SCI_TRACE_LOW("http_SecurityShowCertInfo parameters fail");
		return ;
	}

	//通知SSL。停止
	SSL_UserCnfCert(((HX_SALE_SSL_INSTANCE *)machine_ptr)->hSSl , SSL_ASYNC);
}

/*****************************************************************************/
//  Description :  建立SSL的安全连接
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
void* httpHandshaking(void* machine_ptr)
{
	SSL_CALLBACK_T  astCbFun = {0};
	struct sci_sockaddr  addr;
    struct sci_hostent  * hostent_date = PNULL;
    uint32 ip = 0;
	uint32 hostip = 0;
	uint16 port = SALE_SERVICE_PORT;
	char *addr_str = NULL;

	SCI_TRACE_LOW("httpHandshaking is run!");
	astCbFun.decryptout_cb = http_SecurityRecvDataCllback;
	astCbFun.encryptout_cb = http_SecuritySendDataCllback;
	astCbFun.postmessage_cb = http_SecurityPostMessageCllback;
	astCbFun.showcert_cb = http_SecurityShowCertInfoCllback;

	hostent_date = sci_gethostbyname(g_sale_domain);
	SCI_MEMCPY(&hostip, hostent_date->h_addr_list[0], 4);
    //ntohl(ip);
    ip = ntohl(hostip);

   
    
    addr.family = AF_INET;
    //addr.ip_addr = htonl(ip);
    addr.ip_addr = htonl(ip);
    addr.port = htons(port);
    //memset(addr.sa_data, 0, 8 * sizeof(char));
    SCI_MEMSET((void*)addr.sa_data, 0, 8*sizeof(char));

	addr_str = inet_ntoa(addr.ip_addr);

	SSL_AsyncRegCallback(((HX_SALE_SSL_INSTANCE *)machine_ptr)->hSSl, &astCbFun);

	SSL_ProtocolChoose(((HX_SALE_SSL_INSTANCE *)machine_ptr)->hSSl,SSL_PROTOCOLBOTH,SSL_ASYNC);  //两个版本都支持
	
	SSL_HandShake(((HX_SALE_SSL_INSTANCE *)machine_ptr)->hSSl, addr_str, SALE_SERVICE_PORT, SSL_ASYNC);
}


/*****************************************************************************/
//  Description :  发送数据
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
void* http_Receiveing(void  *httpmachine_ptr, uint8 *data_ptr, uint32 data_len)
{

	SCI_TRACE_LOW("http_Receiveing is run!");
	if((PNULL == httpmachine_ptr) || (PNULL == data_ptr) || (0 == data_len))
	{	
		SCI_TRACE_LOW("http_Receiveing parameters fail");
		return PNULL ;
	}

	SCI_TRACE_LOW("http_Receiveing data_ptr:%s", data_ptr);
	
	HxSaleParseDataInfo(data_ptr);
}

/*****************************************************************************/
//  Description :  接收数据
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
void*  http_Sending(void  *httpmachine_ptr, uint8 *data_ptr, uint32 data_len)
{
	int return_ret = 0;

	SCI_TRACE_LOW("http_Sending is run!");
	if((PNULL == httpmachine_ptr) || (PNULL == data_ptr) || (0 == data_len))
	{	
		SCI_TRACE_LOW("http_Sending parameters fail");
		return PNULL ;
	}
	
	return_ret = sci_sock_send(((HX_SALE_SSL_INSTANCE *)httpmachine_ptr)->fd, data_ptr, data_len, 0);
	SCI_TRACE_LOW("http_SecuritySendData send ret = :%d", return_ret);

	if(return_ret > 0)
	{
		//发送成功,给上层发送消息,释放SSL的资源
		SSL_AsyncMessageProc(((HX_SALE_SSL_INSTANCE *)httpmachine_ptr)->hSSl, SSL_RECV_MESSAGE_SEND_SUCC, data_len);
	}
}

/*****************************************************************************/
//  Description :  创建SSL状态机
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
void*  http_CreateSSL(int socket_id)
{
    SCI_TRACE_LOW("http_Sending is run!");
    SslInstance = (HX_SALE_SSL_INSTANCE *)malloc(sizeof(HX_SALE_SSL_INSTANCE));
   if (PNULL == SslInstance)
   {
   	  return NULL;
   }
   
   SCI_MEMSET(SslInstance,0,sizeof(HX_SALE_SSL_INSTANCE));
   
   SslInstance->fd = socket_id;
   SslInstance->hSSl = SSL_Create(SslInstance, socket_id, SSL_ASYNC);

   return SslInstance;
}

/*****************************************************************************/
//  Description :   后去需要加密的发送数据
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
void  HTTP_SslGetRequestData(char* RequestData)
{
	char json[256] = {0};
        HX_SALE_SEND_DATA_TYPE CustomBuffer = {0};

	SCI_TRACE_LOW("HTTP_SslGetRequestData is run!");
	MMISALE_GetCustomInfo(&CustomBuffer);

	if(PNULL == RequestData)
	{
		SCI_TRACE_LOW("HTTP_SslGetRequestData parameter fail!");
		return;
	}

	sprintf(RequestData,"POST https://%s/fota-open-ota/phone/rom/active HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %d\r\nAccept: */*\r\n\r\n%s\r\n", g_sale_domain, g_sale_domain, strlen(json), json);
}

/*****************************************************************************/
//  Description :   SSL初始化
//  Global resource dependence : none
//  Author: jiemin lai
//  Note: 
/*****************************************************************************/
void  HTTP_SslInit(int socket_id)
{
	SCI_TRACE_LOW("HTTP_SslInit is run!");
	http_CreateSSL(socket_id);
	
	httpHandshaking((void *)SslInstance);
}

#endif

Four, HTTPS debugging problems encountered

 1, Spreadtrum SC6531E \ SC7703 platform only supports SSL 3.0 TLS1.0 version. If the encrypted version of the server is higher than this, the SSL handshake after handshake in HTTP completed, it will refuse to shake hands with our request. Message as follows (Wireshark analysis)

2, HTTPS request is denied

HTTPS default port number is 443, HTTP is 80, after the completion of HTTP debugging switching HTTPS, because there is no change the port number, leading to a handshake request is rejected when initiating a first handshake. CSDN really see on the big brother post, one of the reasons is the port number wrong. Can not find address the post.

 

 

Published 22 original articles · won praise 9 · views 8827

Guess you like

Origin blog.csdn.net/ljm_c_bok/article/details/88043170