1e41f4b71Sopenharmony_ci# Non-anonymous Key Attestation (C/C++) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciThe caller must have the [ohos.permission.ATTEST_KEY](../AccessToken/permissions-for-system-apps.md#ohospermissionattest_key) permission. You need to request the permission based on the APL of your permission. For details, see [Workflow for Using Permissions](../AccessToken/determine-application-mode.md). 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci## Add the dynamic library in the CMake script. 6e41f4b71Sopenharmony_ci```txt 7e41f4b71Sopenharmony_ci target_link_libraries(entry PUBLIC libhuks_ndk.z.so) 8e41f4b71Sopenharmony_ci``` 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci## How to Develop 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci1. Set the key alias (**keyAlias**), which cannot exceed 128 bytes. 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci2. Initialize the parameter set. Use [OH_Huks_InitParamSet](../../reference/apis-universal-keystore-kit/_huks_param_set_api.md#oh_huks_initparamset), [OH_Huks_AddParams](../../reference/apis-universal-keystore-kit/_huks_param_set_api.md#oh_huks_addparams), and [OH_Huks_BuildParamSet](../../reference/apis-universal-keystore-kit/_huks_param_set_api.md#oh_huks_buildparamset) to construct **paramSet**. **paramSet** must contain [OH_Huks_KeyAlg](../../reference/apis-universal-keystore-kit/_huks_type_api.md#oh_huks_keyalg), [OH_Huks_KeySize](../../reference/apis-universal-keystore-kit/_huks_type_api.md#oh_huks_keysize), and [OH_Huks_KeyPurpose](../../reference/apis-universal-keystore-kit/_huks_type_api.md#oh_huks_keypurpose). 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci3. Use [OH_Huks_AttestKeyItem](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_attestkeyitem) with the key alias and parameter set to perform key attestation. 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci```c++ 19e41f4b71Sopenharmony_ci#include "huks/native_huks_api.h" 20e41f4b71Sopenharmony_ci#include "huks/native_huks_param.h" 21e41f4b71Sopenharmony_ci#include <string.h> 22e41f4b71Sopenharmony_ciOH_Huks_Result InitParamSet( 23e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet **paramSet, 24e41f4b71Sopenharmony_ci const struct OH_Huks_Param *params, 25e41f4b71Sopenharmony_ci uint32_t paramCount) 26e41f4b71Sopenharmony_ci{ 27e41f4b71Sopenharmony_ci OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet); 28e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 29e41f4b71Sopenharmony_ci return ret; 30e41f4b71Sopenharmony_ci } 31e41f4b71Sopenharmony_ci ret = OH_Huks_AddParams(*paramSet, params, paramCount); 32e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 33e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(paramSet); 34e41f4b71Sopenharmony_ci return ret; 35e41f4b71Sopenharmony_ci } 36e41f4b71Sopenharmony_ci ret = OH_Huks_BuildParamSet(paramSet); 37e41f4b71Sopenharmony_ci if (ret.errorCode != OH_HUKS_SUCCESS) { 38e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(paramSet); 39e41f4b71Sopenharmony_ci return ret; 40e41f4b71Sopenharmony_ci } 41e41f4b71Sopenharmony_ci return ret; 42e41f4b71Sopenharmony_ci} 43e41f4b71Sopenharmony_cistatic uint32_t g_size = 4096; 44e41f4b71Sopenharmony_cistatic uint32_t CERT_COUNT = 4; 45e41f4b71Sopenharmony_civoid FreeCertChain(struct OH_Huks_CertChain *certChain, const uint32_t pos) 46e41f4b71Sopenharmony_ci{ 47e41f4b71Sopenharmony_ci if (certChain == nullptr || certChain->certs == nullptr) { 48e41f4b71Sopenharmony_ci return; 49e41f4b71Sopenharmony_ci } 50e41f4b71Sopenharmony_ci for (uint32_t j = 0; j < pos; j++) { 51e41f4b71Sopenharmony_ci if (certChain->certs[j].data != nullptr) { 52e41f4b71Sopenharmony_ci free(certChain->certs[j].data); 53e41f4b71Sopenharmony_ci certChain->certs[j].data = nullptr; 54e41f4b71Sopenharmony_ci } 55e41f4b71Sopenharmony_ci } 56e41f4b71Sopenharmony_ci if (certChain->certs != nullptr) { 57e41f4b71Sopenharmony_ci free(certChain->certs); 58e41f4b71Sopenharmony_ci certChain->certs = nullptr; 59e41f4b71Sopenharmony_ci } 60e41f4b71Sopenharmony_ci} 61e41f4b71Sopenharmony_ciint32_t ConstructDataToCertChain(struct OH_Huks_CertChain *certChain) 62e41f4b71Sopenharmony_ci{ 63e41f4b71Sopenharmony_ci if (certChain == nullptr) { 64e41f4b71Sopenharmony_ci return OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT; 65e41f4b71Sopenharmony_ci } 66e41f4b71Sopenharmony_ci certChain->certsCount = CERT_COUNT; 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ci certChain->certs = (struct OH_Huks_Blob *)malloc(sizeof(struct OH_Huks_Blob) * (certChain->certsCount)); 69e41f4b71Sopenharmony_ci if (certChain->certs == nullptr) { 70e41f4b71Sopenharmony_ci return OH_HUKS_ERR_CODE_INTERNAL_ERROR; 71e41f4b71Sopenharmony_ci } 72e41f4b71Sopenharmony_ci for (uint32_t i = 0; i < certChain->certsCount; i++) { 73e41f4b71Sopenharmony_ci certChain->certs[i].size = g_size; 74e41f4b71Sopenharmony_ci certChain->certs[i].data = (uint8_t *)malloc(certChain->certs[i].size); 75e41f4b71Sopenharmony_ci if (certChain->certs[i].data == nullptr) { 76e41f4b71Sopenharmony_ci FreeCertChain(certChain, i); 77e41f4b71Sopenharmony_ci return OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT; 78e41f4b71Sopenharmony_ci } 79e41f4b71Sopenharmony_ci } 80e41f4b71Sopenharmony_ci return 0; 81e41f4b71Sopenharmony_ci} 82e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_genAttestParams[] = { 83e41f4b71Sopenharmony_ci { .tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_RSA }, 84e41f4b71Sopenharmony_ci { .tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048 }, 85e41f4b71Sopenharmony_ci { .tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_VERIFY }, 86e41f4b71Sopenharmony_ci { .tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_SHA256 }, 87e41f4b71Sopenharmony_ci { .tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_PSS }, 88e41f4b71Sopenharmony_ci { .tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_ECB }, 89e41f4b71Sopenharmony_ci}; 90e41f4b71Sopenharmony_ci#define CHALLENGE_DATA "hi_challenge_data" 91e41f4b71Sopenharmony_cistatic struct OH_Huks_Blob g_challenge = { sizeof(CHALLENGE_DATA), (uint8_t *)CHALLENGE_DATA }; 92e41f4b71Sopenharmony_cistatic napi_value AttestKey(napi_env env, napi_callback_info info) 93e41f4b71Sopenharmony_ci{ 94e41f4b71Sopenharmony_ci /* 1. Set the key alias. */ 95e41f4b71Sopenharmony_ci struct OH_Huks_Blob genAlias = { 96e41f4b71Sopenharmony_ci (uint32_t)strlen("test_attest"), 97e41f4b71Sopenharmony_ci (uint8_t *)"test_attest" 98e41f4b71Sopenharmony_ci }; 99e41f4b71Sopenharmony_ci static struct OH_Huks_Param g_attestParams[] = { 100e41f4b71Sopenharmony_ci { .tag = OH_HUKS_TAG_ATTESTATION_CHALLENGE, .blob = g_challenge }, 101e41f4b71Sopenharmony_ci { .tag = OH_HUKS_TAG_ATTESTATION_ID_ALIAS, .blob = genAlias }, 102e41f4b71Sopenharmony_ci }; 103e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *genParamSet = nullptr; 104e41f4b71Sopenharmony_ci struct OH_Huks_ParamSet *attestParamSet = nullptr; 105e41f4b71Sopenharmony_ci OH_Huks_Result ohResult; 106e41f4b71Sopenharmony_ci OH_Huks_Blob certs = { 0 }; 107e41f4b71Sopenharmony_ci OH_Huks_CertChain certChain = { &certs, 0 }; 108e41f4b71Sopenharmony_ci do { 109e41f4b71Sopenharmony_ci /* 2. Initialize the key parameter set. */ 110e41f4b71Sopenharmony_ci ohResult = InitParamSet(&genParamSet, g_genAttestParams, sizeof(g_genAttestParams) / sizeof(OH_Huks_Param)); 111e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 112e41f4b71Sopenharmony_ci break; 113e41f4b71Sopenharmony_ci } 114e41f4b71Sopenharmony_ci ohResult = InitParamSet(&attestParamSet, g_attestParams, sizeof(g_attestParams) / sizeof(OH_Huks_Param)); 115e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 116e41f4b71Sopenharmony_ci break; 117e41f4b71Sopenharmony_ci } 118e41f4b71Sopenharmony_ci ohResult = OH_Huks_GenerateKeyItem(&genAlias, genParamSet, nullptr); 119e41f4b71Sopenharmony_ci if (ohResult.errorCode != OH_HUKS_SUCCESS) { 120e41f4b71Sopenharmony_ci break; 121e41f4b71Sopenharmony_ci } 122e41f4b71Sopenharmony_ci 123e41f4b71Sopenharmony_ci (void)ConstructDataToCertChain(&certChain); 124e41f4b71Sopenharmony_ci /* 3. Attest the key. */ 125e41f4b71Sopenharmony_ci ohResult = OH_Huks_AttestKeyItem(&genAlias, attestParamSet, &certChain); 126e41f4b71Sopenharmony_ci } while (0); 127e41f4b71Sopenharmony_ci FreeCertChain(&certChain, CERT_COUNT); 128e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&genParamSet); 129e41f4b71Sopenharmony_ci OH_Huks_FreeParamSet(&attestParamSet); 130e41f4b71Sopenharmony_ci (void)OH_Huks_DeleteKeyItem(&genAlias, NULL); 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci napi_value ret; 133e41f4b71Sopenharmony_ci napi_create_int32(env, ohResult.errorCode, &ret); 134e41f4b71Sopenharmony_ci return ret; 135e41f4b71Sopenharmony_ci} 136e41f4b71Sopenharmony_ci``` 137