Exemple #1
0
INT EncodePasswordByUsername(CHAR *username, CHAR *passwordmd5, CHAR *encoded)
{
    BYTE md5[16];
    des3_context ctx3;
    BYTE output[16];
    BYTE pwdmd5[16];
	
    CHAR vn[200];
	
#ifdef _WIN32
	DWORD sn;
	GetVolumeInformation("C:\\", vn, sizeof(vn), &sn, NULL, NULL, NULL, 0);
	snprintf(vn, sizeof(vn), "%s%x", username, sn);
#else
	snprintf(vn, sizeof(vn), "%s", username);
#endif
	
    //MD5Buffer(username, strlen(username), md5);
    MD5Buffer(vn, strlen(vn), md5);
	
    hex2buf(passwordmd5, pwdmd5, NULL);
	
    des3_set_3keys( &ctx3, md5, md5 + 8, md5);
    des3_encrypt( &ctx3, (BYTE *)pwdmd5, output);
	
    des3_set_3keys( &ctx3, md5, md5 + 8, md5);
    des3_encrypt( &ctx3, (BYTE *)pwdmd5 + 8, output + 8);
	
    buf2hex(output, 16, encoded);
	
    return OK;
}
Exemple #2
0
/*****************************************************************************
 函 数 名  : pboc_des3_encrypt
 功能描述  : 以3DES-ECB(EDE)模式加密数据,加密过程如下,
 2. 将第一步中生成的数据块分解成8字节数据块,标号为D1,D2,D3,D4等等。
 最后一个数据块长度有可能不足8位。
 3. 如果最后(或唯一)的数据块长度等于8字节,转入第四步;如果不足8字节,
 在右边添加16进制数字 '80'。如果长度已达8字节,转入第四步;否则,
 在其右边添加1字节16进制数字 '00', 直到长度达到8字节。
 4. 每一个数据块使用8.3.3.1中描述的数据加密方式加密。
 参见"PBOC 2.0 第一部分 卡片规范  8.3 数据可靠性"

 输入参数  : const uint8_t enkey[DOUBLE_KEY_SIZE] 双长度(16字节)加密密钥
 const uint8_t *inbuf 输入明文
 int len 输入明文长度,注意,明文长度不能超过255字节
 输出参数  : uint8_t *outbuf 输出密文
 返 回 值  : int  返回 0
 *****************************************************************************/
int pboc_des3_encrypt(const UINT8 enkey[DOUBLE_KEY_SIZE], const UINT8 *inbuf,
		int len, UINT8 *outbuf) {
	des3_context ctx = { { 0 }, { 0 } };
	UINT8 buf[DES_BLOCK_SIZE] = { 0 };
	UINT8 *pdata;

	/* compute length of encrypted data */
	int enclen = (len + 1 + (DES_BLOCK_SIZE - 1)) & (~7);

	des3_set_2keys(&ctx, (UINT8 *) enkey, (UINT8 *) (enkey + DES_KEY_SIZE));

#if 0 /* use in pin encrpty */
	/* encrypt the 1st block, prepad length UINT8 before data */
	buf[0] = (UINT8)len;
	if(len < DES_BLOCK_SIZE - 1)
	{
		memcpy(buf + 1, (void *)inbuf, len);
		buf[len + 1] = 0x80;
	}
	else
	{
		memcpy(buf + 1, (void *)inbuf, DES_BLOCK_SIZE - 1);
	}
#endif
	if (len < DES_BLOCK_SIZE - 1) {
		memcpy(buf, (void *) inbuf, len);
		buf[len] = 0x80;
	} else {
		memcpy(buf, (void *) inbuf, DES_BLOCK_SIZE);
	}

	des3_encrypt(&ctx, buf, outbuf);

	/* encrypt remaining blocks except the last one */
	len -= DES_BLOCK_SIZE - 1;
	pdata = (UINT8 *) inbuf + DES_BLOCK_SIZE - 1;
	outbuf += DES_BLOCK_SIZE;

	while (len >= DES_BLOCK_SIZE) {
		des3_encrypt(&ctx, pdata, outbuf);

		len -= DES_BLOCK_SIZE;
		pdata += DES_BLOCK_SIZE;
		outbuf += DES_BLOCK_SIZE;
	}

	/* encrypt the last block, padding it with '80 00 ...'
	 requested by PBOC STD. */
	if (len > 0) {
		memset(buf, 0, DES_BLOCK_SIZE);
		memcpy(buf, pdata, len);
		buf[len] = 0x80;
		des3_encrypt(&ctx, buf, outbuf);
	}

	memset(&ctx, 0, sizeof(des3_context));
	return enclen;
}
int ikev2_encr_encrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,
		       const u8 *plain, u8 *crypt, size_t len)
{
	struct crypto_cipher *cipher;
	int encr_alg;

#ifdef CCNS_PL
	if (alg == ENCR_3DES) {
		struct des3_key_s des3key;
		size_t i, blocks;
		u8 *pos;

		/* ECB mode is used incorrectly for 3DES!? */
		if (key_len != 24) {
			wpa_printf(MSG_INFO, "IKEV2: Invalid encr key length");
			return -1;
		}
		des3_key_setup(key, &des3key);

		blocks = len / 8;
		pos = crypt;
		for (i = 0; i < blocks; i++) {
			des3_encrypt(pos, &des3key, pos);
			pos += 8;
		}
	} else {
#endif /* CCNS_PL */
	switch (alg) {
	case ENCR_3DES:
		encr_alg = CRYPTO_CIPHER_ALG_3DES;
		break;
	case ENCR_AES_CBC:
		encr_alg = CRYPTO_CIPHER_ALG_AES;
		break;
	default:
		wpa_printf(MSG_DEBUG, "IKEV2: Unsupported encr alg %d", alg);
		return -1;
	}

	cipher = crypto_cipher_init(encr_alg, iv, key, key_len);
	if (cipher == NULL) {
		wpa_printf(MSG_INFO, "IKEV2: Failed to initialize cipher");
		return -1;
	}

	if (crypto_cipher_encrypt(cipher, plain, crypt, len) < 0) {
		wpa_printf(MSG_INFO, "IKEV2: Encryption failed");
		crypto_cipher_deinit(cipher);
		return -1;
	}
	crypto_cipher_deinit(cipher);
#ifdef CCNS_PL
	}
#endif /* CCNS_PL */

	return 0;
}
Exemple #4
0
// 对数据包进行加密和压缩
char *pkg_compress_encrypt(const packet_parser_t *pkg, const char *source, int source_len, int *cipher_body_len)
{
	char *encrypt_string;
	char *compress_string = NULL;
	uLongf compress_dest_len;

	if (source_len < 0)
	{
		source_len = strlen(source);
	}
	
	// 先对数据源进行压缩
	if (pkg->compress_hook == NULL)
	{
		zlib_compress((unsigned char **)(&compress_string), &compress_dest_len, (unsigned char *)source, source_len, 0, COMPRESS_TYPE);
	}
	else
	{
		pkg->compress_hook((unsigned char **)(&compress_string), &compress_dest_len, (unsigned char *)source, source_len, 0, COMPRESS_TYPE);
	}

	printf("source len:%d\tcompress len:%ld\n", source_len, compress_dest_len);
	// 再对数据进行加密
	if (strcmp(pkg->curr_ert.transfer_ert_type, ENCRYPT_AES_128) == 0)
	{
		if (pkg->sym_encrypt_hook == NULL)
		{
			encrypt_string = (char *)aes_encrypt((unsigned char *)compress_string, compress_dest_len, cipher_body_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_ENCRYPT);
		}
		else
		{
			encrypt_string = (char *)aes_encrypt((unsigned char *)compress_string, compress_dest_len, cipher_body_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_ENCRYPT);
		}
	}
	else if (strcmp(pkg->curr_ert.transfer_ert_type, ENCRYPT_DES3_128) == 0)
	{
		if (pkg->sym_encrypt_hook == NULL)
		{
			encrypt_string = (char *)des3_encrypt((unsigned char *)compress_string, compress_dest_len, cipher_body_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_ENCRYPT);
		}
		else
		{
			encrypt_string = (char *)pkg->sym_encrypt_hook((unsigned char *)compress_string, compress_dest_len, cipher_body_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_ENCRYPT);
		}
	}

	if (compress_string)
	{
		free(compress_string);
	}

	return encrypt_string;
}
Exemple #5
0
int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
                          u8 *crypt, size_t len)
{
    size_t i, j, blocks;

    switch (ctx->alg) {
    case CRYPTO_CIPHER_ALG_RC4:
        if (plain != crypt)
            os_memcpy(crypt, plain, len);
        rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
                 ctx->u.rc4.used_bytes, crypt, len);
        ctx->u.rc4.used_bytes += len;
        break;
    case CRYPTO_CIPHER_ALG_AES:
        if (len % ctx->u.aes.block_size)
            return -1;
        blocks = len / ctx->u.aes.block_size;
        for (i = 0; i < blocks; i++) {
            for (j = 0; j < ctx->u.aes.block_size; j++)
                ctx->u.aes.cbc[j] ^= plain[j];
            aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
                        ctx->u.aes.cbc);
            os_memcpy(crypt, ctx->u.aes.cbc,
                      ctx->u.aes.block_size);
            plain += ctx->u.aes.block_size;
            crypt += ctx->u.aes.block_size;
        }
        break;
    case CRYPTO_CIPHER_ALG_3DES:
        if (len % 8)
            return -1;
        blocks = len / 8;
        for (i = 0; i < blocks; i++) {
            for (j = 0; j < 8; j++)
                ctx->u.des3.cbc[j] ^= plain[j];
            des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
                         ctx->u.des3.cbc);
            os_memcpy(crypt, ctx->u.des3.cbc, 8);
            plain += 8;
            crypt += 8;
        }
        break;
    default:
        return -1;
    }

    return 0;
}
Exemple #6
0
char *pkg_uncompress_decrypt(const packet_parser_t *pkg, const char *source, int source_len, int plain_body_len)
{
	char *encrypt_string;
	char *compress_string = NULL;
	int decrypt_dest_len;
	uLongf uncompress_dest_len;

	// 先对数据源进行解密
		if (strcmp(pkg->curr_ert.transfer_ert_type, ENCRYPT_AES_128) == 0)
		{
			if (pkg->sym_encrypt_hook == NULL)
			{
				encrypt_string = (char *)aes_encrypt((unsigned char *)source, source_len, &decrypt_dest_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_DECRYPT);
			}
			else
			{
				encrypt_string = (char *)pkg->sym_encrypt_hook((unsigned char *)source, source_len, &decrypt_dest_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_DECRYPT);
			}
		}
		else if (strcmp(pkg->curr_ert.transfer_ert_type, ENCRYPT_DES3_128) == 0)
		{
			if (pkg->sym_encrypt_hook == NULL)
			{
				encrypt_string = (char *)des3_encrypt((unsigned char *)source, source_len, &decrypt_dest_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_DECRYPT);
			}
			else
			{
				encrypt_string = (char *)pkg->sym_encrypt_hook((unsigned char *)source, source_len, &decrypt_dest_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_DECRYPT);
			}
		}
	// 再对数据进行解压缩
	if (pkg->compress_hook == NULL)
	{
		zlib_compress((unsigned char **)(&compress_string), &uncompress_dest_len, (unsigned char *)encrypt_string, decrypt_dest_len, plain_body_len, UNCOMPRESS_TYPE);
	}
	else
	{
		pkg->compress_hook((unsigned char **)(&compress_string), &uncompress_dest_len, (unsigned char *)encrypt_string, decrypt_dest_len, plain_body_len, UNCOMPRESS_TYPE);
	}

	if (encrypt_string)
	{
		free(encrypt_string);
	}

	return compress_string;
}
// 握奇外部认证使用8字节随机数
int ks_zjvcc_cardtype::ExecExtAuthCmd8(byte ucExtAuthKey[16],int nKeyIndex) {
    byte ucRandom[9]= {0};

    int nRet=GetRandomNum8(ucRandom);
    if(nRet)
        return nRet;

    des3_context ctx3;
    des3_set_2keys( &ctx3, ucExtAuthKey,ucExtAuthKey+8);
    byte ucBuff[64]= {0};
    des3_encrypt(&ctx3,ucRandom,ucBuff);

    byte ucSendData[256]= {0};
    memcpy(ucSendData,"\x00\x82\x00\x00\x08",5);
    ucSendData[3]=nKeyIndex;
    memcpy(ucSendData+5,ucBuff,8);

    byte ucRespData[256]= {0};
    byte ucRespLen = 0;

    return Adpu(ucSendData,0x0D, ucRespData, ucRespLen);
}
int  fast_crypto_cipher_encrypt(struct crypto_cipher *ctx, const uint8_t *plain,
			  uint8_t *crypt, size_t len)
{
    size_t i, j, blocks;
    struct fast_crypto_cipher *fast_ctx;

    fast_ctx = (struct fast_crypto_cipher *)ctx;

    switch (fast_ctx->alg) {
        case CRYPTO_CIPHER_ALG_RC4:
            if (plain != crypt) {
                os_memcpy(crypt, plain, len);
            }  
            rc4_skip(fast_ctx->u.rc4.key, fast_ctx->u.rc4.keylen,
            fast_ctx->u.rc4.used_bytes, crypt, len);
            fast_ctx->u.rc4.used_bytes += len;
            break;
        case CRYPTO_CIPHER_ALG_AES:
            if (len % AES_BLOCK_SIZE) {
                return -1;
            }
            blocks = len / AES_BLOCK_SIZE;
            for (i = 0; i < blocks; i++) {
                for (j = 0; j < AES_BLOCK_SIZE; j++)
                    fast_ctx->u.aes.cbc[j] ^= plain[j];
                mbedtls_aes_encrypt(&(fast_ctx->u.aes.ctx_enc), fast_ctx->u.aes.cbc, fast_ctx->u.aes.cbc);
                os_memcpy(crypt, fast_ctx->u.aes.cbc, AES_BLOCK_SIZE);
                plain += AES_BLOCK_SIZE;
                crypt += AES_BLOCK_SIZE;
            }
            break;
#ifdef CONFIG_DES3
        case CRYPTO_CIPHER_ALG_3DES:
            if (len % 8) {
                return -1;
            }
            blocks = len / 8;
            for (i = 0; i < blocks; i++) {
                for (j = 0; j < 8; j++)
	            fast_ctx->u.des3.cbc[j] ^= plain[j];
                des3_encrypt(fast_ctx->u.des3.cbc, &fast_ctx->u.des3.key,
	                     fast_ctx->u.des3.cbc);
                os_memcpy(crypt, fast_ctx->u.des3.cbc, 8);
                plain += 8;
                crypt += 8;
            }
            break;
#endif
#ifdef CONFIG_DES
        case CRYPTO_CIPHER_ALG_DES:
            if (len % 8) {
                return -1;
            }
            blocks = len / 8;
            for (i = 0; i < blocks; i++) {
                for (j = 0; j < 8; j++)
	            fast_ctx->u.des3.cbc[j] ^= plain[j];
                des_block_encrypt(fast_ctx->u.des.cbc, fast_ctx->u.des.ek,
		                  fast_ctx->u.des.cbc);
                os_memcpy(crypt, fast_ctx->u.des.cbc, 8);
                plain += 8;
                crypt += 8;
            }
            break;
#endif
        default:
            return -1;
    }

    return 0;
}
Exemple #9
0
static int tunet_logon_recv_remaining_data()
{
	BYTE tmpbuf[1024 * 8];
	CHAR tmp[1024];

	CHAR sztmp[255];

	BYTE *p;
	INT len;
	BYTE key77[8];
	
	STRING *str = NULL;
	char des3data[12];
	des3_context ctx3;
	TIME tm;


	UINT32 datalen, port;
	UINT32 uint_money;
	BYTE btag;


//	BOOL sr, sw, se;
	
	if(!main_socket) return OK;
//	printf("tunet_logon_recv_remaining_data() called.\n");
//	os_socket_tcp_status(main_socket, &sr, &sw, &se);


	if(tunet_state != TUNET_STATE_RECV_REMAINING_DATA && tunet_state != TUNET_STATE_KEEPALIVE)
		return OK;

/*

	if(se)
	{
		logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_REMAINING_DATA", NULL, 0);
		return ERR;
	}

	if(!sr) return OK;
*/


	len = os_socket_tcp_recv(main_socket, tmpbuf, sizeof(tmpbuf));
	if(len == -1)
	{
		logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_REMAINING_DATA", NULL, 0);
		return ERR;
	}


	if(len > 0)
	{
		main_socket_buffer = buffer_append(main_socket_buffer, tmpbuf, len);
		logs_append(g_logs, "TUNET_LOGON_RECV", "REMAINING", tmpbuf, len);

		buf2output(tmpbuf, len, tmp, 16);
		//dprintf("data received(recv remaining):\n%s\n", tmp);

		

		p = main_socket_buffer->data;
		while(buffer_fetch_BYTE(main_socket_buffer, &p, &btag))
		{
			switch(btag)
			{
				case 0x01:
					if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen))
						return OK;

					datalen = htonl(datalen);

					memset(keepalive_server, 0, sizeof(keepalive_server));
					if(!buffer_fetch_bytes(main_socket_buffer, &p, (BYTE *)keepalive_server, datalen))
						return OK;

					if(!buffer_fetch_DWORD(main_socket_buffer, &p, &port))
						return OK;

					port = htonl(port);
					keepalive_server_port = (short)port;

					snprintf(sztmp, sizeof(sztmp), "%s:%d", keepalive_server, keepalive_server_port);
					//dprintf("保持活动服务器:%s\n", sztmp);



					//we got the KEEPALIVE server, try to keep alive
					os_tick_clear(keepalive_timeout);
					tunet_state = TUNET_STATE_KEEPALIVE;

					logs_append(g_logs, "TUNET_LOGON_KEEPALIVE_SERVER", sztmp, NULL, 0);

					main_socket_buffer = buffer_rollto(main_socket_buffer, p);
					p = main_socket_buffer->data;

					break;
				case 0x02:
					//出错消息
					if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen))
						return OK;
					datalen = htonl(datalen);

					//dprintf("出错消息长 %d\n", datalen);

					if(!buffer_fetch_STRING(main_socket_buffer, &p, &str, datalen))
						return OK;

					//dprintf("%s\n", str->str);


					tunet_state = TUNET_STATE_ERROR;

					logs_append(g_logs, "TUNET_LOGON_ERROR", str->str, NULL, 0);

					str = string_free(str);

					main_socket_buffer = buffer_rollto(main_socket_buffer, p);
					p = main_socket_buffer->data;

					

					break;
				case 0x05:
					if(buffer_fetch_BYTE(main_socket_buffer, &p, &btag))
					{
						if(btag != 0)
						{
							//dprintf("与消息中介服务器通信结束。\n");
							main_socket = os_socket_tcp_close(main_socket);

							logs_append(g_logs, "TUNET_LOGON_FINISH_MSGSERVER", NULL, NULL, 0);

							main_socket_buffer = buffer_rollto(main_socket_buffer, p);
							p = main_socket_buffer->data;
							
							break;
						}
					}

					BUF_ROLL(p, -1);  //restore the point for further use


					//出错消息
					if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen))
						return OK;
					datalen = htonl(datalen);

					//dprintf("出错消息长 %d\n", datalen);

					if(!buffer_fetch_STRING(main_socket_buffer, &p, &str, datalen))
						return OK;

					//dprintf("%s\n", str->str);
					
					tunet_state = TUNET_STATE_ERROR;

					logs_append(g_logs, "TUNET_LOGON_ERROR", str->str, NULL, 0);

					str = string_free(str);

					main_socket_buffer = buffer_rollto(main_socket_buffer, p);
					p = main_socket_buffer->data;

					
					break;
					
				case 0x04:
				case 0x08:
					if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen))
						return OK;

					datalen = htonl(datalen);

					memset(msg_server, 0, sizeof(msg_server));
					if(!buffer_fetch_bytes(main_socket_buffer, &p, (BYTE *)msg_server, datalen))
						return OK;

					if(!buffer_fetch_DWORD(main_socket_buffer, &p, &port))
						return OK;

					port = htonl(port);

					msg_server_port = (short)port;

					if(!buffer_fetch_bytes(main_socket_buffer, &p, key77, 8))
						return OK;

					//登陆消息
					if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen))
						return OK;
					datalen = htonl(datalen);

					//dprintf("登陆消息长 %d\n", datalen);

					if(!buffer_fetch_STRING(main_socket_buffer, &p, &str, datalen))
						return OK;
					//dprintf("%s\n", str->str);

					logs_append(g_logs, "TUNET_LOGON_MSG", str->str, NULL, 0);

					str = string_free(str);


					//make a new key for keep-alive
					//dprintf("key77 == %s\n", buf2hex(key77, 8, tmp));
					memset(des3data, 0, sizeof(des3data));
					des3_set_3keys( &ctx3, userconfig.md5Password,
										   userconfig.md5Password + 8,
										   userconfig.md5Password );

					des3_encrypt( &ctx3, (uint8 *)key77, (uint8 *)des3data);

					memcpy(keepalive_key, des3data, 8);


					main_socket_buffer = buffer_rollto(main_socket_buffer, p);
					p = main_socket_buffer->data;

					//--------------------------------
					snprintf(sztmp, sizeof(sztmp), "%s:%d", msg_server, msg_server_port);

					//dprintf("准备连接到消息中介服务器 %s 获得活动服务器地址....\n", sztmp);

					logs_append(g_logs, "TUNET_LOGON_MSGSERVER", sztmp, NULL, 0);

					main_socket_buffer = buffer_rollto(main_socket_buffer, p);
					p = main_socket_buffer->data;

					//switch to another server to get alive-server ip
					strcpy(keepalive_server, "");
					main_socket = os_socket_tcp_close(main_socket);
					main_socket = os_socket_tcp_connect(msg_server, msg_server_port, FALSE);

					break;
				case 0x1b:
					if(!buffer_fetch_DWORD(main_socket_buffer, &p, &uint_money))
						return OK;

					uint_money = htonl(uint_money);
					snprintf(sztmp, sizeof(sztmp), "%0.2f", tunet_imoney_to_fmoney(uint_money));
					//dprintf("您在登陆前的余额是:%s\n", sztmp);

					logs_append(g_logs, "TUNET_LOGON_MONEY", sztmp, NULL, 0);

					if(buffer_has_data(main_socket_buffer, p, 16))
					{
						snprintf(sztmp, sizeof(sztmp), "%d.%d.%d.%d/%d.%d.%d.%d", p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);
						logs_append(g_logs, "TUNET_LOGON_IPs", sztmp, NULL, 0);
						//dprintf("登陆IP状况: %s\n", sztmp);
						BUF_ROLL(p, 8);

						
						tm = os_time_convert(htonl(BUFDWORD(p)));
						snprintf(sztmp, sizeof(sztmp), "%d-%d-%d %d:%d:%d", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second );
						logs_append(g_logs, "TUNET_LOGON_SERVERTIME", sztmp, NULL, 0);
						//dprintf("当前服务器时间: %s\n", sztmp);
						BUF_ROLL(p, 4);

						tm = os_time_convert(htonl(BUFDWORD(p)));
						snprintf(sztmp, sizeof(sztmp), "%d-%d-%d %d:%d:%d", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second );
						logs_append(g_logs, "TUNET_LOGON_LASTTIME", sztmp, NULL, 0);
						//dprintf("上次登陆时间: %s\n", sztmp);
						BUF_ROLL(p, 4);
					}
					else
					{
						return OK;
					}

					main_socket_buffer = buffer_rollto(main_socket_buffer, p);
					p = main_socket_buffer->data;

					break;
			}
		}

	}

	return OK;

}
Exemple #10
0
static int tunet_logon_reply_welcome()
{
	BUFFER *buf;

	BYTE des3data[12];
	des3_context ctx3;

	UINT32 limitation;


//	BOOL sr, sw, se;
	
	if(!main_socket) return OK;
	
//	os_socket_tcp_status(main_socket, &sr, &sw, &se);

	if(tunet_state != TUNET_STATE_REPLY_WELCOME) 
		return OK;


/*	if(se)
	{
		logs_append(g_logs, "TUNET_NETWORK_ERROR", "REPLY_WELCOME", NULL, 0);
		return ERR;
	}

	if(!sw) return OK;

*/
	memset(des3data, 0, sizeof(des3data));

    des3_set_3keys( &ctx3, userconfig.md5Password,
                           userconfig.md5Password + 8,
                           userconfig.md5Password );


	des3_encrypt( &ctx3, (uint8 *)welcome_data, (uint8 *)des3data);



	buf = buffer_new(100);
	buf = buffer_append(buf, (BYTE *)"\x03", 1);
	buf = buffer_append(buf, userconfig.md5Username, 16);
	buf = buffer_append(buf, des3data, 8);


	limitation = htonl(userconfig.limitation);
	buf = buffer_append(buf, (BYTE *)&limitation, 4);

	os_socket_tcp_send(main_socket, buf->data, buf->len);

	

	tunet_state = TUNET_STATE_RECV_REMAINING_DATA;

	logs_append(g_logs, "TUNET_LOGON_REPLY_WELCOME", NULL, buf->data, buf->len);

	//dprintf("%s\n", "已经应答welcome的数据包。准备接受剩余数据...");

	buf = buffer_free(buf);

	return OK;

}
// Implementation
static boolean verify_authentication_request(BIO *bio_client, char *username_ret, boolean *is_admin_flag_ret, char *key_exchange_passwd_ret)
{
	boolean   verification_flag;

	MYSQL     *db_conn = NULL;
  	MYSQL_RES *result  = NULL;
  	MYSQL_ROW row;
	char      stat[SQL_STATEMENT_LENGTH + 1];
	char	  err_msg[ERR_MSG_LENGTH + 1];

	char      token_name[TOKEN_NAME_LENGTH + 1];
	char      is_admin_flag_str_tmp[FLAG_LENGTH + 1];   // "0" or "1"
	char      passwd[PASSWD_LENGTH + 1];
	char      salted_passwd_hash_cmp[SHA1_DIGEST_LENGTH + 1];
	char      salted_passwd_hash[SHA1_DIGEST_LENGTH + 1];
	char      salt_value[SALT_VALUE_LENGTH + 1];
	char      passwd_with_salt_value[PASSWD_LENGTH + SALT_VALUE_LENGTH + 1];

	// Receive the verification information
	if(!BIO_recv_file(bio_client, VERIFICATION_INFO_CIPHERTEXT_PATH))
	{
		fprintf(stderr, "Receiving verification information failed\n");
		goto ERROR;
	}

	// Decrypt the verification information with the User Authority's private key
	if(!smime_decrypt_with_cert(VERIFICATION_INFO_CIPHERTEXT_PATH, VERIFICATION_INFO_PLAINTEXT_PATH, UA_CERTFILE_PATH, UA_CERTFILE_PASSWD, err_msg))
	{
		fprintf(stderr, "Decrypting verification information failed\n\"%s\"\n", err_msg);
		goto ERROR;
	}

	unlink(VERIFICATION_INFO_CIPHERTEXT_PATH);

	// Get the verification information from file
	if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 1, token_name, is_admin_flag_str_tmp) != READ_TOKEN_SUCCESS || strcmp(token_name, "is_admin_flag") != 0)
	{
		int_error("Extracting the is_admin_flag failed");
	}

	*is_admin_flag_ret = (strcmp(is_admin_flag_str_tmp, "1") == 0) ? true : false; 

	if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 2, token_name, username_ret) != READ_TOKEN_SUCCESS || strcmp(token_name, "username") != 0)
	{
		int_error("Extracting the username failed");
	}

	if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 3, token_name, passwd) != READ_TOKEN_SUCCESS || strcmp(token_name, "passwd") != 0)
	{
		int_error("Extracting the passwd failed");
	}

	if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 4, token_name, key_exchange_passwd_ret) 
		!= READ_TOKEN_SUCCESS || strcmp(token_name, "key_exchange_passwd") != 0)
	{
		int_error("Extracting the key_exchange_passwd failed");
	}

	unlink(VERIFICATION_INFO_PLAINTEXT_PATH);

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Verify the user
	sprintf(stat, "SELECT salted_passwd_hash, salt_value FROM %s WHERE username LIKE '%s' "
		"COLLATE latin1_general_cs", (*is_admin_flag_ret) ? UA__ADMINS : UA__USERS, username_ret);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
  	row = mysql_fetch_row(result);

	if(row)
	{
		strcpy(salted_passwd_hash_cmp, row[0]);
		strcpy(salt_value, row[1]);

		// Get the salted password hash
		sprintf(passwd_with_salt_value, "%s%s", passwd, salt_value);
		sum_sha1_from_string(passwd_with_salt_value, strlen(passwd_with_salt_value), salted_passwd_hash, SALTED_PASSWD_HASH_PATH);

		if(strcmp(salted_passwd_hash, salted_passwd_hash_cmp) == 0)   // Authentication succeed
		{
			verification_flag = true;
			if(!write_token_into_file("verification_result_flag", "1", true, VERIFICATION_RESULT_PLAINTEXT_PATH))
				int_error("Writing the verification_result_flag failed");
		}
		else   // Authentication failed
		{
			verification_flag = false;
			if(!write_token_into_file("verification_result_flag", "0", true, VERIFICATION_RESULT_PLAINTEXT_PATH))
				int_error("Writing the verification_result_flag failed");

			if(!write_token_into_file("error_msg", "Invalid username or password", false, VERIFICATION_RESULT_PLAINTEXT_PATH))
				int_error("Writing the error_msg failed");
		}
	}
	else      // Authentication failed
	{
		verification_flag = false;
		if(!write_token_into_file("verification_result_flag", "0", true, VERIFICATION_RESULT_PLAINTEXT_PATH))
			int_error("Writing the verification_result_flag failed");

		if(!write_token_into_file("error_msg", "Invalid username or password", false, VERIFICATION_RESULT_PLAINTEXT_PATH))
				int_error("Writing the error_msg failed");
	}

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}
	disconnect_db(&db_conn);

	// Encrypt the verification result with random session password
	if(!des3_encrypt(VERIFICATION_RESULT_PLAINTEXT_PATH, VERIFICATION_RESULT_CIPHERTEXT_PATH, key_exchange_passwd_ret, err_msg))
	{
		fprintf(stderr, "Encrypting the verification result failed\n\"%s\"\n", err_msg);
		goto ERROR;
	}

	unlink(VERIFICATION_RESULT_PLAINTEXT_PATH);

	// Send the verification result
	if(!BIO_send_file(bio_client, VERIFICATION_RESULT_CIPHERTEXT_PATH))
	{
		fprintf(stderr, "Sending the verification result failed");
		goto ERROR;
	}

	unlink(VERIFICATION_RESULT_CIPHERTEXT_PATH);
	return verification_flag;

ERROR:
	unlink(VERIFICATION_INFO_CIPHERTEXT_PATH);
	unlink(VERIFICATION_INFO_PLAINTEXT_PATH);
	unlink(VERIFICATION_RESULT_PLAINTEXT_PATH);
	unlink(VERIFICATION_RESULT_CIPHERTEXT_PATH);
	return false;
}
static boolean ssl_cert_response(BIO *bio_client, char *username, boolean is_admin_flag, char *key_exchange_passwd)
{
	char          *ssl_cert_data = NULL;
	unsigned long ssl_cert_data_length;
	char          ssl_cert_hash[SHA1_DIGEST_LENGTH + 1];

	MYSQL         *db_conn = NULL;
  	MYSQL_RES     *result  = NULL;
  	MYSQL_ROW     row;
	char          stat[SQL_STATEMENT_LENGTH + 1];
	char	      err_msg[ERR_MSG_LENGTH + 1];
	unsigned long *lengths = NULL;

	ssl_cert_data = (char *)malloc(sizeof(char)*1000*1024);
	if(!ssl_cert_data)
	{
		int_error("Allocating memory for \"ssl_cert_data\" failed");
	}

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query the user's SSL certificate and write it to buffer
	sprintf(stat, "SELECT enc_ssl_cert, enc_ssl_cert_hash FROM %s WHERE username LIKE '%s' "
		"COLLATE latin1_general_cs", (is_admin_flag) ? UA__ADMINS : UA__USERS, username);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
  	row = mysql_fetch_row(result);
	if(!row)
		int_error("Getting an SSL certificate from the database failed");

	lengths = mysql_fetch_lengths(result);
	ssl_cert_data_length = lengths[0];

	memcpy(ssl_cert_data, row[0], ssl_cert_data_length);
	strcpy(ssl_cert_hash, row[1]);

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}
	disconnect_db(&db_conn);

	// Write the SSL ceertificate to file and encrypt it with random session password before sending it to the user
	if(!write_bin_file(SSL_CERT_PLAINTEXT_PATH, "wb", ssl_cert_data, ssl_cert_data_length))
	{
		fprintf(stderr, "Writing the SSL certificate hash failed");
		goto ERROR;
	}

	if(!des3_encrypt(SSL_CERT_PLAINTEXT_PATH, SSL_CERT_CIPHERTEXT_PATH, key_exchange_passwd, err_msg))
	{
		fprintf(stderr, "Decrypting the SSL certificate failed\n\"%s\"\n", err_msg);
		goto ERROR;
	}

	unlink(SSL_CERT_PLAINTEXT_PATH);

	// Send the user's SSL certificate
	if(!BIO_send_file(bio_client, SSL_CERT_CIPHERTEXT_PATH))
	{
		fprintf(stderr, "Sending the SSL certificate failed\n");
		goto ERROR;
	}

	unlink(SSL_CERT_CIPHERTEXT_PATH);

	// Write hash value to file and encrypt it with random session password before sending it to the user
	if(!write_bin_file(SSL_CERT_HASH_PLAINTEXT_PATH, "wb", ssl_cert_hash, SHA1_DIGEST_LENGTH))
	{
		fprintf(stderr, "Writing the SSL certificate hash failed");
		goto ERROR;
	}

	if(!des3_encrypt(SSL_CERT_HASH_PLAINTEXT_PATH, SSL_CERT_HASH_CIPHERTEXT_PATH, key_exchange_passwd, err_msg))
	{
		fprintf(stderr, "Decrypting the SSL certificate hash failed\n\"%s\"\n", err_msg);
		goto ERROR;
	}

	unlink(SSL_CERT_HASH_PLAINTEXT_PATH);

	// Send the user's SSL certificate hash
	if(!BIO_send_file(bio_client, SSL_CERT_HASH_CIPHERTEXT_PATH))
	{
		fprintf(stderr, "Sending the SSL certificate hash failed\n");
		goto ERROR;
	}

	unlink(SSL_CERT_HASH_CIPHERTEXT_PATH);

	if(ssl_cert_data)
	{
		free(ssl_cert_data);
		ssl_cert_data = NULL;
	}

	return true;

ERROR:
	unlink(SSL_CERT_PLAINTEXT_PATH);
	unlink(SSL_CERT_CIPHERTEXT_PATH);
	unlink(SSL_CERT_HASH_PLAINTEXT_PATH);
	unlink(SSL_CERT_HASH_CIPHERTEXT_PATH);

	if(ssl_cert_data)
	{
		free(ssl_cert_data);
		ssl_cert_data = NULL;
	}

	return false;
}