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