package org.bouncycastle.tls.crypto.impl.bc; import java.io.IOException; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.DSA; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.digests.NullDigest; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.DSADigestSigner; import org.bouncycastle.tls.AlertDescription; import org.bouncycastle.tls.HashAlgorithm; import org.bouncycastle.tls.SignatureAndHashAlgorithm; import org.bouncycastle.tls.TlsFatalAlert; import org.bouncycastle.tls.crypto.TlsSigner; import org.bouncycastle.tls.crypto.TlsStreamSigner; /** * BC light-weight base class for the signers implementing the two DSA style algorithms from FIPS PUB 186-4: DSA and ECDSA. */ public abstract class BcTlsDSSSigner implements TlsSigner { private final AsymmetricKeyParameter privateKey; private final BcTlsCrypto crypto; protected BcTlsDSSSigner(BcTlsCrypto crypto, AsymmetricKeyParameter privateKey) { this.crypto = crypto; if (privateKey == null) { throw new IllegalArgumentException("'privateKey' cannot be null"); } if (!privateKey.isPrivate()) { throw new IllegalArgumentException("'privateKey' must be private"); } this.privateKey = privateKey; } protected abstract DSA createDSAImpl(short hashAlgorithm); protected abstract short getSignatureAlgorithm(); public byte[] generateRawSignature(SignatureAndHashAlgorithm algorithm, byte[] hash) throws IOException { if (algorithm != null && algorithm.getSignature() != getSignatureAlgorithm()) { throw new IllegalStateException(); } short hashAlgorithm = algorithm == null ? HashAlgorithm.sha1 : algorithm.getHash(); Signer s = new DSADigestSigner(createDSAImpl(hashAlgorithm), new NullDigest()); s.init(true, new ParametersWithRandom(privateKey, crypto.getSecureRandom())); Signer signer = s; if (algorithm == null) { // Note: Only use the SHA1 part of the (MD5/SHA1) hash signer.update(hash, 16, 20); } else { signer.update(hash, 0, hash.length); } try { return signer.generateSignature(); } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.internal_error, e); } } public TlsStreamSigner getStreamSigner(SignatureAndHashAlgorithm algorithm) { return null; } }