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