org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder.java

Source

package org.bouncycastle.openpgp.operator.jcajce;

import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.Provider;

import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;

/**
 * A builder for {@link PGPDigestCalculatorProvider} instances that obtain cryptographic primitives
 * using the JCA API.
 * <p>
 * By default digest calculator providers obtained from this builder will use the default JCA
 * algorithm lookup mechanisms (i.e. specifying no provider), but a specific provider can be
 * specified prior to building.
 * </p>
 */
public class JcaPGPDigestCalculatorProviderBuilder {
    private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());

    /**
     * Default constructor.
     */
    public JcaPGPDigestCalculatorProviderBuilder() {
    }

    /**
     * Sets the provider to use to obtain cryptographic primitives.
     *
     * @param provider the JCA provider to use.
     * @return the current builder.
     */
    public JcaPGPDigestCalculatorProviderBuilder setProvider(Provider provider) {
        this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));

        return this;
    }

    /**
     * Sets the provider to use to obtain cryptographic primitives.
     *
     * @param providerName the name of the JCA provider to use.
     * @return the current builder.
     */
    public JcaPGPDigestCalculatorProviderBuilder setProvider(String providerName) {
        this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));

        return this;
    }

    /**
     * Constructs a new PGPDigestCalculatorProvider
     *
     * @return a PGPDigestCalculatorProvider that will use the JCA algorithm lookup strategy
     *         configured on this builder.
     * @throws PGPException if an error occurs constructing the digest calculator provider.
     */
    public PGPDigestCalculatorProvider build() throws PGPException {
        return new PGPDigestCalculatorProvider() {
            public PGPDigestCalculator get(final int algorithm) throws PGPException {
                final DigestOutputStream stream;
                final MessageDigest dig;

                try {
                    dig = helper.createDigest(algorithm);

                    stream = new DigestOutputStream(dig);
                } catch (GeneralSecurityException e) {
                    throw new PGPException("exception on setup: " + e, e);
                }

                return new PGPDigestCalculator() {
                    public int getAlgorithm() {
                        return algorithm;
                    }

                    public OutputStream getOutputStream() {
                        return stream;
                    }

                    public byte[] getDigest() {
                        return stream.getDigest();
                    }

                    public void reset() {
                        dig.reset();
                    }
                };
            }
        };
    }

    private class DigestOutputStream extends OutputStream {
        private MessageDigest dig;

        DigestOutputStream(MessageDigest dig) {
            this.dig = dig;
        }

        public void write(byte[] bytes, int off, int len) throws IOException {
            dig.update(bytes, off, len);
        }

        public void write(byte[] bytes) throws IOException {
            dig.update(bytes);
        }

        public void write(int b) throws IOException {
            dig.update((byte) b);
        }

        byte[] getDigest() {
            return dig.digest();
        }
    }
}