org.cryptacular.spec.AEADBlockCipherSpec.java Source code

Java tutorial

Introduction

Here is the source code for org.cryptacular.spec.AEADBlockCipherSpec.java

Source

/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.spec;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.modes.AEADBlockCipher;
import org.bouncycastle.crypto.modes.CCMBlockCipher;
import org.bouncycastle.crypto.modes.EAXBlockCipher;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.modes.OCBBlockCipher;

/**
 * Describes an AEAD block cipher in terms of a (algorithm, mode) tuple and
 * provides a facility to create a new instance of the cipher via the {@link
 * #newInstance()} method.
 *
 * @author  Middleware Services
 * @version  $Revision: 2744 $
 */
public class AEADBlockCipherSpec implements Spec<AEADBlockCipher> {

    /** String specification format, <code>algorithm/mode</code>. */
    public static final Pattern FORMAT = Pattern.compile("(?<alg>[A-Za-z0-9_-]+)/(?<mode>\\w+)");

    /** Cipher algorithm algorithm. */
    private final String algorithm;

    /** Cipher mode, e.g. GCM, CCM. */
    private final String mode;

    /**
     * Creates a new instance from a cipher algorithm and mode.
     *
     * @param  algName  Cipher algorithm name.
     * @param  cipherMode  Cipher mode, e.g. GCM, CCM.
     */
    public AEADBlockCipherSpec(final String algName, final String cipherMode) {
        this.algorithm = algName;
        this.mode = cipherMode;
    }

    @Override
    public String getAlgorithm() {
        return algorithm;
    }

    /**
     * Gets the cipher mode.
     *
     * @return  Cipher mode, e.g. CBC, OFB.
     */
    public String getMode() {
        return mode;
    }

    /**
     * Creates a new AEAD block cipher from the specification in this instance.
     *
     * @return  New AEAD block cipher instance.
     */
    @Override
    public AEADBlockCipher newInstance() {
        final BlockCipher blockCipher = new BlockCipherSpec(algorithm).newInstance();
        AEADBlockCipher aeadBlockCipher;
        switch (mode) {

        case "GCM":
            aeadBlockCipher = new GCMBlockCipher(blockCipher);
            break;

        case "CCM":
            aeadBlockCipher = new CCMBlockCipher(blockCipher);
            break;

        case "OCB":
            aeadBlockCipher = new OCBBlockCipher(blockCipher, new BlockCipherSpec(algorithm).newInstance());
            break;

        case "EAX":
            aeadBlockCipher = new EAXBlockCipher(blockCipher);
            break;

        default:
            throw new IllegalStateException("Unsupported mode " + mode);
        }
        return aeadBlockCipher;
    }

    @Override
    public String toString() {
        return algorithm + '/' + mode;
    }

    /**
     * Parses a string representation of a AEAD block cipher specification into an
     * instance of this class.
     *
     * @param  specification  AEAD block cipher specification of the form <code>
     *                        algorithm/mode</code>.
     *
     * @return  Buffered block cipher specification instance.
     */
    public static AEADBlockCipherSpec parse(final String specification) {
        final Matcher m = FORMAT.matcher(specification);
        if (!m.matches()) {
            throw new IllegalArgumentException("Invalid specification " + specification);
        }
        return new AEADBlockCipherSpec(m.group("alg"), m.group("mode"));
    }
}