1# Non-anonymous Key Attestation (C/C++) 2 3<!--Kit: Universal Keystore Kit--> 4<!--Subsystem: Security--> 5<!--Owner: @wutiantian-gitee--> 6<!--Designer: @HighLowWorld--> 7<!--Tester: @wxy1234564846--> 8<!--Adviser: @zengyawen--> 9 10The 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). 11 12## Add the dynamic library in the CMake script. 13```txt 14target_link_libraries(entry PUBLIC libhuks_ndk.z.so) 15``` 16 17## How to Develop 18 191. Specify the key alias. For details about the naming rules, see [Key Generation Overview and Algorithm Specifications](huks-key-generation-overview.md). 20 212. Initialize the parameter set: Construct **paramSet** via [OH_Huks_InitParamSet](../../reference/apis-universal-keystore-kit/capi-native-huks-param-h.md#oh_huks_initparamset), [OH_Huks_AddParams](../../reference/apis-universal-keystore-kit/capi-native-huks-param-h.md#oh_huks_addparams), and [OH_Huks_BuildParamSet](../../reference/apis-universal-keystore-kit/capi-native-huks-param-h.md#oh_huks_buildparamset), and specify the algorithm, key size, and key usage attributes via [OH_HUKS_TAG_ALGORITHM](../../reference/apis-universal-keystore-kit/capi-native-huks-type-h.md#oh_huks_keyalg), [OH_HUKS_TAG_KEY_SIZE](../../reference/apis-universal-keystore-kit/capi-native-huks-type-h.md#oh_huks_keysize), and [OH_HUKS_TAG_PURPOSE](../../reference/apis-universal-keystore-kit/capi-native-huks-type-h.md#oh_huks_keypurpose). 22 233. Generate an asymmetric key. For details, see [Key Generation](huks-key-generation-ndk.md). 24 254. Use [OH_Huks_AttestKeyItem](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_attestkeyitem) with the key alias and parameter set to perform key attestation. 26 27```c++ 28#include "huks/native_huks_api.h" 29#include "huks/native_huks_param.h" 30#include "napi/native_api.h" 31#include <string.h> 32OH_Huks_Result InitParamSet( 33 struct OH_Huks_ParamSet **paramSet, 34 const struct OH_Huks_Param *params, 35 uint32_t paramCount) 36{ 37 OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet); 38 if (ret.errorCode != OH_HUKS_SUCCESS) { 39 return ret; 40 } 41 ret = OH_Huks_AddParams(*paramSet, params, paramCount); 42 if (ret.errorCode != OH_HUKS_SUCCESS) { 43 OH_Huks_FreeParamSet(paramSet); 44 return ret; 45 } 46 ret = OH_Huks_BuildParamSet(paramSet); 47 if (ret.errorCode != OH_HUKS_SUCCESS) { 48 OH_Huks_FreeParamSet(paramSet); 49 return ret; 50 } 51 return ret; 52} 53static uint32_t g_size = 4096; 54static uint32_t CERT_COUNT = 4; 55void FreeCertChain(struct OH_Huks_CertChain *certChain, const uint32_t pos) 56{ 57 if (certChain == nullptr || certChain->certs == nullptr) { 58 return; 59 } 60 for (uint32_t j = 0; j < pos; j++) { 61 if (certChain->certs[j].data != nullptr) { 62 free(certChain->certs[j].data); 63 certChain->certs[j].data = nullptr; 64 } 65 } 66 if (certChain->certs != nullptr) { 67 free(certChain->certs); 68 certChain->certs = nullptr; 69 } 70} 71int32_t ConstructDataToCertChain(struct OH_Huks_CertChain *certChain) 72{ 73 if (certChain == nullptr) { 74 return OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT; 75 } 76 certChain->certsCount = CERT_COUNT; 77 78 certChain->certs = (struct OH_Huks_Blob *)malloc(sizeof(struct OH_Huks_Blob) * (certChain->certsCount)); 79 if (certChain->certs == nullptr) { 80 return OH_HUKS_ERR_CODE_INTERNAL_ERROR; 81 } 82 for (uint32_t i = 0; i < certChain->certsCount; i++) { 83 certChain->certs[i].size = g_size; 84 certChain->certs[i].data = (uint8_t *)malloc(certChain->certs[i].size); 85 if (certChain->certs[i].data == nullptr) { 86 FreeCertChain(certChain, i); 87 return OH_HUKS_ERR_CODE_INTERNAL_ERROR; 88 } 89 } 90 return 0; 91} 92static struct OH_Huks_Param g_genAttestParams[] = { 93 { .tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_RSA }, 94 { .tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048 }, 95 { .tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_VERIFY }, 96 { .tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_SHA256 }, 97 { .tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_PSS }, 98 { .tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_ECB }, 99}; 100#define CHALLENGE_DATA "hi_challenge_data" 101static struct OH_Huks_Blob g_challenge = { sizeof(CHALLENGE_DATA), (uint8_t *)CHALLENGE_DATA }; 102static napi_value AttestKey(napi_env env, napi_callback_info info) 103{ 104 /* 1. Set the key alias. */ 105 struct OH_Huks_Blob genAlias = { 106 (uint32_t)strlen("test_attest"), 107 (uint8_t *)"test_attest" 108 }; 109 static struct OH_Huks_Param g_attestParams[] = { 110 { .tag = OH_HUKS_TAG_ATTESTATION_CHALLENGE, .blob = g_challenge }, 111 { .tag = OH_HUKS_TAG_ATTESTATION_ID_ALIAS, .blob = genAlias }, 112 }; 113 struct OH_Huks_ParamSet *genParamSet = nullptr; 114 struct OH_Huks_ParamSet *attestParamSet = nullptr; 115 OH_Huks_Result ohResult; 116 OH_Huks_Blob certs = { 0 }; 117 OH_Huks_CertChain certChain = { &certs, 0 }; 118 do { 119 /* 2. Initialize the key parameter set. */ 120 ohResult = InitParamSet(&genParamSet, g_genAttestParams, sizeof(g_genAttestParams) / sizeof(OH_Huks_Param)); 121 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 122 break; 123 } 124 ohResult = InitParamSet(&attestParamSet, g_attestParams, sizeof(g_attestParams) / sizeof(OH_Huks_Param)); 125 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 126 break; 127 } 128 ohResult = OH_Huks_GenerateKeyItem(&genAlias, genParamSet, nullptr); 129 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 130 break; 131 } 132 133 ohResult.errorCode = ConstructDataToCertChain(&certChain); 134 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 135 break; 136 } 137 /* 3. Attest the key. */ 138 ohResult = OH_Huks_AttestKeyItem(&genAlias, attestParamSet, &certChain); 139 } while (0); 140 FreeCertChain(&certChain, CERT_COUNT); 141 OH_Huks_FreeParamSet(&genParamSet); 142 OH_Huks_FreeParamSet(&attestParamSet); 143 (void)OH_Huks_DeleteKeyItem(&genAlias, NULL); 144 145 napi_value ret; 146 napi_create_int32(env, ohResult.errorCode, &ret); 147 return ret; 148} 149``` 150