com.dyadicsec.provider.RSASignature 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.pkcs11.*;
import static com.dyadicsec.cryptoki.CK.*;
import java.io.ByteArrayOutputStream;
import java.lang.Object;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
/**
* Created by valery.osheter on 19-Apr-16.
*/
@SuppressWarnings("deprecation")
public class RSASignature extends SignatureSpi
{
private int mechanismType;
private RSAPrivateKey prvKey = null;
private Signature pubSignature = null;
private Session session = null;
private ByteArrayOutputStream buffer = null;
private PSSParameterSpec pss = null;
private int pssSalt = 20;
private int pssHash = CKM_SHA_1;
private int pssMgf = CKG_MGF1_SHA1;
static String getSunProvider(int mechanismType) throws InvalidAlgorithmParameterException
{
switch (mechanismType)
{
case CKM_RSA_PKCS: return "SunJCE";
case CKM_SHA1_RSA_PKCS: return "SunRsaSign";
case CKM_SHA256_RSA_PKCS: return "SunRsaSign";
case CKM_SHA384_RSA_PKCS: return "SunRsaSign";
case CKM_SHA512_RSA_PKCS: return "SunRsaSign";
case CKM_RSA_PKCS_PSS: return "SunRsaSign";
}
throw new InvalidAlgorithmParameterException("Unsupported hash algorithm: " + mechanismType);
}
static String mechanismTypeToHashName(int mechanismType) throws InvalidAlgorithmParameterException
{
switch (mechanismType)
{
case CKM_RSA_PKCS: return "NONE";
case CKM_SHA1_RSA_PKCS: return "SHA1";
case CKM_SHA256_RSA_PKCS: return "SHA256";
case CKM_SHA384_RSA_PKCS: return "SHA384";
case CKM_SHA512_RSA_PKCS: return "SHA512";
}
throw new InvalidAlgorithmParameterException("Unsupported hash algorithm: " + mechanismType);
}
private static int hashNameToType(String hashName) throws InvalidAlgorithmParameterException
{
hashName = hashName.toUpperCase();
if (hashName.equals("SHA1")) return CKM_SHA_1;
if (hashName.equals("SHA-1")) return CKM_SHA_1;
if (hashName.equals("SHA-256")) return CKM_SHA256;
if (hashName.equals("SHA-384")) return CKM_SHA384;
if (hashName.equals("SHA-512")) return CKM_SHA512;
throw new InvalidAlgorithmParameterException("OAEP hash algorithm not supported: " + hashName);
}
private static int hashTypeToPssMechType(int hashType)
{
switch (hashType)
{
case CKM_SHA_1: return CKM_SHA1_RSA_PKCS_PSS;
case CKM_SHA256: return CKM_SHA256_RSA_PKCS_PSS;
case CKM_SHA384: return CKM_SHA384_RSA_PKCS_PSS;
case CKM_SHA512: return CKM_SHA512_RSA_PKCS_PSS;
}
return 0; // should not be
}
private static int hashTypeToMgfType(int hashType) throws InvalidAlgorithmParameterException
{
switch (hashType)
{
case CKM_SHA_1: return CKG_MGF1_SHA1;
case CKM_SHA256: return CKG_MGF1_SHA256;
case CKM_SHA384: return CKG_MGF1_SHA384;
case CKM_SHA512: return CKG_MGF1_SHA512;
}
throw new InvalidAlgorithmParameterException("OAEP MGF hash algorithm not supported: " + hashType);
}
RSASignature(int mechanismType)
{
this.mechanismType = mechanismType;
}
@Override
protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException
{
if (publicKey instanceof RSAPublicKey) publicKey = ((RSAPublicKey) publicKey).getSoftwareKey();
else if (publicKey instanceof java.security.interfaces.RSAPublicKey) ;
else throw new InvalidKeyException("Invalid key type");
try
{
String name;
if (mechanismType==CKM_RSA_PKCS_PSS) name = "RSASSA-PSS";
else name = mechanismTypeToHashName(mechanismType) + "WithRSA";
String sunProviderName = getSunProvider(mechanismType);
Provider sunProvider = Security.getProvider(sunProviderName);
pubSignature = Signature.getInstance(name, sunProviderName);
if (mechanismType==CKM_RSA_PKCS_PSS)
{
if (pss==null) pss = new PSSParameterSpec("SHA-1", "MGF1", null, 20, 1);
pubSignature.setParameter(pss);
}
}
catch (Throwable e) { throw new InvalidKeyException("engineInitVerify failed"); }
pubSignature.initVerify(publicKey);
}
private void checkInit()
{
if (session != null) return;
try
{
CK_MECHANISM mech;
if (mechanismType==CKM_RSA_PKCS_PSS)
{
int pssMechType = hashTypeToPssMechType(pssHash);
CK_RSA_PKCS_PSS_PARAMS pssParams = new CK_RSA_PKCS_PSS_PARAMS(pssMechType, pssHash, pssMgf, pssSalt);
mech = pssParams;
}
else mech = new CK_MECHANISM(mechanismType);
session = prvKey.pkcs11Key.signInit(mech);
}
catch (CKException e) { throw new ProviderException(e); }
if (mechanismType == CKM_RSA_PKCS)
{
if (buffer == null) buffer = new ByteArrayOutputStream();
buffer.reset();
}
}
@Override
protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException
{
if (privateKey instanceof RSAPrivateKey) prvKey = (RSAPrivateKey) 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 == CKM_RSA_PKCS) buffer.write(in, inOffset, inLen);
else
{
try { session.signUpdate(in, inOffset, inLen); }
catch (CKException e) { throw new SignatureException(e); }
}
}
@Override
protected byte[] engineSign() throws SignatureException
{
checkInit();
try
{
int size = prvKey.pkcs11Key.getBitSize();
byte[] result;
if (mechanismType == CKM_RSA_PKCS) result = session.sign(buffer.toByteArray(), size);
else result = session.signFinal(size);
return result;
}
catch (CKException e) { throw new SignatureException(e); }
finally { closeSession(); }
}
@Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException
{
return pubSignature.verify(sigBytes);
}
@Override
protected void engineSetParameter(String param, Object value) throws InvalidParameterException
{
throw new UnsupportedOperationException("setParameter() not supported");
}
@Override
protected void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException
{
if (params == null) return;
if (!(params instanceof PSSParameterSpec)) throw new InvalidAlgorithmParameterException("parameters must be type PSSParameterSpec");
if (mechanismType!=CKM_RSA_PKCS_PSS) throw new InvalidAlgorithmParameterException("No parameters accepted");
PSSParameterSpec pss = (PSSParameterSpec)params;
if (!(pss.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) throw new InvalidAlgorithmParameterException("Only supports MGF1");
if (pss.getTrailerField() != 1) throw new InvalidAlgorithmParameterException("Only supports TrailerFieldBC(1)");
pssSalt = pss.getSaltLength();
pssHash = hashNameToType(pss.getDigestAlgorithm());
int hash = pssHash;
AlgorithmParameterSpec mgfParams = pss.getMGFParameters();
if (mgfParams!=null) hash = hashNameToType(((MGF1ParameterSpec)mgfParams).getDigestAlgorithm());
pssMgf = hashTypeToMgfType(hash);
this.pss = pss;
}
@Override
protected Object engineGetParameter(String param) throws InvalidParameterException
{
throw new UnsupportedOperationException("getParameter() not supported");
}
@Override
protected AlgorithmParameters engineGetParameters()
{
if (pss == null) throw new ProviderException("Missing required PSS parameters");
try
{
AlgorithmParameters ap = AlgorithmParameters.getInstance("RSASSA-PSS");
ap.init(pss);
return ap;
}
catch (GeneralSecurityException e) { throw new ProviderException(e); }
}
public static final class NONEwithRSA extends RSASignature { public NONEwithRSA() { super(CKM_RSA_PKCS ); } }
public static final class SHA1withRSA extends RSASignature { public SHA1withRSA() { super(CKM_SHA1_RSA_PKCS ); } }
public static final class SHA256withRSA extends RSASignature { public SHA256withRSA() { super(CKM_SHA256_RSA_PKCS); } }
public static final class SHA384withRSA extends RSASignature { public SHA384withRSA() { super(CKM_SHA384_RSA_PKCS); } }
public static final class SHA512withRSA extends RSASignature { public SHA512withRSA() { super(CKM_SHA512_RSA_PKCS); } }
public static final class PSS extends RSASignature { public PSS() { super(CKM_RSA_PKCS_PSS ); } }
private void closeSession()
{
if (session != null) session.close();
session = null;
}
}