1package org.bouncycastle.operator.jcajce;
2
3import java.io.IOException;
4import java.io.OutputStream;
5import java.security.GeneralSecurityException;
6import java.security.MessageDigest;
7import java.security.Provider;
8
9import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
10import org.bouncycastle.jcajce.DefaultJcaJceHelper;
11import org.bouncycastle.jcajce.NamedJcaJceHelper;
12import org.bouncycastle.jcajce.ProviderJcaJceHelper;
13import org.bouncycastle.operator.DigestCalculator;
14import org.bouncycastle.operator.DigestCalculatorProvider;
15import org.bouncycastle.operator.OperatorCreationException;
16
17public class JcaDigestCalculatorProviderBuilder
18{
19    private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
20
21    public JcaDigestCalculatorProviderBuilder()
22    {
23    }
24
25    public JcaDigestCalculatorProviderBuilder setProvider(Provider provider)
26    {
27        this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
28
29        return this;
30    }
31
32    public JcaDigestCalculatorProviderBuilder setProvider(String providerName)
33    {
34        this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
35
36        return this;
37    }
38
39    public DigestCalculatorProvider build()
40        throws OperatorCreationException
41    {
42        return new DigestCalculatorProvider()
43        {
44            public DigestCalculator get(final AlgorithmIdentifier algorithm)
45                throws OperatorCreationException
46            {
47                final DigestOutputStream stream;
48
49                try
50                {
51                    MessageDigest dig = helper.createDigest(algorithm);
52
53                    stream = new DigestOutputStream(dig);
54                }
55                catch (GeneralSecurityException e)
56                {
57                    throw new OperatorCreationException("exception on setup: " + e, e);
58                }
59
60                return new DigestCalculator()
61                {
62                    public AlgorithmIdentifier getAlgorithmIdentifier()
63                    {
64                        return algorithm;
65                    }
66
67                    public OutputStream getOutputStream()
68                    {
69                        return stream;
70                    }
71
72                    public byte[] getDigest()
73                    {
74                        return stream.getDigest();
75                    }
76                };
77            }
78        };
79    }
80
81    private class DigestOutputStream
82        extends OutputStream
83    {
84        private MessageDigest dig;
85
86        DigestOutputStream(MessageDigest dig)
87        {
88            this.dig = dig;
89        }
90
91        public void write(byte[] bytes, int off, int len)
92            throws IOException
93        {
94            dig.update(bytes, off, len);
95        }
96
97        public void write(byte[] bytes)
98            throws IOException
99        {
100           dig.update(bytes);
101        }
102
103        public void write(int b)
104            throws IOException
105        {
106           dig.update((byte)b);
107        }
108
109        byte[] getDigest()
110        {
111            return dig.digest();
112        }
113    }
114}