From 5c596e2a9599e1e0eb9ec845f1b6e0e7b59f186a Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Thu, 25 Sep 2025 18:10:58 +0000 Subject: [PATCH] 8360463: Ambiguity in Cipher.getInstance() specification between NoSuchAlgorithmException and NoSuchPaddingException Reviewed-by: mullan --- .../share/classes/javax/crypto/Cipher.java | 48 +++++++++++-------- .../unittest/ChaCha20CipherUnitTest.java | 47 ++++++++++-------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/java.base/share/classes/javax/crypto/Cipher.java b/src/java.base/share/classes/javax/crypto/Cipher.java index 902c3998fbe..b22b8cf5483 100644 --- a/src/java.base/share/classes/javax/crypto/Cipher.java +++ b/src/java.base/share/classes/javax/crypto/Cipher.java @@ -515,12 +515,12 @@ public class Cipher { * transformation * * @throws NoSuchAlgorithmException if {@code transformation} - * is {@code null}, empty, in an invalid format, - * or if no provider supports a {@code CipherSpi} - * implementation for the specified algorithm + * is {@code null}, empty or in an invalid format; + * or if a {@code CipherSpi} implementation is not found or + * is found but does not support the mode * - * @throws NoSuchPaddingException if {@code transformation} - * contains a padding scheme that is not available + * @throws NoSuchPaddingException if a {@code CipherSpi} implementation + * is found but does not support the padding scheme * * @see java.security.Provider */ @@ -573,8 +573,12 @@ public class Cipher { failure = e; } } + if (failure instanceof NoSuchPaddingException nspe) { + throw nspe; + } throw new NoSuchAlgorithmException - ("Cannot find any provider supporting " + transformation, failure); + ("Cannot find any provider supporting " + transformation, + failure); } /** @@ -582,8 +586,8 @@ public class Cipher { * transformation. * *

A new {@code Cipher} object encapsulating the - * {@code CipherSpi} implementation from the specified provider - * is returned. The specified provider must be registered + * {@code CipherSpi} implementation from the specified {@code provider} + * is returned. The specified {@code provider} must be registered * in the security provider list. * *

Note that the list of registered providers may be retrieved via @@ -625,15 +629,16 @@ public class Cipher { * is {@code null} or empty * * @throws NoSuchAlgorithmException if {@code transformation} - * is {@code null}, empty, in an invalid format, - * or if a {@code CipherSpi} implementation for the - * specified algorithm is not available from the specified - * provider + * is {@code null}, empty or in an invalid format; + * or if a {@code CipherSpi} implementation from the specified + * {@code provider} is not found or is found but does not support + * the mode * - * @throws NoSuchPaddingException if {@code transformation} - * contains a padding scheme that is not available + * @throws NoSuchPaddingException if a {@code CipherSpi} implementation + * from the specified {@code provider} is found but does not + * support the padding scheme * - * @throws NoSuchProviderException if the specified provider is not + * @throws NoSuchProviderException if the specified {@code provider} is not * registered in the security provider list * * @see java.security.Provider @@ -706,13 +711,14 @@ public class Cipher { * is {@code null} * * @throws NoSuchAlgorithmException if {@code transformation} - * is {@code null}, empty, in an invalid format, - * or if a {@code CipherSpi} implementation for the - * specified algorithm is not available from the specified - * {@code provider} object + * is {@code null}, empty or in an invalid format; + * or if a {@code CipherSpi} implementation from the specified + * {@code provider} is not found or is found but does not support + * the mode * - * @throws NoSuchPaddingException if {@code transformation} - * contains a padding scheme that is not available + * @throws NoSuchPaddingException if a {@code CipherSpi} implementation + * from the specified {@code provider} is found but does not + * support the padding scheme * * @see java.security.Provider */ diff --git a/test/jdk/com/sun/crypto/provider/Cipher/ChaCha20/unittest/ChaCha20CipherUnitTest.java b/test/jdk/com/sun/crypto/provider/Cipher/ChaCha20/unittest/ChaCha20CipherUnitTest.java index 5216f48d5c3..892f3300d65 100644 --- a/test/jdk/com/sun/crypto/provider/Cipher/ChaCha20/unittest/ChaCha20CipherUnitTest.java +++ b/test/jdk/com/sun/crypto/provider/Cipher/ChaCha20/unittest/ChaCha20CipherUnitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8153029 + * @bug 8153029 8360463 * @library /test/lib * @run main ChaCha20CipherUnitTest * @summary Unit test for com.sun.crypto.provider.ChaCha20Cipher. @@ -38,6 +38,7 @@ import java.util.Arrays; import java.util.HexFormat; import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.ChaCha20ParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -66,32 +67,36 @@ public class ChaCha20CipherUnitTest { private static void testTransformations() throws Exception { System.out.println("== transformations =="); - checkTransformation("ChaCha20", true); - checkTransformation("ChaCha20/None/NoPadding", true); - checkTransformation("ChaCha20-Poly1305", true); - checkTransformation("ChaCha20-Poly1305/None/NoPadding", true); + Class NSAE = NoSuchAlgorithmException.class; + Class NSPE = NoSuchPaddingException.class; - checkTransformation("ChaCha20/ECB/NoPadding", false); - checkTransformation("ChaCha20/None/PKCS5Padding", false); - checkTransformation("ChaCha20-Poly1305/ECB/NoPadding", false); - checkTransformation("ChaCha20-Poly1305/None/PKCS5Padding", false); + checkTransformation("ChaCha20", null); + checkTransformation("ChaCha20/None/NoPadding", null); + checkTransformation("ChaCha20-Poly1305", null); + checkTransformation("ChaCha20-Poly1305/None/NoPadding", null); + checkTransformation("ChaCha20/ECB/NoPadding", NSAE); + checkTransformation("ChaCha20/None/PKCS5Padding", NSPE); + checkTransformation("ChaCha20-Poly1305/ECB/NoPadding", NSAE); + checkTransformation("ChaCha20-Poly1305/None/PKCS5Padding", NSPE); } - private static void checkTransformation(String transformation, - boolean expected) throws Exception { + private static void checkTransformation(String transformation, Class exCls) + throws Exception { try { - Cipher.getInstance(transformation); - if (!expected) { - throw new RuntimeException( - "Unexpected transformation: " + transformation); + Cipher.getInstance(transformation, + System.getProperty("test.provider.name", "SunJCE")); + if (exCls != null) { + throw new RuntimeException("Expected Exception not thrown: " + + exCls); } else { - System.out.println("Expected transformation: " + transformation); + System.out.println(transformation + ": pass"); } - } catch (NoSuchAlgorithmException e) { - if (!expected) { - System.out.println("Unexpected transformation: " + transformation); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + if (e.getClass() != exCls) { + throw new RuntimeException("Unexpected Exception", e); } else { - throw new RuntimeException("Unexpected fail: " + transformation, e); + System.out.println(transformation + ": got expected " + + exCls.getName()); } } }