package com.trilead.ssh2.signature; import com.trilead.ssh2.crypto.CertificateDecoder; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.util.List; /** * @author Michael Clarke */ public abstract class KeyAlgorithm<U extends PublicKey, R extends PrivateKey> { private final String signatureAlgorithm; private final String keyFormat; private final Class<R> keyType; private final Provider provider; protected KeyAlgorithm(String signatureAlgorithm, String keyFormat, Class<R> keyType) { this(signatureAlgorithm, keyFormat, keyType, null); } protected KeyAlgorithm(String signatureAlgorithm, String keyFormat, Class<R> keyType, Provider provider) { super(); this.signatureAlgorithm = signatureAlgorithm; this.keyFormat = keyFormat; this.keyType = keyType; this.provider = provider; } public byte[] generateSignature(byte[] message, R pk, SecureRandom rnd) throws IOException { try { Signature signature = (null == provider ? Signature.getInstance(signatureAlgorithm) : Signature.getInstance(signatureAlgorithm, provider)); signature.initSign(pk, rnd); signature.update(message); return signature.sign(); } catch (GeneralSecurityException ex) { throw new IOException("Could not generate signature", ex); } } public boolean verifySignature(byte[] message, byte[] ds, U dpk) throws IOException { try { Signature signature = (null == provider ? Signature.getInstance(signatureAlgorithm) : Signature.getInstance(signatureAlgorithm, provider)); signature.initVerify(dpk); signature.update(message); return signature.verify(ds); } catch (GeneralSecurityException ex) { throw new IOException("Could not verify signature", ex); } } public String getKeyFormat() { return keyFormat; } public abstract byte[] encodeSignature(byte[] signature) throws IOException; public abstract byte[] decodeSignature(byte[] encodedSignature) throws IOException; public abstract byte[] encodePublicKey(U publicKey) throws IOException; public abstract U decodePublicKey(byte[] encodedPublicKey) throws IOException; public abstract List<CertificateDecoder> getCertificateDecoders(); public boolean supportsKey(PrivateKey key) { return keyType.isAssignableFrom(key.getClass()); } }