aboutsummaryrefslogtreecommitdiff
path: root/keystore-cts/java/com/google/security/wycheproof/testcases/RsaEncryptionTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'keystore-cts/java/com/google/security/wycheproof/testcases/RsaEncryptionTest.java')
-rw-r--r--keystore-cts/java/com/google/security/wycheproof/testcases/RsaEncryptionTest.java225
1 files changed, 0 insertions, 225 deletions
diff --git a/keystore-cts/java/com/google/security/wycheproof/testcases/RsaEncryptionTest.java b/keystore-cts/java/com/google/security/wycheproof/testcases/RsaEncryptionTest.java
deleted file mode 100644
index 5f82420..0000000
--- a/keystore-cts/java/com/google/security/wycheproof/testcases/RsaEncryptionTest.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/**
- * 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 com.google.security.wycheproof;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.crypto.Cipher;
-import javax.crypto.NoSuchPaddingException;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * RSA encryption tests
- *
- * @author bleichen@google.com (Daniel Bleichenbacher)
- */
-@RunWith(JUnit4.class)
-public class RsaEncryptionTest {
-
- /**
- * Providers that implement RSA with PKCS1Padding but not OAEP are outdated and should be avoided
- * even if RSA is currently not used in a project. Such providers promote using an insecure
- * cipher. There is a great danger that PKCS1Padding is used as a temporary workaround, but later
- * stays in the project for much longer than necessary.
- */
- @Test
- public void testOutdatedProvider() throws Exception {
- try {
- Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- try {
- Cipher.getInstance("RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING");
- } catch (NoSuchPaddingException | NoSuchAlgorithmException ex) {
- fail("Provider " + c.getProvider().getName() + " is outdated and should not be used.");
- }
- } catch (NoSuchPaddingException | NoSuchAlgorithmException ex) {
- System.out.println("RSA/ECB/PKCS1Padding is not implemented");
- }
- }
-
- /**
- * Get a PublicKey from a JsonObject.
- *
- * <p>object contains the key in multiple formats: "key" : elements of the public key "keyDer":
- * the key in ASN encoding encoded hexadecimal "keyPem": the key in Pem format encoded hexadecimal
- * The test can use the format that is most convenient.
- */
- // This is a false positive, since errorprone cannot track values passed into a method.
- @SuppressWarnings("InsecureCryptoUsage")
- protected static PrivateKey getPrivateKey(JsonObject object) throws Exception {
- KeyFactory kf;
- kf = KeyFactory.getInstance("RSA");
- byte[] encoded = TestUtil.hexToBytes(object.get("privateKeyPkcs8").getAsString());
- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
- return kf.generatePrivate(keySpec);
- }
-
- /** Convenience method to get a byte array from a JsonObject */
- protected static byte[] getBytes(JsonObject object, String name) throws Exception {
- return JsonUtil.asByteArray(object.get(name));
- }
-
- /**
- * Tries decrypting RSA-PKCS #1 v 1.5 encrypted ciphertext.
- * RSA-PKCS #1 v 1.5 is susceptible to chosen ciphertext attacks. The seriousness of the
- * attack depends on how much information is leaked when decrypting an invalid ciphertext.
- * The test vectors with invalid padding contain a flag "InvalidPkcs1Padding".
- * The test below expects that all test vectors with this flag throw an indistinguishable
- * exception.
- *
- * <p><b>References:</b>
- *
- * <ul>
- * <li>Bleichenbacher, "Chosen ciphertext attacks against protocols based on the RSA encryption
- * standard PKCS# 1" Crypto 98
- * <li>Manger, "A chosen ciphertext attack on RSA optimal asymmetric encryption padding (OAEP)
- * as standardized in PKCS# 1 v2.0", Crypto 2001 This paper shows that OAEP is susceptible
- * to a chosen ciphertext attack if error messages distinguish between different failure
- * condidtions.
- * <li>Bardou, Focardi, Kawamoto, Simionato, Steel, Tsay "Efficient Padding Oracle Attacks on
- * Cryptographic Hardware", Crypto 2012 The paper shows that small differences on what
- * information an attacker receives can make a big difference on the number of chosen
- * message necessary for an attack.
- * <li>Smart, "Errors matter: Breaking RSA-based PIN encryption with thirty ciphertext validity
- * queries" RSA conference, 2010 This paper shows that padding oracle attacks can be
- * successful with even a small number of queries.
- * </ul>
- *
- * <p><b>Some recent bugs:</b> CVE-2012-5081: Java JSSE provider leaked information through
- * exceptions and timing. Both the PKCS #1 padding and the OAEP padding were broken:
- * http://www-brs.ub.ruhr-uni-bochum.de/netahtml/HSS/Diss/MeyerChristopher/diss.pdf
- *
- * <p><b>What this test does not (yet) cover:</b>
- *
- * <ul>
- * <li>A previous version of one of the provider leaked the block type. (when was this fixed?)
- * <li>Some attacks require a large number of ciphertexts to be detected if random ciphertexts
- * are used. Such problems require specifically crafted ciphertexts to run in a unit test.
- * E.g. "Attacking RSA-based Sessions in SSL/TLS" by V. Klima, O. Pokorny, and T. Rosa:
- * https://eprint.iacr.org/2003/052/
- * <li>Timing leakages because of differences in parsing the padding (e.g. CVE-2015-7827) Such
- * differences are too small to be reliably detectable in unit tests.
- * </ul>
- */
- @SuppressWarnings("InsecureCryptoUsage")
- public void testDecryption(String filename) throws Exception {
- final String expectedSchema = "rsaes_pkcs1_decrypt_schema.json";
- JsonObject test = JsonUtil.getTestVectors(filename);
- String schema = test.get("schema").getAsString();
- if (!schema.equals(expectedSchema)) {
- System.out.println(
- "Expecting test vectors with schema "
- + expectedSchema
- + " found vectors with schema "
- + schema);
- }
- // Padding oracle attacks become simpler when the decryption leaks detailed information about
- // invalid paddings. Hence implementations are expected to not include such information in the
- // exception thrown in the case of an invalid padding.
- // Test vectors with an invalid padding have a flag "InvalidPkcs1Padding".
- // Invalid test vectors without this flag are cases where the error are detected before
- // the ciphertext is decrypted, e.g. if the size of the ciphertext is incorrect.
- final String invalidPkcs1Padding = "InvalidPkcs1Padding";
- Set<String> exceptions = new TreeSet<String>();
-
- int errors = 0;
- Cipher decrypter = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- for (JsonElement g : test.getAsJsonArray("testGroups")) {
- JsonObject group = g.getAsJsonObject();
- PrivateKey key = getPrivateKey(group);
- for (JsonElement t : group.getAsJsonArray("tests")) {
- JsonObject testcase = t.getAsJsonObject();
- int tcid = testcase.get("tcId").getAsInt();
- String messageHex = TestUtil.bytesToHex(getBytes(testcase, "msg"));
- byte[] ciphertext = getBytes(testcase, "ct");
- String ciphertextHex = TestUtil.bytesToHex(ciphertext);
- String result = testcase.get("result").getAsString();
- decrypter.init(Cipher.DECRYPT_MODE, key);
- byte[] decrypted = null;
- String exception = "";
- try {
- decrypted = decrypter.doFinal(ciphertext);
- } catch (Exception ex) {
- // TODO(bleichen): The exception thrown should always be
- // a GeneralSecurityException.
- // However, BouncyCastle throws some non-conforming exceptions.
- // For the moment we do not count this as a problem to avoid that
- // more serious bugs remain hidden. In particular, the test expects
- // that all ciphertexts with an invalid padding throw the same
- // indistinguishable exception.
- decrypted = null;
- exception = ex.toString();
- for (JsonElement flag : testcase.getAsJsonArray("flags")) {
- if (flag.getAsString().equals(invalidPkcs1Padding)) {
- exceptions.add(exception);
- break;
- }
- }
- }
- if (decrypted == null && result.equals("valid")) {
- System.out.printf(
- "Valid ciphertext not decrypted. filename:%s tcId:%d ct:%s cause:%s\n",
- filename, tcid, ciphertextHex, exception);
- errors++;
- } else if (decrypted != null) {
- String decryptedHex = TestUtil.bytesToHex(decrypted);
- if (result.equals("invalid")) {
- System.out.printf(
- "Invalid ciphertext decrypted. filename:%s tcId:%d expected:%s decrypted:%s\n",
- filename, tcid, messageHex, decryptedHex);
- errors++;
- } else if (!decryptedHex.equals(messageHex)) {
- System.out.printf(
- "Incorrect decryption. filename:%s tcId:%d expected:%s decrypted:%s\n",
- filename, tcid, messageHex, decryptedHex);
- errors++;
- }
- }
- }
- }
- if (exceptions.size() != 1) {
- System.out.println("Exceptions for RSA/ECB/PKCS1Padding");
- for (String s : exceptions) {
- System.out.println(s);
- }
- fail("Exceptions leak information about the padding");
- }
- assertEquals(0, errors);
- }
-
- @Test
- public void testDecryption2048() throws Exception {
- testDecryption("rsa_pkcs1_2048_test.json");
- }
-
- @Test
- public void testDecryption3072() throws Exception {
- testDecryption("rsa_pkcs1_3072_test.json");
- }
-
- @Test
- public void testDecryption4096() throws Exception {
- testDecryption("rsa_pkcs1_4096_test.json");
- }
-}