diff options
Diffstat (limited to 'libjava/classpath/gnu/javax/crypto/RSACipherImpl.java')
-rw-r--r-- | libjava/classpath/gnu/javax/crypto/RSACipherImpl.java | 299 |
1 files changed, 0 insertions, 299 deletions
diff --git a/libjava/classpath/gnu/javax/crypto/RSACipherImpl.java b/libjava/classpath/gnu/javax/crypto/RSACipherImpl.java deleted file mode 100644 index a4adff0..0000000 --- a/libjava/classpath/gnu/javax/crypto/RSACipherImpl.java +++ /dev/null @@ -1,299 +0,0 @@ -/* RSACipherImpl.java -- - Copyright (C) 2005, 2006 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.javax.crypto; - -import gnu.classpath.debug.Component; -import gnu.classpath.debug.SystemLogger; -import gnu.java.security.sig.rsa.EME_PKCS1_V1_5; -import gnu.java.security.util.ByteArray; - -import java.math.BigInteger; -import java.security.AlgorithmParameters; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.interfaces.RSAKey; -import java.security.interfaces.RSAPrivateCrtKey; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.AlgorithmParameterSpec; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.CipherSpi; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.ShortBufferException; - -public class RSACipherImpl - extends CipherSpi -{ - private static final SystemLogger logger = SystemLogger.SYSTEM; - - private static final byte[] EMPTY = new byte[0]; - private int opmode = -1; - private RSAPrivateKey decipherKey = null; - private RSAPublicKey blindingKey = null; - private RSAPublicKey encipherKey = null; - private SecureRandom random = null; - private byte[] dataBuffer = null; - private int pos = 0; - - protected void engineSetMode(String mode) throws NoSuchAlgorithmException - { - throw new NoSuchAlgorithmException("only one mode available"); - } - - protected void engineSetPadding(String pad) throws NoSuchPaddingException - { - throw new NoSuchPaddingException("only one padding available"); - } - - protected int engineGetBlockSize() - { - return 1; - } - - protected int engineGetOutputSize(int inputLen) - { - int outputLen = 0; - if (decipherKey != null) - outputLen = (decipherKey.getModulus().bitLength() + 7) / 8; - else if (encipherKey != null) - outputLen = (encipherKey.getModulus().bitLength() + 7) / 8; - else - throw new IllegalStateException("not initialized"); - if (inputLen > outputLen) - throw new IllegalArgumentException("not configured to encode " + inputLen - + "bytes; at most " + outputLen); - return outputLen; - } - - protected int engineGetKeySize(final Key key) throws InvalidKeyException - { - if (! (key instanceof RSAKey)) - throw new InvalidKeyException("not an RSA key"); - return ((RSAKey) key).getModulus().bitLength(); - } - - protected byte[] engineGetIV() - { - return null; - } - - protected AlgorithmParameters engineGetParameters() - { - return null; - } - - protected void engineInit(int opmode, Key key, SecureRandom random) - throws InvalidKeyException - { - int outputLen = 0; - if (opmode == Cipher.ENCRYPT_MODE) - { - if (! (key instanceof RSAPublicKey)) - throw new InvalidKeyException("expecting a RSAPublicKey"); - encipherKey = (RSAPublicKey) key; - decipherKey = null; - blindingKey = null; - outputLen = (encipherKey.getModulus().bitLength() + 7) / 8; - } - else if (opmode == Cipher.DECRYPT_MODE) - { - if (key instanceof RSAPrivateKey) - { - decipherKey = (RSAPrivateKey) key; - encipherKey = null; - blindingKey = null; - outputLen = (decipherKey.getModulus().bitLength() + 7) / 8; - } - else if (key instanceof RSAPublicKey) - { - if (decipherKey == null) - throw new IllegalStateException("must configure decryption key first"); - if (! decipherKey.getModulus().equals(((RSAPublicKey) key).getModulus())) - throw new InvalidKeyException("blinding key is not compatible"); - blindingKey = (RSAPublicKey) key; - return; - } - else - throw new InvalidKeyException( - "expecting either an RSAPrivateKey or an RSAPublicKey (for blinding)"); - } - else - throw new IllegalArgumentException("only encryption and decryption supported"); - this.random = random; - this.opmode = opmode; - pos = 0; - dataBuffer = new byte[outputLen]; - } - - protected void engineInit(int opmode, Key key, AlgorithmParameterSpec spec, - SecureRandom random) throws InvalidKeyException - { - engineInit(opmode, key, random); - } - - protected void engineInit(int opmode, Key key, AlgorithmParameters params, - SecureRandom random) throws InvalidKeyException - { - engineInit(opmode, key, random); - } - - protected byte[] engineUpdate(byte[] in, int offset, int length) - { - if (opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE) - throw new IllegalStateException("not initialized"); - System.arraycopy(in, offset, dataBuffer, pos, length); - pos += length; - return EMPTY; - } - - protected int engineUpdate(byte[] in, int offset, int length, byte[] out, - int outOffset) - { - engineUpdate(in, offset, length); - return 0; - } - - protected byte[] engineDoFinal(byte[] in, int offset, int length) - throws IllegalBlockSizeException, BadPaddingException - { - engineUpdate(in, offset, length); - if (opmode == Cipher.DECRYPT_MODE) - { - BigInteger enc = new BigInteger (1, dataBuffer); - byte[] dec = rsaDecrypt (enc); - logger.log (Component.CRYPTO, "RSA: decryption produced\n{0}", - new ByteArray (dec)); - EME_PKCS1_V1_5 pkcs = EME_PKCS1_V1_5.getInstance(decipherKey); - byte[] result = pkcs.decode(dec); - return result; - } - else - { - offset = dataBuffer.length - pos; - if (offset < 3) - throw new IllegalBlockSizeException("input is too large to encrypt"); - EME_PKCS1_V1_5 pkcs = EME_PKCS1_V1_5.getInstance(encipherKey); - if (random == null) - random = new SecureRandom(); - byte[] em = new byte[pos]; - System.arraycopy(dataBuffer, 0, em, 0, pos); - byte[] dec = pkcs.encode(em, random); - logger.log (Component.CRYPTO, "RSA: produced padded plaintext\n{0}", - new ByteArray (dec)); - BigInteger x = new BigInteger (1, dec); - BigInteger y = x.modPow (encipherKey.getPublicExponent (), - encipherKey.getModulus ()); - byte[] enc = y.toByteArray (); - if (enc[0] == 0x00) - { - byte[] tmp = new byte[enc.length - 1]; - System.arraycopy(enc, 1, tmp, 0, tmp.length); - enc = tmp; - } - pos = 0; - return enc; - } - } - - protected int engineDoFinal(byte[] out, int offset) - throws ShortBufferException, IllegalBlockSizeException, - BadPaddingException - { - byte[] result = engineDoFinal(EMPTY, 0, 0); - if (out.length - offset < result.length) - throw new ShortBufferException("need " + result.length + ", have " - + (out.length - offset)); - System.arraycopy(result, 0, out, offset, result.length); - return result.length; - } - - protected int engineDoFinal(final byte[] input, final int offset, - final int length, final byte[] output, - final int outputOffset) - throws ShortBufferException, IllegalBlockSizeException, - BadPaddingException - { - byte[] result = engineDoFinal(input, offset, length); - if (output.length - outputOffset < result.length) - throw new ShortBufferException("need " + result.length + ", have " - + (output.length - outputOffset)); - System.arraycopy(result, 0, output, outputOffset, result.length); - return result.length; - } - - /** - * Decrypts the ciphertext, employing RSA blinding if possible. - */ - private byte[] rsaDecrypt(BigInteger enc) - { - if (random == null) - random = new SecureRandom(); - BigInteger n = decipherKey.getModulus(); - BigInteger r = null; - BigInteger pubExp = null; - if (blindingKey != null) - pubExp = blindingKey.getPublicExponent(); - if (pubExp != null && (decipherKey instanceof RSAPrivateCrtKey)) - pubExp = ((RSAPrivateCrtKey) decipherKey).getPublicExponent(); - if (pubExp != null) - { - r = new BigInteger(n.bitLength() - 1, random); - enc = r.modPow(pubExp, n).multiply(enc).mod(n); - } - BigInteger dec = enc.modPow(decipherKey.getPrivateExponent(), n); - if (pubExp != null) - { - dec = dec.multiply (r.modInverse (n)).mod (n); - } - - byte[] decb = dec.toByteArray(); - if (decb[0] != 0x00) - { - byte[] b = new byte[decb.length + 1]; - System.arraycopy(decb, 0, b, 1, decb.length); - decb = b; - } - return decb; - } -} |