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; }
/***************************************************************************** 函 数 名 : 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; }
// 对数据包进行加密和压缩 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; }
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; }
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; }
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; }
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; }