1# 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 10Ensure network connection during the operation. 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). The parameter set must contain the [OH_Huks_KeyAlg](../../reference/apis-universal-keystore-kit/capi-native-huks-type-h.md#oh_huks_keyalg), [OH_Huks_KeySize](../../reference/apis-universal-keystore-kit/capi-native-huks-type-h.md#oh_huks_keysize), and [OH_Huks_KeyPurpose](../../reference/apis-universal-keystore-kit/capi-native-huks-type-h.md#oh_huks_keypurpose) attributes. 22 233. Use [OH_Huks_AnonAttestKeyItem](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_anonattestkeyitem) with the key alias and parameter set to perform key attestation. 24 25```c++ 26#include "huks/native_huks_api.h" 27#include "huks/native_huks_param.h" 28#include "napi/native_api.h" 29#include <string.h> 30OH_Huks_Result InitParamSet( 31 struct OH_Huks_ParamSet **paramSet, 32 const struct OH_Huks_Param *params, 33 uint32_t paramCount) 34{ 35 OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet); 36 if (ret.errorCode != OH_HUKS_SUCCESS) { 37 return ret; 38 } 39 ret = OH_Huks_AddParams(*paramSet, params, paramCount); 40 if (ret.errorCode != OH_HUKS_SUCCESS) { 41 OH_Huks_FreeParamSet(paramSet); 42 return ret; 43 } 44 ret = OH_Huks_BuildParamSet(paramSet); 45 if (ret.errorCode != OH_HUKS_SUCCESS) { 46 OH_Huks_FreeParamSet(paramSet); 47 return ret; 48 } 49 return ret; 50} 51static uint32_t g_size = 4096; 52static uint32_t CERT_COUNT = 4; 53void FreeCertChain(struct OH_Huks_CertChain *certChain, const uint32_t pos) 54{ 55 if (certChain == nullptr || certChain->certs == nullptr) { 56 return; 57 } 58 for (uint32_t j = 0; j < pos; j++) { 59 if (certChain->certs[j].data != nullptr) { 60 free(certChain->certs[j].data); 61 certChain->certs[j].data = nullptr; 62 } 63 } 64 if (certChain->certs != nullptr) { 65 free(certChain->certs); 66 certChain->certs = nullptr; 67 } 68} 69int32_t ConstructDataToCertChain(struct OH_Huks_CertChain *certChain) 70{ 71 if (certChain == nullptr) { 72 return OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT; 73 } 74 certChain->certsCount = CERT_COUNT; 75 76 certChain->certs = (struct OH_Huks_Blob *)malloc(sizeof(struct OH_Huks_Blob) * (certChain->certsCount)); 77 if (certChain->certs == nullptr) { 78 return OH_HUKS_ERR_CODE_INTERNAL_ERROR; 79 } 80 for (uint32_t i = 0; i < certChain->certsCount; i++) { 81 certChain->certs[i].size = g_size; 82 certChain->certs[i].data = (uint8_t *)malloc(certChain->certs[i].size); 83 if (certChain->certs[i].data == nullptr) { 84 FreeCertChain(certChain, i); 85 return OH_HUKS_ERR_CODE_INTERNAL_ERROR; 86 } 87 } 88 return OH_HUKS_SUCCESS; 89} 90static struct OH_Huks_Param g_genAnonAttestParams[] = { 91 { .tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_RSA }, 92 { .tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_RSA_KEY_SIZE_2048 }, 93 { .tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_VERIFY }, 94 { .tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_SHA256 }, 95 { .tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_PSS }, 96 { .tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_ECB }, 97}; 98#define CHALLENGE_DATA "hi_challenge_data" 99static struct OH_Huks_Blob g_challenge = { sizeof(CHALLENGE_DATA), (uint8_t *)CHALLENGE_DATA }; 100static napi_value AnonAttestKey(napi_env env, napi_callback_info info) 101{ 102 /* 1. Set the key alias. */ 103 struct OH_Huks_Blob genAlias = { 104 (uint32_t)strlen("test_anon_attest"), 105 (uint8_t *)"test_anon_attest" 106 }; 107 static struct OH_Huks_Param g_anonAttestParams[] = { 108 { .tag = OH_HUKS_TAG_ATTESTATION_CHALLENGE, .blob = g_challenge }, 109 { .tag = OH_HUKS_TAG_ATTESTATION_ID_ALIAS, .blob = genAlias }, 110 }; 111 struct OH_Huks_ParamSet *genParamSet = nullptr; 112 struct OH_Huks_ParamSet *anonAttestParamSet = nullptr; 113 OH_Huks_Result ohResult; 114 OH_Huks_Blob certs = { 0 }; 115 OH_Huks_CertChain certChain = { &certs, 0 }; 116 do { 117 /* 2. Initialize the key parameter set. */ 118 ohResult = InitParamSet(&genParamSet, g_genAnonAttestParams, sizeof(g_genAnonAttestParams) / sizeof(OH_Huks_Param)); 119 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 120 break; 121 } 122 ohResult = InitParamSet(&anonAttestParamSet, g_anonAttestParams, sizeof(g_anonAttestParams) / sizeof(OH_Huks_Param)); 123 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 124 break; 125 } 126 ohResult = OH_Huks_GenerateKeyItem(&genAlias, genParamSet, nullptr); 127 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 128 break; 129 } 130 131 ohResult.errorCode = ConstructDataToCertChain(&certChain); 132 if (ohResult.errorCode != OH_HUKS_SUCCESS) { 133 break; 134 } 135 /* 3. Attest the key. */ 136 ohResult = OH_Huks_AnonAttestKeyItem(&genAlias, anonAttestParamSet, &certChain); 137 } while (0); 138 FreeCertChain(&certChain, CERT_COUNT); 139 OH_Huks_FreeParamSet(&genParamSet); 140 OH_Huks_FreeParamSet(&anonAttestParamSet); 141 (void)OH_Huks_DeleteKeyItem(&genAlias, NULL); 142 143 napi_value ret; 144 napi_create_int32(env, ohResult.errorCode, &ret); 145 return ret; 146} 147``` 148