1e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompackage org.bouncycastle.operator.jcajce;
2e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
3e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.IOException;
4e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.OutputStream;
5e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.GeneralSecurityException;
6e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.PrivateKey;
7e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.Provider;
8e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.SecureRandom;
9e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.Signature;
10e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.SignatureException;
11e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
12e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
13e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.jcajce.DefaultJcaJceHelper;
14e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.jcajce.NamedJcaJceHelper;
15e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.jcajce.ProviderJcaJceHelper;
16e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.ContentSigner;
17e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
18e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.OperatorCreationException;
19e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.OperatorStreamException;
20e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.RuntimeOperatorException;
21e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
22e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompublic class JcaContentSignerBuilder
23e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom{
24e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
25e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private SecureRandom random;
26e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private String signatureAlgorithm;
27e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private AlgorithmIdentifier sigAlgId;
28e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
29e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public JcaContentSignerBuilder(String signatureAlgorithm)
30e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
31e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.signatureAlgorithm = signatureAlgorithm;
32e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm);
33e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
34e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
35e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public JcaContentSignerBuilder setProvider(Provider provider)
36e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
37e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
38e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
39e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return this;
40e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
41e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
42e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public JcaContentSignerBuilder setProvider(String providerName)
43e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
44e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
45e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
46e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return this;
47e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
48e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
49e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public JcaContentSignerBuilder setSecureRandom(SecureRandom random)
50e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
51e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        this.random = random;
52e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
53e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        return this;
54e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
55e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
56e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    public ContentSigner build(PrivateKey privateKey)
57e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        throws OperatorCreationException
58e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
59e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        try
60e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
61e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            final Signature sig = helper.createSignature(sigAlgId);
62e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
63e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            if (random != null)
64e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
65e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                sig.initSign(privateKey, random);
66e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
67e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            else
68e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
69e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                sig.initSign(privateKey);
70e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
71e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
72e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            return new ContentSigner()
73e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
74e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                private SignatureOutputStream stream = new SignatureOutputStream(sig);
75e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
76e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                public AlgorithmIdentifier getAlgorithmIdentifier()
77e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                {
78e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    return sigAlgId;
79e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                }
80e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
81e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                public OutputStream getOutputStream()
82e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                {
83e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    return stream;
84e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                }
85e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
86e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                public byte[] getSignature()
87e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                {
88e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    try
89e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    {
90e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                        return stream.getSignature();
91e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    }
92e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    catch (SignatureException e)
93e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    {
94e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                        throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
95e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                    }
96e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                }
97e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            };
98e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
99e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        catch (GeneralSecurityException e)
100e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
101e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e);
102e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
103e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
104e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
105e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    private class SignatureOutputStream
106e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        extends OutputStream
107e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    {
108e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        private Signature sig;
109e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
110e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        SignatureOutputStream(Signature sig)
111e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
112e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            this.sig = sig;
113e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
114e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
115e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        public void write(byte[] bytes, int off, int len)
116e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            throws IOException
117e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
118e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            try
119e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
120e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                sig.update(bytes, off, len);
121e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
122e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            catch (SignatureException e)
123e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
124e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e);
125e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
126e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
127e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
128e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        public void write(byte[] bytes)
129e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            throws IOException
130e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
131e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            try
132e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
133e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                sig.update(bytes);
134e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
135e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            catch (SignatureException e)
136e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
137e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e);
138e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
139e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
140e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
141e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        public void write(int b)
142e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            throws IOException
143e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
144e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            try
145e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
146e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                sig.update((byte)b);
147e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
148e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            catch (SignatureException e)
149e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            {
150e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom                throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e);
151e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            }
152e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
153e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom
154e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        byte[] getSignature()
155e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            throws SignatureException
156e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        {
157e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom            return sig.sign();
158e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom        }
159e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom    }
160e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom}
161