/************************************************************************** * Copyright (c) 2001, 2002, 2003 by Acunia N.V. All rights reserved. * * * * This software is copyrighted by and is the sole property of Acunia N.V. * * and its licensors, if any. All rights, title, ownership, or other * * interests in the software remain the property of Acunia N.V. and its * * licensors, if any. * * * * This software may only be used in accordance with the corresponding * * license agreement. Any unauthorized use, duplication, transmission, * * distribution or disclosure of this software is expressly forbidden. * * * * This Copyright notice may not be removed or modified without prior * * written consent of Acunia N.V. * * * * Acunia N.V. reserves the right to modify this software without notice. * * * * Acunia N.V. * * Philips site 5, box 3 info@acunia.com * * 3001 Leuven http://www.acunia.com * * Belgium - EUROPE * **************************************************************************/ package javax.crypto; import java.security.AlgorithmParameters; import java.security.InvalidKeyException; import java.security.InvalidAlgorithmParameterException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; public class Cipher { static final byte[] EMPTY = new byte[0]; // UNINITIALIZED= 0; public static final int ENCRYPT_MODE = 1; public static final int DECRYPT_MODE = 2; public static final int WRAP_MODE = 3; public static final int UNWRAP_MODE = 4; public static final int PUBLIC_KEY = 1; public static final int PRIVATE_KEY = 2; public static final int SECRET_KEY = 3; public final static Cipher getInstance(String algorithm)throws NoSuchAlgorithmException{ Provider[] p = Security.getProviders(); for (int i=0 ; i < p.length ; i++){ try { return getInstance(algorithm, p[i]); }catch(NoSuchAlgorithmException e){} } throw new NoSuchAlgorithmException("couldn't find "+algorithm); } public final static Cipher getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { int first = algorithm.indexOf('/'); if(first == -1){ SecurityAction action = new SecurityAction(algorithm, provider, "Cipher."); return new Cipher((CipherSpi) action.spi, action.provider, algorithm); } try { SecurityAction action = new SecurityAction(algorithm, provider, "Cipher."); return new Cipher((CipherSpi) action.spi, action.provider, algorithm); }catch(NoSuchAlgorithmException nae){} int last = algorithm.lastIndexOf('/'); String padding = algorithm.substring(last+1); try { SecurityAction action = new SecurityAction(algorithm.substring(0,last), provider, "Cipher."); CipherSpi spi = (CipherSpi)action.spi; spi.engineSetPadding(padding); return new Cipher(spi, action.provider, algorithm); }catch(NoSuchPaddingException nspe){} //TODO -- check if mode is allowed to be empty ... String mode = (first == last ? "" : algorithm.substring(first+1,last)); String base = algorithm.substring(0,first); try { SecurityAction action = new SecurityAction(base+"//"+padding, provider, "Cipher."); CipherSpi spi = (CipherSpi)action.spi; spi.engineSetMode(mode); return new Cipher(spi, action.provider, algorithm); }catch(NoSuchAlgorithmException nae){} SecurityAction action = new SecurityAction(base, provider, "Cipher."); CipherSpi spi = (CipherSpi)action.spi; spi.engineSetMode(mode); try { spi.engineSetPadding(padding); } catch (NoSuchPaddingException e) { throw new NoSuchAlgorithmException(); } return new Cipher(spi, action.provider, algorithm); } public final static Cipher getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { Provider p = Security.getProvider(provider); if (p == null){ throw new NoSuchProviderException("couldn't find "+provider); } return getInstance(algorithm, p); } private Provider provider; private CipherSpi cipherSpi; private String algorithm; private int state; Cipher(CipherSpi cipherSpi, String algorithm){ this.cipherSpi = cipherSpi; this.algorithm = algorithm; } protected Cipher(CipherSpi cipherSpi, Provider provider, String algorithm){ if (cipherSpi == null || provider == null || algorithm == null){ throw new NullPointerException(); } this.cipherSpi = cipherSpi; this.provider = provider; this.algorithm = algorithm; } public final String getAlgorithm(){ return algorithm; } public final Provider getProvider(){ return provider; } public final byte[] doFinal() throws IllegalStateException, IllegalBlockSizeException, BadPaddingException { if((state != DECRYPT_MODE && state != ENCRYPT_MODE)){ throw new IllegalStateException("Cipher is not initialized correctly"); } return cipherSpi.engineDoFinal(EMPTY, 0, 0); } public final int doFinal(byte[] bytes, int offset) throws IllegalStateException, IllegalBlockSizeException, ShortBufferException, BadPaddingException { if((state != DECRYPT_MODE && state != ENCRYPT_MODE)){ throw new IllegalStateException("Cipher is not initialized correctly"); } if((bytes.length - offset - cipherSpi.engineGetOutputSize(0)) < 0){ throw new ShortBufferException(); } return cipherSpi.engineDoFinal(EMPTY, 0, 0, bytes, offset); } public final byte[] doFinal(byte[] in) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException { return doFinal(in, 0, in.length); } public final byte[] doFinal(byte[] in, int offset, int length) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException { if((state != DECRYPT_MODE && state != ENCRYPT_MODE)){ throw new IllegalStateException("Cipher is not initialized correctly"); } return cipherSpi.engineDoFinal(in, offset, length); } public final int doFinal(byte[] in, int offset, int length, byte[] bytes) throws IllegalStateException, ShortBufferException, IllegalBlockSizeException, BadPaddingException { if((bytes.length - cipherSpi.engineGetOutputSize(length)) < 0){ throw new ShortBufferException(); } return cipherSpi.engineDoFinal(in, offset, length, bytes, 0); } public final int doFinal(byte[] in, int offset, int length, byte[] bytes, int offbytes) throws IllegalStateException, ShortBufferException, IllegalBlockSizeException, BadPaddingException { if((bytes.length - offbytes - cipherSpi.engineGetOutputSize(length)) < 0){ throw new ShortBufferException(); } return cipherSpi.engineDoFinal(in, offset, length, bytes, offbytes); } public final int getBlockSize(){ return cipherSpi.engineGetBlockSize(); } public final ExemptionMechanism getExemptionMechanism(){ return null; } public final int getOutputSize(int length) throws IllegalStateException { if((state != DECRYPT_MODE && state != ENCRYPT_MODE)){ throw new IllegalStateException("Cipher is not initialized correctly"); } return cipherSpi.engineGetOutputSize(length); } public final byte[] getIV(){ return cipherSpi.engineGetIV(); } public final AlgorithmParameters getParameters(){ return cipherSpi.engineGetParameters(); } public final void init(int mode, Key key) throws InvalidKeyException { cipherSpi.engineInit(mode, key, new SecureRandom()); state = mode; } public final void init(int mode, Key key, SecureRandom srandom) throws InvalidKeyException { cipherSpi.engineInit(mode, key, srandom); state = mode; } public final void init(int mode, Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { cipherSpi.engineInit(mode, key, params, new SecureRandom()); state = mode; } public final void init(int mode, Key key, AlgorithmParameterSpec params, SecureRandom srandom) throws InvalidKeyException, InvalidAlgorithmParameterException { cipherSpi.engineInit(mode, key, params, srandom); state = mode; } public final void init(int mode, Key key, AlgorithmParameters params) throws InvalidKeyException, InvalidAlgorithmParameterException { cipherSpi.engineInit(mode, key, params, new SecureRandom()); state = mode; } public final void init(int mode, Key key, AlgorithmParameters params, SecureRandom srandom) throws InvalidKeyException, InvalidAlgorithmParameterException { cipherSpi.engineInit(mode, key, params, srandom); state = mode; } public final void init(int mode, java.security.cert.Certificate cert) throws InvalidKeyException { cipherSpi.engineInit(mode, cert.getPublicKey(), new SecureRandom()); state = mode; } public final void init(int mode, java.security.cert.Certificate cert, SecureRandom srandom) throws InvalidKeyException { cipherSpi.engineInit(mode, cert.getPublicKey(), srandom); state = mode; } public final byte[] update(byte[] in) throws IllegalStateException { return update(in, 0, in.length); } public final byte[] update(byte[] in, int offset, int length) throws IllegalStateException { if((state != DECRYPT_MODE && state != ENCRYPT_MODE)){ throw new IllegalStateException("Cipher is not initialized correctly"); } return cipherSpi.engineUpdate(in, offset, length); } public final int update(byte[] in, int offset, int length, byte[] bytes) throws IllegalStateException, ShortBufferException { return update(in, offset, length, bytes, 0); } public final int update(byte[] in, int offset, int length, byte[] bytes, int offbytes) throws IllegalStateException, ShortBufferException { if((state != DECRYPT_MODE && state != ENCRYPT_MODE)){ throw new IllegalStateException("Cipher is not initialized correctly"); } return cipherSpi.engineUpdate(in, offset, length, bytes, offbytes); } public final Key unwrap(byte[] bytes, String keyAlgorithm, int type) throws IllegalStateException, InvalidKeyException, NoSuchAlgorithmException { if(state != UNWRAP_MODE){ throw new IllegalStateException("Cipher is not initialized correctly"); } return cipherSpi.engineUnwrap(bytes, keyAlgorithm, type); } public final byte[] wrap(Key key) throws IllegalStateException, IllegalBlockSizeException, InvalidKeyException { if(state != WRAP_MODE){ throw new IllegalStateException("Cipher is not initialized correctly"); } return cipherSpi.engineWrap(key); } }