1e41f4b71Sopenharmony_ci# Certificate Chain Validator Development 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciA certificate chain is an ordered list of certificates, in which each certificate is signed by the entity identified by the next certificate in the chain. 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciAs shown in the following figure, the certificate chain consists three certificates. The root certificate is self-signed by GlobalSign, which signed the intermediary certificate held by GlobalSign RSA OV SSL CA 2018. GlobalSign RSA OV SSL CA 2018 (the holder of the intermediate certificate) signed the end certificate. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ciYou can refer to the following example to construct a certificate chain from multiple certificates. 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci## How to Develop 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci1. Import the [certFramework](../../reference/apis-device-certificate-kit/js-apis-cert.md) module. 19e41f4b71Sopenharmony_ci ```ts 20e41f4b71Sopenharmony_ci import { cert } from '@kit.DeviceCertificateKit'; 21e41f4b71Sopenharmony_ci ``` 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci2. Use [cert.createCertChainValidator](../../reference/apis-device-certificate-kit/js-apis-cert.md#certcreatecertchainvalidator) to create a certificate chain validator (**CertChainValidator**) object. 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci3. Create a [CertChainData](../../reference/apis-device-certificate-kit/js-apis-cert.md#certchaindata) object. 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci The certificate framework provides a **CertChainValidator** object to validate certificate chains. However, the **CertChainData** object to be validated must comply with the following struct definition. 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci | Name| Type| Readable| Writable| Description| 30e41f4b71Sopenharmony_ci | -------- | -------- | -------- | -------- | -------- | 31e41f4b71Sopenharmony_ci | data | Uint8Array | Yes| Yes| Certificate data, which is in the length (2 bytes)-data format. For example, **08ABCDEFGH07ABCDEFG**. The first two bytes (**08**) indicate the length of the first certificate, which is eight bytes, and the following eight bytes indicate the certificate data. The next two bytes (**07**) indicate the length of another certificate, which is seven bytes, and the seven bytes followed indicate the certificate data.| 32e41f4b71Sopenharmony_ci | count | number | Yes| Yes| Number of certificates.| 33e41f4b71Sopenharmony_ci | encodingFormat | [EncodingFormat](../../reference/apis-device-certificate-kit/js-apis-cert.md#encodingformat) | Yes| Yes| Certificate encoding format.| 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci4. Use [CertChainValidator.validate](../../reference/apis-device-certificate-kit/js-apis-cert.md#validate) to validate the certificate chain data. 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci```ts 38e41f4b71Sopenharmony_ciimport { cert } from '@kit.DeviceCertificateKit'; 39e41f4b71Sopenharmony_ciimport { util } from '@kit.ArkTS'; 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci// CA data, which is only an example. 42e41f4b71Sopenharmony_cilet caCertData = '-----BEGIN CERTIFICATE-----\n' + 43e41f4b71Sopenharmony_ci '...\n' + 44e41f4b71Sopenharmony_ci '...\n' + 45e41f4b71Sopenharmony_ci '...\n' + 46e41f4b71Sopenharmony_ci '-----END CERTIFICATE-----\n'; 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ci// Level-2 CA certificate data, which is only an example. 49e41f4b71Sopenharmony_cilet secondCaCertData = '-----BEGIN CERTIFICATE-----\n' + 50e41f4b71Sopenharmony_ci '...\n' + 51e41f4b71Sopenharmony_ci '...\n' + 52e41f4b71Sopenharmony_ci '...\n' + 53e41f4b71Sopenharmony_ci '-----END CERTIFICATE-----\n'; 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci// Certificate chain validator. In this example, it validates a two-level certificate chain. 56e41f4b71Sopenharmony_cifunction certChainValidatorSample(): void { 57e41f4b71Sopenharmony_ci let textEncoder = new util.TextEncoder(); 58e41f4b71Sopenharmony_ci // Certificate chain validator algorithm. Currently, only PKIX is supported. 59e41f4b71Sopenharmony_ci let algorithm = 'PKIX'; 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci // Create a CertChainValidator object. 62e41f4b71Sopenharmony_ci let validator = cert.createCertChainValidator(algorithm); 63e41f4b71Sopenharmony_ci 64e41f4b71Sopenharmony_ci // CA certificate data. 65e41f4b71Sopenharmony_ci let uint8ArrayOfCaCertData = textEncoder.encodeInto(caCertData); 66e41f4b71Sopenharmony_ci 67e41f4b71Sopenharmony_ci // Length of the CA certificate data. 68e41f4b71Sopenharmony_ci let uint8ArrayOfCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOfCaCertData.byteLength]).buffer); 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci // Data of the level-2 CA certificate. 71e41f4b71Sopenharmony_ci let uint8ArrayOf2ndCaCertData = textEncoder.encodeInto(secondCaCertData); 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ci // Length of the level-2 CA certificate data. 74e41f4b71Sopenharmony_ci let uint8ArrayOf2ndCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOf2ndCaCertData.byteLength]).buffer); 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ci // Binary data of the certificate chain in L-V format: Length of the level-2 CA certificate data + Level-2 CA certificate data + Length of the CA certificate data + CA certificate data 77e41f4b71Sopenharmony_ci let encodingData = new Uint8Array(uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + 78e41f4b71Sopenharmony_ci uint8ArrayOfCaCertDataLen.length + uint8ArrayOfCaCertData.length); 79e41f4b71Sopenharmony_ci for (let i = 0; i < uint8ArrayOf2ndCaCertDataLen.length; i++) { 80e41f4b71Sopenharmony_ci encodingData[i] = uint8ArrayOf2ndCaCertDataLen[i]; 81e41f4b71Sopenharmony_ci } 82e41f4b71Sopenharmony_ci for (let i = 0; i < uint8ArrayOf2ndCaCertData.length; i++) { 83e41f4b71Sopenharmony_ci encodingData[uint8ArrayOf2ndCaCertDataLen.length + i] = uint8ArrayOf2ndCaCertData[i]; 84e41f4b71Sopenharmony_ci } 85e41f4b71Sopenharmony_ci for (let i = 0; i < uint8ArrayOfCaCertDataLen.length; i++) { 86e41f4b71Sopenharmony_ci encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + i] = uint8ArrayOfCaCertDataLen[i]; 87e41f4b71Sopenharmony_ci } 88e41f4b71Sopenharmony_ci for (let i = 0; i < uint8ArrayOfCaCertData.length; i++) { 89e41f4b71Sopenharmony_ci encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + 90e41f4b71Sopenharmony_ci uint8ArrayOfCaCertDataLen.length + i] = uint8ArrayOfCaCertData[i]; 91e41f4b71Sopenharmony_ci } 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci let certChainData: cert.CertChainData = { 94e41f4b71Sopenharmony_ci // Uint8Array in L-V format (certificate data length-certificate data). 95e41f4b71Sopenharmony_ci data: encodingData, 96e41f4b71Sopenharmony_ci // Number of certificates. In this example, there are two certificates in the certification chain. 97e41f4b71Sopenharmony_ci count: 2, 98e41f4b71Sopenharmony_ci // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format. 99e41f4b71Sopenharmony_ci encodingFormat: cert.EncodingFormat.FORMAT_PEM 100e41f4b71Sopenharmony_ci }; 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci // Validate the certificate chain. 103e41f4b71Sopenharmony_ci validator.validate(certChainData, (err, data) => { 104e41f4b71Sopenharmony_ci if (err != null) { 105e41f4b71Sopenharmony_ci // Throw an error as required. 106e41f4b71Sopenharmony_ci console.error(`validate failed, errCode: ${err.code}, errMsg: ${err.message}`); 107e41f4b71Sopenharmony_ci } else { 108e41f4b71Sopenharmony_ci // Validation successful. 109e41f4b71Sopenharmony_ci console.log('validate success'); 110e41f4b71Sopenharmony_ci } 111e41f4b71Sopenharmony_ci }); 112e41f4b71Sopenharmony_ci} 113e41f4b71Sopenharmony_ci``` 114