/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* RSA cipher implementation using the Microsoft Crypto API.
* Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
*
* Objects should be instantiated by calling Cipher.getInstance() using the
* following algorithm name:
*
* . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 padding. The mode (blocktype)
* is selected based on the en/decryption mode and public/private key used.
*
* We only do one RSA operation per doFinal() call. If the application passes
* more data via calls to update() or doFinal(), we throw an
* IllegalBlockSizeException when doFinal() is called (see JCE API spec).
* Bulk encryption using RSA does not make sense and is not standardized.
*
* Note: RSA keys should be at least 512 bits long
*
* @since 1.6
* @author Andreas Sterbenz
* @author Vincent Ryan
*/
// constant for an empty byte array
// mode constant for public key encryption
// mode constant for private key decryption
// mode constant for private key encryption (signing)
// mode constant for public key decryption (verifying)
// constant for PKCS#1 v1.5 RSA
// current mode, one of MODE_* above. Set when init() is called
private int mode;
// active padding type, one of PAD_* above. Set by setPadding()
// buffer for the data
private byte[] buffer;
// offset into the buffer (number of bytes buffered)
private int bufOfs;
// size of the output (the length of the key).
private int outputSize;
// the public key, if we were initialized using a public key
// the private key, if we were initialized using a private key
public RSACipher() {
}
// modes do not make sense for RSA, but allow ECB
// see JCE spec
}
}
// set the padding type
// see JCE spec
throws NoSuchPaddingException {
} else {
throw new NoSuchPaddingException
}
}
// return 0 as block size, we are not a block cipher
// see JCE spec
protected int engineGetBlockSize() {
return 0;
}
// return the output size
// see JCE spec
return outputSize;
}
// no iv, return null
// see JCE spec
protected byte[] engineGetIV() {
return null;
}
// no parameters, return null
// see JCE spec
return null;
}
// see JCE spec
throws InvalidKeyException {
}
// see JCE spec
throw new InvalidAlgorithmParameterException
("Parameters not supported");
}
}
// see JCE spec
throw new InvalidAlgorithmParameterException
("Parameters not supported");
}
}
// initialize this cipher
boolean encrypt;
switch (opmode) {
case Cipher.ENCRYPT_MODE:
encrypt = true;
break;
case Cipher.DECRYPT_MODE:
case Cipher.UNWRAP_MODE:
encrypt = false;
break;
default:
}
// Convert key to MSCAPI format
// Check against the local and global values to make sure
// the sizes are ok. Round up to the nearest byte.
// Adjust key length due to sign bit
try {
} catch (KeyStoreException e) {
throw new InvalidKeyException(e);
}
} else {
}
}
privateKey = null;
} else if (key instanceof PrivateKey) {
} else {
}
bufOfs = 0;
buffer = new byte[outputSize];
}
// internal update method
return;
}
return;
}
}
// internal doFinal() method. Here we perform the actual RSA operation
throw new IllegalBlockSizeException("Data must not be longer "
}
try {
switch (mode) {
case MODE_SIGN:
privateKey.getHCryptKey(), true);
case MODE_VERIFY:
publicKey.getHCryptKey(), false);
case MODE_ENCRYPT:
publicKey.getHCryptKey(), true);
case MODE_DECRYPT:
privateKey.getHCryptKey(), false);
default:
throw new AssertionError("Internal error");
}
} catch (KeyException e) {
throw new ProviderException(e);
} finally {
bufOfs = 0;
}
}
// see JCE spec
return B0;
}
// see JCE spec
int outOfs) {
return 0;
}
// see JCE spec
throws BadPaddingException, IllegalBlockSizeException {
return doFinal();
}
// see JCE spec
throw new ShortBufferException
}
return n;
}
// see JCE spec
throw new InvalidKeyException("Could not obtain encoded key");
}
throw new InvalidKeyException("Key is too long for wrapping");
}
try {
return doFinal();
} catch (BadPaddingException e) {
// should not occur
throw new InvalidKeyException("Wrapping failed", e);
}
}
// see JCE spec
throw new InvalidKeyException("Key is too long for unwrapping");
}
try {
switch (type) {
case Cipher.PUBLIC_KEY:
case Cipher.PRIVATE_KEY:
case Cipher.SECRET_KEY:
default:
}
} catch (BadPaddingException e) {
// should not occur
throw new InvalidKeyException("Unwrapping failed", e);
} catch (IllegalBlockSizeException e) {
// should not occur, handled with length check above
throw new InvalidKeyException("Unwrapping failed", e);
}
}
// see JCE spec
} else {
}
}
// Construct an X.509 encoded public key.
throws InvalidKeyException, NoSuchAlgorithmException {
try {
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchAlgorithmException("No installed provider " +
} catch (InvalidKeySpecException ike) {
}
}
// Construct a PKCS #8 encoded private key.
throws InvalidKeyException, NoSuchAlgorithmException {
try {
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchAlgorithmException("No installed provider " +
} catch (InvalidKeySpecException ike) {
}
}
// Construct an encoded secret key.
}
/*
* It expects and returns ciphertext data in big-endian form.
*/
}