From df6b1a292c069b949fb017fbc5cf114f76ce5e6d Mon Sep 17 00:00:00 2001 From: dny Date: Mon, 18 May 2026 20:36:54 +0800 Subject: [PATCH] fix: harden app command security handling Harden newly added app command paths and keep command-line behavior aligned with supported functionality. - restrict enc output files and SM key-store files to owner-only permissions - fail closed for explicitly configured CA files and enforce s_client host identity checks - keep TLS app mode TLS-only and require client certificates when server verification is enabled - validate SM key UUID inputs and preserve IPv4 split allocation bases during SAN parsing - apply stdin size limits, cast ctype inputs safely, and honor errdecode -hex parsing - reject unsupported GMAC/AES-WRAP/prime -safe command paths and update documentation - apply pkcs12 algorithm options and add focused SDV coverage for the fixed paths Cherry-picked from: https://gitcode.com/openHiTLS/openhitls/merge_requests/1463 Signed-off-by: Dongjianwei001 --- apps/src/app_client.c | 9 ++ apps/src/app_conf.c | 15 ++- apps/src/app_enc.c | 42 +++++++ apps/src/app_keymgmt.c | 105 +++++++++++++++++- apps/src/app_list.c | 9 -- apps/src/app_mac.c | 5 + apps/src/app_pkcs12.c | 3 + apps/src/app_prime.c | 19 +--- apps/src/app_sm.c | 5 + apps/src/app_tls_common.c | 71 +++++++----- apps/src/app_utils.c | 23 ++-- docs/en/4_User Guide/5_Command Line Guide.md | 12 +- docs/zh/4_使用指南/5_命令行指南.md | 12 +- .../testcase/apps/test_suite_ut_app_conf.c | 6 + .../testcase/apps/test_suite_ut_app_conf.data | 3 + .../testcase/apps/test_suite_ut_app_keymgmt.c | 25 ++++- .../testcase/apps/test_suite_ut_app_mac.data | 3 + .../testcase/apps/test_suite_ut_app_pkcs12.c | 10 +- .../testcase/apps/test_suite_ut_app_prime.c | 4 +- .../sdv/testcase/apps/test_suite_ut_app_sm.c | 41 +++++++ .../testcase/apps/test_suite_ut_app_sm.data | 3 + .../sdv/testcase/apps/test_suite_ut_enc.c | 81 +++++++++++++- .../sdv/testcase/apps/test_suite_ut_enc.data | 8 +- .../test_x509_ext_san_leading_zero_ipv4.cnf | 14 +++ 24 files changed, 438 insertions(+), 90 deletions(-) create mode 100644 testcode/testdata/apps/app_conf/test_x509_ext_san_leading_zero_ipv4.cnf diff --git a/apps/src/app_client.c b/apps/src/app_client.c index ddf6023f..a00948b4 100644 --- a/apps/src/app_client.c +++ b/apps/src/app_client.c @@ -31,6 +31,7 @@ #include "app_keymgmt.h" #include "app_utils.h" #include "hitls.h" +#include "hitls_cert.h" #include "hitls_cert_init.h" #include "hitls_session.h" #include "crypt_errno.h" @@ -424,6 +425,14 @@ static HITLS_Config *CreateClientConfig(HITLS_ClientParams *params) HITLS_CFG_FreeConfig(config); return NULL; } + if (!params->verifyNone) { + ret = HITLS_CFG_SetHost(config, params->host); + if (ret != HITLS_SUCCESS) { + AppPrintError("Failed to set verification host: 0x%x\n", ret); + HITLS_CFG_FreeConfig(config); + return NULL; + } + } /* Configure client certificate if provided */ if (protocol == APP_PROTOCOL_TLCP || protocol == APP_PROTOCOL_DTLCP) { diff --git a/apps/src/app_conf.c b/apps/src/app_conf.c index 3c754700..39e539e2 100644 --- a/apps/src/app_conf.c +++ b/apps/src/app_conf.c @@ -95,7 +95,7 @@ static X509KeyUsageMap g_exKuMap[] = { static int32_t FindEndIdx(char *str, char separator, int32_t beginIdx, int32_t currIdx, bool allowEmpty) { - while (currIdx >= 0 && (isspace(str[currIdx]) || str[currIdx] == separator)) { + while (currIdx >= 0 && (isspace((unsigned char)str[currIdx]) || str[currIdx] == separator)) { currIdx--; } if (beginIdx < currIdx) { @@ -112,7 +112,8 @@ static int32_t FindEndIdx(char *str, char separator, int32_t beginIdx, int32_t c int32_t HITLS_APP_SplitString(const char *str, char separator, bool allowEmpty, char **strArr, uint32_t maxArrCnt, uint32_t *realCnt) { - if (str == NULL || strlen(str) == 0 || isspace(separator) || strArr == NULL || maxArrCnt == 0 || realCnt == NULL) { + if (str == NULL || strlen(str) == 0 || isspace((unsigned char)separator) || strArr == NULL || maxArrCnt == 0 || + realCnt == NULL) { return HITLS_APP_INVALID_ARG; } @@ -133,7 +134,7 @@ int32_t HITLS_APP_SplitString(const char *str, char separator, bool allowEmpty, *realCnt = 0; for (int32_t i = 0; i < len; i++) { if (!hasBegin) { - if (isspace(res[i])) { + if (isspace((unsigned char)res[i])) { continue; } if (*realCnt == maxArrCnt) { @@ -509,6 +510,7 @@ static int32_t ParseIPValue(char *value, HITLS_X509_GeneralName *generalName) struct sockaddr_in sockIpv4 = {}; struct sockaddr_in6 sockIpv6 = {}; char *ipv4ValueList[IPV4_VALUE_MAX_CNT] = {0}; + char *ipv4ValueBase = NULL; uint32_t ipSize = 0; if (inet_pton(AF_INET, value, &(sockIpv4.sin_addr)) == 1) { uint32_t valueCnt = 0; @@ -516,9 +518,10 @@ static int32_t ParseIPValue(char *value, HITLS_X509_GeneralName *generalName) if (ret != HITLS_APP_SUCCESS) { return ret; } + ipv4ValueBase = ipv4ValueList[0]; if (valueCnt != IPV4_VALUE_MAX_CNT) { AppPrintError("Failed to split IP string, IP: %s.\n", value); - BSL_SAL_FREE(ipv4ValueList[0]); + BSL_SAL_FREE(ipv4ValueBase); return HITLS_APP_INVALID_IP; } // Normalize IPv4 octets by removing leading zeros (cross-platform fix) @@ -541,7 +544,7 @@ static int32_t ParseIPValue(char *value, HITLS_X509_GeneralName *generalName) generalName->value.data = BSL_SAL_Calloc(ipSize, 1); if (generalName->value.data == NULL) { AppPrintError("Invalid IP format for directory name, IP: %s.\n", value); - BSL_SAL_FREE(ipv4ValueList[0]); + BSL_SAL_FREE(ipv4ValueBase); return HITLS_APP_MEM_ALLOC_FAIL; } for (uint32_t i = 0; i < ipSize; i++) { @@ -552,7 +555,7 @@ static int32_t ParseIPValue(char *value, HITLS_X509_GeneralName *generalName) } } generalName->value.dataLen = ipSize; - BSL_SAL_FREE(ipv4ValueList[0]); + BSL_SAL_FREE(ipv4ValueBase); return HITLS_APP_SUCCESS; } diff --git a/apps/src/app_enc.c b/apps/src/app_enc.c index 267e718c..3b971155 100644 --- a/apps/src/app_enc.c +++ b/apps/src/app_enc.c @@ -90,6 +90,15 @@ static const uint32_t CIPHER_IS_XTS[] = { CRYPT_CIPHER_SM4_XTS, }; +static const uint32_t CIPHER_IS_AES_WRAP[] = { + CRYPT_CIPHER_AES128_WRAP_NOPAD, + CRYPT_CIPHER_AES128_WRAP_PAD, + CRYPT_CIPHER_AES192_WRAP_NOPAD, + CRYPT_CIPHER_AES192_WRAP_PAD, + CRYPT_CIPHER_AES256_WRAP_NOPAD, + CRYPT_CIPHER_AES256_WRAP_PAD, +}; + typedef struct { char *pass; uint32_t passLen; @@ -185,6 +194,16 @@ static int32_t GetMacId(const char *name) return HITLS_APP_GetCidByName(name, HITLS_APP_LIST_OPT_MD_TO_MAC_ALG); } +static bool IsAesWrapCipher(int32_t cipherId) +{ + for (uint32_t i = 0; i < sizeof(CIPHER_IS_AES_WRAP) / sizeof(CIPHER_IS_AES_WRAP[0]); ++i) { + if ((uint32_t)cipherId == CIPHER_IS_AES_WRAP[i]) { + return true; + } + } + return false; +} + // process for the ENC to receive subordinate options static int32_t HandleOpt(EncCmdOpt *encOpt) { @@ -274,6 +293,10 @@ static int32_t CheckParam(EncCmdOpt *encOpt) AppPrintError("Use -help for summary.\n"); return HITLS_APP_OPT_VALUE_INVALID; } + if (IsAesWrapCipher(encOpt->cipherId)) { + AppPrintError("enc: AES-WRAP algorithms are not supported.\n"); + return HITLS_APP_OPT_VALUE_INVALID; + } // if the user does not specify the encryption or decryption mode, // an error is reported and the user is prompted to enter the following information if (encOpt->encTag != 1 && encOpt->encTag != 0) { @@ -307,6 +330,18 @@ static int32_t CheckParam(EncCmdOpt *encOpt) return HITLS_APP_SUCCESS; } +static int32_t SetOutputFilePermission(const char *outFile) +{ + if (outFile == NULL) { + return HITLS_APP_SUCCESS; + } + if (chmod(outFile, S_IRUSR | S_IWUSR) != 0) { + AppPrintError("enc: Failed to set output file permission.\n"); + return HITLS_APP_UIO_FAIL; + } + return HITLS_APP_SUCCESS; +} + // enc determines the input and output paths static int32_t HandleIO(EncCmdOpt *encOpt) { @@ -327,6 +362,13 @@ static int32_t HandleIO(EncCmdOpt *encOpt) AppPrintError("enc: Failed to create the output pipeline.\n"); return HITLS_APP_UIO_FAIL; } + if (SetOutputFilePermission(encOpt->outFile) != HITLS_APP_SUCCESS) { + BSL_UIO_Free(encOpt->encUio->rUio); + BSL_UIO_Free(encOpt->encUio->wUio); + encOpt->encUio->rUio = NULL; + encOpt->encUio->wUio = NULL; + return HITLS_APP_UIO_FAIL; + } return HITLS_APP_SUCCESS; } diff --git a/apps/src/app_keymgmt.c b/apps/src/app_keymgmt.c index 5c66c4c5..b297bfc7 100644 --- a/apps/src/app_keymgmt.c +++ b/apps/src/app_keymgmt.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "securec.h" #include "bsl_uio.h" #include "crypt_eal_rand.h" @@ -156,6 +157,68 @@ static char *GetPubKeyFilePath(const char *workPath, const char *uuid) return GetKeyFullPath(workPath, uuid, "-pub.pem"); } +static bool IsUuidHexChar(char c) +{ + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +static bool IsValidKeyUuid(const char *uuid) +{ + if (uuid == NULL) { + return false; + } + for (uint32_t i = 0; i < APP_KEYMGMT_UUID_STR_SIZE - 1; i++) { + if (!IsUuidHexChar(uuid[i])) { + return false; + } + } + return uuid[APP_KEYMGMT_UUID_STR_SIZE - 1] == '\0'; +} + +static bool IsValidKeyUuidList(const char *uuidList) +{ + if (uuidList == NULL || uuidList[0] == '\0') { + return false; + } + + uint32_t uuidLen = 0; + for (const char *cur = uuidList; ; cur++) { + if (*cur == ',' || *cur == '\0') { + if (uuidLen != APP_KEYMGMT_UUID_STR_SIZE - 1) { + return false; + } + if (*cur == '\0') { + return true; + } + uuidLen = 0; + continue; + } + if (!IsUuidHexChar(*cur) || uuidLen >= APP_KEYMGMT_UUID_STR_SIZE - 1) { + return false; + } + uuidLen++; + } +} + +static int32_t CheckUuid(const char *uuid) +{ + if (!IsValidKeyUuid(uuid)) { + AppPrintError("keymgmt: Invalid uuid, expect %u hex characters.\n", APP_KEYMGMT_UUID_STR_SIZE - 1); + return HITLS_APP_INVALID_ARG; + } + return HITLS_APP_SUCCESS; +} + +static int32_t CheckUuidList(const char *uuidList) +{ + if (!IsValidKeyUuidList(uuidList)) { + AppPrintError("keymgmt: Invalid uuid list, expect comma-separated %u-hex-character uuid values.\n", + APP_KEYMGMT_UUID_STR_SIZE - 1); + return HITLS_APP_INVALID_ARG; + } + return HITLS_APP_SUCCESS; +} + static int32_t WriteKeyFile(KeyMgmtCmdOpt *keyMgmtOpt, const char *uuid, HITLS_PKCS12 *p12) { CRYPT_Pbkdf2Param pbkdf2Param = {0}; @@ -194,11 +257,17 @@ static int32_t WriteKeyFile(KeyMgmtCmdOpt *keyMgmtOpt, const char *uuid, HITLS_P } int32_t ret = HITLS_PKCS12_GenFile(BSL_FORMAT_ASN1, p12, &encodeParam, true, path); - BSL_SAL_Free(path); if (ret != HITLS_PKI_SUCCESS) { + BSL_SAL_Free(path); AppPrintError("keymgmt: Failed to generate pkcs12 key file, errCode: 0x%x.\n", ret); return HITLS_APP_X509_FAIL; } + if (chmod(path, S_IRUSR | S_IWUSR) != 0) { + BSL_SAL_Free(path); + AppPrintError("keymgmt: Failed to set key file permission.\n"); + return HITLS_APP_UIO_FAIL; + } + BSL_SAL_Free(path); return HITLS_APP_SUCCESS; } @@ -483,12 +552,16 @@ static int32_t EraseKeyFile(char *path) static int32_t HITLS_APP_RmvKey(KeyMgmtCmdOpt *keyMgmtOpt, const char *uuid) { + int32_t ret = CheckUuid(uuid); + if (ret != HITLS_APP_SUCCESS) { + return ret; + } char *path = GetKeyFilePath(keyMgmtOpt->smParam->workPath, uuid); if (path == NULL) { return HITLS_APP_INVALID_ARG; } keyMgmtOpt->smParam->status = HITLS_APP_SM_STATUS_APPORVED; - int32_t ret = EraseKeyFile(path); + ret = EraseKeyFile(path); if (ret != HITLS_APP_SUCCESS) { BSL_SAL_Free(path); return ret; @@ -622,6 +695,11 @@ static int32_t CheckOptParam(KeyMgmtCmdOpt *keyMgmtOpt) AppPrintError("keymgmt: The uuid is not specified.\n"); return HITLS_APP_OPT_VALUE_INVALID; } + ret = keyMgmtOpt->deleteTag == 1 ? CheckUuidList(keyMgmtOpt->smParam->uuid) : + CheckUuid(keyMgmtOpt->smParam->uuid); + if (ret != HITLS_APP_SUCCESS) { + return HITLS_APP_OPT_VALUE_INVALID; + } return HITLS_APP_SUCCESS; } @@ -663,6 +741,11 @@ static int32_t CreateKey(KeyMgmtCmdOpt *keyMgmtOpt) static int32_t SplitUuidString(const char *uuid, BslList **uuidList) { + int32_t ret = CheckUuidList(uuid); + if (ret != HITLS_APP_SUCCESS) { + return ret; + } + char *src = BSL_SAL_Dump(uuid, strlen(uuid) + 1); if (src == NULL) { AppPrintError("keymgmt: Failed to dump uuid string.\n"); @@ -687,7 +770,7 @@ static int32_t SplitUuidString(const char *uuid, BslList **uuidList) AppPrintError("keymgmt: Failed to dump single uuid string.\n"); return HITLS_APP_MEM_ALLOC_FAIL; } - int32_t ret = BSL_LIST_AddElement(list, singleUuid, BSL_LIST_POS_END); + ret = BSL_LIST_AddElement(list, singleUuid, BSL_LIST_POS_END); if (ret != BSL_SUCCESS) { BSL_SAL_FREE(singleUuid); BSL_SAL_FREE(src); @@ -735,7 +818,15 @@ static bool IsP12File(const char *file) if (fileLen != 2 * HITLS_APP_UUID_LEN + strlen(suffix)) { // 2: one byte to two hex chars. return false; } - return strcmp(file + fileLen - strlen(suffix), suffix) == 0; + if (strcmp(file + fileLen - strlen(suffix), suffix) != 0) { + return false; + } + for (uint32_t i = 0; i < APP_KEYMGMT_UUID_STR_SIZE - 1; i++) { + if (!IsUuidHexChar(file[i])) { + return false; + } + } + return true; } static int32_t GetAllKeyUuids(const char *workPath, BslList **fileList) @@ -852,6 +943,10 @@ static int32_t SelfTest(KeyMgmtCmdOpt *keyMgmtOpt) static int32_t ReadKeyFile(AppProvider *provider, HITLS_APP_SM_Param *smParam, HITLS_PKCS12 **p12) { + int32_t ret = CheckUuid(smParam->uuid); + if (ret != HITLS_APP_SUCCESS) { + return ret; + } char *path = GetKeyFilePath(smParam->workPath, smParam->uuid); if (path == NULL) { AppPrintError("keymgmt: Failed to get key full path.\n"); @@ -866,7 +961,7 @@ static int32_t ReadKeyFile(AppProvider *provider, HITLS_APP_SM_Param *smParam, H pwdParam.encPwd = &encPwd; pwdParam.macPwd = &encPwd; - int32_t ret = HITLS_PKCS12_ProviderParseFile(APP_GetCurrent_LibCtx(), provider->providerAttr, "ASN1", path, + ret = HITLS_PKCS12_ProviderParseFile(APP_GetCurrent_LibCtx(), provider->providerAttr, "ASN1", path, &pwdParam, p12, true); BSL_SAL_Free(path); if (ret != HITLS_PKI_SUCCESS) { diff --git a/apps/src/app_list.c b/apps/src/app_list.c index 097cd49f..13f905e8 100644 --- a/apps/src/app_list.c +++ b/apps/src/app_list.c @@ -61,8 +61,6 @@ static const CidInfo g_allCipherAlgInfo [] = { {CRYPT_CIPHER_AES128_ECB, "aes128_ecb"}, {CRYPT_CIPHER_AES128_GCM, "aes128_gcm"}, {CRYPT_CIPHER_AES128_OFB, "aes128_ofb"}, - {CRYPT_CIPHER_AES128_WRAP_NOPAD, "aes128-wrap-nopad"}, - {CRYPT_CIPHER_AES128_WRAP_PAD, "aes128-wrap-pad"}, {CRYPT_CIPHER_AES128_XTS, "aes128_xts"}, {CRYPT_CIPHER_AES192_CBC, "aes192_cbc"}, {CRYPT_CIPHER_AES192_CCM, "aes192_ccm"}, @@ -71,8 +69,6 @@ static const CidInfo g_allCipherAlgInfo [] = { {CRYPT_CIPHER_AES192_ECB, "aes192_ecb"}, {CRYPT_CIPHER_AES192_GCM, "aes192_gcm"}, {CRYPT_CIPHER_AES192_OFB, "aes192_ofb"}, - {CRYPT_CIPHER_AES192_WRAP_NOPAD, "aes192-wrap-nopad"}, - {CRYPT_CIPHER_AES192_WRAP_PAD, "aes192-wrap-pad"}, {CRYPT_CIPHER_AES256_CBC, "aes256_cbc"}, {CRYPT_CIPHER_AES256_CCM, "aes256_ccm"}, {CRYPT_CIPHER_AES256_CFB, "aes256_cfb"}, @@ -80,8 +76,6 @@ static const CidInfo g_allCipherAlgInfo [] = { {CRYPT_CIPHER_AES256_ECB, "aes256_ecb"}, {CRYPT_CIPHER_AES256_GCM, "aes256_gcm"}, {CRYPT_CIPHER_AES256_OFB, "aes256_ofb"}, - {CRYPT_CIPHER_AES256_WRAP_NOPAD, "aes256-wrap-nopad"}, - {CRYPT_CIPHER_AES256_WRAP_PAD, "aes256-wrap-pad"}, {CRYPT_CIPHER_AES256_XTS, "aes256_xts"}, {CRYPT_CIPHER_CHACHA20_POLY1305, "chacha20_poly1305"}, {CRYPT_CIPHER_SM4_CBC, "sm4_cbc"}, @@ -141,9 +135,6 @@ static const CidInfo g_allMacAlgInfo[] = { {CRYPT_MAC_CMAC_AES128, "cmac_aes128"}, {CRYPT_MAC_CMAC_AES192, "cmac_aes192"}, {CRYPT_MAC_CMAC_AES256, "cmac_aes256"}, - {CRYPT_MAC_GMAC_AES128, "gmac_aes128"}, - {CRYPT_MAC_GMAC_AES192, "gmac_aes192"}, - {CRYPT_MAC_GMAC_AES256, "gmac_aes256"}, {CRYPT_MAC_SIPHASH64, "siphash64"}, {CRYPT_MAC_SIPHASH128, "siphash128"}, {CRYPT_MAC_CBC_MAC_SM4, "sm4_cbc_mac"}, diff --git a/apps/src/app_mac.c b/apps/src/app_mac.c index cef8aabf..8f61cb3d 100644 --- a/apps/src/app_mac.c +++ b/apps/src/app_mac.c @@ -148,6 +148,11 @@ static int32_t MacOptAlg(MacOpt *macOpt) if (macOpt->algId == BSL_CID_UNKNOWN) { return HITLS_APP_OPT_VALUE_INVALID; } + if (macOpt->algId == CRYPT_MAC_GMAC_AES128 || macOpt->algId == CRYPT_MAC_GMAC_AES192 || + macOpt->algId == CRYPT_MAC_GMAC_AES256) { + AppPrintError("mac: GMAC is not supported by this command.\n"); + return HITLS_APP_OPT_VALUE_INVALID; + } return HITLS_APP_SUCCESS; } diff --git a/apps/src/app_pkcs12.c b/apps/src/app_pkcs12.c index e3bf7b94..012e59de 100644 --- a/apps/src/app_pkcs12.c +++ b/apps/src/app_pkcs12.c @@ -201,6 +201,7 @@ static int32_t ParseKeyPbe(Pkcs12OptCtx *opt) HITLS_APP_PrintStdoutUioUnInit(); return HITLS_APP_OPT_VALUE_INVALID; } + opt->keyPbe = ret; return HITLS_APP_SUCCESS; } @@ -215,6 +216,7 @@ static int32_t ParseCertPbe(Pkcs12OptCtx *opt) HITLS_APP_PrintStdoutUioUnInit(); return HITLS_APP_OPT_VALUE_INVALID; } + opt->certPbe = ret; return HITLS_APP_SUCCESS; } @@ -229,6 +231,7 @@ static int32_t ParseMacAlg(Pkcs12OptCtx *opt) HITLS_APP_PrintStdoutUioUnInit(); return HITLS_APP_OPT_VALUE_INVALID; } + opt->macAlg = ret; return HITLS_APP_SUCCESS; } diff --git a/apps/src/app_prime.c b/apps/src/app_prime.c index 023ca36d..8f5e8a72 100644 --- a/apps/src/app_prime.c +++ b/apps/src/app_prime.c @@ -30,14 +30,12 @@ #include "app_function.h" #include "crypt_bn.h" -#define MIN_SAFE_PRIME_BITS 16 // Minimum bits for safe prime generation #define DEFAULT_PRIME_CHECKS 64 // Default number of primality checks typedef struct { int32_t hex; int32_t generate; int32_t bits; - int32_t safe; int32_t checks; } AppPrimeCtx; @@ -48,8 +46,7 @@ typedef enum OptionChoice { OPT_BITS = 2, OPT_HEX = 3, OPT_GENERATE = 4, - OPT_SAFE = 5, - OPT_CHECKS = 6, + OPT_CHECKS = 5, } OPTION_CHOICE; static const HITLS_CmdOption g_primeOpts[] = { @@ -57,7 +54,6 @@ static const HITLS_CmdOption g_primeOpts[] = { {"bits", OPT_BITS, HITLS_APP_OPT_VALUETYPE_POSITIVE_INT, "Size of number in bits"}, {"hex", OPT_HEX, HITLS_APP_OPT_VALUETYPE_NO_VALUE, "Hex output"}, {"generate", OPT_GENERATE, HITLS_APP_OPT_VALUETYPE_NO_VALUE, "Generate a prime"}, - {"safe", OPT_SAFE, HITLS_APP_OPT_VALUETYPE_NO_VALUE, "Generate a safe prime"}, {"checks", OPT_CHECKS, HITLS_APP_OPT_VALUETYPE_POSITIVE_INT, "Number of checks"}, {NULL, 0, 0, NULL} }; @@ -128,7 +124,7 @@ static int32_t ConvertPrimeToString(BN_BigNum *bn, int32_t hex) return HITLS_APP_SUCCESS; } -static int32_t GeneratePrime(int32_t bits, int32_t hex, int32_t safe) +static int32_t GeneratePrime(int32_t bits, int32_t hex) { int32_t ret; BN_BigNum *bn = NULL; @@ -147,13 +143,9 @@ static int32_t GeneratePrime(int32_t bits, int32_t hex, int32_t safe) goto EXIT; } - ret = BN_GenPrime(bn, NULL, (uint32_t)bits, (bool)safe, optimizer, NULL); + ret = BN_GenPrime(bn, NULL, (uint32_t)bits, false, optimizer, NULL); if (ret != CRYPT_SUCCESS) { AppPrintError("prime: Failed to generate prime, errCode: 0x%x\n", ret); - if (safe && bits < MIN_SAFE_PRIME_BITS) { - AppPrintError("prime: Safe prime generation may require more bits (minimum %d)\n", - MIN_SAFE_PRIME_BITS); - } ret = HITLS_APP_CRYPTO_FAIL; goto EXIT; } @@ -203,9 +195,6 @@ static int32_t ProcessOptionSwitch(OPTION_CHOICE option, AppPrimeCtx *ctx) case OPT_GENERATE: ctx->generate = 1; return HITLS_APP_SUCCESS; - case OPT_SAFE: - ctx->safe = 1; - return HITLS_APP_SUCCESS; case OPT_CHECKS: return HandleOptionChecks(&ctx->checks); default: @@ -293,7 +282,7 @@ int32_t HITLS_PrimeMain(int32_t argc, char **argv) } if (ctx.generate) { - ret = GeneratePrime(ctx.bits, ctx.hex, ctx.safe); + ret = GeneratePrime(ctx.bits, ctx.hex); } else { ret = CheckPrime(checkNumber, ctx.hex, ctx.checks); } diff --git a/apps/src/app_sm.c b/apps/src/app_sm.c index 42b857fc..311a08ea 100644 --- a/apps/src/app_sm.c +++ b/apps/src/app_sm.c @@ -18,6 +18,7 @@ #include #include #ifdef HITLS_APP_SM_MODE +#include #include #endif #include @@ -294,6 +295,10 @@ static int32_t WriteUserFile(char *userFile, UserInfo *userInfo) return HITLS_APP_UIO_FAIL; } BSL_UIO_Free(uio); + if (chmod(userFile, S_IRUSR | S_IWUSR) != 0) { + AppPrintError("Failed to set userFile permission: %s\n", userFile); + return HITLS_APP_UIO_FAIL; + } return HITLS_APP_SUCCESS; } diff --git a/apps/src/app_tls_common.c b/apps/src/app_tls_common.c index 6526e1f8..d5712431 100644 --- a/apps/src/app_tls_common.c +++ b/apps/src/app_tls_common.c @@ -89,6 +89,14 @@ HITLS_Config *CreateProtocolConfig(APP_ProtocolType protocol, AppProvider *provi if (config == NULL) { AppPrintError("Failed to create protocol configuration\n"); } + if (protocol == APP_PROTOCOL_TLS) { + int32_t ret = HITLS_CFG_SetVersionForbid(config, TLCP_VERSION_BITS); + if (ret != HITLS_SUCCESS) { + HITLS_CFG_FreeConfig(config); + AppPrintError("Failed to disable TLCP for TLS protocol, errCode: 0x%x.\n", ret); + return NULL; + } + } #ifdef HITLS_APP_SM_MODE int32_t ret = HITLS_CFG_SetSessionTicketSupport(config, false); if (ret != HITLS_SUCCESS) { @@ -407,20 +415,23 @@ int ConfCertVerification(HITLS_Config *config, APP_CertConfig *certConfig, int ret = HITLS_SUCCESS; bool hasLoadedCA = false; - /* Load CA certificates */ - if (certConfig && certConfig->caFile) { - HITLS_X509_Cert *ca_cert = LoadCertFromFile(certConfig->caFile, certConfig->certFormat, certConfig->provider); - if (ca_cert != NULL) { - ret = HITLS_CFG_AddCertToStore(config, ca_cert, TLS_CERT_STORE_TYPE_DEFAULT, true); - if (ret != HITLS_SUCCESS) { - AppPrintError("Failed to add CA certificate to store: 0x%x\n", ret); - HITLS_X509_CertFree(ca_cert); - return HITLS_APP_ERR_LOAD_CA; - } - HITLS_X509_CertFree(ca_cert); - hasLoadedCA = true; - } - } + /* Load CA certificates */ + if (certConfig && certConfig->caFile) { + HITLS_X509_Cert *ca_cert = LoadCertFromFile(certConfig->caFile, certConfig->certFormat, certConfig->provider); + if (ca_cert == NULL) { + AppPrintError("Failed to load CA certificate from %s\n", certConfig->caFile); + return HITLS_APP_ERR_LOAD_CA; + } + + ret = HITLS_CFG_AddCertToStore(config, ca_cert, TLS_CERT_STORE_TYPE_DEFAULT, true); + if (ret != HITLS_SUCCESS) { + AppPrintError("Failed to add CA certificate to store: 0x%x\n", ret); + HITLS_X509_CertFree(ca_cert); + return HITLS_APP_ERR_LOAD_CA; + } + HITLS_X509_CertFree(ca_cert); + hasLoadedCA = true; + } if (certConfig && certConfig->caChain) { HITLS_X509_List *certlist = NULL; @@ -440,9 +451,12 @@ int ConfCertVerification(HITLS_Config *config, APP_CertConfig *certConfig, } } - BSL_LIST_FREE(certlist, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); - hasLoadedCA = true; - } + BSL_LIST_FREE(certlist, (BSL_LIST_PFUNC_FREE)HITLS_X509_CertFree); + if (ret != HITLS_SUCCESS) { + return ret; + } + hasLoadedCA = true; + } /* If no CA certificate is configured, load default CA path */ if (!hasLoadedCA) { @@ -458,14 +472,21 @@ int ConfCertVerification(HITLS_Config *config, APP_CertConfig *certConfig, AppPrintError("Failed to disable server verification: 0x%x\n", ret); return HITLS_APP_ERR_SET_VERIFY; } - ret = HITLS_CFG_SetClientVerifySupport(config, verifyPeer); - if (ret != HITLS_SUCCESS) { - AppPrintError("Failed to set client verification: 0x%x\n", ret); - return HITLS_APP_ERR_SET_VERIFY; - } - - /* Set verification depth */ - if (verifyDepth > 0) { + ret = HITLS_CFG_SetClientVerifySupport(config, verifyPeer); + if (ret != HITLS_SUCCESS) { + AppPrintError("Failed to set client verification: 0x%x\n", ret); + return HITLS_APP_ERR_SET_VERIFY; + } + if (verifyPeer) { + ret = HITLS_CFG_SetNoClientCertSupport(config, false); + if (ret != HITLS_SUCCESS) { + AppPrintError("Failed to require client certificate: 0x%x\n", ret); + return HITLS_APP_ERR_SET_VERIFY; + } + } + + /* Set verification depth */ + if (verifyDepth > 0) { ret = HITLS_CFG_SetVerifyDepth(config, verifyDepth); if (ret != HITLS_SUCCESS) { AppPrintError("Failed to set verification depth: 0x%x\n", ret); diff --git a/apps/src/app_utils.c b/apps/src/app_utils.c index 4041a254..ae6a7a5a 100644 --- a/apps/src/app_utils.c +++ b/apps/src/app_utils.c @@ -705,11 +705,12 @@ static int32_t ReadPemByUioSymbol(BSL_UIO *memUio, BSL_UIO *rUio, BSL_PEM_Symbol return ret; } -static int32_t ReadBlockFromStdin(BSL_UIO *memUio, BSL_UIO *rUio) +static int32_t ReadBlockFromStdin(BSL_UIO *memUio, BSL_UIO *rUio, uint32_t maxSize) { int32_t ret = HITLS_APP_UIO_FAIL; uint32_t readLen; uint32_t writeLen; + uint64_t totalLen = 0; uint8_t *buf = (uint8_t *)BSL_SAL_Calloc(MAX_DIGEST_SIZE + 1, 1); if (buf == NULL) { return HITLS_APP_MEM_ALLOC_FAIL; @@ -725,15 +726,20 @@ static int32_t ReadBlockFromStdin(BSL_UIO *memUio, BSL_UIO *rUio) ret = HITLS_APP_SUCCESS; break; } + if (totalLen + readLen > maxSize) { + AppPrintError("The maximum file size is %ukb.\n", maxSize / 1024); + break; + } if (BSL_UIO_Write(memUio, buf, readLen, &writeLen) != BSL_SUCCESS || writeLen != readLen) { break; } + totalLen += readLen; } BSL_SAL_FREE(buf); return ret; } -static int32_t ReadPemFromStdin(BSL_BufMem **data, BSL_PEM_Symbol *symbol) +static int32_t ReadPemFromStdin(BSL_BufMem **data, BSL_PEM_Symbol *symbol, uint32_t maxSize) { int32_t ret = HITLS_APP_UIO_FAIL; BSL_UIO *memUio = BSL_UIO_New(BSL_UIO_MemMethod()); @@ -748,7 +754,7 @@ static int32_t ReadPemFromStdin(BSL_BufMem **data, BSL_PEM_Symbol *symbol) return ret; } if (symbol == NULL || symbol->head == NULL || symbol->tail == NULL) { - ret = ReadBlockFromStdin(memUio, rUio); + ret = ReadBlockFromStdin(memUio, rUio, maxSize); } else { ret = ReadPemByUioSymbol(memUio, rUio, symbol); } @@ -786,7 +792,7 @@ int32_t HITLS_APP_ReadData(const char *path, BSL_PEM_Symbol *symbol, char *fileN } if (path == NULL) { BSL_BufMem *buf = NULL; - if (ReadPemFromStdin(&buf, symbol) != HITLS_APP_SUCCESS) { + if (ReadPemFromStdin(&buf, symbol, APP_FILE_MAX_SIZE) != HITLS_APP_SUCCESS) { AppPrintError("Failed to read %s from stdin.\n", fileName); return HITLS_APP_UIO_FAIL; } @@ -1060,14 +1066,15 @@ int32_t HITLS_APP_ReadFileOrStdin(uint8_t **buf, uint64_t *bufLen, const char *i // Special handling for stdin if (inFile == NULL) { - BSL_Buffer data = {0}; - int32_t ret = HITLS_APP_ReadData(NULL, NULL, "data", &data); + BSL_BufMem *data = NULL; + int32_t ret = ReadPemFromStdin(&data, NULL, maxSize); if (ret != HITLS_APP_SUCCESS) { AppPrintError("%s: Failed to read content from stdin\n", module); return ret; } - *buf = data.data; - *bufLen = data.dataLen; + *buf = (uint8_t *)data->data; + *bufLen = data->length; + BSL_SAL_Free(data); return HITLS_APP_SUCCESS; } diff --git a/docs/en/4_User Guide/5_Command Line Guide.md b/docs/en/4_User Guide/5_Command Line Guide.md index 4bb69004..86b9d311 100644 --- a/docs/en/4_User Guide/5_Command Line Guide.md +++ b/docs/en/4_User Guide/5_Command Line Guide.md @@ -31,7 +31,7 @@ The openHiTLS command source code is located in the apps directory, and the comp ||s_server|SSL/TLS server tool| |**Other Utility Tools**|| | ||rand|Generate random numbers of specified length, supporting hexadecimal and Base64 encoded output| -||prime|Generate and test primes, support hexadecimal input/output, and generate safe primes| +||prime|Generate and test primes, support hexadecimal input/output| ## 1.2 Command Usage @@ -106,9 +106,13 @@ hitls list -all-curves ### 3.2.1 enc Symmetric encryption and decryption operations, supporting multiple symmetric algorithms +AES-WRAP algorithms are not supported by the `enc` command. + ### 3.2.2 mac Message authentication code calculation and verification +GMAC algorithms are not supported by the `mac` command. + ### 3.2.3 dgst Message digest calculation and digital signature operations @@ -201,7 +205,7 @@ hitls rand -algorithm hmac-sha256 -hex 10 **Usage**: ``` -hitls prime [-help] [-generate] [-bits num] [-safe] [-hex] [-checks num] [number] +hitls prime [-help] [-generate] [-bits num] [-hex] [-checks num] [number] ``` **Supported Options**: @@ -210,7 +214,6 @@ hitls prime [-help] [-generate] [-bits num] [-safe] [-hex] [-checks num] [number - `-bits `: Specify the bit length of the prime to be generated - `-hex`: Use hexadecimal format for input/output (decimal by default) - `-generate`: Enable prime generation mode -- `-safe`: Generate a safe prime - `-check `: Number of iterations for primality testing (default: 64) **Examples**: @@ -228,9 +231,6 @@ hitls prime [-help] [-generate] [-bits num] [-safe] [-hex] [-checks num] [number # Generate a 256-bit prime ./hitls prime -generate -bits 256 -# Generate a 512-bit safe prime -./hitls prime -generate -bits 512 -safe - # Output in hexadecimal format ./hitls prime -generate -bits 128 -hex ``` diff --git a/docs/zh/4_使用指南/5_命令行指南.md b/docs/zh/4_使用指南/5_命令行指南.md index a4162842..c959b73c 100644 --- a/docs/zh/4_使用指南/5_命令行指南.md +++ b/docs/zh/4_使用指南/5_命令行指南.md @@ -31,7 +31,7 @@ openHiTLS命令源码位于apps目录下,编译结果为hitls,用户可运 ||s_server|SSL/TLS服务端工具 | |**其他实用工具**|| | ||rand|生成指定长度的随机数,支持十六进制和Base64编码输出 | -||prime|生成和检测素数,支持十六进制输入/输出和安全素数生成 | +||prime|生成和检测素数,支持十六进制输入/输出 | ## 1.2 命令使用方式 @@ -106,9 +106,13 @@ hitls list -all-curves ### 3.2.1 enc 对称加密和解密操作,支持多种对称算法 +`enc` 命令不支持 AES-WRAP 算法。 + ### 3.2.2 mac 消息认证码计算和验证 +`mac` 命令不支持 GMAC 算法。 + ### 3.2.3 dgst 消息摘要计算和数字签名操作 @@ -201,7 +205,7 @@ hitls rand -algorithm hmac-sha256 -hex 10 **用法**: ``` -hitls prime [-help] [-generate] [-bits num] [-safe] [-hex] [-checks num] [number] +hitls prime [-help] [-generate] [-bits num] [-hex] [-checks num] [number] ``` **支持的选项**: @@ -210,7 +214,6 @@ hitls prime [-help] [-generate] [-bits num] [-safe] [-hex] [-checks num] [number - `-bits `:指定生成素数的位数 - `-hex`:使用十六进制格式输入/输出,默认十进制格式 - `-generate`:生成素数模式 -- `-safe`:生成安全素数 - `-checks `:素数检测的迭代轮数,默认64轮 **示例**: @@ -228,9 +231,6 @@ hitls prime [-help] [-generate] [-bits num] [-safe] [-hex] [-checks num] [number # 生成 256 位素数 ./hitls prime -generate -bits 256 -# 生成 512 位安全素数 -./hitls prime -generate -bits 512 -safe - # 以十六进制格式输出 ./hitls prime -generate -bits 128 -hex ``` diff --git a/testcode/sdv/testcase/apps/test_suite_ut_app_conf.c b/testcode/sdv/testcase/apps/test_suite_ut_app_conf.c index 35806948..5d8e6426 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_app_conf.c +++ b/testcode/sdv/testcase/apps/test_suite_ut_app_conf.c @@ -15,6 +15,7 @@ /* BEGIN_HEADER */ #include +#include #include "hitls_pki_errno.h" #include "hitls_csr_local.h" @@ -155,6 +156,11 @@ void UT_HITLS_APP_conf_X509Ext_TC001(char *confPath, int expectLoadRet, int expe ASSERT_NE(conf, NULL); ASSERT_EQ(BSL_CONF_Load(conf, confPath), expectLoadRet); if (expectLoadRet == HITLS_APP_SUCCESS) { +#if !(defined(__APPLE__) || defined(__MACH__)) + if (strstr(confPath, "test_x509_ext_san_leading_zero_ipv4.cnf") != NULL) { + expectResult = HITLS_APP_INVALID_IP; + } +#endif ASSERT_EQ(HITLS_APP_CONF_ProcExt(conf, "SAN", ProcExt, ext), expectResult); if (expectResult == HITLS_APP_SUCCESS) { ASSERT_EQ(HITLS_X509_EncodeExt(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, ext->extList, &asnExt), diff --git a/testcode/sdv/testcase/apps/test_suite_ut_app_conf.data b/testcode/sdv/testcase/apps/test_suite_ut_app_conf.data index 2664ed57..c3d69eb0 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_app_conf.data +++ b/testcode/sdv/testcase/apps/test_suite_ut_app_conf.data @@ -94,6 +94,9 @@ UT_HITLS_APP_conf_subj_TC002: UT_HITLS_APP_conf_X509Ext_TC001 UT_HITLS_APP_conf_X509Ext_TC001:"../testdata/apps/app_conf/test_x509_ext_withsan.cnf":BSL_SUCCESS:HITLS_APP_SUCCESS:"3082011C3081B00603551D110481A83081A5810741414140636F6D810742424240636F6D861A485454503A2F2F736F6D65686F73742E636F6D2F434E3D666F6F820358585887040A0A0A0A871000A00000000000000000000000000000A4583056310B300906035504061302554B31233021060355040A0C1A4D79204F7267616E697A6174696F6E2C434E3D4D79204E616D653110300E060355040B0C074D7920556E69743110300E06035504030C074D79204E616D65300F0603551D130101FF040530030101FF300C0603551D0F0405030307FF8030480603551D250101FF043E303C06082B0601050507030106082B0601050507030206082B0601050507030306082B0601050507030406082B0601050507030806082B06010505070309" +UT_HITLS_APP_conf_X509Ext_TC001 IPv4 leading zero first octet +UT_HITLS_APP_conf_X509Ext_TC001:"../testdata/apps/app_conf/test_x509_ext_san_leading_zero_ipv4.cnf":BSL_SUCCESS:HITLS_APP_SUCCESS:"3082011C3081B00603551D110481A83081A5810741414140636F6D810742424240636F6D861A485454503A2F2F736F6D65686F73742E636F6D2F434E3D666F6F820358585887040A0A0A0A871000A00000000000000000000000000000A4583056310B300906035504061302554B31233021060355040A0C1A4D79204F7267616E697A6174696F6E2C434E3D4D79204E616D653110300E060355040B0C074D7920556E69743110300E06035504030C074D79204E616D65300F0603551D130101FF040530030101FF300C0603551D0F0405030307FF8030480603551D250101FF043E303C06082B0601050507030106082B0601050507030206082B0601050507030306082B0601050507030406082B0601050507030806082B06010505070309" + UT_HITLS_APP_conf_X509Ext_TC001 IPv4 test1 UT_HITLS_APP_conf_X509Ext_TC001:"../testdata/apps/app_conf/test_x509_ext_san_errorIpv4_1.cnf":BSL_SUCCESS:HITLS_APP_INVALID_IP:"00" diff --git a/testcode/sdv/testcase/apps/test_suite_ut_app_keymgmt.c b/testcode/sdv/testcase/apps/test_suite_ut_app_keymgmt.c index 4ad64f90..8b74e912 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_app_keymgmt.c +++ b/testcode/sdv/testcase/apps/test_suite_ut_app_keymgmt.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "app_enc.h" #include "app_keymgmt.h" #include "app_dgst.h" @@ -410,6 +411,9 @@ void UT_HITLS_APP_KEYMGMT_TC001(void) STUB_REPLACE(HITLS_APP_SM_RootUserCheck, STUB_HITLS_APP_SM_RootUserCheck); char *uuid = NULL; + char keyPath[1024] = {0}; + struct stat st = {0}; + mode_t oldMask = umask(0022); char *argv[] = {"keymgmt", "-create", "-algid", "sm4", SM_PARAM, NULL}; ASSERT_EQ(AppTestInit(), HITLS_APP_SUCCESS); @@ -419,6 +423,9 @@ void UT_HITLS_APP_KEYMGMT_TC001(void) uuid = GetUuidFromP12(WORK_PATH); ASSERT_TRUE(uuid != NULL); + snprintf(keyPath, sizeof(keyPath), "%s/%s.p12", WORK_PATH, uuid); + ASSERT_EQ(stat(keyPath, &st), 0); + ASSERT_EQ(st.st_mode & 0777, S_IRUSR | S_IWUSR); ret = EncryptAndDecrypt(uuid, "sm4_cbc"); ASSERT_EQ(ret, HITLS_APP_SUCCESS); @@ -439,6 +446,7 @@ void UT_HITLS_APP_KEYMGMT_TC001(void) ASSERT_EQ(ret, HITLS_APP_SUCCESS); EXIT: + (void)umask(oldMask); BSL_SAL_FREE(uuid); AppTestUninit(); STUB_RESTORE(BSL_UI_ReadPwdUtil); @@ -646,6 +654,19 @@ void UT_HITLS_APP_KEYMGMT_TC005(void) ret = HITLS_KeyMgmtMain(sizeof(argv7) / sizeof(argv7[0]) - 1, argv7); ASSERT_EQ(ret, HITLS_APP_OPT_VALUE_INVALID); + // Case 8: Reject UUIDs that are not exactly 64 hex characters. + char invalidUuid[] = "../../target"; + char *argv8[] = {"keymgmt", "-delete", SM_PARAM, "-uuid", invalidUuid, NULL}; + ret = HITLS_KeyMgmtMain(sizeof(argv8) / sizeof(argv8[0]) - 1, argv8); + ASSERT_EQ(ret, HITLS_APP_OPT_VALUE_INVALID); + + // Case 9: Reject invalid UUID elements in comma-separated lists. + char invalidUuidList[] = + "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef,../../target"; + char *argv9[] = {"keymgmt", "-delete", SM_PARAM, "-uuid", invalidUuidList, NULL}; + ret = HITLS_KeyMgmtMain(sizeof(argv9) / sizeof(argv9[0]) - 1, argv9); + ASSERT_EQ(ret, HITLS_APP_OPT_VALUE_INVALID); + EXIT: AppTestUninit(); STUB_RESTORE(BSL_UI_ReadPwdUtil); @@ -774,7 +795,7 @@ void UT_HITLS_APP_KEYMGMT_TC008(void) ASSERT_EQ(AppTestInit(), HITLS_APP_SUCCESS); // Test deleting a non-existent key - pass a randomly generated UUID - char fakeUuid[] = "1234567890abcdef1234567890abcdef"; + char fakeUuid[] = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; char *argv_delete[] = {"keymgmt", "-delete", SM_PARAM, "-uuid", fakeUuid, NULL}; int ret = HITLS_KeyMgmtMain(sizeof(argv_delete) / sizeof(argv_delete[0]) - 1, argv_delete); @@ -920,7 +941,7 @@ void UT_HITLS_APP_KEYMGMT_TC010(void) fclose(fp1); // Construct a list containing existing and non-existing UUIDs - char fakeUuid[] = "1234567890abcdef1234567890abcdef"; + char fakeUuid[] = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; char uuidList[256]; // Note: Put the existing UUID first and the non-existing one after, to verify ordered deletion logic snprintf(uuidList, sizeof(uuidList), "%s,%s", uuid1, fakeUuid); diff --git a/testcode/sdv/testcase/apps/test_suite_ut_app_mac.data b/testcode/sdv/testcase/apps/test_suite_ut_app_mac.data index c39d1678..aa4b9df6 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_app_mac.data +++ b/testcode/sdv/testcase/apps/test_suite_ut_app_mac.data @@ -13,6 +13,9 @@ UT_HITLS_APP_MAC_InvalidOpt_TC001:"mac -name hmac_sha256 -hexkey 0x1234G -in ../ "-key and hexkey": both specified UT_HITLS_APP_MAC_InvalidOpt_TC001:"mac -name hmac_sha256 -key 123456 -hexkey 0x1234 -in ../testdata/apps/mac/test.txt":HITLS_APP_OPT_VALUE_INVALID +"-name": unsupported GMAC +UT_HITLS_APP_MAC_InvalidOpt_TC001:"mac -name gmac_aes128 -hexkey 0x00000000000000000000000000000000 -in ../testdata/apps/mac/test.txt":HITLS_APP_OPT_VALUE_INVALID + normal mac UT_HITLS_APP_MAC_NormalOpt_TC001:"mac -name hmac_sha256 -key 123456 -in ../testdata/apps/mac/test.txt -out mac_out.out":"mac_out.out":"f959b969e71d0f3778b6265a2b06a032c9ac9dd20b51d33a7adc700a3e5df20b" diff --git a/testcode/sdv/testcase/apps/test_suite_ut_app_pkcs12.c b/testcode/sdv/testcase/apps/test_suite_ut_app_pkcs12.c index 3e63f903..59c588de 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_app_pkcs12.c +++ b/testcode/sdv/testcase/apps/test_suite_ut_app_pkcs12.c @@ -342,13 +342,19 @@ void UT_HITLS_APP_PKCS12_TC006(void) char *argv[][18] = { {"pkcs12", "-export", "-in", CERT, "-inkey", PRI_KEY, "-passin", "pass:12345678", "-chain", "-CAfile", CHAIN, "-passout", "pass:12345678", "-out", "out.pfx", "-macalg", "sha224"}, + {"pkcs12", "-export", "-in", CERT, "-inkey", PRI_KEY, "-passin", "pass:12345678", "-chain", "-CAfile", + CHAIN, "-passout", "pass:12345678", "-out", "out.pfx", "-macalg", "sha512"}, {"pkcs12", "-export", "-in", CERT, "-inkey", PRI_KEY, "-passin", "pass:12345678", "-chain", "-CAfile", CHAIN, "-passout", "pass:12345678", "-out", "out.pfx", "-macalg", "INVALID_ALG"}, + {"pkcs12", "-in", "out.pfx", "-passin", "pass:12345678", "-passout", "pass:12345678", "-out", + "decode_pfx.pem"}, }; OptTestData testData[] = { {17, argv[0], HITLS_APP_SUCCESS}, - {17, argv[1], HITLS_APP_OPT_VALUE_INVALID}, + {17, argv[1], HITLS_APP_SUCCESS}, + {17, argv[2], HITLS_APP_OPT_VALUE_INVALID}, + {9, argv[3], HITLS_APP_SUCCESS}, }; ASSERT_EQ(AppPrintErrorUioInit(stderr), HITLS_APP_SUCCESS); @@ -597,4 +603,4 @@ EXIT: AppPrintErrorUioUnInit(); return; } -/* END_CASE */ \ No newline at end of file +/* END_CASE */ diff --git a/testcode/sdv/testcase/apps/test_suite_ut_app_prime.c b/testcode/sdv/testcase/apps/test_suite_ut_app_prime.c index a70724ed..9912f7ca 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_app_prime.c +++ b/testcode/sdv/testcase/apps/test_suite_ut_app_prime.c @@ -86,7 +86,7 @@ EXIT: /** * @test UT_HITLS_APP_prime_TC002 * @spec - - * @title Test safe prime generation + * @title Test unsupported safe prime option */ /* BEGIN_CASE */ void UT_HITLS_APP_prime_TC002(void) @@ -96,7 +96,7 @@ void UT_HITLS_APP_prime_TC002(void) }; OptTestData testData[] = { - {5, argv[0], HITLS_APP_SUCCESS}, + {5, argv[0], HITLS_APP_INVALID_ARG}, }; ASSERT_EQ(AppPrintErrorUioInit(stderr), HITLS_APP_SUCCESS); diff --git a/testcode/sdv/testcase/apps/test_suite_ut_app_sm.c b/testcode/sdv/testcase/apps/test_suite_ut_app_sm.c index 76a8432d..3c8d30a6 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_app_sm.c +++ b/testcode/sdv/testcase/apps/test_suite_ut_app_sm.c @@ -298,6 +298,47 @@ EXIT: } /* END_CASE */ +/** + * @test UT_HITLS_APP_SM_TC004 + * @spec - + * @title Test SM user file permission; expect 0600 even with permissive umask + */ + +/* BEGIN_CASE */ +void UT_HITLS_APP_SM_TC004(void) +{ +#ifndef HITLS_APP_SM_MODE + SKIP_TEST(); +#else + char *password = NULL; + char userFilePath[1024] = {0}; + struct stat st = {0}; + mode_t oldMask = umask(0022); + STUB_REPLACE(BSL_UI_ReadPwdUtil, STUB_BSL_UI_ReadPwdUtil); + STUB_REPLACE(HITLS_APP_SM_IntegrityCheck, STUB_HITLS_APP_SM_IntegrityCheck); + STUB_REPLACE(HITLS_APP_SM_RootUserCheck, STUB_HITLS_APP_SM_RootUserCheck); + + system("rm -rf " WORK_PATH); + system("mkdir -p " WORK_PATH); + ASSERT_EQ(AppTestInit(), HITLS_APP_SUCCESS); + + int32_t status = 0; + ASSERT_EQ(HITLS_APP_SM_Init(&g_appProvider, WORK_PATH, &password, &status), HITLS_APP_SUCCESS); + snprintf(userFilePath, sizeof(userFilePath), "%s/openhitls_user", WORK_PATH); + ASSERT_EQ(stat(userFilePath, &st), 0); + ASSERT_EQ(st.st_mode & 0777, S_IRUSR | S_IWUSR); + +EXIT: + (void)umask(oldMask); + BSL_SAL_FREE(password); + AppTestUninit(); + STUB_RESTORE(BSL_UI_ReadPwdUtil); + STUB_RESTORE(HITLS_APP_SM_IntegrityCheck); + STUB_RESTORE(HITLS_APP_SM_RootUserCheck); +#endif +} +/* END_CASE */ + /** * @test UT_HITLS_APP_SM_TC005 * @spec - diff --git a/testcode/sdv/testcase/apps/test_suite_ut_app_sm.data b/testcode/sdv/testcase/apps/test_suite_ut_app_sm.data index 8346dc44..52e1549c 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_app_sm.data +++ b/testcode/sdv/testcase/apps/test_suite_ut_app_sm.data @@ -7,5 +7,8 @@ UT_HITLS_APP_SM_TC002: UT_HITLS_APP_SM_TC003 UT_HITLS_APP_SM_TC003: +UT_HITLS_APP_SM_TC004 +UT_HITLS_APP_SM_TC004: + UT_HITLS_APP_SM_TC005 UT_HITLS_APP_SM_TC005: diff --git a/testcode/sdv/testcase/apps/test_suite_ut_enc.c b/testcode/sdv/testcase/apps/test_suite_ut_enc.c index 97cfd84b..03d9782d 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_enc.c +++ b/testcode/sdv/testcase/apps/test_suite_ut_enc.c @@ -18,11 +18,14 @@ #include #include #include +#include +#include #include "app_enc.h" #include "app_errno.h" #include "app_help.h" #include "app_print.h" #include "app_opt.h" +#include "app_utils.h" #include "app_provider.h" #include "bsl_uio.h" #include "crypt_eal_cipher.h" @@ -167,7 +170,8 @@ void UT_HITLS_APP_ENC_TC003(void) {"enc", "-enc", "-cipher", "aes128_cbc", "-in", "../testdata/apps/enc/test_encfile", "-pass", "file:../testdata/apps/pass/empty_pass", "-out", "../testdata/apps/enc/res_encfile"}, {"enc", "-enc", "-cipher", "aes128_cbc", "-md", "md_abc", "-in", "../testdata/apps/enc/test_encfile", "-pass", "pass:12345678", "-out", "../testdata/apps/enc/res_encfile"}, {"enc", "-enc", "-cipher", "aes128_cbc", "-in", "../testdata/apps/enc/test_encfile", "-pass", "pass:", "-out", "../testdata/apps/enc/res_encfile"}, - {"enc", "-enc", "-cipher", "aes128_cbc", "-in", "../testdata/apps/enc/test_encfile", "-pass", "file:../testdata/apps/pass/size_1025_pass", "-out", "../testdata/apps/enc/res_encfile"} + {"enc", "-enc", "-cipher", "aes128_cbc", "-in", "../testdata/apps/enc/test_encfile", "-pass", "file:../testdata/apps/pass/size_1025_pass", "-out", "../testdata/apps/enc/res_encfile"}, + {"enc", "-enc", "-cipher", "aes128-wrap-pad", "-in", "../testdata/apps/enc/test_encfile", "-pass", "pass:12345678", "-out", "../testdata/apps/enc/res_encfile"} }; OptTestData testData[] = { @@ -175,7 +179,8 @@ void UT_HITLS_APP_ENC_TC003(void) {10, argv[1], HITLS_APP_PASSWD_FAIL}, {12, argv[2], HITLS_APP_OPT_VALUE_INVALID}, {10, argv[3], HITLS_APP_PASSWD_FAIL}, - {10, argv[4], HITLS_APP_PASSWD_FAIL} + {10, argv[4], HITLS_APP_PASSWD_FAIL}, + {10, argv[5], HITLS_APP_OPT_VALUE_INVALID} }; ASSERT_EQ(AppInit(), HITLS_APP_SUCCESS); @@ -188,4 +193,74 @@ EXIT: AppUninit(); return; } -/* END_CASE */ \ No newline at end of file +/* END_CASE */ + +/** + * @test UT_HITLS_APP_ENC_TC004 + * @spec - + * @title Test enc named output file permission; expect 0600 even with permissive umask + */ + +/* BEGIN_CASE */ +void UT_HITLS_APP_ENC_TC004(void) +{ + char outFile[] = "res_perm_tmpfile"; + char *argv[] = {"enc", "-enc", "-cipher", "aes128_cbc", "-in", "../testdata/apps/enc/test_encfile", + "-pass", "pass:12345678", "-out", outFile}; + struct stat st = {0}; + mode_t oldMask = umask(0022); + + ASSERT_EQ(AppInit(), HITLS_APP_SUCCESS); + (void)remove(outFile); + + int ret = HITLS_EncMain(sizeof(argv) / sizeof(argv[0]), argv); + ASSERT_EQ(ret, HITLS_APP_SUCCESS); + ASSERT_EQ(stat(outFile, &st), 0); + ASSERT_EQ(st.st_mode & 0777, S_IRUSR | S_IWUSR); + +EXIT: + (void)umask(oldMask); + (void)remove(outFile); + AppUninit(); + return; +} +/* END_CASE */ + +/** + * @test UT_HITLS_APP_ENC_TC005 + * @spec - + * @title Test stdin reads respect the caller supplied maximum size + */ + +/* BEGIN_CASE */ +void UT_HITLS_APP_ENC_TC005(void) +{ + char inFile[] = "stdin_limit_tmpfile"; + uint8_t *buf = NULL; + uint64_t bufLen = 0; + int stdinFd = -1; + FILE *fp = fopen(inFile, "wb"); + ASSERT_NE(fp, NULL); + ASSERT_EQ(fwrite("12345", 1, 5, fp), 5); + ASSERT_EQ(fclose(fp), 0); + fp = NULL; + + stdinFd = dup(STDIN_FILENO); + ASSERT_TRUE(stdinFd >= 0); + ASSERT_NE(freopen(inFile, "rb", stdin), NULL); + ASSERT_EQ(HITLS_APP_ReadFileOrStdin(&buf, &bufLen, NULL, 4, "enc"), HITLS_APP_UIO_FAIL); + +EXIT: + BSL_SAL_FREE(buf); + if (fp != NULL) { + (void)fclose(fp); + } + if (stdinFd >= 0) { + (void)dup2(stdinFd, STDIN_FILENO); + (void)close(stdinFd); + clearerr(stdin); + } + (void)remove(inFile); + return; +} +/* END_CASE */ diff --git a/testcode/sdv/testcase/apps/test_suite_ut_enc.data b/testcode/sdv/testcase/apps/test_suite_ut_enc.data index 8c9680c1..1caaaefb 100644 --- a/testcode/sdv/testcase/apps/test_suite_ut_enc.data +++ b/testcode/sdv/testcase/apps/test_suite_ut_enc.data @@ -5,4 +5,10 @@ UT_HITLS_APP_ENC_TC002 UT_HITLS_APP_ENC_TC002: UT_HITLS_APP_ENC_TC003 -UT_HITLS_APP_ENC_TC003: \ No newline at end of file +UT_HITLS_APP_ENC_TC003: + +UT_HITLS_APP_ENC_TC004 +UT_HITLS_APP_ENC_TC004: + +UT_HITLS_APP_ENC_TC005 +UT_HITLS_APP_ENC_TC005: diff --git a/testcode/testdata/apps/app_conf/test_x509_ext_san_leading_zero_ipv4.cnf b/testcode/testdata/apps/app_conf/test_x509_ext_san_leading_zero_ipv4.cnf new file mode 100644 index 00000000..da81f7ee --- /dev/null +++ b/testcode/testdata/apps/app_conf/test_x509_ext_san_leading_zero_ipv4.cnf @@ -0,0 +1,14 @@ +[req] +distinguished_name=req_distinguished_name +req_extensions=SAN +[SAN] +subjectAltName=email : AAA@com,email: BBB@com,URI:HTTP://somehost.com/CN=foo,DNS:XXX,IP:010.10.10.10,IP:a0::,dirName:dir_sect +basicConstraints=critical,CA:TRUE +keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly +extendedKeyUsage=critical,serverAuth,clientAuth,codeSigning,emailProtection,timeStamping,OCSPSigning +[req_distinguished_name] +[dir_sect] +C=UK +O=My Organization,CN=My Name +OU=My Unit +CN=My Name