From e518634374dd5877cd444fe9858a43b21afa2db6 Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Thu, 14 Dec 2023 14:49:49 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9Aabe=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + devapi/CMakeLists.txt | 3 +- devapi/abe/CMakeLists.txt | 7 + devapi/abe/abe_crypto.cc | 319 ++++++++++++++++++++++++++++++ devapi/abe/base64.cc | 103 ++++++++++ devapi/abe/rewrite.cc | 118 +++++++++++ include/mysqlx/CMakeLists.txt | 1 + include/mysqlx/abe/CMakeLists.txt | 7 + include/mysqlx/abe/abe_crypto.h | 64 ++++++ include/mysqlx/abe/base64.h | 144 ++++++++++++++ include/mysqlx/abe/rewrite.h | 139 +++++++++++++ 11 files changed, 905 insertions(+), 1 deletion(-) create mode 100644 devapi/abe/CMakeLists.txt create mode 100644 devapi/abe/abe_crypto.cc create mode 100644 devapi/abe/base64.cc create mode 100644 devapi/abe/rewrite.cc create mode 100644 include/mysqlx/abe/CMakeLists.txt create mode 100644 include/mysqlx/abe/abe_crypto.h create mode 100644 include/mysqlx/abe/base64.h create mode 100644 include/mysqlx/abe/rewrite.h diff --git a/.gitignore b/.gitignore index 30c6ad467..4c70919b2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /CMakeSettings.json .vs out +build diff --git a/devapi/CMakeLists.txt b/devapi/CMakeLists.txt index 14d6a3e31..ee8f374f5 100644 --- a/devapi/CMakeLists.txt +++ b/devapi/CMakeLists.txt @@ -39,8 +39,9 @@ add_library(devapi STATIC crud.cc ${HEADERS} ) +add_subdirectory(abe) -target_link_libraries(devapi PUBLIC common) +target_link_libraries(devapi PUBLIC common abe) add_coverage(devapi) diff --git a/devapi/abe/CMakeLists.txt b/devapi/abe/CMakeLists.txt new file mode 100644 index 000000000..a32f58812 --- /dev/null +++ b/devapi/abe/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(abe STATIC + base64.cc + abe_crypto.cc + rewrite.cc +) +target_include_directories(abe PUBLIC /usr/local/lib /usr/lib/x86_64-linux-gnu) +target_link_libraries(abe PUBLIC mysqlclient crypto relic relic_ec openabe) \ No newline at end of file diff --git a/devapi/abe/abe_crypto.cc b/devapi/abe/abe_crypto.cc new file mode 100644 index 000000000..b7b39ecfb --- /dev/null +++ b/devapi/abe/abe_crypto.cc @@ -0,0 +1,319 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "openssl/crypto.h" +#include "mysqlx/abe/abe_crypto.h" +#include "mysqlx/abe/base64.h" + + +bool abe_crypto::encrypt(string pt, string policy, string &ct){ + + InitializeOpenABE(); + OpenABECryptoContext cpabe("CP-ABE"); + cpabe.importPublicParams(mpk); + cpabe.encrypt(policy.c_str(), pt, ct); + ShutdownOpenABE(); + +// std::cout<<"encrypt succefully!"<>user.user_key; + ifs_key.close(); + return true; +} + +bool abe_crypto::save_user_key(string key_path, string key_str_b64){ + string pt; + + //key_str为base64编码 + size_t key_str_b64_length = key_str_b64.length(); + char * key_str = (char*)malloc(base64_utils::b64_dec_len(key_str_b64_length)); + size_t key_str_length = base64_utils::b64_decode(key_str_b64.c_str(), key_str_b64_length, (char*)key_str); + // base64_utils::b64_decode(key_str_b64.c_str(), key_str_b64_length, (char*)key_str); + + string ct(key_str,key_str_length); + if(!rsa_decrypt(ct, pt)){ + free(key_str); + ABE_ERROR("failed to decrypt abe user key"); + return false; + } + free(key_str); + + if(user.user_key != ""){ + string decide = ""; + std::cout << "You already have abe key, do you want to update it?(Y/n)"; + if(!std::getline(std::cin, decide) || (decide != "y" && decide != "Y" && decide != "")){ + return false; + } + } + //写入abe_user_key + std::ofstream ofs_key(key_path, std::ios::out); + if(!ofs_key){ + ABE_ERROR2("error opening user key-file.\nkey_path=" , key_path); + return false; + } + ofs_key << pt; + user.user_key = pt; + ofs_key.close(); + return true; +} + +bool abe_crypto::import_sk(string rsa_sk_path){ + // 导入rsa密钥文件并读取密钥 + FILE *hPriKeyFile = fopen(rsa_sk_path.c_str(), "rb"); + if (hPriKeyFile == NULL) + { + // assert(false); + return false; + } + std::string strRet; + RSA *pRSAPriKey = RSA_new(); + if (PEM_read_RSAPrivateKey(hPriKeyFile, &pRSAPriKey, 0, 0) == NULL) + { // 密钥读取失败 + // assert(false); + RSA_free(pRSAPriKey); + fclose(hPriKeyFile); + return false; + } + sk = pRSAPriKey; + fclose(hPriKeyFile); + return true; +} + +RSA * abe_crypto::import_pk(const string cert_path, string &err_msg){ + RSA * pk; + // 导入证书文件并读取公钥 + FILE *hPubKeyFile = fopen(cert_path.c_str(), "rb"); + if (hPubKeyFile == NULL) + { + err_msg = "failed to open cert file"; + return NULL; + } + X509 *cert = PEM_read_X509(hPubKeyFile, nullptr, nullptr, nullptr); + if(cert == NULL){ + err_msg = "failed to read publib key from cert file"; + fclose(hPubKeyFile); + return NULL; + } + fclose(hPubKeyFile); + + EVP_PKEY *evp_key = X509_get_pubkey(cert); + if(evp_key == NULL){ + err_msg = "failed to get publib key from cert file"; + X509_free(cert); + return NULL; + } + X509_free(cert); + + pk = EVP_PKEY_get1_RSA(evp_key); + if(pk == NULL){ + err_msg = "failed to get rsa publib key from cert file"; + EVP_PKEY_free(evp_key); + return NULL; + } + EVP_PKEY_free(evp_key); + + return pk; +} + +bool abe_crypto::import_db_cert(string db_cert_path){ + string err_msg; + RSA *pk = import_pk(db_cert_path, err_msg); + if(pk == NULL){ + err_msg += ":" + db_cert_path; + ABE_ERROR(err_msg); + return false; + } + db_pk = pk; + return true; +} + +bool abe_crypto::import_kms_cert(string kms_cert_path){ + string err_msg; + RSA *pk = import_pk(kms_cert_path, err_msg); + if(pk == NULL){ + err_msg += ":" + kms_cert_path; + ABE_ERROR(err_msg); + return false; + } + kms_pk = pk; + return true; +} + +abe_crypto::~abe_crypto(){ + if(kms_pk!= NULL) RSA_free(kms_pk); + if(db_pk!= NULL) RSA_free(db_pk); + if(sk != NULL) RSA_free(sk); +} + +bool abe_crypto::verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, unsigned char * sig, size_t sig_length){ + unsigned char digest[SHA512_DIGEST_LENGTH]; + // 对输入进行hash + SHA512(msg, msg_length, digest); + + // 对签名进行认证 + int ret = RSA_verify(NID_sha512, digest, SHA512_DIGEST_LENGTH, sig, sig_length, pk); + if (ret != 1){ + ABE_ERROR("verify error"); + unsigned long ulErr = ERR_get_error(); + char szErrMsg[1024] = {0}; + ABE_ERROR2("error number:" , ulErr); + ERR_error_string(ulErr, szErrMsg); // 格式:error:errId:库:函数:原因 + std::cout << szErrMsg << std::endl; + return false; + } + return true; + +} + +bool abe_crypto::verify_db_sig(const string msg, const string sig_b64){ + //sig是base64编码,需要先解码 + size_t sig_b64_length = sig_b64.length(); + unsigned char * sig = (unsigned char*)malloc(base64_utils::b64_dec_len(sig_b64_length)); + size_t sig_length = base64_utils::b64_decode(sig_b64.c_str(), sig_b64_length, (char*)sig); + + if(!verify_sig(db_pk, (unsigned char *)msg.c_str(), msg.length(), sig, sig_length)){ + free(sig); + ABE_ERROR("db_sig: verify failed"); + return false; + } + ABE_LOG("db_sig: verify success"); + free(sig); + return true; +} + +bool abe_crypto::verify_kms_sig(const string msg_b64, const string sig_b64){ + + //msg和sig都是base64编码,需要先解码 + size_t msg_b64_length = msg_b64.length(); + unsigned char * msg = (unsigned char*)malloc(base64_utils::b64_dec_len(msg_b64_length)); + size_t msg_length = base64_utils::b64_decode(msg_b64.c_str(), msg_b64_length, (char*)msg); + + size_t sig_b64_length = sig_b64.length(); + unsigned char * sig = (unsigned char*)malloc(base64_utils::b64_dec_len(sig_b64_length)); + size_t sig_length = base64_utils::b64_decode(sig_b64.c_str(), sig_b64_length, (char*)sig); + + if(!verify_sig(kms_pk, msg, msg_length, sig, sig_length)){ + free(msg); + free(sig); + ABE_ERROR("kms_sig: verify failed"); + return false; + } + + ABE_LOG("kms_sig: verify success"); + free(msg); + free(sig); + return true; +} + +//注意ct初始化时必须指定长度,否则ct.length会因为0x00而截断 +bool abe_crypto::rsa_decrypt(const string ct, string &pt){ + int nLen = RSA_size(sk); + char *pDecode = new char[nLen + 1]; + bool flag = true; + // 解密,不限长度,但为RSA_Decrypt_length的整数倍 + if (ct.length() < RSA_Decrypt_length + 1) + { // 一个分组的情况 + int ret = RSA_private_decrypt(ct.length(), (const unsigned char *)ct.c_str(), + (unsigned char *)pDecode, sk, RSA_PKCS1_PADDING); + if (ret >= 0) + { // 解密成功 + pt = std::string((char *)pDecode, ret); + } + else + { // 解密失败 + pt = ""; + flag = false; + } + } + else + { // 多个分组 + for (int i = 0; i < (int)ct.length() / (int)RSA_Decrypt_length; i++) + { + std::string Data = ct.substr(i * RSA_Decrypt_length, RSA_Decrypt_length); + int ret = RSA_private_decrypt(Data.length(), (const unsigned char *)Data.c_str(), + (unsigned char *)pDecode, sk, RSA_PKCS1_PADDING); + if (ret >= 0) + { + pt += std::string(pDecode, ret); + } + else + { // 解密失败 + pt = ""; + flag = false; + break; + } + } + } + + delete[] pDecode; + CRYPTO_cleanup_all_ex_data(); + return flag; +} \ No newline at end of file diff --git a/devapi/abe/base64.cc b/devapi/abe/base64.cc new file mode 100644 index 000000000..910adc01c --- /dev/null +++ b/devapi/abe/base64.cc @@ -0,0 +1,103 @@ +#include "mysqlx/abe/base64.h" +#include +#include +typedef unsigned int uint32; +#define BASE64_ERROR(msg) std::cerr << "base64 error: " << (msg) << std::endl; +unsigned base64_utils::b64_encode(const char* src, unsigned len, char* dst) +{ + char *p = NULL; + const char *s = NULL, *end = src + len; + int pos = 2; + uint32 buf = 0; + + s = src; + p = dst; + + while (s < end) { + buf |= (unsigned char)*s << (pos << 3); + pos--; + s++; + + /* write it out */ + if (pos < 0) { + *p++ = _base64[(buf >> 18) & 0x3f]; + *p++ = _base64[(buf >> 12) & 0x3f]; + *p++ = _base64[(buf >> 6) & 0x3f]; + *p++ = _base64[buf & 0x3f]; + + pos = 2; + buf = 0; + } + } + if (pos != 2) { + *p++ = _base64[(buf >> 18) & 0x3f]; + *p++ = _base64[(buf >> 12) & 0x3f]; + *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '='; + *p++ = '='; + } + + return p - dst; +} + +unsigned base64_utils::b64_decode(const char* src, unsigned len, char* dst) +{ + const char *srcend = src + len, *s = src; + char* p = dst; + char c; + int b = 0; + uint32 buf = 0; + int pos = 0, end = 0; + + while (s < srcend) { + c = *s++; + + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') + continue; + + if (c == '=') { + /* end sequence */ + if (!end) { + if (pos == 2) + end = 1; + else if (pos == 3) + end = 2; + else + BASE64_ERROR("(unexpected \"=\")"); + } + b = 0; + } else { + b = -1; + if (c > 0 && c < 127) + b = b64lookup[(unsigned char)c]; + if (b < 0) + BASE64_ERROR("symbol"); + } + /* add it to buffer */ + buf = (buf << 6) + b; + pos++; + if (pos == 4) { + *p++ = (buf >> 16) & 255; + if (end == 0 || end > 1) + *p++ = (buf >> 8) & 255; + if (end == 0 || end > 2) + *p++ = buf & 255; + buf = 0; + pos = 0; + } + } + + if (pos != 0) + BASE64_ERROR("end sequence"); + + return p - dst; +} + +unsigned base64_utils::b64_enc_len(unsigned srclen) +{ + return (srclen + 2) / 3 * 4; +} + +unsigned base64_utils::b64_dec_len(unsigned srclen) +{ + return srclen / 4 * 3; +} \ No newline at end of file diff --git a/devapi/abe/rewrite.cc b/devapi/abe/rewrite.cc new file mode 100644 index 000000000..ccafd6b8b --- /dev/null +++ b/devapi/abe/rewrite.cc @@ -0,0 +1,118 @@ +#include "mysqlx/abe/rewrite.h" +#include +#include +#include +#include +using std::string; + + +/*因sql-parser库对mysql语句支持很不友好,且当前并未找到实用的sql解析库 +*(最好是能解析mysql语句,然后可以反序列化,即解析后修改相关项,恢复成sql语句) +* 暂使用正则表达式实现abe_enc/abe_dec的匹配和重写 +* 文本内容理论要求:不能为空 +* policy理论要求:\w(字母,数字,下划线),| 属性分隔符,空白字符如空格等,等号,小数点,百分号 +* 加密函数格式:abe_enc(,) +* 解密函数格式:abe_dec() +*/ + +CommandType simple_parse(const string sql){ + std::smatch result; + for(auto it: PATTERNS_ALL.mp){ + if(std::regex_match(sql, result, it.second)){ + return it.first; + } + } + return COM_OTHER; +} + + +bool rewrite_plan::insert_handler(string &real_sql, const string &raw_sql){ + std::regex pattern = PATTERNS_ALL.ABE_ENC_SQL_PATTERN; + std::regex pattern_enc = PATTERNS_ALL.ABE_ENC_PATTERN; + string new_sql = raw_sql; + std::smatch result; + while (std::regex_match(new_sql, result, pattern, std::regex_constants::format_first_only)){ + is_enc = true;//需要加密 + //abe_enc只有两个参数,data和policy + struct enc_field temp; + temp.data = result[1]; + temp.policy = result[2]; + + string cipher; + crypto->encrypt(temp.data, temp.policy, cipher); + + temp.enc_data = "'" + cipher + "'"; + + new_sql = std::regex_replace(new_sql, pattern_enc, temp.enc_data, std::regex_constants::format_first_only); + enc_plan.push_back(temp); + // std::cout << "new_sql: " << new_sql << std::endl; + } + + real_sql = new_sql; + return true; +} + +bool rewrite_plan::select_handler(string &real_sql, const string &raw_sql){ + std::regex pattern = PATTERNS_ALL.ABE_DEC_SQL_PATTERN; + std::regex pattern_dec = PATTERNS_ALL.ABE_DEC_PATTERN; + std::smatch result; + string new_sql = raw_sql; + while (std::regex_match(new_sql, result, pattern, std::regex_constants::format_first_only)){ + is_dec = true;//需要解密 + + //abe_dec只有一个参数,field_name + struct dec_field temp; + temp.field_name = result[1]; + new_sql = std::regex_replace(new_sql, pattern_dec, temp.field_name, std::regex_constants::format_first_only); + dec_plan.push_back(temp); + // std::cout << "new_sql: " << new_sql << std::endl; + } + real_sql = new_sql; + return true; +} + +bool rewrite_plan::parse_and_rewrite(){ + + std::string sql = raw_sql; + //只有show/select命令需要打印查询结果,其他的不需要 + com_type = simple_parse(sql); + + switch (com_type) + { + case COM_SELECT:{ + // std::cout << "select statement" << std::endl; + + select_handler(real_sql, raw_sql); + // std::cout << "after replace: " << real_sql << std::endl; + break; + } + case COM_INSERT:{ + // std::cout << "insert statement" << std::endl; + insert_handler(real_sql, raw_sql); + // std::cout << "after replace: " << real_sql << std::endl; + break; + } + case COM_GET_ABE_KEY:{ + real_sql = "select owner,encrypted_key,sig_db,sig_db_type,sig_kms,sig_kms_type from mysql.abe_user_key"; + real_sql += " where owner = '" + crypto->user.user_id + "';"; + break; + } + case COM_SHOW: + case COM_SELECT_CURRENT_USER: + case COM_OTHER:{ + real_sql = sql; + break; + } + default: + break; + } + return true; +} + +std::vector rewrite_plan::field_name_list() const { + std::vector list; + for(auto item : dec_plan){ + list.push_back(item.field_name); + } + return list; +} \ No newline at end of file diff --git a/include/mysqlx/CMakeLists.txt b/include/mysqlx/CMakeLists.txt index 05d0210fe..8dfcb912b 100644 --- a/include/mysqlx/CMakeLists.txt +++ b/include/mysqlx/CMakeLists.txt @@ -31,6 +31,7 @@ SET(headers common_constants.h common.h xapi.h xdevapi.h) check_headers(${headers}) +ADD_HEADERS_DIR(abe) ADD_HEADERS_DIR(common) ADD_HEADERS_DIR(devapi) ADD_HEADERS(${headers}) diff --git a/include/mysqlx/abe/CMakeLists.txt b/include/mysqlx/abe/CMakeLists.txt new file mode 100644 index 000000000..e4bbf555a --- /dev/null +++ b/include/mysqlx/abe/CMakeLists.txt @@ -0,0 +1,7 @@ +SET(headers base64.h abe_crypto.h rewrite.h) + +check_headers(${headers}) + +ADD_HEADERS(${headers}) +ADD_HEADER_CHECKS() +INSTALL(FILES ${headers} DESTINATION ${INSTALL_INCLUDE_DIR}/mysqlx/abe COMPONENT XDevAPIDev) diff --git a/include/mysqlx/abe/abe_crypto.h b/include/mysqlx/abe/abe_crypto.h new file mode 100644 index 000000000..b7c25d9f1 --- /dev/null +++ b/include/mysqlx/abe/abe_crypto.h @@ -0,0 +1,64 @@ +#ifndef ABE_CRYPTO_H +#define ABE_CRYPTO_H +#include +#include +#include +#include +#include +#include +#include +#include +#include "openssl/crypto.h" + +using namespace oabe; +using namespace oabe::crypto; +using std::string; + +#define ABE_ERROR(msg) std::cerr << "error: " << (msg) << std::endl; +#define ABE_ERROR2(msg,comment) std::cerr << (msg) << (comment) << std::endl; +#define ABE_LOG(msg) std::cout << (msg) << std::endl; + +#define RSA_Encrypt_length 245 +#define RSA_Decrypt_length 256 + +struct abe_user{ + string user_id; + string user_key = ""; + string user_attr; +}; + +class abe_crypto{ +public: + + abe_crypto(string name){user.user_id = name;}//name或者说user_id,即用户标识,一般和登录的数据库用户同名 + + bool init(string mpk_path, string key_path, string kms_cert_path, string db_cert_path, string rsa_sk_path); + void set_name(string namehost){user.user_id = namehost;} + void set_att(string att) {user.user_attr = att;} + bool import_mpk(string mpk_path); + bool import_user_key(string key_path); + bool save_user_key(string key_path, string key_str); + bool check_abe_key(); //true: abe_key已存在 + + bool encrypt(string pt, string policy, string &ct); + bool decrypt(string ct, string &pt); + + bool import_db_cert(string db_cert_path); + bool import_kms_cert(string kms_cert_path); + bool import_sk(string rsa_sk_path); + + bool verify_db_sig(const string msg, const string sig_db_b64); + bool verify_kms_sig(const string msg_b64, const string sig_kms_b64); + + struct abe_user user; + ~abe_crypto(); +private: + string mpk; + RSA *kms_pk = NULL; + RSA *db_pk = NULL; + RSA *sk = NULL; + bool verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, unsigned char * sig, size_t sig_length); + bool rsa_decrypt(const string ct, string &pt); + RSA * import_pk(const string cert_path, string &err_msg); +}; +#endif \ No newline at end of file diff --git a/include/mysqlx/abe/base64.h b/include/mysqlx/abe/base64.h new file mode 100644 index 000000000..f4e32b453 --- /dev/null +++ b/include/mysqlx/abe/base64.h @@ -0,0 +1,144 @@ +#ifndef SQL_ABE_BASE64_H +#define SQL_ABE_BASE64_H + +namespace base64_utils { + static const char _base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + static const char b64lookup[128] = { + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 62, + -1, + -1, + -1, + 63, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + -1, + -1, + -1, + -1, + -1, + -1, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + -1, + -1, + -1, + -1, + -1, + }; + + unsigned b64_encode(const char* src, unsigned len, char* dst); + unsigned b64_decode(const char* src, unsigned len, char* dst); + unsigned b64_enc_len(unsigned srclen); + unsigned b64_dec_len(unsigned srclen); +} + +#endif // SEC_ABE_UTILS_H \ No newline at end of file diff --git a/include/mysqlx/abe/rewrite.h b/include/mysqlx/abe/rewrite.h new file mode 100644 index 000000000..eb80fb6f8 --- /dev/null +++ b/include/mysqlx/abe/rewrite.h @@ -0,0 +1,139 @@ +// #include "SQLParser.h" +// #include "util/sqlhelper.h" +#ifndef REWRITE_H +#define REWRITE_H +#include +#include +#include +#include +#include +#include "abe_crypto.h" + +using std::string; + + +enum CommandType{ + BEGIN, + COM_SELECT_CURRENT_USER, + COM_GET_ABE_KEY, + COM_SELECT, + COM_INSERT, + COM_SHOW, + END, + + COM_OTHER, + WRONG_SQL +}; + + +struct RegexPatterns{ +public: + std::regex ABE_ENC_PATTERN; + std::regex ABE_ENC_SQL_PATTERN; + std::regex ABE_DEC_PATTERN; + std::regex ABE_DEC_SQL_PATTERN; + + std::unordered_map mp; + + RegexPatterns(){ + const string ABE_ANY_R = ".*?"; + const string ABE_COMMA_R = "\\s*,\\s*"; + const string ABE_SUFIX_R = "\\s*\\)"; + + const string ABE_ENC_PREFIX_R = "abe_enc\\(\\s*"; + const string ABE_ENC_DATA_R = "['\"`]((?:\\\\\"|\\\\\\(|\\\\\\)|[^\"\\(\\)])+)['\"`]"; // 真实正则:((?:\\"|\\\(|\\\)|[^\"\(\)])+) + const string ABE_ENC_POLICY_R = "['\"`]((?:\\\\\"|\\\\\\(|\\\\\\)|[^\"\\(\\)])+)['\"`]"; + const string ABE_ENC_REGEX = ABE_ENC_PREFIX_R + ABE_ENC_DATA_R + + ABE_COMMA_R + ABE_ENC_POLICY_R + ABE_SUFIX_R; //加密函数正则 + const string ABE_ENC_SQL_REGEX = ABE_ANY_R + ABE_ENC_REGEX + ABE_ANY_R; + + const string ABE_DEC_PREFIX_R = "abe_dec\\(\\s*"; + const string ABE_DEC_FIELD_R = "[`]*(\\w+)[`]*"; + const string ABE_DEC_REGEX = ABE_DEC_PREFIX_R + ABE_DEC_FIELD_R + ABE_SUFIX_R; //解密函数正则 + const string ABE_DEC_SQL_REGEX = ABE_ANY_R + ABE_DEC_REGEX + ABE_ANY_R; + + const string COM_SELECT_SQL_REGEX = "\\s*select.*"; + const string COM_INSERT_SQL_REGEX = "\\s*insert.*"; + const string COM_SHOW_SQL_REGEX = "\\s*show.*"; + const string COM_SELECT_CURRENT_USER_SQL_REGEX = "\\s*select\\s+current_user().*"; + const string GET_ABE_KEY_REGEX = "\\s*show\\s+current_abe_key;\\s*"; + + ABE_ENC_PATTERN = std::regex(ABE_ENC_REGEX, std::regex::icase); + ABE_ENC_SQL_PATTERN = std::regex(ABE_ENC_SQL_REGEX, std::regex::icase); + ABE_DEC_PATTERN = std::regex(ABE_DEC_REGEX, std::regex::icase); + ABE_DEC_SQL_PATTERN = std::regex(ABE_DEC_SQL_REGEX, std::regex::icase); + + mp[COM_SELECT] = std::regex(COM_SELECT_SQL_REGEX, std::regex::icase); + mp[COM_INSERT] = std::regex(COM_INSERT_SQL_REGEX, std::regex::icase); + mp[COM_SHOW] = std::regex(COM_SHOW_SQL_REGEX, std::regex::icase); + mp[COM_SELECT_CURRENT_USER] = std::regex(COM_SELECT_CURRENT_USER_SQL_REGEX, std::regex::icase); + mp[COM_GET_ABE_KEY] = std::regex(GET_ABE_KEY_REGEX, std::regex::icase); + } +}; +static RegexPatterns PATTERNS_ALL; + +//一个改写点,包括abe策略(用户输入)、明文data、密文enc_data +struct enc_field{ + string policy; + string data; + string enc_data; +}; + +//解密改写点 +struct dec_field{ + string field_name; //要解密的field_name + int field_num; //要解密的field位置,如select a,b,abe_dec()的abe_dec位置为2(从0开始) +}; + + +class rewrite_plan{ +public: + /* + * input: 用户输入的原始sql语句 + * real_sql: 重写完成后真正要执行的sql语句 + */ + rewrite_plan(string input) : raw_sql(input), is_enc(false), is_dec(false) {} + + bool parse_and_rewrite(); + + bool need_print() const{ return (com_type == COM_SELECT || com_type == COM_SHOW);} + bool need_enc() const { return is_enc; } + bool need_dec() const { return is_dec; } + + void set_crypto(struct abe_crypto &c){ + crypto = &c; + } + + //需要解密的列名 + std::vector field_name_list() const; + + struct abe_crypto * crypto; //abe算法 + + /* + * 查询,包括select/show,需要输出查询结果 + */ + CommandType com_type; + + //只考虑owner,encrypted_key,sig_db,sig_db_type,sig_kms,sig_kms_type + static constexpr int TABLE_ABE_UER_KEY_FIELD_NUM = 6; + enum abe_user_key_field {F_OWNER_NUM = 0,F_KEY_NUM = 1,F_SIG_DB_NUM = 2, F_SIG_DB_TYPE_NUM = 3, + F_SIG_KMS_NUM = 4, F_SIG_KMS_TYPE_NUM = 5}; + string raw_sql; //用户输入sql + string real_sql; + +private: + bool is_enc; //true:加密时,一般为插入 + bool is_dec; //true,解密一般为查询 + + std::vector enc_plan; //改写点列表 + + //解密需要: + std::vector dec_plan; + + + bool insert_handler(string &real_sql, const string &raw_sql); + bool select_handler(string &real_sql, const string &raw_sql); + + +}; +#endif \ No newline at end of file From a43206de28b383644390487a0a1c9a35c6a3161b Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Mon, 18 Dec 2023 17:43:15 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9Aabe=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + devapi/CMakeLists.txt | 1 + devapi/abe/abe_crypto.cc | 69 +++++++------- devapi/abe/base64.cc | 20 +++- devapi/abe/rewrite.cc | 25 +++-- devapi/abe_extern.cc | 160 ++++++++++++++++++++++++++++++++ include/mysqlx/CMakeLists.txt | 2 +- include/mysqlx/abe/abe_crypto.h | 52 ++++++----- include/mysqlx/abe/base64.h | 5 +- include/mysqlx/abe/rewrite.h | 67 +++++++------ include/mysqlx/abe_extern.h | 79 ++++++++++++++++ 11 files changed, 377 insertions(+), 104 deletions(-) create mode 100644 devapi/abe_extern.cc create mode 100644 include/mysqlx/abe_extern.h diff --git a/.gitignore b/.gitignore index 4c70919b2..4b69f29e1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .vs out build +.vscode diff --git a/devapi/CMakeLists.txt b/devapi/CMakeLists.txt index ee8f374f5..286723490 100644 --- a/devapi/CMakeLists.txt +++ b/devapi/CMakeLists.txt @@ -37,6 +37,7 @@ add_library(devapi STATIC result.cc document.cc crud.cc + abe_extern.cc ${HEADERS} ) add_subdirectory(abe) diff --git a/devapi/abe/abe_crypto.cc b/devapi/abe/abe_crypto.cc index b7b39ecfb..8018c186f 100644 --- a/devapi/abe/abe_crypto.cc +++ b/devapi/abe/abe_crypto.cc @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include #include @@ -10,34 +12,36 @@ #include "mysqlx/abe/abe_crypto.h" #include "mysqlx/abe/base64.h" +namespace mysqlx{ +namespace abe{ -bool abe_crypto::encrypt(string pt, string policy, string &ct){ +bool abe_crypto::encrypt(std::string pt, std::string policy, std::string &ct){ - InitializeOpenABE(); - OpenABECryptoContext cpabe("CP-ABE"); + oabe::InitializeOpenABE(); + oabe::OpenABECryptoContext cpabe("CP-ABE"); cpabe.importPublicParams(mpk); cpabe.encrypt(policy.c_str(), pt, ct); - ShutdownOpenABE(); + oabe::ShutdownOpenABE(); // std::cout<<"encrypt succefully!"< #include + +namespace mysqlx{ +namespace abe{ +namespace base64_utils { + typedef unsigned int uint32; #define BASE64_ERROR(msg) std::cerr << "base64 error: " << (msg) << std::endl; -unsigned base64_utils::b64_encode(const char* src, unsigned len, char* dst) + +unsigned b64_encode(const char* src, unsigned len, char* dst) { char *p = NULL; const char *s = NULL, *end = src + len; @@ -39,7 +45,7 @@ unsigned base64_utils::b64_encode(const char* src, unsigned len, char* dst) return p - dst; } -unsigned base64_utils::b64_decode(const char* src, unsigned len, char* dst) +unsigned b64_decode(const char* src, unsigned len, char* dst) { const char *srcend = src + len, *s = src; char* p = dst; @@ -92,12 +98,16 @@ unsigned base64_utils::b64_decode(const char* src, unsigned len, char* dst) return p - dst; } -unsigned base64_utils::b64_enc_len(unsigned srclen) +unsigned b64_enc_len(unsigned srclen) { return (srclen + 2) / 3 * 4; } -unsigned base64_utils::b64_dec_len(unsigned srclen) +unsigned b64_dec_len(unsigned srclen) { return srclen / 4 * 3; -} \ No newline at end of file +} + +} +}//namespace mysqlx::abe +}//namespace mysqlx \ No newline at end of file diff --git a/devapi/abe/rewrite.cc b/devapi/abe/rewrite.cc index ccafd6b8b..f76a04a12 100644 --- a/devapi/abe/rewrite.cc +++ b/devapi/abe/rewrite.cc @@ -3,7 +3,7 @@ #include #include #include -using std::string; +// using std::std::string; /*因sql-parser库对mysql语句支持很不友好,且当前并未找到实用的sql解析库 @@ -14,8 +14,10 @@ using std::string; * 加密函数格式:abe_enc(,) * 解密函数格式:abe_dec() */ +namespace mysqlx{ +namespace abe{ -CommandType simple_parse(const string sql){ +CommandType simple_parse(const std::string sql){ std::smatch result; for(auto it: PATTERNS_ALL.mp){ if(std::regex_match(sql, result, it.second)){ @@ -26,10 +28,10 @@ CommandType simple_parse(const string sql){ } -bool rewrite_plan::insert_handler(string &real_sql, const string &raw_sql){ +bool rewrite_plan::insert_handler(std::string &real_sql, const std::string &raw_sql){ std::regex pattern = PATTERNS_ALL.ABE_ENC_SQL_PATTERN; std::regex pattern_enc = PATTERNS_ALL.ABE_ENC_PATTERN; - string new_sql = raw_sql; + std::string new_sql = raw_sql; std::smatch result; while (std::regex_match(new_sql, result, pattern, std::regex_constants::format_first_only)){ is_enc = true;//需要加密 @@ -38,7 +40,7 @@ bool rewrite_plan::insert_handler(string &real_sql, const string &raw_sql){ temp.data = result[1]; temp.policy = result[2]; - string cipher; + std::string cipher; crypto->encrypt(temp.data, temp.policy, cipher); temp.enc_data = "'" + cipher + "'"; @@ -52,11 +54,11 @@ bool rewrite_plan::insert_handler(string &real_sql, const string &raw_sql){ return true; } -bool rewrite_plan::select_handler(string &real_sql, const string &raw_sql){ +bool rewrite_plan::select_handler(std::string &real_sql, const std::string &raw_sql){ std::regex pattern = PATTERNS_ALL.ABE_DEC_SQL_PATTERN; std::regex pattern_dec = PATTERNS_ALL.ABE_DEC_PATTERN; std::smatch result; - string new_sql = raw_sql; + std::string new_sql = raw_sql; while (std::regex_match(new_sql, result, pattern, std::regex_constants::format_first_only)){ is_dec = true;//需要解密 @@ -109,10 +111,13 @@ bool rewrite_plan::parse_and_rewrite(){ return true; } -std::vector rewrite_plan::field_name_list() const { - std::vector list; +std::vector rewrite_plan::get_field_name_list() const { + std::vector list; for(auto item : dec_plan){ list.push_back(item.field_name); } return list; -} \ No newline at end of file +} + +}//namespace mysqlx::abe +}//namespace mysqlx \ No newline at end of file diff --git a/devapi/abe_extern.cc b/devapi/abe_extern.cc new file mode 100644 index 000000000..c1846fe9f --- /dev/null +++ b/devapi/abe_extern.cc @@ -0,0 +1,160 @@ +#include "mysqlx/abe_extern.h" +#include +#include +#include "mysqlx/abe/rewrite.h" +#include "mysqlx/abe/abe_crypto.h" +#include "mysqlx/xdevapi.h" + + +namespace mysqlx{ +using rewrite_plan = mysqlx::abe::rewrite_plan; +using abe_crypto = mysqlx::abe::abe_crypto; + +RowResult abe_query::execute(){ + parse_and_rewrite(); + + field_name_list = get_field_name_list(); + + RowResult res = sess->sql(real_sql).execute(); + + auto it = res.getColumns().begin(); + auto end = res.getColumns().end(); + unsigned int i=0; + for (;it != end;++it){ + std::string field_name = (*it).getColumnName(); + auto temp = std::find(field_name_list.begin(), field_name_list.end(), field_name); + if(temp != field_name_list.end()){ + //该列是使用了abe_dec的列 + f_flag.push_back(1); + field_num_list.push_back(i); + }else{ + //普通列 + f_flag.push_back(0); + } + i++; + } + return res; +} + +std::string abe_query::recover(const std::string &ct){ + std::string pt; + if(!crypto->decrypt(ct, pt)){ + return pt; + } + return ""; +} + + +std::string abe_env::get_current_user_key(){ + std::string str = "select owner,encrypted_key,sig_db,sig_db_type,sig_kms,sig_kms_type from mysql.abe_user_key"; + str += " where owner = '" + abe.user.user_id + "';"; + + RowResult res = sess->sql(str).execute(); + + int field_num = res.count(); + int row_num = res.getColumnCount(); + if(row_num != 1){ + ABE_LOG("It seems that you don't have the abe key, please contact the admininistrator"); + } + if(field_num != rewrite_plan::TABLE_ABE_UER_KEY_FIELD_NUM){ + ABE_ERROR("system table 'abe_user_key' error"); + return ""; + } + + auto it = res.begin(); + std::string key_str = (*it).get(rewrite_plan::F_KEY_NUM).get(); + std::string sig_db = (*it).get(rewrite_plan::F_SIG_DB_NUM).get(); + std::string sig_db_type = (*it).get(rewrite_plan::F_SIG_DB_TYPE_NUM).get(); + std::string sig_kms = (*it).get(rewrite_plan::F_SIG_KMS_NUM).get(); + std::string sig_kms_type = (*it).get(rewrite_plan::F_SIG_KMS_TYPE_NUM).get(); + + std::string namehost = abe.user.user_id; + std::string attrlist = abe.user.user_attr; + if(!(abe.verify_db_sig(namehost + attrlist,sig_db) + && abe.verify_kms_sig(key_str,sig_kms))){ + return ""; + } + return key_str; + +} + +std::string abe_env::get_current_user(){ + + RowResult res = sess->sql("select current_user()").execute(); + + int field_num = res.count(); + int row_num = res.getColumnCount(); + if(row_num != 1 || field_num != 1) return ""; + + auto it = res.begin(); + auto str = (*it).get(1).get(); + std::string namehost(str); + return namehost; +} + +std::string abe_env::get_current_user_abe_attribute(){ + + RowResult res = sess->sql("select current_abe_attribute()").execute(); + + int field_num = res.count(); + int row_num = res.getColumnCount(); + if(row_num != 1 || field_num != 1) return ""; + + auto it = res.begin(); + auto str = (*it).get(1).get(); + std::string att(str); + return att; +} + +bool abe_env::abe_prepare_queries(const abe_parameters ¶ms){ + std::string namehost = get_current_user(); + if(namehost == ""){ + // ABE_ERROR("can't get your username and host!"); + return false; + }else{ + abe.set_name(namehost); + + } + std::string attrlist = get_current_user_abe_attribute(); + if(attrlist == ""){ + // ABE_ERROR("can't get your attrlist, please contact adminastrator."); + return false; + }else{ + abe.set_att(attrlist); + } + + if(!check_abe_key()){ + std::string abe_key = get_current_user_key(); + if(abe_key == ""){ + return false; + }else{ + //todo:存储abe_key的逻辑 + abe.save_user_key(params.abe_key_path, abe_key); + } + } + return true; + +} + +bool abe_env::init(const abe_parameters ¶ms){ + if(!abe.init(params.abe_pp_path, params.abe_key_path, + params.kms_cert_path, params.db_cert_path, + params.rsa_sk_path) + || abe_prepare_queries(params)){ + // ABE_ERROR("failed to init abe system"); + return false; + } + return false; +} + +bool abe_encrypt(abe_crypto &abe, std::string pt, std::string policy, std::string &ct ){ + abe.encrypt(pt, policy, ct); + return true; +} + +bool abe_decrypt(abe_crypto &abe, std::string ct, std::string &pt){ + abe.decrypt(ct, pt); + return true; +} + +}//namespace mysqlx diff --git a/include/mysqlx/CMakeLists.txt b/include/mysqlx/CMakeLists.txt index 8dfcb912b..320bbfe70 100644 --- a/include/mysqlx/CMakeLists.txt +++ b/include/mysqlx/CMakeLists.txt @@ -27,7 +27,7 @@ # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SET(headers common_constants.h common.h xapi.h xdevapi.h) +SET(headers common_constants.h common.h xapi.h xdevapi.h abe_extern.h) check_headers(${headers}) diff --git a/include/mysqlx/abe/abe_crypto.h b/include/mysqlx/abe/abe_crypto.h index b7c25d9f1..05e7ea2b4 100644 --- a/include/mysqlx/abe/abe_crypto.h +++ b/include/mysqlx/abe/abe_crypto.h @@ -2,17 +2,14 @@ #define ABE_CRYPTO_H #include #include -#include -#include #include #include #include #include #include "openssl/crypto.h" -using namespace oabe; -using namespace oabe::crypto; -using std::string; +namespace mysqlx{ +namespace abe{ #define ABE_ERROR(msg) std::cerr << "error: " << (msg) << std::endl; #define ABE_ERROR2(msg,comment) std::cerr << (msg) << (comment) << std::endl; @@ -22,43 +19,48 @@ using std::string; #define RSA_Decrypt_length 256 struct abe_user{ - string user_id; - string user_key = ""; - string user_attr; + std::string user_id; + std::string user_key = ""; + std::string user_attr; }; class abe_crypto{ public: - abe_crypto(string name){user.user_id = name;}//name或者说user_id,即用户标识,一般和登录的数据库用户同名 + abe_crypto(){} + abe_crypto(std::string name){user.user_id = name;}//name或者说user_id,即用户标识,一般和登录的数据库用户同名 - bool init(string mpk_path, string key_path, string kms_cert_path, string db_cert_path, string rsa_sk_path); - void set_name(string namehost){user.user_id = namehost;} - void set_att(string att) {user.user_attr = att;} - bool import_mpk(string mpk_path); - bool import_user_key(string key_path); - bool save_user_key(string key_path, string key_str); + bool init(std::string mpk_path, std::string key_path, std::string kms_cert_path, std::string db_cert_path, std::string rsa_sk_path); + void set_name(std::string namehost){user.user_id = namehost;} + void set_att(std::string att) {user.user_attr = att;} + bool import_mpk(std::string mpk_path); + bool import_user_key(std::string key_path); + bool save_user_key(std::string key_path, std::string key_str); bool check_abe_key(); //true: abe_key已存在 - bool encrypt(string pt, string policy, string &ct); - bool decrypt(string ct, string &pt); + bool encrypt(std::string pt, std::string policy, std::string &ct); + bool decrypt(std::string ct, std::string &pt); - bool import_db_cert(string db_cert_path); - bool import_kms_cert(string kms_cert_path); - bool import_sk(string rsa_sk_path); + bool import_db_cert(std::string db_cert_path); + bool import_kms_cert(std::string kms_cert_path); + bool import_sk(std::string rsa_sk_path); - bool verify_db_sig(const string msg, const string sig_db_b64); - bool verify_kms_sig(const string msg_b64, const string sig_kms_b64); + bool verify_db_sig(const std::string msg, const std::string sig_db_b64); + bool verify_kms_sig(const std::string msg_b64, const std::string sig_kms_b64); struct abe_user user; ~abe_crypto(); private: - string mpk; + std::string mpk; RSA *kms_pk = NULL; RSA *db_pk = NULL; RSA *sk = NULL; bool verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, unsigned char * sig, size_t sig_length); - bool rsa_decrypt(const string ct, string &pt); - RSA * import_pk(const string cert_path, string &err_msg); + bool rsa_decrypt(const std::string ct, std::string &pt); + RSA * import_pk(const std::string cert_path, std::string &err_msg); }; + +}//namespace mysqlx::abe +}//namespace mysqlx + #endif \ No newline at end of file diff --git a/include/mysqlx/abe/base64.h b/include/mysqlx/abe/base64.h index f4e32b453..8bd920354 100644 --- a/include/mysqlx/abe/base64.h +++ b/include/mysqlx/abe/base64.h @@ -1,6 +1,7 @@ #ifndef SQL_ABE_BASE64_H #define SQL_ABE_BASE64_H - +namespace mysqlx{ +namespace abe{ namespace base64_utils { static const char _base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -141,4 +142,6 @@ namespace base64_utils { unsigned b64_dec_len(unsigned srclen); } +}//namespace mysqlx::abe +}//namespace mysqlx #endif // SEC_ABE_UTILS_H \ No newline at end of file diff --git a/include/mysqlx/abe/rewrite.h b/include/mysqlx/abe/rewrite.h index eb80fb6f8..d54bba926 100644 --- a/include/mysqlx/abe/rewrite.h +++ b/include/mysqlx/abe/rewrite.h @@ -9,9 +9,9 @@ #include #include "abe_crypto.h" -using std::string; - +namespace mysqlx{ +namespace abe{ enum CommandType{ BEGIN, COM_SELECT_CURRENT_USER, @@ -36,27 +36,27 @@ struct RegexPatterns{ std::unordered_map mp; RegexPatterns(){ - const string ABE_ANY_R = ".*?"; - const string ABE_COMMA_R = "\\s*,\\s*"; - const string ABE_SUFIX_R = "\\s*\\)"; - - const string ABE_ENC_PREFIX_R = "abe_enc\\(\\s*"; - const string ABE_ENC_DATA_R = "['\"`]((?:\\\\\"|\\\\\\(|\\\\\\)|[^\"\\(\\)])+)['\"`]"; // 真实正则:((?:\\"|\\\(|\\\)|[^\"\(\)])+) - const string ABE_ENC_POLICY_R = "['\"`]((?:\\\\\"|\\\\\\(|\\\\\\)|[^\"\\(\\)])+)['\"`]"; - const string ABE_ENC_REGEX = ABE_ENC_PREFIX_R + ABE_ENC_DATA_R + const std::string ABE_ANY_R = ".*?"; + const std::string ABE_COMMA_R = "\\s*,\\s*"; + const std::string ABE_SUFIX_R = "\\s*\\)"; + + const std::string ABE_ENC_PREFIX_R = "abe_enc\\(\\s*"; + const std::string ABE_ENC_DATA_R = "['\"`]((?:\\\\\"|\\\\\\(|\\\\\\)|[^\"\\(\\)])+)['\"`]"; // 真实正则:((?:\\"|\\\(|\\\)|[^\"\(\)])+) + const std::string ABE_ENC_POLICY_R = "['\"`]((?:\\\\\"|\\\\\\(|\\\\\\)|[^\"\\(\\)])+)['\"`]"; + const std::string ABE_ENC_REGEX = ABE_ENC_PREFIX_R + ABE_ENC_DATA_R + ABE_COMMA_R + ABE_ENC_POLICY_R + ABE_SUFIX_R; //加密函数正则 - const string ABE_ENC_SQL_REGEX = ABE_ANY_R + ABE_ENC_REGEX + ABE_ANY_R; + const std::string ABE_ENC_SQL_REGEX = ABE_ANY_R + ABE_ENC_REGEX + ABE_ANY_R; - const string ABE_DEC_PREFIX_R = "abe_dec\\(\\s*"; - const string ABE_DEC_FIELD_R = "[`]*(\\w+)[`]*"; - const string ABE_DEC_REGEX = ABE_DEC_PREFIX_R + ABE_DEC_FIELD_R + ABE_SUFIX_R; //解密函数正则 - const string ABE_DEC_SQL_REGEX = ABE_ANY_R + ABE_DEC_REGEX + ABE_ANY_R; + const std::string ABE_DEC_PREFIX_R = "abe_dec\\(\\s*"; + const std::string ABE_DEC_FIELD_R = "[`]*(\\w+)[`]*"; + const std::string ABE_DEC_REGEX = ABE_DEC_PREFIX_R + ABE_DEC_FIELD_R + ABE_SUFIX_R; //解密函数正则 + const std::string ABE_DEC_SQL_REGEX = ABE_ANY_R + ABE_DEC_REGEX + ABE_ANY_R; - const string COM_SELECT_SQL_REGEX = "\\s*select.*"; - const string COM_INSERT_SQL_REGEX = "\\s*insert.*"; - const string COM_SHOW_SQL_REGEX = "\\s*show.*"; - const string COM_SELECT_CURRENT_USER_SQL_REGEX = "\\s*select\\s+current_user().*"; - const string GET_ABE_KEY_REGEX = "\\s*show\\s+current_abe_key;\\s*"; + const std::string COM_SELECT_SQL_REGEX = "\\s*select.*"; + const std::string COM_INSERT_SQL_REGEX = "\\s*insert.*"; + const std::string COM_SHOW_SQL_REGEX = "\\s*show.*"; + const std::string COM_SELECT_CURRENT_USER_SQL_REGEX = "\\s*select\\s+current_user().*"; + const std::string GET_ABE_KEY_REGEX = "\\s*show\\s+current_abe_key;\\s*"; ABE_ENC_PATTERN = std::regex(ABE_ENC_REGEX, std::regex::icase); ABE_ENC_SQL_PATTERN = std::regex(ABE_ENC_SQL_REGEX, std::regex::icase); @@ -74,14 +74,14 @@ static RegexPatterns PATTERNS_ALL; //一个改写点,包括abe策略(用户输入)、明文data、密文enc_data struct enc_field{ - string policy; - string data; - string enc_data; + std::string policy; + std::string data; + std::string enc_data; }; //解密改写点 struct dec_field{ - string field_name; //要解密的field_name + std::string field_name; //要解密的field_name int field_num; //要解密的field位置,如select a,b,abe_dec()的abe_dec位置为2(从0开始) }; @@ -92,7 +92,7 @@ class rewrite_plan{ * input: 用户输入的原始sql语句 * real_sql: 重写完成后真正要执行的sql语句 */ - rewrite_plan(string input) : raw_sql(input), is_enc(false), is_dec(false) {} + rewrite_plan(std::string input) : raw_sql(input), is_enc(false), is_dec(false) {} bool parse_and_rewrite(); @@ -104,8 +104,12 @@ class rewrite_plan{ crypto = &c; } + void set_crypto(struct abe_crypto *c){ + crypto = c; + } + //需要解密的列名 - std::vector field_name_list() const; + std::vector get_field_name_list() const; struct abe_crypto * crypto; //abe算法 @@ -118,8 +122,8 @@ class rewrite_plan{ static constexpr int TABLE_ABE_UER_KEY_FIELD_NUM = 6; enum abe_user_key_field {F_OWNER_NUM = 0,F_KEY_NUM = 1,F_SIG_DB_NUM = 2, F_SIG_DB_TYPE_NUM = 3, F_SIG_KMS_NUM = 4, F_SIG_KMS_TYPE_NUM = 5}; - string raw_sql; //用户输入sql - string real_sql; + std::string raw_sql; //用户输入sql + std::string real_sql; private: bool is_enc; //true:加密时,一般为插入 @@ -131,9 +135,12 @@ class rewrite_plan{ std::vector dec_plan; - bool insert_handler(string &real_sql, const string &raw_sql); - bool select_handler(string &real_sql, const string &raw_sql); + bool insert_handler(std::string &real_sql, const std::string &raw_sql); + bool select_handler(std::string &real_sql, const std::string &raw_sql); }; + +}//namespace mysqlx::abe +}//namespace mysqlx #endif \ No newline at end of file diff --git a/include/mysqlx/abe_extern.h b/include/mysqlx/abe_extern.h new file mode 100644 index 000000000..15d67c0da --- /dev/null +++ b/include/mysqlx/abe_extern.h @@ -0,0 +1,79 @@ +#ifndef ABE_EXTERN_H +#define ABE_EXTERN_H +#include +#include +#include "abe/rewrite.h" +#include "abe/abe_crypto.h" +#include "xdevapi.h" +// #include "devapi/detail/result.h" +namespace mysqlx { + +struct abe_parameters{ + string rsa_sk_path; //rsa私钥路径,用于解密 + string db_cert_path; //db证书,用于验签 + string kms_cert_path; //kms证书,用于验签 + + string abe_key_path; //abe密钥路径 + string abe_pp_path; //abe公共参数路径,也可称mpk +}; + +class abe_query : public abe::rewrite_plan{ +public: + abe_query(Session * sess, abe::abe_crypto * abe, std::string sql): rewrite_plan(sql){ + this->sess = sess; + set_crypto(abe); + } + + //重写并执行 + RowResult execute(); + + //解密 + std::string recover(const std::string &ct); + + //需要解密的列名 + std::vector field_name_list; + std::vector field_num_list; + std::vector f_flag;//指示某列是否需要解密 +private: + Session * sess; +}; + +class abe_env{ +public: + abe_env(Session &sess){ + this->sess = &sess; + } + + /* + 初始化abe的环境,包括所需abe密钥和证书、私钥等 + */ + bool init(const abe_parameters ¶ms); + + /* + 仿照原来的用法 + env.sql("select * ...").execute(); + */ + abe_query sql(std::string input){ + return abe_query(sess, &abe, input); + } + + bool check_abe_key(){ + return abe.check_abe_key(); + } + +private: + Session * sess; + abe::abe_crypto abe; + + bool abe_prepare_queries(const abe_parameters ¶ms); + std::string get_current_user(); + std::string get_current_user_abe_attribute(); + std::string get_current_user_key(); +}; + + +bool abe_encrypt(abe::abe_crypto &abe, std::string pt, std::string policy, std::string &ct ); +bool abe_decrypt(abe::abe_crypto &abe, std::string ct, std::string &pt); +} +// const std::string abe_rewrite(const std::string &query, const abe_crypto &abe); +#endif //ABE_EXTERN_H \ No newline at end of file From 8f17fb9d221bd6be1495cec672630ac3b7566176 Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Fri, 22 Dec 2023 15:31:16 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E2=80=9Crefer?= =?UTF-8?q?ence=20undefined=20to=20xxx=E2=80=9D=E7=AD=89=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapi/abe/abe_crypto.cc | 5 ++++- devapi/abe/base64.cc | 3 +++ devapi/abe/rewrite.cc | 2 ++ devapi/abe_extern.cc | 11 +++++++---- include/mysqlx/abe/abe_crypto.h | 7 +++++-- include/mysqlx/abe/base64.h | 5 +++++ include/mysqlx/abe/rewrite.h | 4 ++++ include/mysqlx/abe_extern.h | 17 ++++++++++------- include/mysqlx/common/api.h | 4 ++++ 9 files changed, 44 insertions(+), 14 deletions(-) diff --git a/devapi/abe/abe_crypto.cc b/devapi/abe/abe_crypto.cc index 8018c186f..6046934f4 100644 --- a/devapi/abe/abe_crypto.cc +++ b/devapi/abe/abe_crypto.cc @@ -13,6 +13,7 @@ #include "mysqlx/abe/base64.h" namespace mysqlx{ +MYSQLX_ABI_BEGIN(2,0) namespace abe{ bool abe_crypto::encrypt(std::string pt, std::string policy, std::string &ct){ @@ -27,7 +28,7 @@ bool abe_crypto::encrypt(std::string pt, std::string policy, std::string &ct){ return true; } -bool abe_crypto::decrypt(std::string ct, std::string &pt){ +bool abe_crypto::decrypt(const std::string ct, std::string &pt){ if(!check_abe_key()){ return false; @@ -321,4 +322,6 @@ bool abe_crypto::rsa_decrypt(const std::string ct, std::string &pt){ } }//namespace mysqlx::abe + +MYSQLX_ABI_END(2,0) }//namespace mysqlx \ No newline at end of file diff --git a/devapi/abe/base64.cc b/devapi/abe/base64.cc index bcb3a284e..a13d68f4e 100644 --- a/devapi/abe/base64.cc +++ b/devapi/abe/base64.cc @@ -3,6 +3,7 @@ #include namespace mysqlx{ +MYSQLX_ABI_BEGIN(2,0) namespace abe{ namespace base64_utils { @@ -110,4 +111,6 @@ unsigned b64_dec_len(unsigned srclen) } }//namespace mysqlx::abe + +MYSQLX_ABI_END(2,0) }//namespace mysqlx \ No newline at end of file diff --git a/devapi/abe/rewrite.cc b/devapi/abe/rewrite.cc index f76a04a12..443e96f87 100644 --- a/devapi/abe/rewrite.cc +++ b/devapi/abe/rewrite.cc @@ -15,6 +15,7 @@ * 解密函数格式:abe_dec() */ namespace mysqlx{ +MYSQLX_ABI_BEGIN(2,0) namespace abe{ CommandType simple_parse(const std::string sql){ @@ -120,4 +121,5 @@ std::vector rewrite_plan::get_field_name_list() const { } }//namespace mysqlx::abe +MYSQLX_ABI_END(2,0) }//namespace mysqlx \ No newline at end of file diff --git a/devapi/abe_extern.cc b/devapi/abe_extern.cc index c1846fe9f..237b5d0df 100644 --- a/devapi/abe_extern.cc +++ b/devapi/abe_extern.cc @@ -7,6 +7,8 @@ namespace mysqlx{ +MYSQLX_ABI_BEGIN(2,0) + using rewrite_plan = mysqlx::abe::rewrite_plan; using abe_crypto = mysqlx::abe::abe_crypto; @@ -39,9 +41,9 @@ RowResult abe_query::execute(){ std::string abe_query::recover(const std::string &ct){ std::string pt; if(!crypto->decrypt(ct, pt)){ - return pt; + return ""; } - return ""; + return pt; } @@ -87,7 +89,7 @@ std::string abe_env::get_current_user(){ if(row_num != 1 || field_num != 1) return ""; auto it = res.begin(); - auto str = (*it).get(1).get(); + auto str = (*it).get(0).get(); std::string namehost(str); return namehost; } @@ -101,7 +103,7 @@ std::string abe_env::get_current_user_abe_attribute(){ if(row_num != 1 || field_num != 1) return ""; auto it = res.begin(); - auto str = (*it).get(1).get(); + auto str = (*it).get(0).get(); std::string att(str); return att; } @@ -157,4 +159,5 @@ bool abe_decrypt(abe_crypto &abe, std::string ct, std::string &pt){ return true; } +MYSQLX_ABI_END(2,0) }//namespace mysqlx diff --git a/include/mysqlx/abe/abe_crypto.h b/include/mysqlx/abe/abe_crypto.h index 05e7ea2b4..5d15299ff 100644 --- a/include/mysqlx/abe/abe_crypto.h +++ b/include/mysqlx/abe/abe_crypto.h @@ -7,8 +7,10 @@ #include #include #include "openssl/crypto.h" +#include "../common/api.h" namespace mysqlx{ +MYSQLX_ABI_BEGIN(2,0) namespace abe{ #define ABE_ERROR(msg) std::cerr << "error: " << (msg) << std::endl; @@ -24,7 +26,7 @@ struct abe_user{ std::string user_attr; }; -class abe_crypto{ +class PUBLIC_API abe_crypto{ public: abe_crypto(){} @@ -39,7 +41,7 @@ class abe_crypto{ bool check_abe_key(); //true: abe_key已存在 bool encrypt(std::string pt, std::string policy, std::string &ct); - bool decrypt(std::string ct, std::string &pt); + bool decrypt(const std::string ct, std::string &pt); bool import_db_cert(std::string db_cert_path); bool import_kms_cert(std::string kms_cert_path); @@ -61,6 +63,7 @@ class abe_crypto{ }; }//namespace mysqlx::abe +MYSQLX_ABI_END(2,0) }//namespace mysqlx #endif \ No newline at end of file diff --git a/include/mysqlx/abe/base64.h b/include/mysqlx/abe/base64.h index 8bd920354..98b8ba16f 100644 --- a/include/mysqlx/abe/base64.h +++ b/include/mysqlx/abe/base64.h @@ -1,6 +1,9 @@ #ifndef SQL_ABE_BASE64_H #define SQL_ABE_BASE64_H +#include "../common/api.h" namespace mysqlx{ +MYSQLX_ABI_BEGIN(2,0) + namespace abe{ namespace base64_utils { static const char _base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -143,5 +146,7 @@ namespace base64_utils { } }//namespace mysqlx::abe + +MYSQLX_ABI_END(2,0) }//namespace mysqlx #endif // SEC_ABE_UTILS_H \ No newline at end of file diff --git a/include/mysqlx/abe/rewrite.h b/include/mysqlx/abe/rewrite.h index d54bba926..7af80bdde 100644 --- a/include/mysqlx/abe/rewrite.h +++ b/include/mysqlx/abe/rewrite.h @@ -8,9 +8,12 @@ #include #include #include "abe_crypto.h" +#include "../common/api.h" namespace mysqlx{ +MYSQLX_ABI_BEGIN(2,0) + namespace abe{ enum CommandType{ BEGIN, @@ -142,5 +145,6 @@ class rewrite_plan{ }; }//namespace mysqlx::abe +MYSQLX_ABI_END(2,0) }//namespace mysqlx #endif \ No newline at end of file diff --git a/include/mysqlx/abe_extern.h b/include/mysqlx/abe_extern.h index 15d67c0da..064ed4029 100644 --- a/include/mysqlx/abe_extern.h +++ b/include/mysqlx/abe_extern.h @@ -7,17 +7,18 @@ #include "xdevapi.h" // #include "devapi/detail/result.h" namespace mysqlx { +MYSQLX_ABI_BEGIN(2,0) struct abe_parameters{ - string rsa_sk_path; //rsa私钥路径,用于解密 - string db_cert_path; //db证书,用于验签 - string kms_cert_path; //kms证书,用于验签 + std::string rsa_sk_path; //rsa私钥路径,用于解密 + std::string db_cert_path; //db证书,用于验签 + std::string kms_cert_path; //kms证书,用于验签 - string abe_key_path; //abe密钥路径 - string abe_pp_path; //abe公共参数路径,也可称mpk + std::string abe_key_path; //abe密钥路径 + std::string abe_pp_path; //abe公共参数路径,也可称mpk }; -class abe_query : public abe::rewrite_plan{ +class PUBLIC_API abe_query : public abe::rewrite_plan{ public: abe_query(Session * sess, abe::abe_crypto * abe, std::string sql): rewrite_plan(sql){ this->sess = sess; @@ -38,7 +39,7 @@ class abe_query : public abe::rewrite_plan{ Session * sess; }; -class abe_env{ +class PUBLIC_API abe_env{ public: abe_env(Session &sess){ this->sess = &sess; @@ -74,6 +75,8 @@ class abe_env{ bool abe_encrypt(abe::abe_crypto &abe, std::string pt, std::string policy, std::string &ct ); bool abe_decrypt(abe::abe_crypto &abe, std::string ct, std::string &pt); + +MYSQLX_ABI_END(2,0) } // const std::string abe_rewrite(const std::string &query, const abe_crypto &abe); #endif //ABE_EXTERN_H \ No newline at end of file diff --git a/include/mysqlx/common/api.h b/include/mysqlx/common/api.h index 9e0525f35..d7c3f03d1 100644 --- a/include/mysqlx/common/api.h +++ b/include/mysqlx/common/api.h @@ -92,6 +92,10 @@ MYSQLX_ABI_BEGIN(2,0) namespace common { } + namespace abe { + + } + MYSQLX_ABI_END(2,0) /* From ed3909ae36592633e61e8f482b4976c5555fde87 Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Fri, 22 Dec 2023 17:48:32 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9Aabe=E5=AF=86?= =?UTF-8?q?=E9=92=A5=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapi/abe/abe_crypto.cc | 2 -- devapi/abe_extern.cc | 35 ++++++++++++++++++++++------------- include/mysqlx/abe_extern.h | 7 ++++++- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/devapi/abe/abe_crypto.cc b/devapi/abe/abe_crypto.cc index 6046934f4..5f5309f03 100644 --- a/devapi/abe/abe_crypto.cc +++ b/devapi/abe/abe_crypto.cc @@ -112,8 +112,6 @@ bool abe_crypto::save_user_key(std::string key_path, std::string key_str_b64){ free(key_str); if(pt == ""){ - //todo: 后续可以考虑增加一个参数决定每次启动是否更新abe_key - //或者提供一个函数让程序员自行决定是否更新 return false; } //写入abe_user_key diff --git a/devapi/abe_extern.cc b/devapi/abe_extern.cc index 237b5d0df..b5c864921 100644 --- a/devapi/abe_extern.cc +++ b/devapi/abe_extern.cc @@ -5,6 +5,12 @@ #include "mysqlx/abe/abe_crypto.h" #include "mysqlx/xdevapi.h" +#define SQL_CURRENT_USER_KEY_PRIFIX \ + "select owner,encrypted_key,sig_db,sig_db_type,sig_kms,sig_kms_type \ + from mysql.abe_user_key where owner = '" +#define SQL_CURRENT_USER_KEY_SUFFIX "'" +#define SQL_CURRENT_USER_ATT "select current_abe_attribute()" +#define SQL_CURRENT_USER "select current_user()" namespace mysqlx{ MYSQLX_ABI_BEGIN(2,0) @@ -48,13 +54,14 @@ std::string abe_query::recover(const std::string &ct){ std::string abe_env::get_current_user_key(){ - std::string str = "select owner,encrypted_key,sig_db,sig_db_type,sig_kms,sig_kms_type from mysql.abe_user_key"; - str += " where owner = '" + abe.user.user_id + "';"; + std::string str = std::string(SQL_CURRENT_USER_KEY_PRIFIX); + str += abe.user.user_id; + str += std::string(SQL_CURRENT_USER_KEY_SUFFIX); RowResult res = sess->sql(str).execute(); - int field_num = res.count(); - int row_num = res.getColumnCount(); + int row_num = res.count(); + int field_num = res.getColumnCount(); if(row_num != 1){ ABE_LOG("It seems that you don't have the abe key, please contact the admininistrator"); } @@ -82,7 +89,7 @@ std::string abe_env::get_current_user_key(){ std::string abe_env::get_current_user(){ - RowResult res = sess->sql("select current_user()").execute(); + RowResult res = sess->sql(SQL_CURRENT_USER).execute(); int field_num = res.count(); int row_num = res.getColumnCount(); @@ -96,7 +103,7 @@ std::string abe_env::get_current_user(){ std::string abe_env::get_current_user_abe_attribute(){ - RowResult res = sess->sql("select current_abe_attribute()").execute(); + RowResult res = sess->sql(SQL_CURRENT_USER_ATT).execute(); int field_num = res.count(); int row_num = res.getColumnCount(); @@ -126,18 +133,20 @@ bool abe_env::abe_prepare_queries(const abe_parameters ¶ms){ } if(!check_abe_key()){ - std::string abe_key = get_current_user_key(); - if(abe_key == ""){ - return false; - }else{ - //todo:存储abe_key的逻辑 - abe.save_user_key(params.abe_key_path, abe_key); - } + update_abe_key(params.abe_key_path); } return true; } +bool abe_env::update_abe_key(std::string abe_key_path){ + std::string abe_key = get_current_user_key(); + if(abe_key == ""){ + return false; + } + return abe.save_user_key(abe_key_path, abe_key); +} + bool abe_env::init(const abe_parameters ¶ms){ if(!abe.init(params.abe_pp_path, params.abe_key_path, params.kms_cert_path, params.db_cert_path, diff --git a/include/mysqlx/abe_extern.h b/include/mysqlx/abe_extern.h index 064ed4029..e317ce77e 100644 --- a/include/mysqlx/abe_extern.h +++ b/include/mysqlx/abe_extern.h @@ -62,7 +62,12 @@ class PUBLIC_API abe_env{ return abe.check_abe_key(); } -private: + /* + init时如果存在abe_key则不重复下载,使用update_abe_key可以强制更新abe_key + */ + bool update_abe_key(std::string abe_key_path); + + Session * sess; abe::abe_crypto abe; From 941dbc9091a39aec6158d0774a14e4106690a59c Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Sun, 24 Dec 2023 23:37:21 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9A=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=E4=B8=BAtry-catch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapi/abe/abe_crypto.cc | 106 ++++++++------------ devapi/abe_extern.cc | 172 ++++++++++++++++---------------- include/mysqlx/abe/abe_crypto.h | 56 ++++++++--- include/mysqlx/abe_extern.h | 10 +- 4 files changed, 175 insertions(+), 169 deletions(-) diff --git a/devapi/abe/abe_crypto.cc b/devapi/abe/abe_crypto.cc index 5f5309f03..2108f1abd 100644 --- a/devapi/abe/abe_crypto.cc +++ b/devapi/abe/abe_crypto.cc @@ -16,22 +16,19 @@ namespace mysqlx{ MYSQLX_ABI_BEGIN(2,0) namespace abe{ -bool abe_crypto::encrypt(std::string pt, std::string policy, std::string &ct){ +void abe_crypto::encrypt(std::string pt, std::string policy, std::string &ct){ oabe::InitializeOpenABE(); oabe::OpenABECryptoContext cpabe("CP-ABE"); cpabe.importPublicParams(mpk); cpabe.encrypt(policy.c_str(), pt, ct); oabe::ShutdownOpenABE(); - -// std::cout<<"encrypt succefully!"<>user.user_key; @@ -94,7 +84,7 @@ bool abe_crypto::import_user_key(std::string key_path){ return true; } -bool abe_crypto::save_user_key(std::string key_path, std::string key_str_b64){ +void abe_crypto::save_user_key(std::string key_path, std::string key_str_b64){ std::string pt; //key_str为base64编码 @@ -107,32 +97,25 @@ bool abe_crypto::save_user_key(std::string key_path, std::string key_str_b64){ if(!rsa_decrypt(ct, pt)){ free(key_str); ABE_ERROR("failed to decrypt abe user key"); - return false; } free(key_str); - if(pt == ""){ - return false; - } //写入abe_user_key std::ofstream ofs_key(key_path, std::ios::out); if(!ofs_key){ ABE_ERROR2("error opening user key-file.\nkey_path=" , key_path); - return false; } ofs_key << pt; user.user_key = pt; ofs_key.close(); - return true; } -bool abe_crypto::import_sk(std::string rsa_sk_path){ +void abe_crypto::import_sk(std::string rsa_sk_path){ // 导入rsa密钥文件并读取密钥 FILE *hPriKeyFile = fopen(rsa_sk_path.c_str(), "rb"); if (hPriKeyFile == NULL) { - // assert(false); - return false; + ABE_ERROR2("read file failed, file_path=", rsa_sk_path); } std::string strRet; RSA *pRSAPriKey = RSA_new(); @@ -141,11 +124,10 @@ bool abe_crypto::import_sk(std::string rsa_sk_path){ // assert(false); RSA_free(pRSAPriKey); fclose(hPriKeyFile); - return false; + ABE_ERROR2("read rsa prikey failed, file_path=", rsa_sk_path); } sk = pRSAPriKey; fclose(hPriKeyFile); - return true; } RSA * abe_crypto::import_pk(const std::string cert_path, std::string &err_msg){ @@ -184,28 +166,24 @@ RSA * abe_crypto::import_pk(const std::string cert_path, std::string &err_msg){ return pk; } -bool abe_crypto::import_db_cert(std::string db_cert_path){ +void abe_crypto::import_db_cert(std::string db_cert_path){ std::string err_msg; RSA *pk = import_pk(db_cert_path, err_msg); if(pk == NULL){ err_msg += ":" + db_cert_path; - ABE_ERROR(err_msg); - return false; + ABE_ERROR(err_msg.c_str()); } db_pk = pk; - return true; } -bool abe_crypto::import_kms_cert(std::string kms_cert_path){ +void abe_crypto::import_kms_cert(std::string kms_cert_path){ std::string err_msg; RSA *pk = import_pk(kms_cert_path, err_msg); if(pk == NULL){ err_msg += ":" + kms_cert_path; - ABE_ERROR(err_msg); - return false; + ABE_ERROR(err_msg.c_str()); } kms_pk = pk; - return true; } abe_crypto::~abe_crypto(){ @@ -214,7 +192,7 @@ abe_crypto::~abe_crypto(){ if(sk != NULL) RSA_free(sk); } -bool abe_crypto::verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, unsigned char * sig, size_t sig_length){ +void abe_crypto::verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, unsigned char * sig, size_t sig_length){ unsigned char digest[SHA512_DIGEST_LENGTH]; // 对输入进行hash SHA512(msg, msg_length, digest); @@ -222,35 +200,33 @@ bool abe_crypto::verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, uns // 对签名进行认证 int ret = RSA_verify(NID_sha512, digest, SHA512_DIGEST_LENGTH, sig, sig_length, pk); if (ret != 1){ - ABE_ERROR("verify error"); unsigned long ulErr = ERR_get_error(); char szErrMsg[1024] = {0}; - ABE_ERROR2("error number:" , ulErr); ERR_error_string(ulErr, szErrMsg); // 格式:error:errId:库:函数:原因 - std::cout << szErrMsg << std::endl; - return false; + ABE_ERROR2("abe_key verify error: ", szErrMsg); } - return true; } -bool abe_crypto::verify_db_sig(const std::string msg, const std::string sig_b64){ +void abe_crypto::verify_db_sig(const std::string msg, const std::string sig_b64){ //sig是base64编码,需要先解码 size_t sig_b64_length = sig_b64.length(); unsigned char * sig = (unsigned char*)malloc(base64_utils::b64_dec_len(sig_b64_length)); size_t sig_length = base64_utils::b64_decode(sig_b64.c_str(), sig_b64_length, (char*)sig); - if(!verify_sig(db_pk, (unsigned char *)msg.c_str(), msg.length(), sig, sig_length)){ + try{ + verify_sig(db_pk, (unsigned char *)msg.c_str(), msg.length(), sig, sig_length); free(sig); - ABE_ERROR("db_sig: verify failed"); - return false; + }catch(const ::mysqlx::abe::Error& e){ + free(sig); + ABE_ERROR2("db_sig:", e.what()); + }catch(...){ + free(sig); + ABE_ERROR("nknown exception"); } - ABE_LOG("db_sig: verify success"); - free(sig); - return true; } -bool abe_crypto::verify_kms_sig(const std::string msg_b64, const std::string sig_b64){ +void abe_crypto::verify_kms_sig(const std::string msg_b64, const std::string sig_b64){ //msg和sig都是base64编码,需要先解码 size_t msg_b64_length = msg_b64.length(); @@ -261,17 +237,19 @@ bool abe_crypto::verify_kms_sig(const std::string msg_b64, const std::string sig unsigned char * sig = (unsigned char*)malloc(base64_utils::b64_dec_len(sig_b64_length)); size_t sig_length = base64_utils::b64_decode(sig_b64.c_str(), sig_b64_length, (char*)sig); - if(!verify_sig(kms_pk, msg, msg_length, sig, sig_length)){ + try{ + verify_sig(kms_pk, msg, msg_length, sig, sig_length); free(msg); free(sig); - ABE_ERROR("kms_sig: verify failed"); - return false; + }catch(const ::mysqlx::abe::Error& e){ + free(msg); + free(sig); + ABE_ERROR2("kms_sig:", e.what()); + }catch(...){ + free(msg); + free(sig); + ABE_ERROR("nknown exception"); } - - ABE_LOG("kms_sig: verify success"); - free(msg); - free(sig); - return true; } //注意ct初始化时必须指定长度,否则ct.length会因为0x00而截断 diff --git a/devapi/abe_extern.cc b/devapi/abe_extern.cc index b5c864921..9ec8b6ce5 100644 --- a/devapi/abe_extern.cc +++ b/devapi/abe_extern.cc @@ -45,127 +45,127 @@ RowResult abe_query::execute(){ } std::string abe_query::recover(const std::string &ct){ - std::string pt; - if(!crypto->decrypt(ct, pt)){ - return ""; + try{ + std::string pt; + crypto->decrypt(ct, pt); + return pt; } - return pt; + CATCH_AND_WRAP } std::string abe_env::get_current_user_key(){ - std::string str = std::string(SQL_CURRENT_USER_KEY_PRIFIX); - str += abe.user.user_id; - str += std::string(SQL_CURRENT_USER_KEY_SUFFIX); + try{ + std::string str = std::string(SQL_CURRENT_USER_KEY_PRIFIX); + str += abe.user.user_id; + str += std::string(SQL_CURRENT_USER_KEY_SUFFIX); - RowResult res = sess->sql(str).execute(); + RowResult res = sess->sql(str).execute(); - int row_num = res.count(); - int field_num = res.getColumnCount(); - if(row_num != 1){ - ABE_LOG("It seems that you don't have the abe key, please contact the admininistrator"); - } - if(field_num != rewrite_plan::TABLE_ABE_UER_KEY_FIELD_NUM){ - ABE_ERROR("system table 'abe_user_key' error"); - return ""; - } + int row_num = res.count(); + int field_num = res.getColumnCount(); + if(row_num != 1){ + throw_error("It seems that you don't have the abe key, please contact the admininistrator."); + } + if(field_num != rewrite_plan::TABLE_ABE_UER_KEY_FIELD_NUM){ + throw_error("system table 'abe_user_key' error"); + } - auto it = res.begin(); - std::string key_str = (*it).get(rewrite_plan::F_KEY_NUM).get(); - std::string sig_db = (*it).get(rewrite_plan::F_SIG_DB_NUM).get(); - std::string sig_db_type = (*it).get(rewrite_plan::F_SIG_DB_TYPE_NUM).get(); - std::string sig_kms = (*it).get(rewrite_plan::F_SIG_KMS_NUM).get(); - std::string sig_kms_type = (*it).get(rewrite_plan::F_SIG_KMS_TYPE_NUM).get(); - - std::string namehost = abe.user.user_id; - std::string attrlist = abe.user.user_attr; - if(!(abe.verify_db_sig(namehost + attrlist,sig_db) - && abe.verify_kms_sig(key_str,sig_kms))){ - return ""; + auto it = res.begin(); + std::string key_str = (*it).get(rewrite_plan::F_KEY_NUM).get(); + std::string sig_db = (*it).get(rewrite_plan::F_SIG_DB_NUM).get(); + std::string sig_db_type = (*it).get(rewrite_plan::F_SIG_DB_TYPE_NUM).get(); + std::string sig_kms = (*it).get(rewrite_plan::F_SIG_KMS_NUM).get(); + std::string sig_kms_type = (*it).get(rewrite_plan::F_SIG_KMS_TYPE_NUM).get(); + + std::string namehost = abe.user.user_id; + std::string attrlist = abe.user.user_attr; + abe.verify_db_sig(namehost + attrlist,sig_db); + abe.verify_kms_sig(key_str,sig_kms); + return key_str; } - return key_str; - + CATCH_AND_WRAP } std::string abe_env::get_current_user(){ + try{ + RowResult res = sess->sql(SQL_CURRENT_USER).execute(); - RowResult res = sess->sql(SQL_CURRENT_USER).execute(); - - int field_num = res.count(); - int row_num = res.getColumnCount(); - if(row_num != 1 || field_num != 1) return ""; + int field_num = res.count(); + int row_num = res.getColumnCount(); + if(row_num != 1 || field_num != 1){ + throw_error("abe query failed: get current user."); + } - auto it = res.begin(); - auto str = (*it).get(0).get(); - std::string namehost(str); - return namehost; + auto it = res.begin(); + auto str = (*it).get(0).get(); + std::string namehost(str); + return namehost; + } + CATCH_AND_WRAP } std::string abe_env::get_current_user_abe_attribute(){ + try{ + RowResult res = sess->sql(SQL_CURRENT_USER_ATT).execute(); - RowResult res = sess->sql(SQL_CURRENT_USER_ATT).execute(); - - int field_num = res.count(); - int row_num = res.getColumnCount(); - if(row_num != 1 || field_num != 1) return ""; + int field_num = res.count(); + int row_num = res.getColumnCount(); + if(row_num != 1 || field_num != 1){ + throw_error("abe query failed: get current user abe attribute."); + } - auto it = res.begin(); - auto str = (*it).get(0).get(); - std::string att(str); - return att; + auto it = res.begin(); + auto str = (*it).get(0).get(); + std::string att(str); + return att; + } + CATCH_AND_WRAP } -bool abe_env::abe_prepare_queries(const abe_parameters ¶ms){ - std::string namehost = get_current_user(); - if(namehost == ""){ - // ABE_ERROR("can't get your username and host!"); - return false; - }else{ +void abe_env::abe_prepare_queries(const abe_parameters ¶ms){ + try{ + std::string namehost = get_current_user(); abe.set_name(namehost); - - } - std::string attrlist = get_current_user_abe_attribute(); - if(attrlist == ""){ - // ABE_ERROR("can't get your attrlist, please contact adminastrator."); - return false; - }else{ + std::string attrlist = get_current_user_abe_attribute(); abe.set_att(attrlist); + if(!check_abe_key()){ + update_abe_key(params.abe_key_path); + } } - - if(!check_abe_key()){ - update_abe_key(params.abe_key_path); - } - return true; - + CATCH_AND_WRAP } -bool abe_env::update_abe_key(std::string abe_key_path){ - std::string abe_key = get_current_user_key(); - if(abe_key == ""){ - return false; +void abe_env::update_abe_key(std::string abe_key_path){ + try{ + std::string abe_key = get_current_user_key(); + abe.save_user_key(abe_key_path, abe_key); } - return abe.save_user_key(abe_key_path, abe_key); + CATCH_AND_WRAP } -bool abe_env::init(const abe_parameters ¶ms){ - if(!abe.init(params.abe_pp_path, params.abe_key_path, +void abe_env::init(const abe_parameters ¶ms){ + try{ + abe.init(params.abe_pp_path, params.abe_key_path, params.kms_cert_path, params.db_cert_path, - params.rsa_sk_path) - || abe_prepare_queries(params)){ - // ABE_ERROR("failed to init abe system"); - return false; + params.rsa_sk_path); + abe_prepare_queries(params); } - return false; + CATCH_AND_WRAP } -bool abe_encrypt(abe_crypto &abe, std::string pt, std::string policy, std::string &ct ){ - abe.encrypt(pt, policy, ct); - return true; +void abe_encrypt(abe_crypto &abe, std::string pt, std::string policy, std::string &ct ){ + try{ + abe.encrypt(pt, policy, ct); + } + CATCH_AND_WRAP } -bool abe_decrypt(abe_crypto &abe, std::string ct, std::string &pt){ - abe.decrypt(ct, pt); - return true; +void abe_decrypt(abe_crypto &abe, std::string ct, std::string &pt){ + try{ + abe.decrypt(ct, pt); + } + CATCH_AND_WRAP } MYSQLX_ABI_END(2,0) diff --git a/include/mysqlx/abe/abe_crypto.h b/include/mysqlx/abe/abe_crypto.h index 5d15299ff..c75834ab5 100644 --- a/include/mysqlx/abe/abe_crypto.h +++ b/include/mysqlx/abe/abe_crypto.h @@ -8,14 +8,42 @@ #include #include "openssl/crypto.h" #include "../common/api.h" +#include "../common/error.h" namespace mysqlx{ MYSQLX_ABI_BEGIN(2,0) namespace abe{ -#define ABE_ERROR(msg) std::cerr << "error: " << (msg) << std::endl; -#define ABE_ERROR2(msg,comment) std::cerr << (msg) << (comment) << std::endl; -#define ABE_LOG(msg) std::cout << (msg) << std::endl; +//define the abe error class, maintain the independence of abe module +class PUBLIC_API Error : public common::Error +{ +public: + Error(const char *msg) + : common::Error(msg) + {} +}; + +inline +void throw_error(const char *msg) +{ + throw Error(msg); +} + +inline void my_abe_throw_error2(const std::string msg, const std::string comment){ + std::string str = std::string(msg) + std::string(comment); + throw_error(str.c_str()); +} + +inline void my_abe_throw_error3(const std::string msg, const std::string comment1, const std::string comment2){ + std::string str = std::string(msg) + std::string(comment1) + std::string(comment2); + throw_error(str.c_str()); +} + +#define ABE_ERROR(msg) throw_error(msg); +#define ABE_ERROR2(msg,comment) my_abe_throw_error2(msg, comment); +#define ABE_ERROR3(msg,comment1, comment2) my_abe_throw_error3(msg, comment1, comment2); +// #define ABE_LOG(msg) std::cout << (msg) << std::endl; + #define RSA_Encrypt_length 245 #define RSA_Decrypt_length 256 @@ -32,23 +60,23 @@ class PUBLIC_API abe_crypto{ abe_crypto(){} abe_crypto(std::string name){user.user_id = name;}//name或者说user_id,即用户标识,一般和登录的数据库用户同名 - bool init(std::string mpk_path, std::string key_path, std::string kms_cert_path, std::string db_cert_path, std::string rsa_sk_path); + void init(std::string mpk_path, std::string key_path, std::string kms_cert_path, std::string db_cert_path, std::string rsa_sk_path); void set_name(std::string namehost){user.user_id = namehost;} void set_att(std::string att) {user.user_attr = att;} - bool import_mpk(std::string mpk_path); + void import_mpk(std::string mpk_path); bool import_user_key(std::string key_path); - bool save_user_key(std::string key_path, std::string key_str); + void save_user_key(std::string key_path, std::string key_str); bool check_abe_key(); //true: abe_key已存在 - bool encrypt(std::string pt, std::string policy, std::string &ct); - bool decrypt(const std::string ct, std::string &pt); + void encrypt(std::string pt, std::string policy, std::string &ct); + void decrypt(const std::string ct, std::string &pt); - bool import_db_cert(std::string db_cert_path); - bool import_kms_cert(std::string kms_cert_path); - bool import_sk(std::string rsa_sk_path); + void import_db_cert(std::string db_cert_path); + void import_kms_cert(std::string kms_cert_path); + void import_sk(std::string rsa_sk_path); - bool verify_db_sig(const std::string msg, const std::string sig_db_b64); - bool verify_kms_sig(const std::string msg_b64, const std::string sig_kms_b64); + void verify_db_sig(const std::string msg, const std::string sig_db_b64); + void verify_kms_sig(const std::string msg_b64, const std::string sig_kms_b64); struct abe_user user; ~abe_crypto(); @@ -57,7 +85,7 @@ class PUBLIC_API abe_crypto{ RSA *kms_pk = NULL; RSA *db_pk = NULL; RSA *sk = NULL; - bool verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, unsigned char * sig, size_t sig_length); + void verify_sig(RSA *pk, unsigned char * msg, size_t msg_length, unsigned char * sig, size_t sig_length); bool rsa_decrypt(const std::string ct, std::string &pt); RSA * import_pk(const std::string cert_path, std::string &err_msg); }; diff --git a/include/mysqlx/abe_extern.h b/include/mysqlx/abe_extern.h index e317ce77e..8ec18eff9 100644 --- a/include/mysqlx/abe_extern.h +++ b/include/mysqlx/abe_extern.h @@ -48,7 +48,7 @@ class PUBLIC_API abe_env{ /* 初始化abe的环境,包括所需abe密钥和证书、私钥等 */ - bool init(const abe_parameters ¶ms); + void init(const abe_parameters ¶ms); /* 仿照原来的用法 @@ -65,21 +65,21 @@ class PUBLIC_API abe_env{ /* init时如果存在abe_key则不重复下载,使用update_abe_key可以强制更新abe_key */ - bool update_abe_key(std::string abe_key_path); + void update_abe_key(std::string abe_key_path); Session * sess; abe::abe_crypto abe; - bool abe_prepare_queries(const abe_parameters ¶ms); + void abe_prepare_queries(const abe_parameters ¶ms); std::string get_current_user(); std::string get_current_user_abe_attribute(); std::string get_current_user_key(); }; -bool abe_encrypt(abe::abe_crypto &abe, std::string pt, std::string policy, std::string &ct ); -bool abe_decrypt(abe::abe_crypto &abe, std::string ct, std::string &pt); +void abe_encrypt(abe::abe_crypto &abe, std::string pt, std::string policy, std::string &ct ); +void abe_decrypt(abe::abe_crypto &abe, std::string ct, std::string &pt); MYSQLX_ABI_END(2,0) } From cd17d5618a7d116fb3b52bdd35406179c8e11d65 Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Sun, 24 Dec 2023 23:42:49 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9A=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86=E5=BD=A2=E5=BC=8F?= =?UTF-8?q?=E4=B8=BAtry-catch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapi/abe_extern.cc | 45 +++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/devapi/abe_extern.cc b/devapi/abe_extern.cc index 9ec8b6ce5..056274984 100644 --- a/devapi/abe_extern.cc +++ b/devapi/abe_extern.cc @@ -19,29 +19,32 @@ using rewrite_plan = mysqlx::abe::rewrite_plan; using abe_crypto = mysqlx::abe::abe_crypto; RowResult abe_query::execute(){ - parse_and_rewrite(); - - field_name_list = get_field_name_list(); - - RowResult res = sess->sql(real_sql).execute(); - - auto it = res.getColumns().begin(); - auto end = res.getColumns().end(); - unsigned int i=0; - for (;it != end;++it){ - std::string field_name = (*it).getColumnName(); - auto temp = std::find(field_name_list.begin(), field_name_list.end(), field_name); - if(temp != field_name_list.end()){ - //该列是使用了abe_dec的列 - f_flag.push_back(1); - field_num_list.push_back(i); - }else{ - //普通列 - f_flag.push_back(0); + try{ + parse_and_rewrite(); + + field_name_list = get_field_name_list(); + + RowResult res = sess->sql(real_sql).execute(); + + auto it = res.getColumns().begin(); + auto end = res.getColumns().end(); + unsigned int i=0; + for (;it != end;++it){ + std::string field_name = (*it).getColumnName(); + auto temp = std::find(field_name_list.begin(), field_name_list.end(), field_name); + if(temp != field_name_list.end()){ + //该列是使用了abe_dec的列 + f_flag.push_back(1); + field_num_list.push_back(i); + }else{ + //普通列 + f_flag.push_back(0); + } + i++; } - i++; + return res; } - return res; + CATCH_AND_WRAP } std::string abe_query::recover(const std::string &ct){ From f940e8c2f34734aaeb2cad698a4e1816b78d7a30 Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Mon, 25 Dec 2023 16:05:05 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E5=A2=9E=E5=8A=A0abe=5Fenv::recover?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapi/abe_extern.cc | 8 ++++++++ include/mysqlx/abe_extern.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/devapi/abe_extern.cc b/devapi/abe_extern.cc index 056274984..508a7ff4e 100644 --- a/devapi/abe_extern.cc +++ b/devapi/abe_extern.cc @@ -56,6 +56,14 @@ std::string abe_query::recover(const std::string &ct){ CATCH_AND_WRAP } +std::string abe_env::recover(const std::string &ct){ + try{ + std::string pt; + abe.decrypt(ct, pt); + return pt; + } + CATCH_AND_WRAP +} std::string abe_env::get_current_user_key(){ try{ diff --git a/include/mysqlx/abe_extern.h b/include/mysqlx/abe_extern.h index 8ec18eff9..0213387ff 100644 --- a/include/mysqlx/abe_extern.h +++ b/include/mysqlx/abe_extern.h @@ -58,6 +58,9 @@ class PUBLIC_API abe_env{ return abe_query(sess, &abe, input); } + //解密 + std::string recover(const std::string &ct); + bool check_abe_key(){ return abe.check_abe_key(); } From 50a88b10b9eab503caea3c013c05b309f0c4973e Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Wed, 31 Jan 2024 10:17:58 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9AREADME?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 235 ++++++++++++++++++++++++++---------------------------- 1 file changed, 115 insertions(+), 120 deletions(-) diff --git a/README.md b/README.md index 243513d50..db34d858b 100644 --- a/README.md +++ b/README.md @@ -1,138 +1,133 @@ # MySQL Connector/C++ -This is a release of MySQL Connector/C++, [the C++ interface](https://dev.mysql.com/doc/dev/connector-cpp/8.0/) for communicating with MySQL servers. +## ABE支持 -For detailed information please visit the official [MySQL Connector/C++ documentation](https://dev.mysql.com/doc/dev/connector-cpp/8.0/). +### 使用 -## Licensing +要使用ABE功能,需引用abe_extern.h头文件。 -Please refer to files README and LICENSE, available in this repository, and [Legal Notices in documentation](https://dev.mysql.com/doc/connector-cpp/8.0/en/preface.html) for further details. +开放接口和使用方法可参考如下示例: -## Download & Install - -MySQL Connector/C++ can be installed from pre-compiled packages that can be downloaded from the [MySQL downloads page](https://dev.mysql.com/downloads/connector/cpp/). -The process of installing of Connector/C++ from a binary distribution is described in [MySQL online manuals](https://dev.mysql.com/doc/connector-cpp/8.0/en/connector-cpp-installation-binary.html) - -### Building from sources - -MySQL Connector/C++ can be installed from the source. Please check [MySQL online manuals](https://dev.mysql.com/doc/connector-cpp/8.0/en/connector-cpp-installation-source.html) - -### GitHub Repository - -This repository contains the MySQL Connector/C++ source code as per latest released version. You should expect to see the same contents here and within the latest released Connector/C++ package. - -## Sample Code - -``` +```cpp #include -#include - -using ::std::cout; -using ::std::endl; -using namespace ::mysqlx; - - -int main(int argc, const char* argv[]) -try { - - const char *url = (argc > 1 ? argv[1] : "mysqlx://root@127.0.0.1"); - - cout << "Creating session on " << url - << " ..." << endl; - - Session sess(url); - - cout <<"Session accepted, creating collection..." < ids = add.getGeneratedIds(); - for (string id : ids) - cout <<"- added doc with id: " << id < 1 and name like 'ba%'").execute(); - - int i = 0; - for (DbDoc doc : docs) - { - cout <<"doc#" < +#include +#include +#include +using namespace mysqlx; +using std::cout; +using std::endl; +using std::vector; + +//数据库连接 +Session get_connect(){ + //注意 mysqlcppconn8 默认使用的端口:33060,若连接3306端口会提示错误 + //使用用户名:testabe + //用户 root 的密码是:123456 + //主机:172.17.0.9 + //端口:33060 + //数据库:company + cout << "start connecting...\n"; + + SessionSettings option("172.17.0.9", 33060, "testabe", "123456"); + Session sess(option); + + cout <<"Done!" <() <<" "; + cout << (*it).get(1).get(); //这个string是mysqlx的string,继承自std::u16string + cout << endl; } - - cout << endl; - } - cout <<"Done!" <() + */ + abe_query query = env.sql("select id,title,abe_dec(data) from share;"); + RowResult rs2 = query.execute(); + // cout << "real_sql = " << query.real_sql << endl; + for (auto it = rs2.begin();it != rs2.end();++it){ + cout << (*it).get(0).get() << "\t"; + cout << (*it).get(1).get() << "\t"; + auto ustr = (*it).get(2).get(); + try{ + cout << env.recover(ustr); + }catch(const Error &e){ + cout << "can't decrypt"; + } + cout << endl; + } + cout << "abe query end." << endl; + } -catch (const char *ex) +int main() { - cout <<"EXCEPTION: " < Date: Mon, 5 Feb 2024 03:10:58 +0000 Subject: [PATCH 09/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E5=A4=9A?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E4=B8=8B=E4=B8=8D=E8=83=BD=E4=BD=BF=E7=94=A8?= =?UTF-8?q?ABE=E5=8A=A0=E8=A7=A3=E5=AF=86=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devapi/abe/abe_crypto.cc | 23 +++++++++++++++++------ include/mysqlx/abe/abe_crypto.h | 3 +++ include/mysqlx/abe_extern.h | 11 +++++++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/devapi/abe/abe_crypto.cc b/devapi/abe/abe_crypto.cc index 2108f1abd..80628a749 100644 --- a/devapi/abe/abe_crypto.cc +++ b/devapi/abe/abe_crypto.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -17,12 +18,12 @@ MYSQLX_ABI_BEGIN(2,0) namespace abe{ void abe_crypto::encrypt(std::string pt, std::string policy, std::string &ct){ - - oabe::InitializeOpenABE(); + oabe::OpenABEStateContext thread_context; + thread_context.initializeThread(); oabe::OpenABECryptoContext cpabe("CP-ABE"); cpabe.importPublicParams(mpk); cpabe.encrypt(policy.c_str(), pt, ct); - oabe::ShutdownOpenABE(); + thread_context.shutdownThread(); } void abe_crypto::decrypt(const std::string ct, std::string &pt){ @@ -31,15 +32,16 @@ void abe_crypto::decrypt(const std::string ct, std::string &pt){ ABE_ERROR("no abe key!"); } - oabe::InitializeOpenABE(); + oabe::OpenABEStateContext thread_context; + thread_context.initializeThread(); oabe::OpenABECryptoContext cpabe("CP-ABE"); cpabe.importPublicParams(mpk); cpabe.importUserKey(user.user_id.c_str(), user.user_key); if(!cpabe.decrypt(user.user_id.c_str(), ct, pt)){ - oabe::ShutdownOpenABE(); + thread_context.shutdownThread(); ABE_ERROR("abe: can't decrypt."); } - oabe::ShutdownOpenABE(); + thread_context.shutdownThread(); } bool abe_crypto::check_abe_key(){ @@ -297,6 +299,15 @@ bool abe_crypto::rsa_decrypt(const std::string ct, std::string &pt){ return flag; } +void _initialize_abe(){ + oabe::InitializeOpenABE(); +} + +void _shutdown_abe(){ + oabe::ShutdownOpenABE(); +} + + }//namespace mysqlx::abe MYSQLX_ABI_END(2,0) diff --git a/include/mysqlx/abe/abe_crypto.h b/include/mysqlx/abe/abe_crypto.h index c75834ab5..156a7a7bb 100644 --- a/include/mysqlx/abe/abe_crypto.h +++ b/include/mysqlx/abe/abe_crypto.h @@ -90,6 +90,9 @@ class PUBLIC_API abe_crypto{ RSA * import_pk(const std::string cert_path, std::string &err_msg); }; +void PUBLIC_API _initialize_abe(); +void PUBLIC_API _shutdown_abe(); + }//namespace mysqlx::abe MYSQLX_ABI_END(2,0) }//namespace mysqlx diff --git a/include/mysqlx/abe_extern.h b/include/mysqlx/abe_extern.h index 0213387ff..39001a2a3 100644 --- a/include/mysqlx/abe_extern.h +++ b/include/mysqlx/abe_extern.h @@ -81,8 +81,15 @@ class PUBLIC_API abe_env{ }; -void abe_encrypt(abe::abe_crypto &abe, std::string pt, std::string policy, std::string &ct ); -void abe_decrypt(abe::abe_crypto &abe, std::string ct, std::string &pt); +void PUBLIC_API abe_encrypt(abe::abe_crypto &abe, std::string pt, std::string policy, std::string &ct ); +void PUBLIC_API abe_decrypt(abe::abe_crypto &abe, std::string ct, std::string &pt); + +void PUBLIC_API initialize_abe(){ + abe::_initialize_abe(); +} +void PUBLIC_API shutdown_abe(){ + abe::_shutdown_abe(); +} MYSQLX_ABI_END(2,0) } From f8b9508b33e2e3b42049ffd9e68d622c436c2aa1 Mon Sep 17 00:00:00 2001 From: hpq <2080240649@qq.com> Date: Mon, 5 Feb 2024 03:12:57 +0000 Subject: [PATCH 10/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9AREADME?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index db34d858b..e4f955cf1 100644 --- a/README.md +++ b/README.md @@ -108,9 +108,11 @@ void abe_example1(Session &sess) { int main() { try{ + initialize_abe(); Session sess = get_connect(); normal_example(sess); abe_example1(sess); + shutdown_abe(); } catch (const Error& e) { cout << e.what() <