| package org.bouncycastle.operator.jcajce; |
| |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.security.GeneralSecurityException; |
| import java.security.PrivateKey; |
| import java.security.Provider; |
| import java.security.SecureRandom; |
| import java.security.Signature; |
| import java.security.SignatureException; |
| |
| import org.bouncycastle.asn1.x509.AlgorithmIdentifier; |
| import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; |
| import org.bouncycastle.jcajce.util.NamedJcaJceHelper; |
| import org.bouncycastle.jcajce.util.ProviderJcaJceHelper; |
| import org.bouncycastle.operator.ContentSigner; |
| import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; |
| import org.bouncycastle.operator.OperatorCreationException; |
| import org.bouncycastle.operator.OperatorStreamException; |
| import org.bouncycastle.operator.RuntimeOperatorException; |
| |
| public class JcaContentSignerBuilder |
| { |
| private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper()); |
| private SecureRandom random; |
| private String signatureAlgorithm; |
| private AlgorithmIdentifier sigAlgId; |
| |
| public JcaContentSignerBuilder(String signatureAlgorithm) |
| { |
| this.signatureAlgorithm = signatureAlgorithm; |
| this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm); |
| } |
| |
| public JcaContentSignerBuilder setProvider(Provider provider) |
| { |
| this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider)); |
| |
| return this; |
| } |
| |
| public JcaContentSignerBuilder setProvider(String providerName) |
| { |
| this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName)); |
| |
| return this; |
| } |
| |
| public JcaContentSignerBuilder setSecureRandom(SecureRandom random) |
| { |
| this.random = random; |
| |
| return this; |
| } |
| |
| public ContentSigner build(PrivateKey privateKey) |
| throws OperatorCreationException |
| { |
| try |
| { |
| final Signature sig = helper.createSignature(sigAlgId); |
| final AlgorithmIdentifier signatureAlgId = sigAlgId; |
| |
| if (random != null) |
| { |
| sig.initSign(privateKey, random); |
| } |
| else |
| { |
| sig.initSign(privateKey); |
| } |
| |
| return new ContentSigner() |
| { |
| private SignatureOutputStream stream = new SignatureOutputStream(sig); |
| |
| public AlgorithmIdentifier getAlgorithmIdentifier() |
| { |
| return signatureAlgId; |
| } |
| |
| public OutputStream getOutputStream() |
| { |
| return stream; |
| } |
| |
| public byte[] getSignature() |
| { |
| try |
| { |
| return stream.getSignature(); |
| } |
| catch (SignatureException e) |
| { |
| throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e); |
| } |
| } |
| }; |
| } |
| catch (GeneralSecurityException e) |
| { |
| throw new OperatorCreationException("cannot create signer: " + e.getMessage(), e); |
| } |
| } |
| |
| private class SignatureOutputStream |
| extends OutputStream |
| { |
| private Signature sig; |
| |
| SignatureOutputStream(Signature sig) |
| { |
| this.sig = sig; |
| } |
| |
| public void write(byte[] bytes, int off, int len) |
| throws IOException |
| { |
| try |
| { |
| sig.update(bytes, off, len); |
| } |
| catch (SignatureException e) |
| { |
| throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); |
| } |
| } |
| |
| public void write(byte[] bytes) |
| throws IOException |
| { |
| try |
| { |
| sig.update(bytes); |
| } |
| catch (SignatureException e) |
| { |
| throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); |
| } |
| } |
| |
| public void write(int b) |
| throws IOException |
| { |
| try |
| { |
| sig.update((byte)b); |
| } |
| catch (SignatureException e) |
| { |
| throw new OperatorStreamException("exception in content signer: " + e.getMessage(), e); |
| } |
| } |
| |
| byte[] getSignature() |
| throws SignatureException |
| { |
| return sig.sign(); |
| } |
| } |
| } |