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

com.unbound.provider.UBRSACipher 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.unbound.provider;

import com.dyadicsec.provider.KeyGenSpec;
import com.unbound.client.*;

import javax.crypto.*;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;


public final class UBRSACipher extends CipherSpi
{
  private final CipherOper oper = Client.getInstance().newCipherOperation();
  private OAEPParameterSpec oaepSpec = null;
  private KeyParameters unwrapKeyParameter = null;

  public UBRSACipher()
  {
    oper.mode = CipherMode.RSA_PKCS1;
    oper.bufferMode = true;
  }

  private static String paddingTypeToName(CipherMode mode, HashType oaepHashType)
  {
    if (mode==CipherMode.RSA_RAW) return "NOPadding";
    if (mode==CipherMode.RSA_PKCS1) return "PKCS1Padding";
    return "OAEPWith" + oaepHashType.getMdName() + "AndMGF1Padding";
  }

  private static HashType oaepPaddingToHashType(String padding) throws NoSuchPaddingException
  {
    padding = padding.toUpperCase();
    if (padding.equals("OAEPPADDING")) return HashType.SHA1; // SHA1
    if (padding.startsWith("OAEPWITH") && padding.endsWith("ANDMGF1PADDING"))
    {
        String hashName = padding.substring(8, padding.length() - 14);
        try { return HashType.getFromName(hashName); }
        catch (InvalidAlgorithmParameterException e) { throw new NoSuchPaddingException("padding not supported: " + padding); }
    }
    throw new NoSuchPaddingException("padding not supported: " + padding);
  }

  private AlgorithmParameterSpec getParameterSpec() throws InvalidAlgorithmParameterException
  {
    if (oaepSpec == null)
    {
      if (oper.mode != CipherMode.RSA_OAEP) return null;
      oaepSpec = new OAEPParameterSpec(oper.hashType.getMdName(), "MGF1", oper.mgfHashType.getMgfSpec(), PSource.PSpecified.DEFAULT);
    }
    return oaepSpec;
  }

  private void init(int opmode, Key key, AlgorithmParameterSpec paramSpec, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException
  {
    oper.reset();
    PublicKey pub = null;

    switch (opmode)
    {
      case Cipher.ENCRYPT_MODE:
      case Cipher.WRAP_MODE:
        if (key instanceof UBRSAPublicKey)
        {
          if (opmode == Cipher.WRAP_MODE) oper.keyObject = (KeyObject) ((UBRSAPublicKey) key).object;
          else pub = ((UBRSAPublicKey) key).getPublicKey();
        }
        else if (key instanceof RSAPublicKey) pub = (RSAPublicKey) key;
        else throw new InvalidKeyException("Invalid key type");
        oper.encMode = true;
        break;

      case Cipher.DECRYPT_MODE:
      case Cipher.UNWRAP_MODE:
        if (key instanceof UBRSAPrivateKey) oper.keyObject = (KeyObject)((UBRSAPrivateKey) key).object;
        else throw new InvalidKeyException("Invalid key type");
        oper.encMode = false;
        break;

      default:
        throw new InvalidKeyException("Unknown mode: " + opmode);
    }

    if (paramSpec != null)
    {
      if (oper.mode!=CipherMode.RSA_OAEP) throw new InvalidAlgorithmParameterException("Wrong padding parameter");
      oper.mode.setParams(oper, paramSpec);
    }

    if (pub!=null)
    {
      try { oper.swCipher = Cipher.getInstance("RSA/ECB/" + paddingTypeToName(oper.mode, oper.hashType), "SunJCE"); }
      catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException e) { throw new ProviderException(e); }
      oper.swCipher.init(opmode, pub, getParameterSpec(), secureRandom);
    }
  }

  // ------------------------- interface --------------------------
  @Override
  protected void engineSetMode(String mode) throws NoSuchAlgorithmException
  {
    mode = mode.toUpperCase();
    if (!mode.equals("NONE") && !mode.equals("ECB")) throw new NoSuchAlgorithmException("Mode not supported: " + mode);
  }

  @Override
  protected void engineSetPadding(String padding) throws NoSuchPaddingException
  {
    padding = padding.toUpperCase();
    if (padding.equals("NOPADDING"))  oper.mode = CipherMode.RSA_RAW;
    else if (padding.equals("PKCS1PADDING")) oper.mode = CipherMode.RSA_PKCS1;
    else if (padding.equals("OAEPPADDING")) oper.mode = CipherMode.RSA_OAEP;
    else if (padding.startsWith("OAEPWITH") && padding.endsWith("ANDMGF1PADDING")) oper.mode = CipherMode.RSA_OAEP;
    else throw new NoSuchPaddingException("Unsupported padding: " + padding);

    if (oper.mode == CipherMode.RSA_OAEP)
    {
      oper.hashType = oaepPaddingToHashType(padding);
      oper.mgfHashType = HashType.SHA1;
    }
  }

  @Override
  protected int engineGetBlockSize()
  {
    return 0;
  }

  @Override
  protected int engineGetOutputSize(int inputLen) { return ((RSAPrivateKeyObject)oper.keyObject).getModulus().bitLength()/8; }

  @Override
  protected byte[] engineGetIV() { return null; }

  @Override
  protected AlgorithmParameters engineGetParameters()
  {
    try
    {
      AlgorithmParameterSpec spec = getParameterSpec();
      if (spec==null) return null;
      AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP");
      params.init(spec);
      return params;
    }
    catch (Throwable e) { throw new RuntimeException("Invalid algorithm parameters not supported");  }
  }

  @Override
  protected void engineInit(int opmode, Key key, SecureRandom secureRandom) throws InvalidKeyException
  {
    try { init(opmode, key, null, secureRandom); }
    catch (InvalidAlgorithmParameterException e) { throw new InvalidKeyException("Wrong parameters", e); }
  }

  @Override
  protected void engineInit(int opmode, Key key, AlgorithmParameterSpec algorithmParameterSpec, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException
  {
    if (algorithmParameterSpec instanceof KeyGenSpec)
    {
      if (opmode!=Cipher.UNWRAP_MODE) throw new InvalidAlgorithmParameterException("KeyParameter is supported only in UNWRAP_MODE");
      unwrapKeyParameter = ((KeyGenSpec)algorithmParameterSpec).getKeyParams();
      algorithmParameterSpec = ((KeyGenSpec)algorithmParameterSpec).getOriginal();
    }
    else unwrapKeyParameter = null;

    init(opmode, key, algorithmParameterSpec, secureRandom);
  }

  @Override
  protected void engineInit(int opmode, Key key, AlgorithmParameters algorithmParameters, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException
  {
    OAEPParameterSpec spec = null;

    if (algorithmParameters != null)
    {
      try { spec = algorithmParameters.getParameterSpec(OAEPParameterSpec.class); }
      catch (InvalidParameterSpecException e) { throw new InvalidKeyException("Wrong parameters", e); }
    }

    init(opmode, key, spec, secureRandom);
  }

  @Override
  protected byte[] engineUpdate(byte[] in, int inOffset, int inLen)
  {
    return oper.update(in, inOffset, inLen);
  }

  @Override
  protected int engineUpdate(byte[] in, int inOffset, int inLen, byte[] out, int outOffset) throws ShortBufferException
  {
    return oper.update(in, inOffset, inLen, out, outOffset);
  }

  @Override
  protected byte[] engineDoFinal(byte[] in, int inOffset, int inLen) throws IllegalBlockSizeException, BadPaddingException
  {
    return oper.finalEncDec(in, inOffset, inLen);
  }

  @Override
  protected int engineDoFinal(byte[] in, int inOffset, int inLen, byte[] out, int outOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException
  {
    return oper.finalEncDec(in, inOffset, inLen, out, outOffset);
  }

  @Override
  protected byte[] engineWrap(Key key) throws InvalidKeyException,  IllegalBlockSizeException
  {
    if (key instanceof UBSecretKey) return oper.wrap(((UBSecretKey)key).object);
    return oper.swWrap(key);
  }

  @Override
  protected Key engineUnwrap(byte[] wrappedKey, String algorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException
  {
    if (wrappedKeyType != Cipher.SECRET_KEY) throw new UnsupportedOperationException("wrappedKeyType == " + wrappedKeyType);

    if (unwrapKeyParameter==null || !unwrapKeyParameter.isToken()) return oper.swUnwrap(wrappedKey, algorithm, wrappedKeyType);

    SecretKeyObject keyObject = (SecretKeyObject)oper.unwrap(wrappedKey, null, ObjectType.get(algorithm), unwrapKeyParameter);
    return new UBSecretKey(keyObject);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy