CRL Development

This topic walks you through on how to create a certificate revocation list (CRL) instance, obtain CRL information, check whether a certificate has been revoked, and print the revocation date if the certificate has been revoked.

How to Develop

  1. Import the certFramework and cryptoFramework modules.

    import { cert } from '@kit.DeviceCertificateKit';
    import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    
  2. Use cert.createX509CRL to create an X.509 CRL instance.

  3. Obtain CRL information.

    Here is an example of obtaining the CRL version, CRL type, CRL issuer name, and string-type data of the CRL object. For more field information, see @ohos.security.cert (Certificate).

  4. Create a PublicKey instance.

    For details, see convertKey.

  5. Use X509CRL.verify to verify the signature.

  6. Use cert.createX509Cert to create an X509Cert object based on the existing X.509 certificate data.

  7. Use X509CRL.isRevoked to check whether the X.509 certificate has been revoked.

  8. Use X509CRL.getRevokedCert to obtain the revoked certificate.

  9. Use X509CRLEntry.getRevocationDate to obtain the date when the certificate was revoked.



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

// ...
// CRL example.
function crlSample(): void {
  let textEncoder = new util.TextEncoder();
  let encodingBlob: cert.EncodingBlob = {
    // Convert the CRL data from a string to a Uint8Array.
    data: textEncoder.encodeInto(crlData),
    // CRL format. Only the PEM and DER formats are supported. In this example, the CRL is in PEM format.
    encodingFormat: cert.EncodingFormat.FORMAT_PEM
  };

  // Create an X509CRL instance.
  cert.createX509CRL(encodingBlob, (err, x509Crl) => {
    if (err != null) {
      // The X509CRL instance fails to be created.
      console.error(`createX509Crl failed, errCode: ${err.code}, errMsg:${err.message} `);
      return;
    }
    // The X509CRL instance is successfully created.
    console.info('createX509CRL result: success.');

    // Obtain the CRL version.
    let version = x509Crl.getVersion();
    // Obtain the CRL type.
    let revokedType = x509Crl.getType();
    console.info(`X509 CRL version: ${version}, type :${revokedType}`);

    // Obtain the CRL issuer name.
    let issuerName = x509Crl.getIssuerName(cert.EncodingType.ENCODING_UTF8);
    console.info(`X509 CRL issuerName: ${issuerName}`);

    // Obtain the string-type data of the CRL object.
    let crlString = x509Crl.toString(cert.EncodingType.ENCODING_UTF8);
    console.info(`X509 CRL crlString: ${crlString}`);


    // Pass in the public key binary data to convertKey() of @ohos.security.cryptoFramework to obtain a public key instance.
    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) {
              // Signature verification is successful.
              console.info('verify result: success.');
            } else {
              // Signature verification fails.
              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}`);
    }

    // Use createX509Cert() of certFramework to create an X509Cert instance.
    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, cert) => {
      serial = cert.getCertSerialNumber();
      if (err == null) {
        try {
          // Check whether the certificate has been revoked.
          revokedFlag = x509Crl.isRevoked(cert);
          console.info(`revokedFlag is: ${revokedFlag}`);
          if (!revokedFlag) {
            console.info('the given cert is not revoked.');
            return;
          }
          // Obtain the revoked certificate based on the serial number.
          try {
            let crlEntry = x509Crl.getRevokedCert(serial);
            console.info('getRevokedCert result: success.');
            let serialNumber = crlEntry.getSerialNumber();
            console.info(`crlEntry serialNumber is: ${serialNumber}`);

            // Obtain the revocation date of the certificate.
            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}`);
      }
    })

  });
}