Class CertificateParser

java.lang.Object
javacardx.security.cert.CertificateParser

public abstract class CertificateParser extends Object
The CertificateParser class is used to parse certificates and create Certificate instances.

A parser instance is created for a specific certificate format (e.g. X509)

The parser can be used in two ways:

  • to parse certificate elements from a provided byte array
  • to allocate a Certificate instance and initialize it with a subset of selected elements copied from the specified byte array

Certificate Parsing

The CertificateParser instance can be used to parse certificates from a byte array and to trigger a CertificateParser.ParserHandler for each element found. The handler receives information on each element found including its value.

Example: parsing and verification

 public class CertExample1 implements FieldHandler, KeyHandler, ExtensionHandler {

    private final CertificateParser parser = CertificateParser.getInstance(CertificateParser.TYPE_X509_DER);
    private PublicKey pubKey;
    private final Certificate rootCert;

    public CertExample1(Certificate root) {
        this.rootCert = root;
    }
    // parse certificate, verify signature with root cert, extract and return public key
    public PublicKey parse(byte[] data, short offset, short length) throws CertificateException {
        parser.parseCert(data, offset, length, this, rootCert.getPublicKey());
        return pubKey;
    }

    // --- FieldHandler ----------------------------------------------------------
    @Override
    public boolean onField(short fieldID, byte[] field) {
        switch (fieldID) {
        case X509Certificate.FIELD_TBS_NOT_AFTER:
            if (expired(field)) {
                CertificateException.throwIt(EXPIRED);
            }
            break;
        case X509Certificate.FIELD_TBS_PUBLIC_KEY_INFO:
            if (pubKey == null) {
                // KeyHandler has not been called because type not supported
                // use proprietary decoder
                pubKey = decodeKey(value);
            }
            break;
        }
        return false;
    }

    // --- ExtensionHandler ------------------------------------------------------
    @Override
    public boolean onExtension(byte[] oid, boolean isCritical, byte[] value) {
        if (Util.arrayCompare(oid, (short) 0, OID_KEY_USAGE, (short) 0, OID_KEY_USAGE.length) == 0) {
            // check usage
        }
    }

    // --- KeyHandler ------------------------------------------------------------
    @Override
    public PublicKey onKey(byte keytype, short params) {
        if (keytype == KeyBuilder.TYPE_XEC) {
            pubKey = (PublicKey) KeyBuilder.buildXECKey(
                    NamedParameterSpec.getInstance(params),
                    JCSystem.MEMORY_TYPE_PERSISTENT,
                    false);
        } else {
            pubKey = (PublicKey) KeyBuilder.buildKey(keytype, params, false);
        }
        return pubKey;
    }
}
 
Note: The parsing may fail at any time due to an invalid element encoding (fail-fast processing since there is no copy of the source buffer). Consequently, the handler is not called for subsequent elements if an invalid element is found. This could also be the case if the buffer is modified during parsing with invalid data after the ones already parsed (for example if the handler modifies the buffer)

Parsing and allocating a Certificate instance

The CertificateParser instance can be used to parse an existing byte array and to create a new Certificate instance. A X509Certificate.FieldHandler is used to specify which certificate fields should be stored to be used to initialize a new Certificate instance.

Example: Parsing and creation of a new Certificate instance

 public class CertExample2 implements FieldHandler, ExtensionHandler {

     private final CertificateParser parser = CertificateParser.getInstance(CertificateParser.TYPE_X509_DER);

     public Certificate buildCert(byte[] data, short offset, short length) throws CertificateException {
         return parser.buildCert(data, offset, length, this);
     }

     // --- FieldHandler ----------------------------------------------------------
     @Override
     public boolean onField(short fieldID, byte[] field) {
         switch (fieldID) {
         case X509Certificate.FIELD_TBS_ISSUER:    // store issuer name
         case X509Certificate.FIELD_TBS_NOT_AFTER: // store validity date
         case X509Certificate.FIELD_TBS_NOT_BEFORE:// store validity date
         case X509Certificate.FIELD_TBS_SUBJECT:   // store subject
             return true;
         }
         // skip other fields
         return false;
     }

     // --- ExtensionHandler ------------------------------------------------------
     @Override
     public boolean onExtension(byte[] oid, boolean isCritical, byte[] value) {
        // keep critical extensions
        // and Subject Alternative Name (OID: 2.5.29.17)
        return
           isCritical ||
           Util.arrayCompare(oid, (short)0, OID_SUBJECT_ALT_NAME, (short)0, OID_SUBJECT_ALT_NAME.length) == 0);
     }
 }
 

Since:
3.1
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static interface 
    A KeyHandler is triggered by a CertificateParser and allows to fill the fields of a PublicKey pre-allocated by the application with the values of the public key of the certificate.
    static interface 
    ParserHandler is the base interface for all handlers that can be triggered by the CertificateParser at the time a certificate is built or parsed.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final short
    Parser for X.509 v1, v2 and v3 DER-encoded certificates (see RFC 5280)
  • Method Summary

    Modifier and Type
    Method
    Description
    abstract Certificate
    buildCert(byte[] data, short offset, short length, CertificateParser.ParserHandler handler)
    Parse certificate data and create a Certificate instance.
    abstract Certificate
    buildCert(byte[] data, short offset, short length, CertificateParser.ParserHandler handler, PublicKey key)
    Parse certificate data and create a Certificate instance.
    getInstance(short type)
    Creates an instance of a parser for the specified certificate format
    abstract void
    parseCert(byte[] data, short offset, short length, CertificateParser.ParserHandler handler)
    Parse certificate data and trigger the handle for each element found.
    abstract boolean
    parseCert(byte[] data, short offset, short length, CertificateParser.ParserHandler handler, PublicKey key)
    Parse certificate data, trigger the handle for each element found, and verify it using the specified public key.

    Methods inherited from class Object

    equals
    Modifier and Type
    Method
    Description
    boolean
    Compares two Objects for equality.