Skip to content

Commit 53abe8a

Browse files
committed
backport 35dabb1a5f31d985f00de21badeeedb026a63b94
1 parent 0f2ffb5 commit 53abe8a

File tree

19 files changed

+1402
-202
lines changed

19 files changed

+1402
-202
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package com.sun.crypto.provider;
27+
28+
import java.io.ByteArrayOutputStream;
29+
import java.security.MessageDigest;
30+
import java.security.PrivateKey;
31+
import java.security.PublicKey;
32+
import java.security.SecureRandom;
33+
import java.security.SignatureSpi;
34+
import java.security.InvalidKeyException;
35+
import java.security.InvalidAlgorithmParameterException;
36+
import java.security.InvalidParameterException;
37+
import java.security.SignatureException;
38+
import java.security.spec.AlgorithmParameterSpec;
39+
import javax.crypto.Cipher;
40+
import javax.crypto.BadPaddingException;
41+
import javax.crypto.IllegalBlockSizeException;
42+
43+
/**
44+
* NONEwithRSA Signature implementation using the RSA/ECB/PKCS1Padding Cipher
45+
* implementation from SunJCE.
46+
*/
47+
public final class RSACipherAdaptor extends SignatureSpi {
48+
49+
private final RSACipher c;
50+
private ByteArrayOutputStream verifyBuf;
51+
52+
public RSACipherAdaptor() {
53+
c = new RSACipher();
54+
}
55+
56+
@Override
57+
protected void engineInitVerify(PublicKey publicKey)
58+
throws InvalidKeyException {
59+
c.engineInit(Cipher.DECRYPT_MODE, publicKey, null);
60+
if (verifyBuf == null) {
61+
verifyBuf = new ByteArrayOutputStream(128);
62+
} else {
63+
verifyBuf.reset();
64+
}
65+
}
66+
67+
@Override
68+
protected void engineInitSign(PrivateKey privateKey)
69+
throws InvalidKeyException {
70+
c.engineInit(Cipher.ENCRYPT_MODE, privateKey, null);
71+
verifyBuf = null;
72+
}
73+
74+
@Override
75+
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
76+
throws InvalidKeyException {
77+
c.engineInit(Cipher.ENCRYPT_MODE, privateKey, random);
78+
verifyBuf = null;
79+
}
80+
81+
@Override
82+
protected void engineUpdate(byte b) throws SignatureException {
83+
engineUpdate(new byte[] {b}, 0, 1);
84+
}
85+
86+
@Override
87+
protected void engineUpdate(byte[] b, int off, int len)
88+
throws SignatureException {
89+
if (verifyBuf != null) {
90+
verifyBuf.write(b, off, len);
91+
} else {
92+
byte[] out = c.engineUpdate(b, off, len);
93+
if ((out != null) && (out.length != 0)) {
94+
throw new SignatureException
95+
("Cipher unexpectedly returned data");
96+
}
97+
}
98+
}
99+
100+
@Override
101+
protected byte[] engineSign() throws SignatureException {
102+
try {
103+
return c.engineDoFinal(null, 0, 0);
104+
} catch (IllegalBlockSizeException | BadPaddingException e) {
105+
throw new SignatureException("doFinal() failed", e);
106+
}
107+
}
108+
109+
@Override
110+
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
111+
try {
112+
byte[] out = c.engineDoFinal(sigBytes, 0, sigBytes.length);
113+
byte[] data = verifyBuf.toByteArray();
114+
verifyBuf.reset();
115+
return MessageDigest.isEqual(out, data);
116+
} catch (BadPaddingException e) {
117+
// e.g. wrong public key used
118+
// return false rather than throwing exception
119+
return false;
120+
} catch (IllegalBlockSizeException e) {
121+
throw new SignatureException("doFinal() failed", e);
122+
}
123+
}
124+
125+
@Override
126+
protected void engineSetParameter(AlgorithmParameterSpec params)
127+
throws InvalidAlgorithmParameterException {
128+
if (params != null) {
129+
throw new InvalidParameterException("Parameters not supported");
130+
}
131+
}
132+
133+
@Override
134+
@SuppressWarnings("deprecation")
135+
protected void engineSetParameter(String param, Object value)
136+
throws InvalidParameterException {
137+
throw new InvalidParameterException("Parameters not supported");
138+
}
139+
140+
@Override
141+
@SuppressWarnings("deprecation")
142+
protected Object engineGetParameter(String param)
143+
throws InvalidParameterException {
144+
throw new InvalidParameterException("Parameters not supported");
145+
}
146+
}

src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ public Void run() {
147147
void putEntries() {
148148
// reuse attribute map and reset before each reuse
149149
HashMap<String, String> attrs = new HashMap<>(3);
150+
attrs.put("SupportedKeyClasses",
151+
"java.security.interfaces.RSAPublicKey" +
152+
"|java.security.interfaces.RSAPrivateKey");
153+
ps("Signature", "NONEwithRSA",
154+
"com.sun.crypto.provider.RSACipherAdaptor", null, attrs);
155+
// continue adding cipher specific attributes
150156
attrs.put("SupportedModes", "ECB");
151157
attrs.put("SupportedPaddings", "NOPADDING|PKCS1PADDING|OAEPPADDING"
152158
+ "|OAEPWITHMD5ANDMGF1PADDING"
@@ -158,9 +164,6 @@ void putEntries() {
158164
+ "|OAEPWITHSHA-512ANDMGF1PADDING"
159165
+ "|OAEPWITHSHA-512/224ANDMGF1PADDING"
160166
+ "|OAEPWITHSHA-512/256ANDMGF1PADDING");
161-
attrs.put("SupportedKeyClasses",
162-
"java.security.interfaces.RSAPublicKey" +
163-
"|java.security.interfaces.RSAPrivateKey");
164167
ps("Cipher", "RSA",
165168
"com.sun.crypto.provider.RSACipher", null, attrs);
166169

src/java.base/share/classes/java/security/KeyStore.java

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import javax.security.auth.callback.*;
3838

3939
import sun.security.util.Debug;
40+
import sun.security.util.CryptoAlgorithmConstraints;
4041

4142
/**
4243
* This class represents a storage facility for cryptographic
@@ -839,12 +840,21 @@ private String getProviderName() {
839840
* the {@link Security#getProviders() Security.getProviders()} method.
840841
*
841842
* @implNote
842-
* The JDK Reference Implementation additionally uses the
843-
* {@code jdk.security.provider.preferred}
843+
* The JDK Reference Implementation additionally uses
844+
* <ul>
845+
* <li>the {@code jdk.security.provider.preferred}
844846
* {@link Security#getProperty(String) Security} property to determine
845-
* the preferred provider order for the specified algorithm. This
847+
* the preferred provider order for the specified keystore type. This
846848
* may be different from the order of providers returned by
847849
* {@link Security#getProviders() Security.getProviders()}.
850+
* </li>
851+
* <li>the {@code jdk.crypto.disabledAlgorithms}
852+
* {@link Security#getProperty(String) Security} property to determine
853+
* if the specified keystore type is allowed. If the
854+
* {@systemProperty jdk.crypto.disabledAlgorithms} is set, it supersedes
855+
* the security property value.
856+
* </li>
857+
* </ul>
848858
*
849859
* @param type the type of keystore.
850860
* See the KeyStore section in the <a href=
@@ -866,6 +876,11 @@ public static KeyStore getInstance(String type)
866876
throws KeyStoreException
867877
{
868878
Objects.requireNonNull(type, "null type name");
879+
880+
if (!CryptoAlgorithmConstraints.permits("KEYSTORE", type)) {
881+
throw new KeyStoreException(type + " is disabled");
882+
}
883+
869884
try {
870885
Object[] objs = Security.getImpl(type, "KeyStore", (String)null);
871886
return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
@@ -885,6 +900,14 @@ public static KeyStore getInstance(String type)
885900
* <p> Note that the list of registered providers may be retrieved via
886901
* the {@link Security#getProviders() Security.getProviders()} method.
887902
*
903+
* @implNote
904+
* The JDK Reference Implementation additionally uses
905+
* the {@code jdk.crypto.disabledAlgorithms}
906+
* {@link Security#getProperty(String) Security} property to determine
907+
* if the specified keystore type is allowed. If the
908+
* {@systemProperty jdk.crypto.disabledAlgorithms} is set, it supersedes
909+
* the security property value.
910+
*
888911
* @param type the type of keystore.
889912
* See the KeyStore section in the <a href=
890913
* "{@docRoot}/../specs/security/standard-names.html#keystore-types">
@@ -913,8 +936,15 @@ public static KeyStore getInstance(String type, String provider)
913936
throws KeyStoreException, NoSuchProviderException
914937
{
915938
Objects.requireNonNull(type, "null type name");
916-
if (provider == null || provider.isEmpty())
939+
940+
if (provider == null || provider.isEmpty()) {
917941
throw new IllegalArgumentException("missing provider");
942+
}
943+
944+
if (!CryptoAlgorithmConstraints.permits("KEYSTORE", type)) {
945+
throw new KeyStoreException(type + " is disabled");
946+
}
947+
918948
try {
919949
Object[] objs = Security.getImpl(type, "KeyStore", provider);
920950
return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
@@ -931,6 +961,14 @@ public static KeyStore getInstance(String type, String provider)
931961
* object is returned. Note that the specified provider object
932962
* does not have to be registered in the provider list.
933963
*
964+
* @implNote
965+
* The JDK Reference Implementation additionally uses
966+
* the {@code jdk.crypto.disabledAlgorithms}
967+
* {@link Security#getProperty(String) Security} property to determine
968+
* if the specified keystore type is allowed. If the
969+
* {@systemProperty jdk.crypto.disabledAlgorithms} is set, it supersedes
970+
* the security property value.
971+
*
934972
* @param type the type of keystore.
935973
* See the KeyStore section in the <a href=
936974
* "{@docRoot}/../specs/security/standard-names.html#keystore-types">
@@ -958,8 +996,15 @@ public static KeyStore getInstance(String type, Provider provider)
958996
throws KeyStoreException
959997
{
960998
Objects.requireNonNull(type, "null type name");
961-
if (provider == null)
999+
1000+
if (provider == null) {
9621001
throw new IllegalArgumentException("missing provider");
1002+
}
1003+
1004+
if (!CryptoAlgorithmConstraints.permits("KEYSTORE", type)) {
1005+
throw new KeyStoreException(type + " is disabled");
1006+
}
1007+
9631008
try {
9641009
Object[] objs = Security.getImpl(type, "KeyStore", provider);
9651010
return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
@@ -1675,6 +1720,14 @@ public final void setEntry(String alias, Entry entry,
16751720
* <p> Note that the list of registered providers may be retrieved via
16761721
* the {@link Security#getProviders() Security.getProviders()} method.
16771722
*
1723+
* @implNote
1724+
* The JDK Reference Implementation additionally uses
1725+
* the {@code jdk.crypto.disabledAlgorithms}
1726+
* {@link Security#getProperty(String) Security} property to determine
1727+
* if the specified keystore type is allowed. If the
1728+
* {@systemProperty jdk.crypto.disabledAlgorithms} is set, it supersedes
1729+
* the security property value. Disallowed type will be skipped.
1730+
*
16781731
* @param file the keystore file
16791732
* @param password the keystore password, which may be {@code null}
16801733
*
@@ -1731,6 +1784,14 @@ public static final KeyStore getInstance(File file, char[] password)
17311784
* <p> Note that the list of registered providers may be retrieved via
17321785
* the {@link Security#getProviders() Security.getProviders()} method.
17331786
*
1787+
* @implNote
1788+
* The JDK Reference Implementation additionally uses
1789+
* the {@code jdk.crypto.disabledAlgorithms}
1790+
* {@link Security#getProperty(String) Security} property to determine
1791+
* if the specified keystore type is allowed. If the
1792+
* {@systemProperty jdk.crypto.disabledAlgorithms} is set, it supersedes
1793+
* the security property value. Disallowed type will be skipped.
1794+
*
17341795
* @param file the keystore file
17351796
* @param param the {@code LoadStoreParameter} that specifies how to load
17361797
* the keystore, which may be {@code null}
@@ -1802,8 +1863,12 @@ private static final KeyStore getInstance(File file, char[] password,
18021863
kdebug.println(s.getAlgorithm()
18031864
+ " keystore detected: " + file);
18041865
}
1805-
keystore = new KeyStore(impl, p, s.getAlgorithm());
1806-
break;
1866+
String ksAlgo = s.getAlgorithm();
1867+
if (CryptoAlgorithmConstraints.permits(
1868+
"KEYSTORE", ksAlgo)) {
1869+
keystore = new KeyStore(impl, p, ksAlgo);
1870+
break;
1871+
}
18071872
}
18081873
} catch (NoSuchAlgorithmException e) {
18091874
// ignore

0 commit comments

Comments
 (0)