证书吊销列表对象的创建、解析和校验
=================

以校验证书是否已吊销为例，完成证书吊销列表对象的创建、解析和校验。若证书已被吊销，将打印被吊销日期。

#### 开发步骤

1.  导入[证书模块](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cert)和[加解密算法库框架](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cryptoframework)。
    
    import { cert } from '@kit.DeviceCertificateKit';
    import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    
2.  基于已有的CRL数据，调用[cert.createX509CRL](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cert#certcreatex509crl11)创建X.509证书吊销列表的对象。
    
3.  解析证书吊销列表信息。
    
    此处以获取证书吊销列表版本、证书吊销列表类型、证书吊销列表颁发者名称、证书吊销列表对象的字符串类型数据为例，更多字段信息获取接口请查看API参考文档[X509CRL11+](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cert#x509crl11)。
    
4.  基于已有公钥信息，创建PublicKey公钥对象。
    
    具体可参考加解密算法库框架-指定二进制数据生成非对称密钥对[convertKey](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cryptoframework#convertkey-3)。
    
5.  调用[X509CRL.verify](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cert#verify11)校验签名合法性。
    
6.  基于已有的X.509证书数据，调用[cert.createX509Cert](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cert#certcreatex509cert)创建证书对象。
    
7.  调用[X509CRL.isRevoked](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cert#isrevoked11)判断X.509证书是否已被吊销。
    
8.  调用[X509CRL.getRevokedCert](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cert#getrevokedcert11)获取被吊销证书对象。
    
9.  调用[X509CRLEntry.getRevocationDate](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cert#getrevocationdate11)获取被吊销日期。
    

import { cert } from '@kit.DeviceCertificateKit';
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { util } from '@kit.ArkTS';

// ...
// CRL示例
function crlSample(): void {
  let textEncoder = new util.TextEncoder();
  let encodingBlob: cert.EncodingBlob = {
    // 将CRL数据从string转为Uint8Array。
    data: textEncoder.encodeInto(crlData),
    // CRL格式，仅支持PEM和DER格式。在这个例子中，CRL用的是PEM格式。
    encodingFormat: cert.EncodingFormat.FORMAT\_PEM
  };

  // 创建X509CRL实例。
  cert.createX509CRL(encodingBlob, (err, x509Crl) => {
    if (err != null) {
      // 创建X509CRL实例失败。
      console.error(\`createX509Crl failed, errCode: ${err.code}, errMsg:${err.message} \`);
      return;
    }
    // 创建X509CRL实例成功。
    console.info('createX509CRL result: success.');

    // 获取CRL的版本。
    let version = x509Crl.getVersion();
    // 获取证书吊销列表类型。
    let revokedType = x509Crl.getType();
    console.info(\`X509 CRL version: ${version}, type :${revokedType}\`);

    // 获取证书吊销列表颁发者名称。
    let issuerName = x509Crl.getIssuerName(cert.EncodingType.ENCODING\_UTF8);
    console.info(\`X509 CRL issuerName: ${issuerName}\`);

    // 获取证书吊销列表对象的字符串类型数据。
    let crlString = x509Crl.toString(cert.EncodingType.ENCODING\_UTF8);
    console.info(\`X509 CRL crlString: ${crlString}\`);


    // 公钥的二进制数据需要传入@ohos.security.cryptoFramework的convertKey()方法去获取公钥对象。
    try {
      let keyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES\_3');
      console.info('createAsyKeyGenerator result: success.');
      let pubEncodingBlob: cryptoFramework.DataBlob = {
        data: pubKeyData,
      };
      keyGenerator.convertKey(pubEncodingBlob, null, (e, keyPair) => {
        if (e == null) {
          console.info('convertKey result: success.');
          x509Crl.verify(keyPair.pubKey, (err, data) => {
            if (err == null) {
              // 签名验证成功。
              console.info('verify result: success.');
            } else {
              // 签名验证失败。
              console.error(\`verify failed, errCode: ${err.code}, errMsg: ${err.message}\`);
            }
          });
        } else {
          console.error(\`convert key failed, errCode: ${e.code}, errMsg: ${e.message}\`);
        }
      })
    } catch (error) {
      let e: BusinessError = error as BusinessError;
      console.error(\`get pubKey failed, errCode: ${e.code}, errMsg: ${e.message}\`);
    }

    // 使用certFramework的createX509Cert()方法创建一个X509Cert实例。
    let certBlob: cert.EncodingBlob = {
      data: textEncoder.encodeInto(certData),
      encodingFormat: cert.EncodingFormat.FORMAT\_PEM
    };
    let revokedFlag = true;
    let serial: bigint = BigInt('0');
    cert.createX509Cert(certBlob, (err, x509Cert) => {
      serial = x509Cert.getCertSerialNumber();
      if (err == null) {
        try {
          // 检查证书是否被吊销。
          revokedFlag = x509Crl.isRevoked(x509Cert);
          console.info(\`revokedFlag is: ${revokedFlag}\`);
          if (!revokedFlag) {
            console.info('the given x509Cert is not revoked.');
            return;
          }
          // 根据序列号来获取被吊销的证书。
          try {
            let crlEntry = x509Crl.getRevokedCert(serial);
            console.info('getRevokedCert result: success.');
            let serialNumber = crlEntry.getSerialNumber();
            console.info(\`crlEntry serialNumber is: ${serialNumber}\`);

            // 获取被吊销证书的吊销日期。
            let date = crlEntry.getRevocationDate();
            console.info(\`revocation date is: ${date}\`);
          } catch (error) {
            let e: BusinessError = error as BusinessError;
            console.error(\`getRevokedCert failed, errCode: ${e.code}, errMsg: ${e.message}\`);
          }
        } catch (error) {
          let e: BusinessError = error as BusinessError;
          console.error(\`isRevoked failed, errCode: ${e.code}, errMsg:${e.message}\`);
        }
      } else {
        console.error(\`create x509 cert failed, errCode: ${err.code}, errMsg: ${err.message}\`);
      }
    })

  });
}