1# Certificate Chain Validator Development 2 3 4A 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. 5 6 7As 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. 8 9 10 11 12 13You can refer to the following example to construct a certificate chain from multiple certificates. 14 15 16## How to Develop 17 181. Import the [certFramework](../../reference/apis-device-certificate-kit/js-apis-cert.md) module. 19 ```ts 20 import { cert } from '@kit.DeviceCertificateKit'; 21 ``` 22 232. Use [cert.createCertChainValidator](../../reference/apis-device-certificate-kit/js-apis-cert.md#certcreatecertchainvalidator) to create a certificate chain validator (**CertChainValidator**) object. 24 253. Create a [CertChainData](../../reference/apis-device-certificate-kit/js-apis-cert.md#certchaindata) object. 26 27 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. 28 29 | Name| Type| Readable| Writable| Description| 30 | -------- | -------- | -------- | -------- | -------- | 31 | 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.| 32 | count | number | Yes| Yes| Number of certificates.| 33 | encodingFormat | [EncodingFormat](../../reference/apis-device-certificate-kit/js-apis-cert.md#encodingformat) | Yes| Yes| Certificate encoding format.| 34 354. Use [CertChainValidator.validate](../../reference/apis-device-certificate-kit/js-apis-cert.md#validate) to validate the certificate chain data. 36 37```ts 38import { cert } from '@kit.DeviceCertificateKit'; 39import { util } from '@kit.ArkTS'; 40 41// CA data, which is only an example. 42let caCertData = '-----BEGIN CERTIFICATE-----\n' + 43 '...\n' + 44 '...\n' + 45 '...\n' + 46 '-----END CERTIFICATE-----\n'; 47 48// Level-2 CA certificate data, which is only an example. 49let secondCaCertData = '-----BEGIN CERTIFICATE-----\n' + 50 '...\n' + 51 '...\n' + 52 '...\n' + 53 '-----END CERTIFICATE-----\n'; 54 55// Certificate chain validator. In this example, it validates a two-level certificate chain. 56function certChainValidatorSample(): void { 57 let textEncoder = new util.TextEncoder(); 58 // Certificate chain validator algorithm. Currently, only PKIX is supported. 59 let algorithm = 'PKIX'; 60 61 // Create a CertChainValidator object. 62 let validator = cert.createCertChainValidator(algorithm); 63 64 // CA certificate data. 65 let uint8ArrayOfCaCertData = textEncoder.encodeInto(caCertData); 66 67 // Length of the CA certificate data. 68 let uint8ArrayOfCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOfCaCertData.byteLength]).buffer); 69 70 // Data of the level-2 CA certificate. 71 let uint8ArrayOf2ndCaCertData = textEncoder.encodeInto(secondCaCertData); 72 73 // Length of the level-2 CA certificate data. 74 let uint8ArrayOf2ndCaCertDataLen = new Uint8Array(new Uint16Array([uint8ArrayOf2ndCaCertData.byteLength]).buffer); 75 76 // 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 77 let encodingData = new Uint8Array(uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + 78 uint8ArrayOfCaCertDataLen.length + uint8ArrayOfCaCertData.length); 79 for (let i = 0; i < uint8ArrayOf2ndCaCertDataLen.length; i++) { 80 encodingData[i] = uint8ArrayOf2ndCaCertDataLen[i]; 81 } 82 for (let i = 0; i < uint8ArrayOf2ndCaCertData.length; i++) { 83 encodingData[uint8ArrayOf2ndCaCertDataLen.length + i] = uint8ArrayOf2ndCaCertData[i]; 84 } 85 for (let i = 0; i < uint8ArrayOfCaCertDataLen.length; i++) { 86 encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + i] = uint8ArrayOfCaCertDataLen[i]; 87 } 88 for (let i = 0; i < uint8ArrayOfCaCertData.length; i++) { 89 encodingData[uint8ArrayOf2ndCaCertDataLen.length + uint8ArrayOf2ndCaCertData.length + 90 uint8ArrayOfCaCertDataLen.length + i] = uint8ArrayOfCaCertData[i]; 91 } 92 93 let certChainData: cert.CertChainData = { 94 // Uint8Array in L-V format (certificate data length-certificate data). 95 data: encodingData, 96 // Number of certificates. In this example, there are two certificates in the certification chain. 97 count: 2, 98 // Certificate format. Only PEM and DER are supported. In this example, the certificate is in PEM format. 99 encodingFormat: cert.EncodingFormat.FORMAT_PEM 100 }; 101 102 // Validate the certificate chain. 103 validator.validate(certChainData, (err, data) => { 104 if (err != null) { 105 // Throw an error as required. 106 console.error(`validate failed, errCode: ${err.code}, errMsg: ${err.message}`); 107 } else { 108 // Validation successful. 109 console.log('validate success'); 110 } 111 }); 112} 113``` 114