All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dyadicsec.provider.RSASignature Maven / Gradle / Ivy

Go to download

This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi

There is a newer version: 42761
Show newest version
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;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy