diff --git a/src/main/java/com/ibm/crypto/plus/provider/OpenJCEPlusFIPS.java b/src/main/java/com/ibm/crypto/plus/provider/OpenJCEPlusFIPS.java index 6be69dbd0..53906eba0 100644 --- a/src/main/java/com/ibm/crypto/plus/provider/OpenJCEPlusFIPS.java +++ b/src/main/java/com/ibm/crypto/plus/provider/OpenJCEPlusFIPS.java @@ -24,6 +24,8 @@ public final class OpenJCEPlusFIPS extends OpenJCEPlusProvider { private static final boolean printFipsDeveloperModeWarning = Boolean.parseBoolean(System.getProperty("openjceplus.fips.devmodewarn", "true")); + private static final boolean allowNonOAEPFIPS = Boolean.parseBoolean(System.getProperty("com.ibm.openjceplusfips.allowNonOAEP", "false")); + private static final String info = "OpenJCEPlusFIPS Provider implements the following:\n" + "Algorithm parameter : AES, DiffieHellman, DSA, EC, GCM, OAEP, RSAPSS\n" @@ -208,8 +210,21 @@ private void registerAlgorithms(Provider jce) { "com.ibm.crypto.plus.provider.AESCipher", aliases)); aliases = null; + Map rsaAttr = new HashMap<>(); + + String supportedPaddings = "OAEPPADDING" + + "|OAEPWITHSHA1ANDMGF1PADDING" + + "|OAEPWITHSHA-1ANDMGF1PADDING"; + if (allowNonOAEPFIPS) { + supportedPaddings += "|NOPADDING|PKCS1PADDING"; + } + rsaAttr.put("SupportedModes", "ECB"); + rsaAttr.put("SupportedPaddings", supportedPaddings); + rsaAttr.put("SupportedKeyClasses", + "java.security.interfaces.RSAPublicKey" + + "|java.security.interfaces.RSAPrivateKey"); putService(new OpenJCEPlusService(jce, "Cipher", "RSA", "com.ibm.crypto.plus.provider.RSA", - aliases)); + aliases, rsaAttr)); aliases = new String[] {"AESWrap"}; putService(new OpenJCEPlusService(jce, "Cipher", "AES/KW/NoPadding", diff --git a/src/main/java/com/ibm/crypto/plus/provider/RSA.java b/src/main/java/com/ibm/crypto/plus/provider/RSA.java index 70ac521e5..20d486785 100644 --- a/src/main/java/com/ibm/crypto/plus/provider/RSA.java +++ b/src/main/java/com/ibm/crypto/plus/provider/RSA.java @@ -47,11 +47,14 @@ public final class RSA extends CipherSpi { private static final boolean doTypeChecking; private static final String DO_TYPE_CHECKING = "com.ibm.crypto.provider.DoRSATypeChecking"; + private static final boolean allowNonOAEPFIPS; + private static final String ALLOW_NON_OAEP_FIPS = "com.ibm.openjceplusfips.allowNonOAEP"; private final static byte[] B0 = new byte[0]; static { doTypeChecking = Boolean.parseBoolean(System.getProperty(DO_TYPE_CHECKING, "true")); + allowNonOAEPFIPS = Boolean.parseBoolean(System.getProperty(ALLOW_NON_OAEP_FIPS, "false")); } public RSA(OpenJCEPlusProvider provider) { @@ -358,7 +361,7 @@ private void checkOAEPParameters(OAEPParameterSpec spec) @Override protected void engineSetMode(String mode) throws NoSuchAlgorithmException { - if (mode == null || mode.matches(" |ECB|SSL")) { + if (mode == null || mode.matches("ECB")) { return; } throw new NoSuchAlgorithmException("Unsupported mode " + mode); @@ -366,16 +369,22 @@ protected void engineSetMode(String mode) throws NoSuchAlgorithmException { @Override protected void engineSetPadding(String padding) throws NoSuchPaddingException { - if (padding.equalsIgnoreCase("NoPadding")) { - this.padding = RSAPadding.NoPadding; - } else if (padding.equalsIgnoreCase("PKCS1Padding")) { - this.padding = RSAPadding.PKCS1Padding; - } else if (padding.equalsIgnoreCase("OAEPPadding") + if (padding.equalsIgnoreCase("OAEPPadding") || padding.equalsIgnoreCase("OAEPWithSHA-1AndMGF1Padding") || padding.equalsIgnoreCase("OAEPWithSHA1AndMGF1Padding")) { this.padding = RSAPadding.OAEPPadding; } else { - throw new NoSuchPaddingException("Padding: " + padding + " not implemented"); + if (provider.isFIPS() && !allowNonOAEPFIPS) { + throw new NoSuchPaddingException("Padding: " + padding + " not supported through FIPS provider"); + } else { + if (padding.equalsIgnoreCase("NoPadding")) { + this.padding = RSAPadding.NoPadding; + } else if (padding.equalsIgnoreCase("PKCS1Padding")) { + this.padding = RSAPadding.PKCS1Padding; + } else { + throw new NoSuchPaddingException("Padding: " + padding + " not implemented"); + } + } } } diff --git a/src/test/java/ibm/jceplus/junit/base/BaseTestRSA.java b/src/test/java/ibm/jceplus/junit/base/BaseTestRSA.java index 0fab8df3d..e41427601 100644 --- a/src/test/java/ibm/jceplus/junit/base/BaseTestRSA.java +++ b/src/test/java/ibm/jceplus/junit/base/BaseTestRSA.java @@ -43,6 +43,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; public class BaseTestRSA extends BaseTestCipher { @@ -197,26 +198,36 @@ public void plainKeyCipher(String alg, int mode, Key key, String in, String out, @Test public void testRSACipher_PKCS1Padding() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + encryptDecrypt("RSA/ECB/PKCS1Padding"); } @Test public void testRSACipher_NoPadding() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + encryptDecrypt("RSA/ECB/NoPadding"); } @Test public void testRSACipher_ECB_PKCS1Padding() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + encryptDecrypt("RSA/ECB/PKCS1Padding"); } @Test public void testRSACipher_ECB_NoPadding() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + encryptDecrypt("RSA/ECB/NoPadding"); } @Test public void testRSACipher_ECB_ZeroPadding() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + encryptDecrypt("RSA/ECB/ZeroPadding"); } @@ -230,11 +241,6 @@ public void testRSACipherForSSL() throws Exception { encryptDecrypt("RSAforSSL"); } - @Test - public void testRSACipher_SSL_PKCS1Padding() throws Exception { - encryptDecrypt("RSA/SSL/PKCS1Padding"); - } - @Test public void testRSACipherWithOAEPPadding() throws Exception { byte[] message = getMessage_OAEP_SHA1(); @@ -312,25 +318,22 @@ public void testRSAShortBuffer() throws Exception { @Test public void testRSAShortBuffer2() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + String algorithm = "RSA/ECB/NoPadding"; int outputByteLength = 64; int finalOffset = 65; try { - Cipher cipher = Cipher.getInstance(algorithm, getProviderName()); if (cipher.equals(null)) System.out.println("The cipher was null."); cipher.init(Cipher.ENCRYPT_MODE, rsaPub); - byte[] newplainText2 = new byte[outputByteLength]; - cipher.doFinal(newplainText2, finalOffset); - fail("Expected ShortBufferException did not occur"); - } catch (ShortBufferException ex) { assertTrue(true); } @@ -360,6 +363,7 @@ public void testRSABadPadding() throws Exception { @Test public void testRSAIllegalMode() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); // Test RSA Cipher Cipher cp = Cipher.getInstance("RSA/ECB/PKCS1Padding", getProviderName()); @@ -376,7 +380,6 @@ public void testRSAIllegalMode() throws Exception { boolean success = decryptResultsMatch(cp.getAlgorithm(), plainText, newPlainText); assertTrue(success, "Decrypted text does not match expected"); - } @Test @@ -386,26 +389,36 @@ public void testRSACipher_getParams() throws Exception { @Test public void testRSACipher_PKCS1Padding_getParams() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + checkGetParamsNull("RSA/ECB/PKCS1Padding"); } @Test public void testRSACipher_NoPadding_getParams() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + checkGetParamsNull("RSA/ECB/NoPadding"); } @Test public void testRSACipher_ECB_PKCS1Padding_getParams() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + checkGetParamsNull("RSA/ECB/PKCS1Padding"); } @Test public void testRSACipher_ECB_NoPadding_getParams() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + checkGetParamsNull("RSA/ECB/NoPadding"); } @Test public void testRSACipher_ECB_ZeroPadding_getParams() throws Exception { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + checkGetParamsNull("RSA/ECB/ZeroPadding"); } @@ -419,11 +432,6 @@ public void testRSACipherForSSL_getParams() throws Exception { checkGetParamsNull("RSAforSSL"); } - @Test - public void testRSACipher_SSL_PKCS1Padding_getParams() throws Exception { - checkGetParamsNull("RSA/SSL/PKCS1Padding"); - } - @Test public void testRSACipherWithOAEPPadding_getParams() throws Exception { checkGetParamsNotNull("RSA/ECB/OAEPPadding"); diff --git a/src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInterop.java b/src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInterop.java index 7807f99fd..064208179 100644 --- a/src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInterop.java +++ b/src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInterop.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; public class BaseTestRSAKeyInterop extends BaseTestJunit5Interop { @@ -475,6 +476,7 @@ public void testSignPlusAndVerifyJCECrt() { @Test public void testEncryptPlusDecryptJCE() { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); try { @@ -514,6 +516,8 @@ public void testEncryptPlusDecryptJCE() { @Test public void testEncryptJCEDecryptPlus() { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + byte[] msgBytes = ("This is a short message".getBytes()); //long message to be encrypted and decrypted using RSA public and Private key;" + // "encrypt with JCE and decrypt with JCEPlus and vice versa").getBytes(); diff --git a/src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInteropBC.java b/src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInteropBC.java index 99a0b4b0f..f344da44a 100644 --- a/src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInteropBC.java +++ b/src/test/java/ibm/jceplus/junit/base/BaseTestRSAKeyInteropBC.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; public class BaseTestRSAKeyInteropBC extends BaseTestJunit5Interop { @@ -500,6 +501,7 @@ public void testSignPlusAndVerifyBCCrt() { @Test public void testEncryptPlusDecryptBC() { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); try { @@ -543,6 +545,8 @@ public void testEncryptPlusDecryptBC() { @Test public void testEncryptBCDecryptPlus() { + assumeFalse("OpenJCEPlusFIPS".equals(getProviderName())); + byte[] msgBytes = ("This is a short message".getBytes()); //long message to be encrypted and decrypted using RSA public and Private key;" + // "encrypt with BC and decrypt with BCPlus and vice versa").getBytes();