Prechádzať zdrojové kódy

Z991239-1621 #comment 协助通道合入国密版本

胡琛80272472 4 rokov pred
rodič
commit
420b6c1fd7

+ 3 - 0
Other/libbizchan/CMakeLists.txt

@@ -8,6 +8,8 @@ set(${MODULE_PREFIX}_SRCS
 	quicklz.h
 	jpeg2k.h
 	bizchan.h
+    chinaEncrypt.h
+    chinaEncrypt.cpp
 )
 
 add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})
@@ -21,6 +23,7 @@ conan_cmake_run(REQUIRES openjpeg/2.0.0@LR04.02_ThirdParty/testing
 target_include_directories(${MODULE_NAME} PRIVATE
 	"${CONAN_RVCFRAMEWORK_ROOT}/include"
 	${RVC_COMMON_INCLUDE_DIR}
+    ${CONAN_INCLUDE_DIRS_LIBKYSM}
     ${CONAN_INCLUDE_DIRS_OPENJPEG}
     ${OTHER_LIB_BASE_DIR}/libscreencodec
     ${OTHER_LIB_BASE_DIR}/acmstrdec

+ 171 - 99
Other/libbizchan/bizchan.cpp

@@ -33,6 +33,7 @@
 #include "ListEntry.h"
 #include <screencodec.h>
 #include "jpeg2k.h"
+#include "chinaEncrypt.h"
 
 #ifdef RVC_OS_WIN
 #include <DbgHelp.h>
@@ -44,6 +45,8 @@
 #define DEFAULT_RX_BUF_SIZE	8192
 #define KEY_LEN	16
 
+#define ENCRYPT_CHINA	1
+
 #ifndef RVC_OS_WIN
 #include "SpBase.h"
 
@@ -133,6 +136,7 @@ struct bizchan_t
 	char remote_pwd[KEY_LEN];
 	RC4_KEY local_key;
 	RC4_KEY remote_key;
+	int remote_version;
 	LARGE_INTEGER last_remote_active_time;
 	LARGE_INTEGER last_local_active_time;
 	screen_decoder_session_t *dec_session;
@@ -151,6 +155,8 @@ static lpfn_cryptionfun encodestring = NULL;
 static lpfn_cryptionfun decodestring_mobile = NULL;
 static lpfn_cryptionfun encodestring_mobile = NULL;
 
+static unsigned char  seed_key []= {0x81,0x32,0x13,0xf5,0x29,0x3b,0x52,0x37,0x61,0x98,0x33,0x15,0x72,0x31,0xfe,0x34};
+
 static __inline unsigned int hash32_buf(const void *bf, size_t len, unsigned int hash)
 {
 	const unsigned char *s = (const unsigned char*)bf;
@@ -211,6 +217,33 @@ static __inline void GetTick(LARGE_INTEGER *last, LARGE_INTEGER *lt)
 #endif
 }
 
+
+static void Dbg(bizchan_t *chan, int level, const char *fmt, ...)
+{
+	int n;
+	va_list arg;
+	va_start(arg, fmt);
+	if (chan->cb.dbg) {
+		n = _vscprintf(fmt, arg);
+		if (n > 0) {
+			char *buf = (char*)_alloca((size_t)(n + 3));
+			vsprintf(buf, fmt, arg);
+			(*chan->cb.dbg)(chan, level, buf, chan->cb.user_data);
+		}
+	}
+	else {
+		n = _vscprintf(fmt, arg);
+		if (n > 0) {
+			char *buf = (char*)_alloca((size_t)(n + 3));
+			vsprintf(buf, fmt, arg);
+			strcat(buf, "\r\n");
+			OutputDebugStringA((LPCSTR)buf);
+			printf(buf);
+		}
+	}
+	va_end(arg);
+}
+
 BIZCHAN_API(int) bizchan_lib_init()
 {
 #ifdef RVC_OS_WIN
@@ -290,18 +323,14 @@ static int callback_check(const bizchan_callback_t *cb)
 
 static void invoke_on_connect(bizchan_t *chan, int error)
 {
-	char buffer[128];
-	if (error == 0) {
-		snprintf(buffer, 128, "b_primary_server: %d, proxy_server:%s", chan->b_primary_server, chan->config.proxy_server);
-		chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
-		chan->cb.on_connect(chan,
-			error,
+	if (error == 0)
+		chan->cb.on_connect(chan, 
+			error, 
 			chan->b_primary_server ? chan->config.proxy_server : chan->config.bak_proxy_server,
-			chan->remote_video_rtp_port,
-			chan->remote_video_desc,
+			chan->remote_video_rtp_port, 
+			chan->remote_video_desc, 
 			chan->remote_client_id,
 			chan->cb.user_data);
-	}
 	else
 		chan->cb.on_connect(chan, 
 			error, 
@@ -332,6 +361,7 @@ static void invoke_on_recv_pkt(bizchan_t *chan, int type, int sub_type, int id,
 		fflush(rx_log_fp);
 	}*/
 
+	//Dbg(chan, "invoke_on_recv_pkt, type:%d, sub_type:%d, id:%d, pkt_size:%d", type, sub_type, id, pkt_size);
 	if (type == ACM_TYPE_SRN) {
 		int cat = ACM_SRN_CAT(sub_type);
 		if (cat == ACM_SRN_ANS) {
@@ -396,9 +426,10 @@ static void invoke_on_recv_pkt(bizchan_t *chan, int type, int sub_type, int id,
 	} else if (type == ACM_TYPE_SYNC) {
 		if (chan->winsync_on_recv_cb) {
 			chan->winsync_on_recv_cb(sub_type, pkt, pkt_size, chan->winsync_user_data);
-		} else {
-			chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
 		}
+		//同时上报应用层,用于应用层判断采用哪种同步方式(Sivilight或者chrome H5)
+		chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
+		
 	} else if (type == ACM_TYPE_MODE) {
 		if (chan->mode_cb) {
 			chan->mode_cb(TRUE, chan->winsync_user_data);
@@ -455,49 +486,57 @@ static int on_recv2(bizchan_t *chan, SOCKET conn)
 
 static int on_recv(bizchan_t *chan, SOCKET conn)
 {
-	char buffer[128];
 	recv_info_t *ri = &chan->recv_info;
 	int n;
 	int result = 0;
 
 	do {
-		chan->cb.dbg(chan, 0, "on_recv start", chan->cb.user_data);
 		n = recv(conn, ri->buf+ri->offset, ri->buf_len-ri->offset, 0);
-		snprintf(buffer, 128, "on_recv n:%d, ri->offset:%d, ri->buf_len:%d, sizeof(acm_hdr):%d", n, ri->offset, ri->buf_len, sizeof(acm_hdr));
-		chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
+		Dbg(chan, 0, "on_recv n:%d, ri->offset:%d, ri->buf_len:%d, sizeof(acm_hdr):%d", n, ri->offset, ri->buf_len, sizeof(acm_hdr));
 		if (n > 0) {
 			int i = 0;
 			ri->offset += n;
 			GetTick(&chan->last_remote_active_time, &chan->last_remote_active_time);
 			while (ri->offset-i >= sizeof(acm_hdr)) {
 				acm_hdr *hdr = (acm_hdr*)&ri->buf[i];
+				//Dbg(chan, "on_recv, i:%d offset:%d, recv_length:%d", i,  ri->offset, n);
+				//Dbg(chan, "on_recv, encrypt:%u, type:%u, sub_type:%u, length:%lu, compress:%u", hdr->encrypt, hdr->type, hdr->sub_type, hdr->length, hdr->compress);
 				if (hdr->length == 0) {
 					printf("broken");
 				}
-				snprintf(buffer, 128, "on_recv length:%d, encrypt:%d, compress:%d", hdr->length, hdr->encrypt, hdr->compress);
-				chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
 				if (ri->offset-i >= hdr->length+sizeof(acm_hdr)) {
-					if (hdr->encrypt) {
+					if (hdr->encrypt) 
+					{
+						int dec_length = hdr->length;
 						char *dec_buf = (char*)malloc(hdr->length);
-						RC4_set_key(&chan->remote_key, sizeof(chan->remote_pwd), (unsigned char*)chan->remote_pwd);
-						RC4(&chan->remote_key, hdr->length, (const unsigned char*)(&hdr->data[0]), (unsigned char*)dec_buf);
-						if (hdr->compress) {
+						int sm4_dec_result = DecStrWithSM4_ECB(chan->remote_pwd, sizeof(chan->remote_pwd), (unsigned char*)(&hdr->data[0]), hdr->length, (unsigned char*)dec_buf, &dec_length);
+						if (sm4_dec_result != 0){
+							//Dbg(chan, "DecStrWithSM4_ECB failed, type:%u, sub_type:%u, length:%lu", hdr->type, hdr->sub_type, hdr->length);
+							RC4_set_key(&chan->remote_key, sizeof(chan->remote_pwd), (unsigned char*)chan->remote_pwd);
+							RC4(&chan->remote_key, hdr->length, (const unsigned char*)(&hdr->data[0]), (unsigned char*)dec_buf);
+							dec_length = hdr->length;
+						}
+						if (hdr->compress) 
+						{
 							int len = (int)qlz_size_decompressed(dec_buf);
 							char *unzip_buf = (char*)malloc(len);
 							len = qlz_decompress(dec_buf, unzip_buf, &ri->decompress_state);
-							if (check_hash(unzip_buf, len, hdr->hash)) {
+							if (check_hash(unzip_buf, len, hdr->hash)) 
+							{
 								invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
 							} else {
-								OutputDebugStringA("pkt hash failed!\n");
-								chan->cb.dbg(chan, 0, "pkt hash failed! 1", chan->cb.user_data);
+								//OutputDebugStringA("pkt hash failed!\n");
+								Dbg(chan, 0, "encrypt compress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu, unzip:%d", hdr->type, hdr->sub_type, hdr->length, hdr->hash, len);
 							}
 							free(unzip_buf);
 						} else {
-							if (check_hash(dec_buf, hdr->length, hdr->hash)) {
-								invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, dec_buf, hdr->length);
-							} else {
-								OutputDebugStringA("pkt hash failed!\n");
-								chan->cb.dbg(chan, 0, "pkt hash failed! 2", chan->cb.user_data);
+							//sm4解密后hdr->length长度与内容长度不一致,采用dec_length变量
+							if (check_hash(dec_buf, dec_length, hdr->hash)) {
+								invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, dec_buf, dec_length);
+							}
+							else {
+								//OutputDebugStringA("pkt hash failed!\n");
+								Dbg(chan, 0, "encrypt uncompress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu", hdr->type, hdr->sub_type, hdr->length, hdr->hash);
 							}
 						}
 						free(dec_buf);
@@ -509,16 +548,16 @@ static int on_recv(bizchan_t *chan, SOCKET conn)
 							if (check_hash(unzip_buf, len, hdr->hash)) {
 								invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
 							} else {
-								OutputDebugStringA("pkt hash failed!\n");
-								chan->cb.dbg(chan, 0, "pkt hash failed! 3", chan->cb.user_data);
+								//OutputDebugStringA("pkt hash failed!\n");
+								Dbg(chan, 0, "compress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu, unzip:%d", hdr->type, hdr->sub_type, hdr->length, hdr->hash, len);
 							}
 							free(unzip_buf);
 						} else {
 							if (check_hash((char*)&hdr->data[0], hdr->length, hdr->hash)) {
 								invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, (const char*)&hdr->data[0], hdr->length);
 							} else {
-								OutputDebugStringA("pkt hash failed!\n");
-								chan->cb.dbg(chan, 0, "pkt hash failed! 4", chan->cb.user_data);
+								//OutputDebugStringA("pkt hash failed!\n");
+								Dbg(chan, 0, "uncompress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu", hdr->type, hdr->sub_type, hdr->length, hdr->hash);
 							}
 						}
 					}
@@ -547,15 +586,14 @@ static int on_recv(bizchan_t *chan, SOCKET conn)
 	else {
 		result = (n < 0 || (errno == EWOULDBLOCK) || (errno == EINTR) || (errno == EAGAIN)) ? 0 : -1;
 	}
-	snprintf(buffer, 128, "on_recv n:%d, result:%d, errno:%d", n, result, errno);
-	chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
+
+	Dbg(chan, 0, "on_recv n:%d, result:%d, errno:%d", n, result, errno);
 	return result;
 #endif
 }
 
 static int on_send(bizchan_t *chan, SOCKET conn)
 {
-	char buffer[128];
 	send_info_t *si = &chan->send_info;
 	int n = 1;//默认为1
 	int result = -1; 
@@ -569,22 +607,31 @@ static int on_send(bizchan_t *chan, SOCKET conn)
 		do {
 			send_buf_node *t = CONTAINING_RECORD(ListEntry_GetHead(&si->send_list), send_buf_node, entry);
 			if (t->need_encrypt) {
+				//SM4加密,密文会比明文长16字节
+				int enc_length = t->left + sizeof(acm_hdr)+16;
 				acm_hdr *hdr = (acm_hdr*)t->buf;
-				char *enc_buf = (char*)malloc(t->left+sizeof(acm_hdr));
-				RC4_set_key(&chan->local_key, sizeof(chan->local_pwd), (unsigned char*)chan->local_pwd);
-				RC4(&chan->local_key, t->left, (const unsigned char*)(&hdr->data[0]), (unsigned char*)(enc_buf+sizeof(acm_hdr)));
+				char *enc_buf = (char*)malloc(t->left+sizeof(acm_hdr) + 16);
+				//version为2代表支持国密,采用SM4加密
+				if(chan->remote_version != 1){
+					EncStrWithSM4_ECB(chan->local_pwd, sizeof(chan->local_pwd), (unsigned char*)(&hdr->data[0]), hdr->length, (unsigned char*)(enc_buf+sizeof(acm_hdr)), &enc_length);
+					hdr->length = enc_length;
+					t->left = enc_length + sizeof(acm_hdr);
+				    //Dbg(chan, "enc_length:%d", enc_length);
+				} else {
+					RC4_set_key(&chan->local_key, sizeof(chan->local_pwd), (unsigned char*)chan->local_pwd);
+				    RC4(&chan->local_key, t->left, (const unsigned char*)(&hdr->data[0]), (unsigned char*)(enc_buf+sizeof(acm_hdr)));
+			    }
 				memcpy(enc_buf, hdr, sizeof(acm_hdr));
 				free(t->buf);
 				t->buf = enc_buf;
 				t->need_encrypt = 0;
 			}
 			n = send(conn, t->buf+t->sended, t->left, 0);
-			snprintf(buffer, 128, "on_send n:%d, t->sended:%d, t->left:%d", n, t->sended, t->left);
-			chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
+			Dbg(chan, 0, "on_send n:%d, t->sended:%d, t->left:%d", n, t->sended, t->left);
 			if (n > 0) {
 				char tmp[32];
 				sprintf(tmp, "send out %d bytes!\n", n);
-				OutputDebugStringA(tmp);
+				//OutputDebugStringA(tmp);
 				t->left -= n;
 				t->sended += n;
 				if (t->left == 0) {
@@ -742,13 +789,22 @@ static void process(bizchan_t *chan)
 						{
 							error = netevents.iErrorCode[FD_WRITE_BIT];
 							if (error == 0) {
+								int enc_length = KEY_LEN;
 								proxy_hdr hdr = {0};
 								hdr.tag[0] = 'A';
 								hdr.tag[1] = 'C';
 								hdr.tag[2] = 'M';
 								hdr.version = ACM_PROTOCOL_VERSION;
-								generate_rand_key(chan->local_pwd, sizeof(chan->local_pwd));
+								generate_rand_key(chan->local_pwd, KEY_LEN/2);
+								//等待全部升级后再采用SM4加密
+                                #if ENCRYPT_CHINA
+								EncWithSM4_ECB(seed_key, (unsigned char*)&chan->local_pwd[0], KEY_LEN / 2,
+									(unsigned char*)&hdr.encrypt_key[0], &enc_length);
+                                Dbg(chan, "use SM4 password_crypt_type");
+                                #else
 								encodefun((unsigned char*)&hdr.encrypt_key[0], sizeof(hdr.encrypt_key), (unsigned char*)&chan->local_pwd[0], sizeof(chan->local_pwd));
+                                Dbg(chan, "use old password_crypt_type");
+								#endif
 								hdr.encrypt_keyhash = hash_key(chan->local_pwd, sizeof(chan->local_pwd));
 								memset(hdr.callee_id, ' ', sizeof(hdr.callee_id));
 								memset(hdr.caller_id, ' ', sizeof(hdr.caller_id));
@@ -787,11 +843,21 @@ static void process(bizchan_t *chan)
 									if (t > 0) {
 										ack_hdr_recv_bytes += t;
 										if (ack_hdr_recv_bytes == sizeof(ack_hdr)) {
-											decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
+											int dec_length = KEY_LEN;
+											int result = DecWithSM4_ECB(seed_key,
+												(unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key), 
+												(unsigned char*)&chan->remote_pwd[0], &dec_length);
+											Dbg(chan, "use SM4 Decode password result:%d", result);
+											if(result != 0){
+												result = decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
+												Dbg(chan, "use old Decode password result:%d", result);
+											}
 											if (check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash)) {
 												chan->remote_video_rtp_port = ack_hdr.rtp_port;
 												chan->remote_video_desc = ack_hdr.media_desc;
 												memcpy(chan->remote_client_id, ack_hdr.client_id, sizeof(chan->remote_client_id));
+												chan->remote_version = ack_hdr.version;
+												Dbg(chan, "remote_acm_version:%d", chan->remote_version);
 												chan->connected = TRUE;
 												break;
 											} else {
@@ -838,7 +904,8 @@ static void process(bizchan_t *chan)
 				rc = on_send(chan, conn);
 				if (rc != 0)
 					break;
-			} else if (dwRet == WAIT_OBJECT_0+1) 
+			} 
+			else if (dwRet == WAIT_OBJECT_0+1) 
 			{
 				WSANETWORKEVENTS netevents;
 				if (WSAEnumNetworkEvents(conn, evts[1], &netevents) != SOCKET_ERROR) 
@@ -854,7 +921,9 @@ static void process(bizchan_t *chan)
 						break;
 					}
 				}
-			} else if (dwRet == WAIT_TIMEOUT) {
+			} 
+			else if (dwRet == WAIT_TIMEOUT) 
+			{
 				LARGE_INTEGER now;
 				GetTick(&chan->last_remote_active_time, &now);
 				if (now.QuadPart - chan->last_remote_active_time.QuadPart >= PING_INTERVAL) {
@@ -872,12 +941,14 @@ static void process(bizchan_t *chan)
 	}
 
 on_error:
-	OutputDebugStringA("on_error");
+	//OutputDebugStringA("on_error");
+	Dbg(chan, "on_error");
 	if (!chan->connected) {
 		invoke_on_connect(chan, -1); // connect failed!
 	} else {
 		//....
-		OutputDebugStringA("connected, and error!");
+		//OutputDebugStringA("connected, and error!");
+		Dbg(chan, "connected, and error!");
 	}
 
 	if (conn != INVALID_SOCKET)
@@ -900,13 +971,21 @@ static void do_shake_send(bizchan_t* chan, SOCKET conn, int* error) {
 		decodefun = decodestring_mobile;
 	}
 
+	int enc_length = KEY_LEN;
 	hdr.tag[0] = 'A';
 	hdr.tag[1] = 'C';
 	hdr.tag[2] = 'M';
 	hdr.version = ACM_PROTOCOL_VERSION;
-	generate_rand_key(chan->local_pwd, sizeof(chan->local_pwd));
+	generate_rand_key(chan->local_pwd, KEY_LEN / 2);
+	//等待全部升级后再采用SM4加密
+#if ENCRYPT_CHINA
+	EncWithSM4_ECB(seed_key, (unsigned char*)&chan->local_pwd[0], KEY_LEN / 2,
+		(unsigned char*)&hdr.encrypt_key[0], &enc_length);
+	Dbg(chan, 0, "use SM4 password_crypt_type");
+#else
 	encodefun((unsigned char*)&hdr.encrypt_key[0], sizeof(hdr.encrypt_key), (unsigned char*)&chan->local_pwd[0], sizeof(chan->local_pwd));
-
+	Dbg(chan, 0, "use old password_crypt_type");
+#endif
 	hdr.encrypt_keyhash = hash_key(chan->local_pwd, sizeof(chan->local_pwd));
 	memset(hdr.callee_id, ' ', sizeof(hdr.callee_id));
 	memset(hdr.caller_id, ' ', sizeof(hdr.caller_id));
@@ -921,6 +1000,7 @@ static void do_shake_send(bizchan_t* chan, SOCKET conn, int* error) {
 	}
 	hdr.rtp_port = chan->config.video.rtp_port;
 	hdr.media_desc = chan->config.video.desc;
+
 	if (send(conn, (char*)&hdr, sizeof(hdr), 0) != sizeof(hdr)) {
 		*error = -1;
 	}
@@ -932,7 +1012,6 @@ static void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
 	int ack_hdr_recv_bytes = 0;
 	lpfn_cryptionfun encodefun = encodestring;
 	lpfn_cryptionfun decodefun = decodestring;
-	char buffer[128];
 
 	if (1 == chan->config.crypt_type) {
 		encodefun = encodestring_mobile;
@@ -947,20 +1026,29 @@ static void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
 			//chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
 			ack_hdr_recv_bytes += t;
 			if (ack_hdr_recv_bytes == sizeof(ack_hdr)) {
-				decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
-				//chan->cb.dbg(chan, 0, "do_shake_recv remote_pwd:", chan->cb.user_data);
-				//chan->cb.dbg(chan, 0, chan->remote_pwd, chan->cb.user_data);
+				int dec_length = KEY_LEN;
+				int result = DecWithSM4_ECB(seed_key,
+					(unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key),
+					(unsigned char*)&chan->remote_pwd[0], &dec_length);
+				Dbg(chan, 0, "use SM4 Decode password result:%d", result);
+				if (result != 0) {
+					result = decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
+					Dbg(chan, 0, "use old Decode password result:%d", result);
+				}
 				if (check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash)) {
 					chan->remote_video_rtp_port = ack_hdr.rtp_port;
 					chan->remote_video_desc = ack_hdr.media_desc;
 					memcpy(chan->remote_client_id, ack_hdr.client_id, sizeof(chan->remote_client_id));
+					chan->remote_version = ack_hdr.version;
+					Dbg(chan, 0, "remote_acm_version:%d", chan->remote_version);
 					chan->connected = TRUE;
 					break;
 				}
 				else {
 					*error = -1;
-					chan->cb.dbg(chan, 0, "do_shake_recv check_hash failed", chan->cb.user_data);
+					Dbg(chan, 0, "do_shake_recv check_hash failed");
 				}
+
 			}
 		}
 	} while (t > 0 && *error == 0);
@@ -970,9 +1058,8 @@ static void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
 #else
 	if (t <= 0 && ((errno != EWOULDBLOCK) || (errno != EINTR) || (errno != EAGAIN))) {
 		*error = -1;
-		snprintf(buffer, 128, "do_shake_recv errno:%d", errno);
-		chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
-		chan->cb.dbg(chan, 0, "do_shake_recv t<=0 failed", chan->cb.user_data);
+		Dbg(chan, 0, "do_shake_recv errno:%d", errno);
+		Dbg(chan, 0, "do_shake_recv t<=0 failed");
 	}
 #endif
 }
@@ -1028,7 +1115,7 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
 #else
 		close(m_hSocket);
 #endif
-		chan->cb.dbg(chan, 0, "connect_server set_socket_noblock failed", chan->cb.user_data);
+		Dbg(chan, 0, "connect_server set_socket_noblock failed");
 	}
 
 	addrSrv.sin_family = AF_INET;
@@ -1036,7 +1123,7 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
 	addrSrv.sin_port = htons(port);
 	int ret = connect(m_hSocket, (struct sockaddr*)&addrSrv, sizeof(addrSrv));
 	if (ret == 0) {
-		chan->cb.dbg(chan, 0, "connect_server connect success 1.", chan->cb.user_data);
+		Dbg(chan, 0, "connect_server connect success 1.");
 		return m_hSocket;
 	}
 #ifdef RVC_OS_WIN
@@ -1048,10 +1135,8 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
 #else
 	//linux下需要检测EINPROGRESS和EINTR  
 	if (ret < 0 && (errno != EINPROGRESS && errno != EINTR)) {
-		char buffer[128];
 		close(m_hSocket);
-		snprintf(buffer, 128, "connect_server connect failed, errno: %d", errno);
-		chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
+		Dbg(chan, 0, "connect_server connect failed, errno: %d", errno);
 		return INVALID_SOCKET;
 	}
 #endif
@@ -1069,11 +1154,11 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
 #else
 		close(m_hSocket);
 #endif
-		chan->cb.dbg(chan, 0, "connect_server connect timeout.", chan->cb.user_data);
+		Dbg(chan, 0, "connect_server connect timeout.");
 		return INVALID_SOCKET;
 	}
 
-	chan->cb.dbg(chan, 0, "connect_server connect success 2.", chan->cb.user_data);
+	Dbg(chan, 0, "connect_server connect success 2.");
 	return m_hSocket;
 }
 
@@ -1099,18 +1184,18 @@ static void process(bizchan_t* chan) {
 #if 0
 		do_shake_send(chan, conn, &error);
 		if (error != 0) {
-			chan->cb.dbg(chan, 0, "do_shake_send failed", chan->cb.user_data);
+			Dbg(chan, 0, "do_shake_send failed");
 			goto on_error;
 		}
 		do_shake_recv(chan, conn, &error);
 		if (error != 0) {
-			chan->cb.dbg(chan, 0, "do_shake_recv failed", chan->cb.user_data);
+			Dbg(chan, 0, "do_shake_recv failed");
 			goto on_error;
 		}
 #else
 		do_shake_send(chan, conn, &error);
 		if (error != 0) {
-			chan->cb.dbg(chan, 0, "do_shake_send failed", chan->cb.user_data);
+			Dbg(chan, 0, "do_shake_send failed");
 			goto on_error;
 		}
 		while (!chan->stop_flag && !chan->connected) {
@@ -1123,13 +1208,13 @@ static void process(bizchan_t* chan) {
 			int activity = select(maxfd + 1, &read_fds, &write_fds, &except_fds, &tv);
 			if (activity == -1) {
 				perror("select()");
-				chan->cb.dbg(chan, 0, "process shake select -1", chan->cb.user_data);
+				Dbg(chan, 0, "process shake select -1");
 				goto on_error;
 			}
 			else if (activity == 0) {
 				// timeout
 				printf("select() returns 0.\n");
-				chan->cb.dbg(chan, 0, "process shake select 0", chan->cb.user_data);
+				Dbg(chan, 0, "process shake select 0");
 				goto on_error;
 			}else {
 				/* All fd_set's should be checked. */
@@ -1141,7 +1226,7 @@ static void process(bizchan_t* chan) {
 					char pipe_read_buffer[4];
 					int n = read(chan->evt[0], pipe_read_buffer, 4);
 					if (n < 0) {
-						chan->cb.dbg(chan, 0, "process shake pipe read < 0", chan->cb.user_data);
+						Dbg(chan, 0, "process shake pipe read < 0");
 					}
 				}
 				if (FD_ISSET(conn, &except_fds)) {
@@ -1159,22 +1244,9 @@ static void process(bizchan_t* chan) {
 	{
 		char buffer[128];
 		int rc;
-		/*rc = set_socket_noblock(conn);
-		if (rc)
-		{
-			on_close(chan);
-			chan->cb.dbg(chan, 2, "set_socket_noblock failed", chan->cb.user_data);
-			goto on_error;
-		}*/
+
 		invoke_on_connect(chan, 0);
 		chan->recv_info.offset = 0;
-		/*rc = on_recv(chan, conn);
-		if (rc)
-		{
-			on_close(chan);
-			chan->cb.dbg(chan, 2, "on_recv failed", chan->cb.user_data);
-			goto on_error;
-		}*/
 		while (!chan->stop_flag)
 		{
 			struct timeval tv;
@@ -1186,7 +1258,7 @@ static void process(bizchan_t* chan) {
 			int activity = select(maxfd + 1, &read_fds, &write_fds, &except_fds, &tv);
 			if (activity == -1) {
 				perror("select()");
-				chan->cb.dbg(chan, 0, "chan select() error.", chan->cb.user_data);
+				Dbg(chan, 0, "chan select() error.");
 				goto on_error;
 			}
 			else if (activity == 0) {
@@ -1218,11 +1290,11 @@ static void process(bizchan_t* chan) {
 							break;
 					}
 					else {
-						chan->cb.dbg(chan, 0, "pipe read < 0", chan->cb.user_data);
+						Dbg(chan, 0, "pipe read < 0");
 					}
 				}
 				if (FD_ISSET(conn, &except_fds)) {
-					chan->cb.dbg(chan, 0, "select() except_fds set.", chan->cb.user_data);
+					Dbg(chan, 0, "select() except_fds set.");
 					error = -1;
 				}
 				if (error != 0) {
@@ -1234,16 +1306,16 @@ static void process(bizchan_t* chan) {
 	}
 
 on_error:
-	OutputDebugStringA("on_error");
-	chan->cb.dbg(chan, 0, "on_error", chan->cb.user_data);
+	//OutputDebugStringA("on_error");
+	Dbg(chan, 0, "on_error");
 
 	if (!chan->connected) {
 		invoke_on_connect(chan, -1); // connect failed!
 	}
 	else {
 		//....
-		OutputDebugStringA("connected, and error!");
-		chan->cb.dbg(chan, 0, "connected, and error!", chan->cb.user_data);
+		//OutputDebugStringA("connected, and error!");
+		Dbg(chan, 0, "connected, and error!");
 	}
 
 	if (conn != INVALID_SOCKET) {
@@ -1271,7 +1343,7 @@ static void* work_proc(void* arg)
 		//....
 	}
 #else
-	chan->cb.dbg(chan, 0, "work_proc start", chan->cb.user_data);
+	Dbg(chan, 0, "work_proc start");
 	process(chan);
 #endif
 	return 0;
@@ -1503,14 +1575,14 @@ BIZCHAN_API(int) bizchan_start_connect(bizchan_t *chan)
 	}
 
 	if (chan->work_thread) {
-		chan->cb.dbg(chan, 2, "work_thread exsit!!!", chan->cb.user_data);
+		Dbg(chan, 2, "work_thread exsit!!!");
 		return -1;
 	}
 
 #ifdef RVC_OS_WIN
 	WSAResetEvent(chan->evt);
 #endif
-	chan->cb.dbg(chan, 0, "bizchan_start_connect 2", chan->cb.user_data);
+	Dbg(chan, 0, "bizchan_start_connect 2");
 
 	chan->stop_flag = 0;
 	chan->connected = 0;
@@ -1523,22 +1595,22 @@ BIZCHAN_API(int) bizchan_start_connect(bizchan_t *chan)
 #else
 	int err = pthread_create(&chan->work_thread, NULL, work_proc, chan);
 	if (0 == err) {
-		Dbg("create work thread success, %lu.", chan->work_thread);
+		Dbg(chan, 0, "create work thread success, %lu.", chan->work_thread);
 	}
 	else {
-		Dbg("create work thread failed.");
+		Dbg(chan, 0, "create work thread failed.");
 	}
 #endif // RVC_OS_WIN
 
 	// we now return, when connected, on_connect will invoked in work_proc thread
-	chan->cb.dbg(chan, 0, "bizchan_start_connect success", chan->cb.user_data);
+	Dbg(chan, 0, "bizchan_start_connect success");
 
 	return 0;
 }
 
 BIZCHAN_API(int) bizchan_start_close(bizchan_t *chan)
 {
-	chan->cb.dbg(chan, 2, "bizchan_start_close", chan->cb.user_data);
+	Dbg(chan, 2, "bizchan_start_close");
 	chan->stop_flag = 1;
 #ifdef RVC_OS_WIN
 	WSASetEvent(chan->evt);

+ 108 - 0
Other/libbizchan/chinaEncrypt.cpp

@@ -0,0 +1,108 @@
+#include "chinaEncrypt.h"
+#include "CMBSMDLL.h"
+#include <stdio.h>
+#include <string.h>
+
+#ifdef RVC_OS_WIN
+
+#include <windows.h>
+#endif
+
+
+int SM3Hash(unsigned char* pData, int nLen, unsigned char hash[32])
+{
+	return CMBSM3Digest(pData, nLen, hash);
+}
+
+char* GetSMVersion()
+{
+	return CMBSMGetVersion();
+}
+
+int CreateSM2KeyPair(unsigned char* pPubKeyBuf, int* pPubKeyBufLen, unsigned char* pPriKeyBuf, int* pPriKeyBufLen)
+{
+	return CMBSM2KeyGen(pPubKeyBuf, pPubKeyBufLen, pPriKeyBuf, pPriKeyBufLen);
+}
+
+int EncWithSM2PubKey(unsigned char* pSource, int nSourceLen, unsigned char* pDest, int* pDestLen, unsigned char* pPubKey, int nKeyLen)
+{
+	return CMBSM2Encrypt(pPubKey, nKeyLen, pSource, nSourceLen, pDest, pDestLen);
+}
+
+int DecWithSM2PriKey(unsigned char* pSource, int nSourceLen, unsigned char* pDest, int* pDestLen, unsigned char* pPriKey, int nKeyLen)
+{
+	return CMBSM2Decrypt(pPriKey, nKeyLen, pSource, nSourceLen, pDest, pDestLen);
+}
+
+int  SM2SignWithSM3(unsigned char* privkey, int privkey_len, unsigned char* msg, int msg_len, unsigned char* signature, int* sig_len)
+{
+	return CMBSM2SignWithSM3(privkey, privkey_len, msg, msg_len, signature, sig_len);
+}
+
+int  SM2VerifyWithSM3(unsigned char* pubkey, int pubkey_len, unsigned char* msg, int msg_len, unsigned char* signature, int sig_len)
+{
+	return CMBSM2VerifyWithSM3(pubkey, pubkey_len, msg, msg_len, signature, sig_len);
+}
+
+
+void GenerateSM4_ECBkey(char *keyStr, int keyStr_len, unsigned char key[16])
+{
+	unsigned char tempKey[32] = { 0 };
+	if (keyStr != NULL)
+	{
+		SM3Hash((unsigned char *)keyStr, keyStr_len > 32 ? 32 : keyStr_len, tempKey);
+		memcpy(key, tempKey, 16);
+	}
+	else
+		memset(key, 0, 16);
+	
+	//Aschex_2_bcdhex(tempKey, 32, key);
+}
+
+
+int EncStrWithSM4_ECB(char *keyStr, int keyStr_len, unsigned char* input, int length, unsigned char* output, int* output_len)
+{
+	unsigned char key[17] = { 0 };
+	GenerateSM4_ECBkey(keyStr, keyStr_len, key);
+	return CMBSM4EncryptWithECB(key, input, length, output, output_len);
+	
+}
+
+int DecStrWithSM4_ECB(char *keyStr, int keyStr_len, unsigned char* input, int length, unsigned char* output, int* output_len)
+{
+	unsigned char key[17] = { 0 };
+	GenerateSM4_ECBkey(keyStr, keyStr_len, key);
+	return CMBSM4DecryptWithECB(key, input, length, output, output_len);
+}
+
+
+int EncWithSM4_ECB(unsigned char key[16], unsigned char* input, int length, unsigned char* output, int* output_len)
+{
+	return CMBSM4EncryptWithECB(key, input, length, output, output_len);
+}
+
+int DecWithSM4_ECB(unsigned char key[16], unsigned char* input, int length, unsigned char* output, int* output_len)
+{
+	return CMBSM4DecryptWithECB(key, input, length, output, output_len);
+}
+
+
+int EncStrWithSM4_CBC(char *keyStr, int keyStr_len, unsigned char iv[16], unsigned char* input, int length, unsigned char* output, int* output_len)
+{
+	unsigned char key[17] = { 0 };
+	GenerateSM4_ECBkey(keyStr, keyStr_len, key);
+	return CMBSM4EncryptWithCBC(key, iv, input, length, output, output_len);
+	
+}
+
+int DecStrWithSM4_CBC(char *keyStr, int keyStr_len, unsigned char iv[16], unsigned char* input, int length, unsigned char* output, int* output_len)
+{
+	unsigned char key[17] = { 0 };
+	GenerateSM4_ECBkey(keyStr, keyStr_len, key);
+	return CMBSM4DecryptWithCBC(key, iv, input, length, output, output_len);
+}
+
+int SM3File(char* file, unsigned char hash[32])
+{
+	return CMBSM3FileDigest(file, hash);
+}

+ 184 - 0
Other/libbizchan/chinaEncrypt.h

@@ -0,0 +1,184 @@
+#ifndef CHINA_ENCRYPT
+#define CHINA_ENCRYPT
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+// 获取SM234的version, 调用打印厂商和版本号
+/*
+	* 功能:获取厂商信息和版本信息
+	* 输入:无
+	* 返回值:
+	* TianDiRong-1.0-x86		天地融32位版本1.0
+	* TianDiRong-1.0-x64		天地融64位版本1.0
+	* KeYou-1.0-x86			科友32位版本1.0
+	* KeYou-1.0-x64			科友64位版本1.0
+
+	*/
+
+char* GetSMVersion();
+
+// 计算SM3的值
+int SM3Hash(unsigned char* pData, int nLen, unsigned char hash[32]);	//替换MD5
+//计算文件的SM3的值
+int SM3File(char* file, unsigned char hash[32]);
+
+/*
+	功能:生成SM2公私钥对
+	输入:
+	pPubKeyBuf : pubkey缓冲区的长度,至少为65字节
+	pPriKeyBuf:	privkey缓冲区的长度,至少为32字节
+	输出:
+	pPubKeyBuf:   	公钥
+	pPubKeyBufLen : 公钥的字节数
+	pPriKeyBuf:		私钥
+	pPriKeyBufLen:	私钥的字节数
+	返回值:
+	*/
+int CreateSM2KeyPair(unsigned char* pPubKeyBuf, int* pPubKeyBufLen, unsigned char* pPriKeyBuf, int* pPriKeyBufLen);
+/*
+	功能:用SM2公钥加密数据。
+	输入:
+	pPubKey: 	公钥
+	nKeyLen:	公钥的字节数
+	pSource:     	要加密的数据
+	nSourceLen:	pSource的字节数
+	pDestLen : pDest缓冲区的长度,必须至少比pSource的长度多97字节
+	输出:
+	pDest : 加密结果
+	pDestLen : 加密结果的字节数
+	返回值:
+	*/
+int EncWithSM2PubKey(unsigned char* pSource, int nSourceLen, unsigned char* pDest, int* pDestLen, unsigned char* pPubKey, int nKeyLen);
+
+	/*
+	功能:用SM2私钥解密数据。
+	输入:
+	pPriKey: 	私钥
+	nKeyLen:	私钥的字节数
+	pSource : 要解密的数据,不少于97字节。
+	nSourceLen:	pSource的字节数
+	pDestLen : pDest缓冲区的长度,至少为nSourceLen ~ 97字节
+	输出:
+	pDest : 解密结果
+	pDestLen : 解密结果的字节数
+	返回值:
+	*/
+int DecWithSM2PriKey(unsigned char* pSource, int nSourceLen, unsigned char* pDest, int* pDestLen, unsigned char* pPriKey, int nKeyLen);
+
+
+/*
+功能:SM2签名,userid默认为“1234567812345678”
+输入:
+privkey: 	私钥
+privkey_len: 私钥的字节数
+msg : 待签名的数据
+msg_len : 待签名的数据长度
+sig_len:		signature缓冲区的长度
+输出:
+signature:  	签名
+sig_len:		signature的长度
+返回值:
+true:		成功
+len:	signature为空时,返回所需的长度
+其他:	待定义
+*/
+int  SM2SignWithSM3(unsigned char* privkey, int privkey_len, unsigned char* msg, int msg_len, unsigned char* signature, int* sig_len);
+
+/*
+	功能:验证SM2签名,userid默认为“1234567812345678”
+	输入:
+	pubkey: 	公钥
+	pubkey _len:	公钥的字节数
+	msg:  		签名数据
+	msg_len:	签名数据的字节数
+	signature:  	签名
+	sig_len:		签名的字节数
+	返回值:
+	true:		成功
+	其他:	待定义
+	*/
+
+int  SM2VerifyWithSM3(unsigned char* pubkey, int pubkey_len, unsigned char* msg, int msg_len, unsigned char* signature, int sig_len);
+
+
+/*
+	* 功能:SM4的ECB加密
+	* 输入:
+	key: 输入keyStr,为字符串
+	input:需要加密的数据
+	length:加密数据的长度
+	output:加密后数据
+	output_len:输入output的最大长度,返回加密 后output的长度
+	* 返回值:
+		是否成功
+	*/
+
+
+
+int EncStrWithSM4_ECB(char *keyStr, int keyStr_len, unsigned char* input, int length, unsigned char* output, int* output_len);
+/*
+	* 功能:SM4的ECB解密
+	* 输入:
+	key: 输入keyStr,为字符串
+	input:需要解密的数据
+	length:解密数据的长度
+	output:解密后数据
+	output_len:输入output的最大长度,返回解密后output的长度
+	* 返回值:
+		是否成功
+	*/
+int DecStrWithSM4_ECB(char *keyStr, int keyStr_len, unsigned char* input, int length, unsigned char* output, int* output_len);
+
+/*
+	* 功能:SM4的ECB加密
+	* 输入:
+	key: 输入16位的密钥,可通过SM3Hash生成
+	* 返回值:
+		是否成功
+	*/
+int EncWithSM4_ECB(unsigned char key[16], unsigned char* input, int length, unsigned char* output, int* output_len);
+/*
+	* 功能:SM4的ECB解密
+	* 输入:
+	key: 输入16位的密钥,可通过SM3Hash生成
+	* 返回值:
+		是否成功
+	*/
+int DecWithSM4_ECB(unsigned char key[16], unsigned char* input, int length, unsigned char* output, int* output_len);
+
+
+/*
+	* 功能:SM4的CBC加密
+	* 输入:
+	key: 输入keyStr,为字符串
+	iv:初始向量
+	input:需要加密的数据
+	length:加密数据的长度
+	output:加密后数据
+	output_len:输入output的最大长度,返回加密 后output的长度
+	* 返回值:
+		是否成功
+	*/
+int EncStrWithSM4_CBC(char *keyStr, int keyStr_len, unsigned char iv[16], unsigned char* input, int length, unsigned char* output, int* output_len);
+
+/*
+	* 功能:SM4的CBC解密
+	* 输入:
+	key: 输入keyStr,为字符串
+	iv:初始向量
+	input:需要解密的数据
+	length:解密数据的长度
+	output:解密后数据
+	output_len:输入output的最大长度,返回解密后output的长度
+	* 返回值:
+		是否成功
+	*/
+int DecStrWithSM4_CBC(char *keyStr, int keyStr_len, unsigned char iv[16], unsigned char* input, int length, unsigned char* output, int* output_len);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif