com.dyadicsec.provider.ECDSASignature Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unbound-java-provider Show documentation
Show all versions of unbound-java-provider Show documentation
This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi
package com.dyadicsec.provider;
import com.dyadicsec.cryptoki.CK;
import com.dyadicsec.pkcs11.*;
import java.math.BigInteger;
import java.security.SignatureSpi;
import java.security.Signature;
import java.security.SignatureException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.ProviderException;
import java.security.KeyStoreException;
import java.security.InvalidParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Arrays;
/**
* Created by valery.osheter on 19-Apr-16.
*/
public class ECDSASignature extends SignatureSpi
{
private int mechanismType;
protected ECPrivateKey prvKey = null;
protected Signature pubSignature = null;
protected Session session = null;
private final byte[] buffer = new byte[64];
private int bufferOffset = 0;
protected ECDSASignature(int mechanismType)
{
this.mechanismType = mechanismType;
}
static String mechanismTypeToHashName(int mechanismType) throws InvalidAlgorithmParameterException
{
switch (mechanismType)
{
case CK.CKM_ECDSA: return "NONE";
case CK.CKM_ECDSA_SHA1: return "SHA1";
case CK.CKM_ECDSA_SHA256: return "SHA256";
case CK.CKM_ECDSA_SHA384: return "SHA384";
case CK.CKM_ECDSA_SHA512: return "SHA512";
}
throw new InvalidAlgorithmParameterException("Unsupported hash algorithm: " + mechanismType);
}
@Override
protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException
{
if (publicKey instanceof ECPublicKey) publicKey = ((ECPublicKey) publicKey).getSoftwareKey();
else if (publicKey instanceof java.security.interfaces.ECPublicKey);
else throw new InvalidKeyException("Invalid key type");
try { pubSignature = Signature.getInstance(mechanismTypeToHashName(mechanismType)+"withECDSA", "SunEC"); }
catch (Exception e) { throw new InvalidKeyException("engineInitVerify failed"); }
pubSignature.initVerify(publicKey);
}
protected void checkInit()
{
if (session!=null) return;
bufferOffset = 0;
try
{
session = prvKey.pkcs11Key.signInit(new CK_MECHANISM(mechanismType));
}
catch (CKException e) { throw new ProviderException(e); }
}
@Override
protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException
{
if (privateKey instanceof ECPrivateKey) prvKey = (ECPrivateKey) privateKey;
else throw new InvalidKeyException("Invalid key type");
try { prvKey.save(); }
catch (KeyStoreException e) { throw new InvalidKeyException(e); }
closeSession();
checkInit();
}
@Override
protected void engineUpdate(byte b) throws SignatureException
{
if (pubSignature!=null)
{
pubSignature.update(b);
return;
}
byte[] in = {b};
engineUpdate(in, 0, 1);
}
@Override
protected void engineUpdate(byte[] in, int inOffset, int inLen) throws SignatureException
{
if (pubSignature!=null)
{
pubSignature.update(in, inOffset, inLen);
return;
}
checkInit();
if (mechanismType== CK.CKM_ECDSA)
{
if (bufferOffset+inLen >= buffer.length) throw new SignatureException("Invalid input length");
System.arraycopy(in, inOffset, buffer, bufferOffset, inLen);
bufferOffset += inLen;
}
else
{
try { session.signUpdate(in, inOffset, inLen); }
catch (CKException e) { throw new SignatureException(e); }
}
}
private static byte[] encodeSignature(byte[] signature)
{
int n = signature.length/2;
BigInteger r = new BigInteger(1, Arrays.copyOfRange(signature, 0, n));
BigInteger s = new BigInteger(1, Arrays.copyOfRange(signature, n, n*2));
return DER.encode(DER.TAG_SEQUENCE, DER.cat(DER.encode(r), DER.encode(s)));
}
@Override
protected byte[] engineSign() throws SignatureException
{
try
{
int size = prvKey.pkcs11Key.getCurve().getSize() * 2;
byte[] signature ;
if (mechanismType== CK.CKM_ECDSA) signature = session.sign(buffer, 0, bufferOffset, size);
else signature = session.signFinal(size);
return encodeSignature(signature);
}
catch (CKException e) { throw new SignatureException(e); }
finally { closeSession(); }
}
@Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException
{
return pubSignature.verify(sigBytes);
}
@Override
@Deprecated
protected void engineSetParameter(String param, Object value) throws InvalidParameterException
{
throw new UnsupportedOperationException("setParameter() not supported");
}
@Override
@Deprecated
protected Object engineGetParameter(String param) throws InvalidParameterException
{
throw new UnsupportedOperationException("getParameter() not supported");
}
public static final class Raw extends ECDSASignature
{
public Raw() { super(CK.CKM_ECDSA); }
}
public static final class SHA1 extends ECDSASignature
{
public SHA1() { super(CK.CKM_ECDSA_SHA1); }
}
public static final class SHA256 extends ECDSASignature
{
public SHA256() { super(CK.CKM_ECDSA_SHA256); }
}
public static final class SHA384 extends ECDSASignature
{
public SHA384() { super(CK.CKM_ECDSA_SHA384); }
}
public static final class SHA512 extends ECDSASignature
{
public SHA512() { super(CK.CKM_ECDSA_SHA512); }
}
private void closeSession()
{
if (session!=null) session.close();
session = null;
}
}