/luni/src/test/java/libcore/javax/crypto/CipherTest.java
Java | 960 lines | 793 code | 94 blank | 73 comment | 89 complexity | 86435a2e14dc19ea5f5c2d6a41fc29b0 MD5 | raw file
- /*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package libcore.javax.crypto;
- import com.android.org.bouncycastle.asn1.x509.KeyUsage;
- import java.io.ByteArrayOutputStream;
- import java.io.PrintStream;
- import java.math.BigInteger;
- import java.security.InvalidAlgorithmParameterException;
- import java.security.InvalidKeyException;
- import java.security.Key;
- import java.security.KeyFactory;
- import java.security.PrivateKey;
- import java.security.Provider;
- import java.security.PublicKey;
- import java.security.SecureRandom;
- import java.security.Security;
- import java.security.cert.Certificate;
- import java.security.interfaces.RSAPrivateKey;
- import java.security.interfaces.RSAPublicKey;
- import java.security.spec.AlgorithmParameterSpec;
- import java.security.spec.RSAPrivateKeySpec;
- import java.security.spec.RSAPublicKeySpec;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Set;
- import javax.crypto.BadPaddingException;
- import javax.crypto.Cipher;
- import javax.crypto.IllegalBlockSizeException;
- import javax.crypto.KeyGenerator;
- import javax.crypto.SecretKey;
- import javax.crypto.SecretKeyFactory;
- import javax.crypto.ShortBufferException;
- import javax.crypto.spec.IvParameterSpec;
- import javax.crypto.spec.PBEKeySpec;
- import javax.crypto.spec.PBEParameterSpec;
- import javax.crypto.spec.SecretKeySpec;
- import junit.framework.TestCase;
- import libcore.java.security.StandardNames;
- import libcore.java.security.TestKeyStore;
- public final class CipherTest extends TestCase {
- private static final String[] RSA_PROVIDERS = ((StandardNames.IS_RI)
- ? new String[] { "SunJCE" }
- : new String[] { "BC" , "AndroidOpenSSL" });
- private static final String[] AES_PROVIDERS = ((StandardNames.IS_RI)
- ? new String[] { "SunJCE" }
- : new String[] { "BC" }); // TOOD: , "AndroidOpenSSL"
- private static final boolean IS_UNLIMITED;
- static {
- boolean is_unlimited;
- if (StandardNames.IS_RI) {
- try {
- String algorithm = "PBEWITHMD5ANDTRIPLEDES";
- Cipher.getInstance(algorithm).init(getEncryptMode(algorithm),
- getEncryptKey(algorithm),
- getAlgorithmParameterSpec(algorithm));
- is_unlimited = true;
- } catch (Exception e) {
- is_unlimited = false;
- System.out.println("WARNING: Some tests disabled due to lack of "
- + "'Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files'");
- }
- } else {
- is_unlimited = true;
- }
- IS_UNLIMITED = is_unlimited;
- }
- private static boolean isUnsupported(String algorithm) {
- if (algorithm.equals("RC2")) {
- return true;
- }
- if (algorithm.equals("PBEWITHMD5ANDRC2")) {
- return true;
- }
- if (algorithm.startsWith("PBEWITHSHA1ANDRC2")) {
- return true;
- }
- if (algorithm.equals("PBEWITHSHAAND40BITRC2-CBC")) {
- return true;
- }
- if (algorithm.equals("PBEWITHSHAAND128BITRC2-CBC")) {
- return true;
- }
- if (algorithm.equals("PBEWITHSHAANDTWOFISH-CBC")) {
- return true;
- }
- if (!IS_UNLIMITED) {
- if (algorithm.equals("PBEWITHMD5ANDTRIPLEDES")) {
- return true;
- }
- }
- return false;
- }
- private synchronized static int getEncryptMode(String algorithm) throws Exception {
- if (isWrap(algorithm)) {
- return Cipher.WRAP_MODE;
- }
- return Cipher.ENCRYPT_MODE;
- }
- private synchronized static int getDecryptMode(String algorithm) throws Exception {
- if (isWrap(algorithm)) {
- return Cipher.UNWRAP_MODE;
- }
- return Cipher.DECRYPT_MODE;
- }
- private static String getBaseAlgorithm(String algorithm) {
- if (algorithm.equals("AESWRAP")) {
- return "AES";
- }
- if (algorithm.startsWith("AES/")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHMD5AND128BITAES-CBC-OPENSSL")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHMD5AND192BITAES-CBC-OPENSSL")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHMD5AND256BITAES-CBC-OPENSSL")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHSHA256AND128BITAES-CBC-BC")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHSHA256AND192BITAES-CBC-BC")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHSHA256AND256BITAES-CBC-BC")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHSHAAND128BITAES-CBC-BC")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHSHAAND192BITAES-CBC-BC")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHSHAAND256BITAES-CBC-BC")) {
- return "AES";
- }
- if (algorithm.equals("PBEWITHMD5ANDDES")) {
- return "DES";
- }
- if (algorithm.equals("PBEWITHSHA1ANDDES")) {
- return "DES";
- }
- if (algorithm.equals("DESEDEWRAP")) {
- return "DESEDE";
- }
- if (algorithm.equals("PBEWITHSHAAND2-KEYTRIPLEDES-CBC")) {
- return "DESEDE";
- }
- if (algorithm.equals("PBEWITHSHAAND3-KEYTRIPLEDES-CBC")) {
- return "DESEDE";
- }
- if (algorithm.equals("PBEWITHMD5ANDTRIPLEDES")) {
- return "DESEDE";
- }
- if (algorithm.equals("PBEWITHSHA1ANDDESEDE")) {
- return "DESEDE";
- }
- if (algorithm.equals("RSA/ECB/NOPADDING")) {
- return "RSA";
- }
- if (algorithm.equals("RSA/ECB/PKCS1PADDING")) {
- return "RSA";
- }
- if (algorithm.equals("PBEWITHSHAAND40BITRC4")) {
- return "ARC4";
- }
- if (algorithm.equals("PBEWITHSHAAND128BITRC4")) {
- return "ARC4";
- }
- return algorithm;
- }
- private static boolean isAsymmetric(String algorithm) {
- return getBaseAlgorithm(algorithm).equals("RSA");
- }
- private static boolean isWrap(String algorithm) {
- return algorithm.endsWith("WRAP");
- }
- private static boolean isPBE(String algorithm) {
- return algorithm.startsWith("PBE");
- }
- private static Map<String, Key> ENCRYPT_KEYS = new HashMap<String, Key>();
- private synchronized static Key getEncryptKey(String algorithm) throws Exception {
- Key key = ENCRYPT_KEYS.get(algorithm);
- if (key != null) {
- return key;
- }
- if (algorithm.startsWith("RSA")) {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(RSA_2048_modulus,
- RSA_2048_privateExponent);
- key = kf.generatePrivate(keySpec);
- } else if (isPBE(algorithm)) {
- SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
- key = skf.generateSecret(new PBEKeySpec("secret".toCharArray()));
- } else {
- KeyGenerator kg = KeyGenerator.getInstance(getBaseAlgorithm(algorithm));
- if (StandardNames.IS_RI && algorithm.equals("AES")) {
- kg.init(128);
- }
- key = kg.generateKey();
- }
- ENCRYPT_KEYS.put(algorithm, key);
- return key;
- }
- private static Map<String, Key> DECRYPT_KEYS = new HashMap<String, Key>();
- private synchronized static Key getDecryptKey(String algorithm) throws Exception {
- Key key = DECRYPT_KEYS.get(algorithm);
- if (key != null) {
- return key;
- }
- if (algorithm.startsWith("RSA")) {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(RSA_2048_modulus,
- RSA_2048_publicExponent);
- key = kf.generatePublic(keySpec);
- } else {
- assertFalse(algorithm, isAsymmetric(algorithm));
- key = getEncryptKey(algorithm);
- }
- DECRYPT_KEYS.put(algorithm, key);
- return key;
- }
- private static Map<String, Integer> EXPECTED_BLOCK_SIZE = new HashMap<String, Integer>();
- static {
- setExpectedBlockSize("AES", 16);
- setExpectedBlockSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
- setExpectedBlockSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
- setExpectedBlockSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
- setExpectedBlockSize("PBEWITHSHA256AND128BITAES-CBC-BC", 16);
- setExpectedBlockSize("PBEWITHSHA256AND192BITAES-CBC-BC", 16);
- setExpectedBlockSize("PBEWITHSHA256AND256BITAES-CBC-BC", 16);
- setExpectedBlockSize("PBEWITHSHAAND128BITAES-CBC-BC", 16);
- setExpectedBlockSize("PBEWITHSHAAND192BITAES-CBC-BC", 16);
- setExpectedBlockSize("PBEWITHSHAAND256BITAES-CBC-BC", 16);
- if (StandardNames.IS_RI) {
- setExpectedBlockSize("AESWRAP", 16);
- } else {
- setExpectedBlockSize("AESWRAP", 0);
- }
- setExpectedBlockSize("ARC4", 0);
- setExpectedBlockSize("ARCFOUR", 0);
- setExpectedBlockSize("PBEWITHSHAAND40BITRC4", 0);
- setExpectedBlockSize("PBEWITHSHAAND128BITRC4", 0);
- setExpectedBlockSize("BLOWFISH", 8);
- setExpectedBlockSize("DES", 8);
- setExpectedBlockSize("PBEWITHMD5ANDDES", 8);
- setExpectedBlockSize("PBEWITHSHA1ANDDES", 8);
- setExpectedBlockSize("DESEDE", 8);
- setExpectedBlockSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", 8);
- setExpectedBlockSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", 8);
- setExpectedBlockSize("PBEWITHMD5ANDTRIPLEDES", 8);
- setExpectedBlockSize("PBEWITHSHA1ANDDESEDE", 8);
- if (StandardNames.IS_RI) {
- setExpectedBlockSize("DESEDEWRAP", 8);
- } else {
- setExpectedBlockSize("DESEDEWRAP", 0);
- }
- if (StandardNames.IS_RI) {
- setExpectedBlockSize("RSA", 0);
- setExpectedBlockSize("RSA/ECB/NoPadding", 0);
- setExpectedBlockSize("RSA/ECB/PKCS1Padding", 0);
- } else {
- setExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, 256);
- setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, 256);
- setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.ENCRYPT_MODE, 245);
- // BC strips the leading 0 for us even when NoPadding is specified
- setExpectedBlockSize("RSA", Cipher.ENCRYPT_MODE, "BC", 255);
- setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, "BC", 255);
- setExpectedBlockSize("RSA", Cipher.DECRYPT_MODE, 256);
- setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
- setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 256);
- }
- }
- private static String modeKey(String algorithm, int mode) {
- return algorithm + ":" + mode;
- }
- private static String modeProviderKey(String algorithm, int mode, String provider) {
- return algorithm + ":" + mode + ":" + provider;
- }
- private static void setExpectedSize(Map<String, Integer> map,
- String algorithm, int value) {
- algorithm = algorithm.toUpperCase(Locale.US);
- map.put(algorithm, value);
- }
- private static void setExpectedSize(Map<String, Integer> map,
- String algorithm, int mode, int value) {
- setExpectedSize(map, modeKey(algorithm, mode), value);
- }
- private static void setExpectedSize(Map<String, Integer> map,
- String algorithm, int mode, String provider, int value) {
- setExpectedSize(map, modeProviderKey(algorithm, mode, provider), value);
- }
- private static int getExpectedSize(Map<String, Integer> map, String algorithm, int mode, String provider) {
- Integer expected = map.get(modeProviderKey(algorithm, mode, provider));
- if (expected != null) {
- return expected;
- }
- expected = map.get(modeKey(algorithm, mode));
- if (expected != null) {
- return expected;
- }
- expected = map.get(algorithm);
- assertNotNull("Algorithm " + algorithm + " not found in " + map, expected);
- return expected;
- }
- private static void setExpectedBlockSize(String algorithm, int value) {
- setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, value);
- }
- private static void setExpectedBlockSize(String algorithm, int mode, int value) {
- setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, value);
- }
- private static void setExpectedBlockSize(String algorithm, int mode, String provider, int value) {
- setExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, provider, value);
- }
- private static int getExpectedBlockSize(String algorithm, int mode, String provider) {
- return getExpectedSize(EXPECTED_BLOCK_SIZE, algorithm, mode, provider);
- }
- private static Map<String, Integer> EXPECTED_OUTPUT_SIZE = new HashMap<String, Integer>();
- static {
- setExpectedOutputSize("AES", Cipher.ENCRYPT_MODE, 16);
- setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", 16);
- setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", 16);
- setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", 16);
- setExpectedOutputSize("PBEWITHSHA256AND128BITAES-CBC-BC", 16);
- setExpectedOutputSize("PBEWITHSHA256AND192BITAES-CBC-BC", 16);
- setExpectedOutputSize("PBEWITHSHA256AND256BITAES-CBC-BC", 16);
- setExpectedOutputSize("PBEWITHSHAAND128BITAES-CBC-BC", 16);
- setExpectedOutputSize("PBEWITHSHAAND192BITAES-CBC-BC", 16);
- setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", 16);
- setExpectedOutputSize("AES", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHMD5AND128BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHMD5AND192BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHMD5AND256BITAES-CBC-OPENSSL", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHA256AND128BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHA256AND192BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHA256AND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHAAND128BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHAAND192BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
- if (StandardNames.IS_RI) {
- setExpectedOutputSize("AESWRAP", Cipher.WRAP_MODE, 8);
- setExpectedOutputSize("AESWRAP", Cipher.UNWRAP_MODE, 0);
- } else {
- setExpectedOutputSize("AESWRAP", -1);
- }
- setExpectedOutputSize("ARC4", 0);
- setExpectedOutputSize("ARCFOUR", 0);
- setExpectedOutputSize("PBEWITHSHAAND40BITRC4", 0);
- setExpectedOutputSize("PBEWITHSHAAND128BITRC4", 0);
- setExpectedOutputSize("BLOWFISH", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("BLOWFISH", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("DES", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("DES", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("DESEDE", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("PBEWITHSHA1ANDDESEDE", Cipher.ENCRYPT_MODE, 8);
- setExpectedOutputSize("DESEDE", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.DECRYPT_MODE, 0);
- setExpectedOutputSize("PBEWITHSHA1ANDDESEDE", Cipher.DECRYPT_MODE, 0);
- if (StandardNames.IS_RI) {
- setExpectedOutputSize("DESEDEWRAP", Cipher.WRAP_MODE, 16);
- setExpectedOutputSize("DESEDEWRAP", Cipher.UNWRAP_MODE, 0);
- } else {
- setExpectedOutputSize("DESEDEWRAP", -1);
- }
- setExpectedOutputSize("RSA", Cipher.ENCRYPT_MODE, 256);
- setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.ENCRYPT_MODE, 256);
- setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.ENCRYPT_MODE, 256);
- setExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, 256);
- setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
- setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 245);
- // BC strips the leading 0 for us even when NoPadding is specified
- setExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, "BC", 255);
- setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, "BC", 255);
- }
- private static void setExpectedOutputSize(String algorithm, int value) {
- setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, value);
- }
- private static void setExpectedOutputSize(String algorithm, int mode, int value) {
- setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, value);
- }
- private static void setExpectedOutputSize(String algorithm, int mode, String provider, int value) {
- setExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, provider, value);
- }
- private static int getExpectedOutputSize(String algorithm, int mode, String provider) {
- return getExpectedSize(EXPECTED_OUTPUT_SIZE, algorithm, mode, provider);
- }
- private static byte[] ORIGINAL_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c };
- private static byte[] PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT = new byte[] {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0x0b, 0x0c
- };
- private static byte[] PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT = new byte[] {
- (byte) 0x00, (byte) 0x01, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c
- };
- private static byte[] PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT = new byte[] {
- (byte) 0x00, (byte) 0x02, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c
- };
- private static byte[] getExpectedPlainText(String algorithm) {
- if (algorithm.equals("RSA/ECB/NOPADDING")) {
- return PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT;
- }
- return ORIGINAL_PLAIN_TEXT;
- }
- private static AlgorithmParameterSpec getAlgorithmParameterSpec(String algorithm) {
- if (!isPBE(algorithm)) {
- return null;
- }
- final byte[] salt = new byte[8];
- new SecureRandom().nextBytes(salt);
- return new PBEParameterSpec(salt, 1024);
- }
- public void test_getInstance() throws Exception {
- final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
- PrintStream out = new PrintStream(errBuffer);
- Set<String> seenBaseCipherNames = new HashSet<String>();
- Set<String> seenCiphersWithModeAndPadding = new HashSet<String>();
- Provider[] providers = Security.getProviders();
- for (Provider provider : providers) {
- Set<Provider.Service> services = provider.getServices();
- for (Provider.Service service : services) {
- String type = service.getType();
- if (!type.equals("Cipher")) {
- continue;
- }
- String algorithm = service.getAlgorithm();
- /*
- * Any specific modes and paddings aren't tested directly here,
- * but we need to make sure we see the bare algorithm from some
- * provider. We will test each mode specifically when we get the
- * base cipher.
- */
- final int firstSlash = algorithm.indexOf('/');
- if (firstSlash == -1) {
- seenBaseCipherNames.add(algorithm);
- } else {
- final String baseCipherName = algorithm.substring(0, firstSlash);
- if (!seenBaseCipherNames.contains(baseCipherName)) {
- seenCiphersWithModeAndPadding.add(baseCipherName);
- }
- continue;
- }
- try {
- test_Cipher_Algorithm(provider, algorithm);
- } catch (Throwable e) {
- out.append("Error encountered checking " + algorithm
- + " with provider " + provider.getName() + "\n");
- e.printStackTrace(out);
- }
- Set<String> modes = StandardNames.getModesForCipher(algorithm);
- if (modes != null) {
- for (String mode : modes) {
- Set<String> paddings = StandardNames.getPaddingsForCipher(algorithm);
- if (paddings != null) {
- for (String padding : paddings) {
- final String algorithmName = algorithm + "/" + mode + "/" + padding;
- try {
- test_Cipher_Algorithm(provider, algorithmName);
- } catch (Throwable e) {
- out.append("Error encountered checking " + algorithmName
- + " with provider " + provider.getName() + "\n");
- e.printStackTrace(out);
- }
- }
- }
- }
- }
- }
- }
- seenCiphersWithModeAndPadding.removeAll(seenBaseCipherNames);
- assertEquals("Ciphers seen with mode and padding but not base cipher",
- Collections.EMPTY_SET, seenCiphersWithModeAndPadding);
- out.flush();
- if (errBuffer.size() > 0) {
- throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
- }
- }
- private void test_Cipher_Algorithm(Provider provider, String algorithm) throws Exception {
- // Cipher.getInstance(String)
- Cipher c1 = Cipher.getInstance(algorithm);
- assertEquals(algorithm, c1.getAlgorithm());
- test_Cipher(c1);
- // Cipher.getInstance(String, Provider)
- Cipher c2 = Cipher.getInstance(algorithm, provider);
- assertEquals(algorithm, c2.getAlgorithm());
- assertEquals(provider, c2.getProvider());
- test_Cipher(c2);
- // KeyGenerator.getInstance(String, String)
- Cipher c3 = Cipher.getInstance(algorithm, provider.getName());
- assertEquals(algorithm, c3.getAlgorithm());
- assertEquals(provider, c3.getProvider());
- test_Cipher(c3);
- }
- private void test_Cipher(Cipher c) throws Exception {
- String algorithm = c.getAlgorithm().toUpperCase(Locale.US);
- if (isUnsupported(algorithm)) {
- return;
- }
- String providerName = c.getProvider().getName();
- String cipherID = algorithm + ":" + providerName;
- try {
- c.getOutputSize(0);
- } catch (IllegalStateException expected) {
- }
- // TODO: test keys from different factories (e.g. OpenSSLRSAPrivateKey vs JCERSAPrivateKey)
- Key encryptKey = getEncryptKey(algorithm);
- final AlgorithmParameterSpec spec = getAlgorithmParameterSpec(algorithm);
- int encryptMode = getEncryptMode(algorithm);
- c.init(encryptMode, encryptKey, spec);
- assertEquals(cipherID, getExpectedBlockSize(algorithm, encryptMode, providerName), c.getBlockSize());
- assertEquals(cipherID, getExpectedOutputSize(algorithm, encryptMode, providerName), c.getOutputSize(0));
- int decryptMode = getDecryptMode(algorithm);
- c.init(decryptMode, encryptKey, spec);
- assertEquals(cipherID, getExpectedBlockSize(algorithm, decryptMode, providerName), c.getBlockSize());
- assertEquals(cipherID, getExpectedOutputSize(algorithm, decryptMode, providerName), c.getOutputSize(0));
- // TODO: test Cipher.getIV()
- // TODO: test Cipher.getParameters()
- assertNull(cipherID, c.getExemptionMechanism());
- c.init(getEncryptMode(algorithm), encryptKey, spec);
- if (isWrap(algorithm)) {
- byte[] cipherText = c.wrap(encryptKey);
- c.init(getDecryptMode(algorithm), getDecryptKey(algorithm), spec);
- int keyType = (isAsymmetric(algorithm)) ? Cipher.PRIVATE_KEY : Cipher.SECRET_KEY;
- Key decryptedKey = c.unwrap(cipherText, encryptKey.getAlgorithm(), keyType);
- assertEquals("encryptKey.getAlgorithm()=" + encryptKey.getAlgorithm()
- + " decryptedKey.getAlgorithm()=" + decryptedKey.getAlgorithm()
- + " encryptKey.getEncoded()=" + Arrays.toString(encryptKey.getEncoded())
- + " decryptedKey.getEncoded()=" + Arrays.toString(decryptedKey.getEncoded()),
- encryptKey, decryptedKey);
- } else {
- byte[] cipherText = c.doFinal(ORIGINAL_PLAIN_TEXT);
- c.init(getDecryptMode(algorithm), getDecryptKey(algorithm), spec);
- byte[] decryptedPlainText = c.doFinal(cipherText);
- assertEquals(cipherID,
- Arrays.toString(getExpectedPlainText(algorithm)),
- Arrays.toString(decryptedPlainText));
- }
- }
- public void testInputPKCS1Padding() throws Exception {
- for (String provider : RSA_PROVIDERS) {
- testInputPKCS1Padding(provider);
- }
- }
- private void testInputPKCS1Padding(String provider) throws Exception {
- testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
- try {
- testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getEncryptKey("RSA"), getDecryptKey("RSA"));
- fail();
- } catch (BadPaddingException expected) {
- }
- try {
- testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_01_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
- fail();
- } catch (BadPaddingException expected) {
- }
- testInputPKCS1Padding(provider, PKCS1_BLOCK_TYPE_02_PADDED_PLAIN_TEXT, getDecryptKey("RSA"), getEncryptKey("RSA"));
- }
- private void testInputPKCS1Padding(String provider, byte[] prePaddedPlainText, Key encryptKey, Key decryptKey) throws Exception {
- Cipher encryptCipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
- encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey);
- byte[] cipherText = encryptCipher.doFinal(prePaddedPlainText);
- Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
- decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
- byte[] plainText = decryptCipher.doFinal(cipherText);
- assertEquals(Arrays.toString(ORIGINAL_PLAIN_TEXT),
- Arrays.toString(plainText));
- }
- public void testOutputPKCS1Padding() throws Exception {
- for (String provider : RSA_PROVIDERS) {
- testOutputPKCS1Padding(provider);
- }
- }
- private void testOutputPKCS1Padding(String provider) throws Exception {
- testOutputPKCS1Padding(provider, (byte) 1, getEncryptKey("RSA"), getDecryptKey("RSA"));
- testOutputPKCS1Padding(provider, (byte) 2, getDecryptKey("RSA"), getEncryptKey("RSA"));
- }
- private void testOutputPKCS1Padding(String provider, byte expectedBlockType, Key encryptKey, Key decryptKey) throws Exception {
- Cipher encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
- encryptCipher.init(Cipher.ENCRYPT_MODE, encryptKey);
- byte[] cipherText = encryptCipher.doFinal(ORIGINAL_PLAIN_TEXT);
- Cipher decryptCipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
- decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey);
- byte[] plainText = decryptCipher.doFinal(cipherText);
- assertPadding(provider, expectedBlockType, ORIGINAL_PLAIN_TEXT, plainText);
- }
- private void assertPadding(String provider, byte expectedBlockType, byte[] expectedData, byte[] actualDataWithPadding) {
- assertNotNull(provider, actualDataWithPadding);
- int expectedOutputSize = getExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, provider);
- assertEquals(provider, expectedOutputSize, actualDataWithPadding.length);
- int expectedBlockTypeOffset;
- if (provider.equals("BC")) {
- // BC strips the leading 0 for us on decrypt even when NoPadding is specified...
- expectedBlockTypeOffset = 0;
- } else {
- expectedBlockTypeOffset = 1;
- assertEquals(provider, 0, actualDataWithPadding[0]);
- }
- byte actualBlockType = actualDataWithPadding[expectedBlockTypeOffset];
- assertEquals(provider, expectedBlockType, actualBlockType);
- int actualDataOffset = actualDataWithPadding.length - expectedData.length;
- if (actualBlockType == 1) {
- int expectedDataOffset = expectedBlockTypeOffset + 1;
- for (int i = expectedDataOffset; i < actualDataOffset - 1; i++) {
- assertEquals(provider, (byte) 0xFF, actualDataWithPadding[i]);
- }
- }
- assertEquals(provider, 0x00, actualDataWithPadding[actualDataOffset-1]);
- byte[] actualData = new byte[expectedData.length];
- System.arraycopy(actualDataWithPadding, actualDataOffset, actualData, 0, actualData.length);
- assertEquals(provider, Arrays.toString(expectedData), Arrays.toString(actualData));
- }
- public void testCipherInitWithCertificate () throws Exception {
- // no key usage specified, everything is fine
- assertCipherInitWithKeyUsage(0, true, true, true, true);
- // common case is that encrypt/wrap is prohibited when special usage is specified
- assertCipherInitWithKeyUsage(KeyUsage.digitalSignature, false, true, false, true);
- assertCipherInitWithKeyUsage(KeyUsage.nonRepudiation, false, true, false, true);
- assertCipherInitWithKeyUsage(KeyUsage.keyAgreement, false, true, false, true);
- assertCipherInitWithKeyUsage(KeyUsage.keyCertSign, false, true, false, true);
- assertCipherInitWithKeyUsage(KeyUsage.cRLSign, false, true, false, true);
- // Note they encipherOnly/decipherOnly don't have to do with
- // ENCRYPT_MODE or DECRYPT_MODE, but restrict usage relative
- // to keyAgreement. There is not a *_MODE option that
- // corresponds to this in Cipher, the RI does not enforce
- // anything in Cipher.
- // http://code.google.com/p/android/issues/detail?id=12955
- assertCipherInitWithKeyUsage(KeyUsage.encipherOnly, false, true, false, true);
- assertCipherInitWithKeyUsage(KeyUsage.decipherOnly, false, true, false, true);
- assertCipherInitWithKeyUsage(KeyUsage.keyAgreement | KeyUsage.encipherOnly,
- false, true, false, true);
- assertCipherInitWithKeyUsage(KeyUsage.keyAgreement | KeyUsage.decipherOnly,
- false, true, false, true);
- // except when wrapping a key is specifically allowed or
- assertCipherInitWithKeyUsage(KeyUsage.keyEncipherment, false, true, true, true);
- // except when wrapping data encryption is specifically allowed
- assertCipherInitWithKeyUsage(KeyUsage.dataEncipherment, true, true, false, true);
- }
- private void assertCipherInitWithKeyUsage (int keyUsage,
- boolean allowEncrypt,
- boolean allowDecrypt,
- boolean allowWrap,
- boolean allowUnwrap) throws Exception {
- Certificate certificate = certificateWithKeyUsage(keyUsage);
- assertCipherInitWithKeyUsage(certificate, allowEncrypt, Cipher.ENCRYPT_MODE);
- assertCipherInitWithKeyUsage(certificate, allowDecrypt, Cipher.DECRYPT_MODE);
- assertCipherInitWithKeyUsage(certificate, allowWrap, Cipher.WRAP_MODE);
- assertCipherInitWithKeyUsage(certificate, allowUnwrap, Cipher.UNWRAP_MODE);
- }
- private void assertCipherInitWithKeyUsage(Certificate certificate,
- boolean allowMode,
- int mode) throws Exception {
- Cipher cipher = Cipher.getInstance("RSA");
- if (allowMode) {
- cipher.init(mode, certificate);
- } else {
- try {
- cipher.init(mode, certificate);
- String modeString;
- switch (mode) {
- case Cipher.ENCRYPT_MODE:
- modeString = "ENCRYPT_MODE";
- break;
- case Cipher.DECRYPT_MODE:
- modeString = "DECRYPT_MODE";
- break;
- case Cipher.WRAP_MODE:
- modeString = "WRAP_MODE";
- break;
- case Cipher.UNWRAP_MODE:
- modeString = "UNWRAP_MODE";
- break;
- default:
- throw new AssertionError("Unknown Cipher.*_MODE " + mode);
- }
- fail("Should have had InvalidKeyException for " + modeString
- + " for " + certificate);
- } catch (InvalidKeyException expected) {
- }
- }
- }
- private Certificate certificateWithKeyUsage(int keyUsage) throws Exception {
- // note the rare usage of non-zero keyUsage
- return new TestKeyStore.Builder()
- .aliasPrefix("rsa-dsa-ec")
- .keyUsage(keyUsage)
- .build()
- .getPrivateKey("RSA", "RSA").getCertificate();
- }
- /*
- * Test vectors generated with this private key:
- *
- * -----BEGIN RSA PRIVATE KEY-----
- * MIIEpAIBAAKCAQEA4Ec+irjyKE/rnnQv+XSPoRjtmGM8kvUq63ouvg075gMpvnZq
- * 0Q62pRXQ0s/ZvqeTDwwwZTeJn3lYzT6FsB+IGFJNMSWEqUslHjYltUFB7b/uGYgI
- * 4buX/Hy0m56qr2jpyY19DtxTu8D6ADQ1bWMF+7zDxwAUBThqu8hzyw8+90JfPTPf
- * ezFa4DbSoLZq/UdQOxab8247UWJRW3Ff2oPeryxYrrmr+zCXw8yd2dvl7ylsF2E5
- * Ao6KZx5jBW1F9AGI0sQTNJCEXeUsJTTpxrJHjAe9rpKII7YtBmx3cPn2Pz26JH9T
- * CER0e+eqqF2FO4vSRKzsPePImrRkU6tNJMOsaQIDAQABAoIBADd4R3al8XaY9ayW
- * DfuDobZ1ZOZIvQWXz4q4CHGG8macJ6nsvdSA8Bl6gNBzCebGqW+SUzHlf4tKxvTU
- * XtpFojJpwJ/EKMB6Tm7fc4oV3sl/q9Lyu0ehTyDqcvz+TDbgGtp3vRN82NTaELsW
- * LpSkZilx8XX5hfoYjwVsuX7igW9Dq503R2Ekhs2owWGWwwgYqZXshdOEZ3kSZ7O/
- * IfJzcQppJYYldoQcW2cSwS1L0govMpmtt8E12l6VFavadufK8qO+gFUdBzt4vxFi
- * xIrSt/R0OgI47k0lL31efmUzzK5kzLOTYAdaL9HgNOw65c6cQIzL8OJeQRQCFoez
- * 3UdUroECgYEA9UGIS8Nzeyki1BGe9F4t7izUy7dfRVBaFXqlAJ+Zxzot8HJKxGAk
- * MGMy6omBd2NFRl3G3x4KbxQK/ztzluaomUrF2qloc0cv43dJ0U6z4HXmKdvrNYMz
- * im82SdCiZUp6Qv2atr+krE1IHTkLsimwZL3DEcwb4bYxidp8QM3s8rECgYEA6hp0
- * LduIHO23KIyH442GjdekCdFaQ/RF1Td6C1cx3b/KLa8oqOE81cCvzsM0fXSjniNa
- * PNljPydN4rlPkt9DgzkR2enxz1jyfeLgj/RZZMcg0+whOdx8r8kSlTzeyy81Wi4s
- * NaUPrXVMs7IxZkJLo7bjESoriYw4xcFe2yOGkzkCgYBRgo8exv2ZYCmQG68dfjN7
- * pfCvJ+mE6tiVrOYr199O5FoiQInyzBUa880XP84EdLywTzhqLNzA4ANrokGfVFeS
- * YtRxAL6TGYSj76Bb7PFBV03AebOpXEqD5sQ/MhTW3zLVEt4ZgIXlMeYWuD/X3Z0f
- * TiYHwzM9B8VdEH0dOJNYcQKBgQDbT7UPUN6O21P/NMgJMYigUShn2izKBIl3WeWH
- * wkQBDa+GZNWegIPRbBZHiTAfZ6nweAYNg0oq29NnV1toqKhCwrAqibPzH8zsiiL+
- * OVeVxcbHQitOXXSh6ajzDndZufwtY5wfFWc+hOk6XvFQb0MVODw41Fy9GxQEj0ch
- * 3IIyYQKBgQDYEUWTr0FfthLb8ZI3ENVNB0hiBadqO0MZSWjA3/HxHvD2GkozfV/T
- * dBu8lkDkR7i2tsR8OsEgQ1fTsMVbqShr2nP2KSlvX6kUbYl2NX08dR51FIaWpAt0
- * aFyCzjCQLWOdck/yTV4ulAfuNO3tLjtN9lqpvP623yjQe6aQPxZXaA==
- * -----END RSA PRIVATE KEY-----
- *
- */
- private static final BigInteger RSA_2048_modulus = new BigInteger(new byte[] {
- (byte) 0x00, (byte) 0xe0, (byte) 0x47, (byte) 0x3e, (byte) 0x8a, (byte) 0xb8, (byte) 0xf2, (byte) 0x28,
- (byte) 0x4f, (byte) 0xeb, (byte) 0x9e, (byte) 0x74, (byte) 0x2f, (byte) 0xf9, (byte) 0x74, (byte) 0x8f,
- (byte) 0xa1, (byte) 0x18, (byte) 0xed, (byte) 0x98, (byte) 0x63, (byte) 0x3c, (byte) 0x92, (byte) 0xf5,
- (byte) 0x2a, (byte) 0xeb, (byte) 0x7a, (byte) 0x2e, (byte) 0xbe, (byte) 0x0d, (byte) 0x3b, (byte) 0xe6,
- (byte) 0x03, (byte) 0x29, (byte) 0xbe, (byte) 0x76, (byte) 0x6a, (byte) 0xd1, (byte) 0x0e, (byte) 0xb6,
- (byte) 0xa5, (byte) 0x15, (byte) 0xd0, (byte) 0xd2, (byte) 0xcf, (byte) 0xd9, (byte) 0xbe, (byte) 0xa7,
- (byte) 0x93, (byte) 0x0f, (byte) 0x0c, (byte) 0x30, (byte) 0x65, (byte) 0x37, (byte) 0x89, (byte) 0x9f,
- (byte) 0x79, (byte) 0x58, (byte) 0xcd, (byte) 0x3e, (byte) 0x85, (byte) 0xb0, (byte) 0x1f, (byte) 0x88,
- (byte) 0x18, (byte) 0x52, (byte) 0x4d, (byte) 0x31, (byte) 0x25, (byte) 0x84, (byte) 0xa9, (byte) 0x4b,
- (byte) 0x25, (byte) 0x1e, (byte) 0x36, (byte) 0x25, (byte) 0xb5, (byte) 0x41, (byte) 0x41, (byte) 0xed,
- (byte) 0xbf, (byte) 0xee, (byte) 0x19, (byte) 0x88, (byte) 0x08, (byte) 0xe1, (byte) 0xbb, (byte) 0x97,
- (byte) 0xfc, (byte) 0x7c, (byte) 0xb4, (byte) 0x9b, (byte) 0x9e, (byte) 0xaa, (byte) 0xaf, (byte) 0x68,
- (byte) 0xe9, (byte) 0xc9, (byte) 0x8d, (byte) 0x7d, (byte) 0x0e, (byte) 0xdc, (byte) 0x53, (byte) 0xbb,
- (byte) 0xc0, (byte) 0xfa, (byte) 0x00, (byte) 0x34, (byte) 0x35, (byte) 0x6d, (byte) 0x63, (byte) 0x05,
- (byte) 0xfb, (byte) 0xbc, (byte) 0xc3, (byte) 0xc7, (byte) 0x00, (byte) 0x14, (byte) 0x05, (byte) 0x38,
- (byte) 0x6a, (byte) 0xbb, (byte) 0xc8, (byte) 0x73, (byte) 0xcb, (byte) 0x0f, (byte) 0x3e, (byte) 0xf7,
- (byte) 0x42, (byte) 0x5f, (byte) 0x3d, (byte) 0x33, (byte) 0xdf, (byte) 0x7b, (byte) 0x31, (byte) 0x5a,
- (byte) 0xe0, (byte) 0x36, (byte) 0xd2, (byte) 0xa0, (byte) 0xb6, (byte) 0x6a, (byte) 0xfd, (byte) 0x47,
- (byte) 0x50, (byte) 0x3b, (byte) 0x16, (byte) 0x9b, (byte) 0xf3, (byte) 0x6e, (byte) 0x3b, (byte) 0x51,
- (byte) 0x62, (byte) 0x51, (byte) 0x5b, (byte) 0x71, (byte) 0x5f, (byte) 0xda, (byte) 0x83, (byte) 0xde,
- (byte) 0xaf, (byte) 0x2c, (byte) 0x58, (byte) 0xae, (byte) 0xb9, (byte) 0xab, (byte) 0xfb, (byte) 0x30,
- (byte) 0x97, (byte) 0xc3, (byte) 0xcc, (byte) 0x9d, (byte) 0xd9, (byte) 0xdb, (byte) 0xe5, (byte) 0xef,
- (byte) 0x29, (byte) 0x6c, (byte) 0x17, (byte) 0x61, (byte) 0x39, (byte) 0x02, (byte) 0x8e, (byte) 0x8a,
- (byte) 0x67, (byte) 0x1e, (byte) 0x63, (byte) 0x05, (byte) 0x6d, (byte) 0x45, (byte) 0xf4, (byte) 0x01,
- (byte) 0x88, (byte) 0xd2, (byte) 0xc4, (byte) 0x13, (byte) 0x34, (byte) 0x90, (byte) 0x84, (byte) 0x5d,
- (byte) 0xe5, (byte) 0x2c, (byte) 0x25, (byte) 0x34, (byte) 0xe9, (byte) 0xc6, (byte) 0xb2, (byte) 0x47,
- (byte) 0x8c, (byte) 0x07, (byte) 0xbd, (byte) 0xae, (byte) 0x92, (byte) 0x88, (byte) 0x23, (byte) 0xb6,
- (byte) 0x2d, (byte) 0x06, (byte) 0x6c, (byte) 0x77, (byte) 0x70, (byte) 0xf9, (byte) 0xf6, (byte) 0x3f,
- (byte) 0x3d, (byte) 0xba, (byte) 0x24, (byte) 0x7f, (byte) 0x53, (byte) 0x08, (byte) 0x44, (byte) 0x74,
- (byte) 0x7b, (byte) 0xe7, (byte) 0xaa, (byte) 0xa8, (byte) 0x5d, (byte) 0x85, (byte) 0x3b, (byte) 0x8b,
- (byte) 0xd2, (byte) 0x44, (byte) 0xac, (byte) 0xec, (byte) 0x3d, (byte) 0xe3, (byte) 0xc8, (byte) 0x9a,
- (byte) 0xb4, (byte) 0x64, (byte) 0x53, (byte) 0xab, (byte) 0x4d, (byte) 0x24, (byte) 0xc3, (byte) 0xac,
- (byte) 0x69,
- });
- private static final BigInteger RSA_2048_privateExponent = new BigInteger(new byte[] {
- (byte) 0x37, (byte) 0x78, (byte) 0x47, (byte) 0x76, (byte) 0xa5, (byte) 0xf1, (byte) 0x76, (byte) 0x98,
- (byte) 0xf5, (byte) 0xac, (byte) 0x96, (byte) 0x0d, (byte) 0xfb, (byte) 0x83, (byte) 0xa1, (byte) 0xb6,
- (byte) 0x75, (byte) 0x64, (byte) 0xe6, (byte) 0x48, (byte) 0xbd, (byte) 0x05, (byte) 0x97, (byte) 0xcf,
- (byte) 0x8a, (byte) 0xb8, (byte) 0x08, (byte) 0x71, (byte) 0x86, (byte) 0xf2, (byte) 0x66, (byte) 0x9c,
- (byte) 0x27, (byte) 0xa9, (byte) 0xec, (byte) 0xbd, (byte) 0xd4, (byte) 0