// // Created by xajhuang on 2022/12/2. // #include #include "config.h" #include "misc.h" #include "proto.h" #include "crypto.h" #include "user_errno.h" #include "zlog_module.h" #define CURRENT_PROTOCOL_VERSION (1) typedef struct { unsigned int ver; unsigned int cryptoType; unsigned long long timeStamp; unsigned int code; cJSON *msgContend; } PROTOCOL_WARP, *PPROTOCOL_WARP; const char *proto_decode_context(const char *pString, unsigned int *pVer, unsigned long long *pTm) { cJSON *pMsgCtx; unsigned char *pBase64; int decodeSize; unsigned int outSize = 0; char *pMsgContent = NULL; cJSON *pRoot = cJSON_Parse(pString); if (!pRoot) { return NULL; } cJSON *pCrypto = cJSON_GetObjectItem(pRoot, "cryptoType"); if (!pCrypto) { cJSON_Delete(pRoot); return NULL; } if (pVer) { cJSON *pObj = cJSON_GetObjectItem(pRoot, "ver"); if (pObj) { *pVer = pObj->valueint; } } if (pTm) { cJSON *pObj = cJSON_GetObjectItem(pRoot, "timeStamp"); if (pObj) { *pTm = (unsigned long long)pObj->valuedouble; } } pMsgCtx = cJSON_GetObjectItem(pRoot, "msgContent"); if (!pMsgCtx) { cJSON_Delete(pRoot); return NULL; } switch (pCrypto->valueint) { case CRYPTO_NONE: pMsgContent = cJSON_Print(pMsgCtx); break; case CRYPTO_BASE64: pMsgContent = (char *)base64_decode(pMsgCtx->valuestring, (unsigned int *)&outSize); break; case CRYPTO_AES128: case CRYPTO_AES256: case CRYPTO_3DES: { int cryptoType; const char *pKey = config_get_proto_crypto_key(); if (pCrypto->valueint == CRYPTO_AES128) { cryptoType = AES128_ECB_PKCS7PADDING; } else if (pCrypto->valueint == CRYPTO_AES256) { cryptoType = AES256_ECB_PKCS7PADDING; } else if (pCrypto->valueint == CRYPTO_3DES) { cryptoType = DES3_ECB_PKCS7PADDING; } else { cJSON_Delete(pRoot); return NULL; } pBase64 = (unsigned char *)base64_decode(pMsgCtx->valuestring, (unsigned int *)&outSize); if (symmetric_decrypto(cryptoType, pBase64, outSize, (unsigned char **)(&pMsgContent), &decodeSize, pKey) != ERR_SUCCESS) { free((void *)pBase64); if (pMsgContent) { free(pMsgContent); } cJSON_Delete(pRoot); return NULL; } else { pMsgContent[decodeSize] = 0; } free((void *)pBase64); } break; } cJSON_Delete(pRoot); return pMsgContent; } const char *proto_create_new(cJSON *pMsgCtx, int httpCode) { const char *pStrProto; cJSON *pRoot; PROTOCOL_WARP pro = {.ver = CURRENT_PROTOCOL_VERSION, .cryptoType = config_get_proto_crypto_type(), .timeStamp = get_current_time_ms(), .code = httpCode}; pRoot = cJSON_CreateObject(); if (pRoot == NULL) { return NULL; } cJSON_AddNumberToObject(pRoot, "ver", pro.ver); cJSON_AddNumberToObject(pRoot, "cryptoType", pro.cryptoType); cJSON_AddNumberToObject(pRoot, "timeStamp", (double)pro.timeStamp); cJSON_AddNumberToObject(pRoot, "code", pro.code); if (pMsgCtx == NULL) { pro.msgContend = cJSON_CreateObject(); } else { pro.msgContend = pMsgCtx; } switch (pro.cryptoType) { case CRYPTO_NONE: cJSON_AddItemToObject(pRoot, "msgContent", pro.msgContend); break; case CRYPTO_BASE64: { const char *pStrMsg = cJSON_Print(pro.msgContend); const char *base64 = base64_encode((unsigned char *)pStrMsg, strlen(pStrMsg)); cJSON_AddStringToObject(pRoot, "msgContent", base64); free((void *)base64); cJSON_free(pro.msgContend); } break; case CRYPTO_AES128: case CRYPTO_AES256: case CRYPTO_3DES: { int cryptoType; const char *pKey = config_get_proto_crypto_key(); const char *base64; const char *pStrMsg = cJSON_Print(pro.msgContend); if (pro.cryptoType == CRYPTO_AES128) { cryptoType = AES128_ECB_PKCS7PADDING; } else if (pro.cryptoType == CRYPTO_AES256) { cryptoType = AES256_ECB_PKCS7PADDING; } else { cryptoType = DES3_ECB_PKCS7PADDING; } if (pKey == NULL || strlen(pKey) == 0) { LOG_MOD(error, ZLOG_MOD_PROTO, "Cryptography key empty of algorithm %d, Used default algorithm BASE64\n", cryptoType); base64 = base64_encode((unsigned char *)pStrMsg, strlen(pStrMsg)); pro.cryptoType = CRYPTO_BASE64; } else { int ret; unsigned char *buf; int outSize = 0; ret = symmetric_encrypto(cryptoType, (unsigned char *)pStrMsg, strlen(pStrMsg), &buf, &outSize, pKey); if (ret != ERR_SUCCESS) { LOG_MOD(error, ZLOG_MOD_PROTO, "Unsupported protocol crypto : %d, Used default algorithm BASE64\n", cryptoType); base64 = base64_encode((unsigned char *)pStrMsg, strlen(pStrMsg)); pro.cryptoType = CRYPTO_BASE64; } else { base64 = base64_encode((unsigned char *)buf, outSize); } } cJSON_AddStringToObject(pRoot, "msgContent", base64); free((void *)base64); cJSON_free(pro.msgContend); } break; default: LOG_MOD(error, ZLOG_MOD_PROTO, "Unsupported protocol crypto algorithms: %d, Used default algorithm BASE64\n", pro.cryptoType); cJSON_free(pro.msgContend); cJSON_Delete(pRoot); return NULL; } pStrProto = cJSON_PrintUnformatted(pRoot); LOG_MOD(trace, ZLOG_MOD_PROTO, "Create: \n%s\n", pStrProto); cJSON_Delete(pRoot); return pStrProto; }