Skip to content

Commit c0e4ddc

Browse files
Merge pull request #30675 from adriankalafut/improve-fips-exception-handling-2025-01-30
Repair NullPointer exception thrown in AESKeyManager.java
2 parents 8fbe3a3 + 37df761 commit c0e4ddc

File tree

5 files changed

+71
-62
lines changed

5 files changed

+71
-62
lines changed

dev/com.ibm.ws.crypto.passwordutil/bnd.bnd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ instrument.disabled: true
4949
com.ibm.websphere.org.osgi.service.component;version=latest,\
5050
com.ibm.wsspi.org.osgi.service.component.annotations;version=latest,\
5151
com.ibm.ws.kernel.service;version=latest,\
52-
com.ibm.ws.kernel.boot;version=latest, \
52+
com.ibm.ws.kernel.boot;version=latest,\
53+
com.ibm.ws.kernel.boot.core;version=latest,\
5354
com.ibm.ws.kernel.security.thread;version=latest,\
5455
com.ibm.ws.org.osgi.annotation.versioning;version=latest
5556

dev/com.ibm.ws.crypto.passwordutil/resources/com/ibm/ws/crypto/util/internal/resources/Messages.nlsprops

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,20 @@ PASSWORDUTIL_UNSUPPORTEDENCODING_EXCEPTION.explanation=The password was not encr
4949
PASSWORDUTIL_UNSUPPORTEDENCODING_EXCEPTION.useraction=Check the server log and if the custom password encryption is used check the custom password encryption logs for further information.
5050
PASSWORDUTIL_INVALID_BASE64_STRING=CWWKS1859E: The password was not decrypted because a decoding error was reported.
5151
PASSWORDUTIL_INVALID_BASE64_STRING.explanation=The encrypted password was not encoded properly.
52-
PASSWORDUTIL_INVALID_BASE64_STRING.useraction=Make sure that the encrypted password is not truncated and encoded by using Base64 encoding.
53-
52+
PASSWORDUTIL_INVALID_BASE64_STRING.useraction=Make sure that the encrypted password is not truncated and encoded with Base64 encoding.
53+
PASSWORDUTIL_EXCEPTION_FIPS130_AES128_UNAVAILABLE_ALGORITHM=CWWKS1860E: AES-128 encrypted passwords cannot be used when FIPS 140-3 is enabled. Regenerate the password with AES-256 using the securityUtility command.
54+
PASSWORDUTIL_EXCEPTION_FIPS130_AES128_UNAVAILABLE_ALGORITHM.explanation=FIPS-130 is enabled and does not support AES-128. Use the securityUtility command to encrypt the password using AES-256.
55+
PASSWORDUTIL_EXCEPTION_FIPS130_AES128_UNAVAILABLE_ALGORITHM.useraction=Make sure the password is encrypted with AES-256.
56+
PASSWORDUTIL_UNAVAILABLE_ENCRYPTION_ALGORITHM_EXCEPTION=CWWKS1861E: AES password encryption failed. Check your java.security settings and add the missing algorithm.
57+
PASSWORDUTIL_UNAVAILABLE_ENCRYPTION_ALGORITHM_EXCEPTION.explanation=An encryption algorithm is missing from your java.security file.
58+
PASSWORDUTIL_UNAVAILABLE_ENCRYPTION_ALGORITHM_EXCEPTION.useraction=Make sure that the algorithm is added to your java.security file.
59+
PASSWORDUTIL_UNAVAILABLE_DECRYPTION_ALGORITHM_EXCEPTION=CWWKS1862E: AES password decryption failed. Check your java.security settings and add the missing algorithm.
60+
PASSWORDUTIL_UNAVAILABLE_DECRYPTION_ALGORITHM_EXCEPTION.explanation=An encryption algorithm is missing from your java.security file.
61+
PASSWORDUTIL_UNAVAILABLE_DECRYPTION_ALGORITHM_EXCEPTION.useraction=Make sure that the algorithm is added to your java.security file.
5462

5563
# ---------------- This is an exception message ------------
5664
PASSWORDUTIL_DUPLICATE_CUSTOM_ENCRYPTION=More than one CustomPasswordEncryption implementation is detected. Only one CustomPasswordEncryption implementation is supported. The list of detected CustomPasswordEncryption implementation is as follows:
5765
PASSWORDUTIL_ERROR_IN_EXTENSION_MANIFEST_FILE=An error was reported while processing the extension manifest file {0}. This file was ignored. The custom encryption is not available. The error message is {1}.
5866
PASSWORDUTIL_ERROR_MISSING_HEADER=The required header {0} was not found in the extension manifest file {1}. The custom encryption is not available.
5967
PASSWORDUTIL_ERROR_NO_FEATURE_MANIFEST=The feature manifest file which corresponds with the extension manifest file {0} was not found. The custom encryption is not available.
60-
PASSWORDUTIL_ERROR_UNSUPPORTED_OPERATION=The decryption operation is not supported by the hash algorithm.
68+
PASSWORDUTIL_ERROR_UNSUPPORTED_OPERATION=The decryption operation is not supported by the hash algorithm.

dev/com.ibm.ws.crypto.passwordutil/src/com/ibm/websphere/crypto/PasswordUtil.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
package com.ibm.websphere.crypto;
1515

1616
import java.nio.charset.StandardCharsets;
17+
import java.security.NoSuchAlgorithmException;
18+
import java.security.spec.InvalidKeySpecException;
1719
import java.util.HashMap;
1820
import java.util.Map;
1921
import java.util.logging.Level;
@@ -22,6 +24,7 @@
2224
import com.ibm.ws.common.encoder.Base64Coder;
2325
import com.ibm.ws.crypto.util.InvalidPasswordCipherException;
2426
import com.ibm.ws.crypto.util.PasswordCipherUtil;
27+
import com.ibm.ws.crypto.util.MessageUtils;
2528
import com.ibm.ws.crypto.util.PasswordHashGenerator;
2629
import com.ibm.wsspi.security.crypto.EncryptedInfo;
2730

@@ -637,13 +640,20 @@ private static String decode_password(String encoded_string, String crypto_algor
637640
try {
638641
decrypted_bytes = PasswordCipherUtil.decipher(encrypted_bytes, crypto_algorithm);
639642
} catch (InvalidPasswordCipherException e) {
640-
logger.logp(Level.SEVERE, PasswordUtil.class.getName(), "decode_password", "PASSWORDUTIL_CYPHER_EXCEPTION", e);
643+
String message = e.getMessage();
644+
if (message != null && message.contains("FIPS 140-3")) {
645+
logger.logp(Level.SEVERE, PasswordUtil.class.getName(), "decode_password", MessageUtils.getMessage("PASSWORDUTIL_EXCEPTION_FIPS130_AES128_UNAVAILABLE_ALGORITHM"), e);
646+
} else {
647+
logger.logp(Level.SEVERE, PasswordUtil.class.getName(), "decode_password", "PASSWORDUTIL_CYPHER_EXCEPTION", e);
648+
}
641649
return null;
642650
} catch (UnsupportedCryptoAlgorithmException e) {
643651
logger.logp(Level.SEVERE, PasswordUtil.class.getName(), "decode_password", "PASSWORDUTIL_UNKNOWN_ALGORITHM_EXCEPTION", e);
644652
return null;
653+
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
654+
logger.logp(Level.SEVERE, PasswordUtil.class.getName(), "decode_password", MessageUtils.getMessage("PASSWORDUTIL_UNAVAILABLE_DECRYPTION_ALGORITHM_EXCEPTION"), e);
655+
return null;
645656
}
646-
647657
if ((decrypted_bytes != null) && (decrypted_bytes.length > 0)) {
648658
// convert decrypted password byte[] to string
649659
decoded_string = convert_to_string(decrypted_bytes);
@@ -714,6 +724,9 @@ public static String encode_password(String decoded_string, String crypto_algori
714724
} catch (UnsupportedCryptoAlgorithmException e) {
715725
logger.logp(Level.SEVERE, PasswordUtil.class.getName(), "encode_password", "PASSWORDUTIL_UNKNOWN_ALGORITHM_EXCEPTION", e);
716726
return null;
727+
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
728+
logger.logp(Level.SEVERE, PasswordUtil.class.getName(), "decode_password", MessageUtils.getMessage("PASSWORDUTIL_UNAVAILABLE_ENCRYPTION_ALGORITHM_EXCEPTION"), e);
729+
return null;
717730
}
718731
}
719732
if ((encrypted_bytes != null) && (encrypted_bytes.length > 0)) {
@@ -744,5 +757,4 @@ public static String encode_password(String decoded_string, String crypto_algori
744757

745758
return buffer.toString();
746759
}
747-
748760
}

dev/com.ibm.ws.crypto.passwordutil/src/com/ibm/ws/crypto/util/AESKeyManager.java

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
*/
3232
public class AESKeyManager {
3333
private static final AtomicReference<KeyStringResolver> _resolver = new AtomicReference<KeyStringResolver>();
34-
private static final boolean DEBUG = Boolean.getBoolean("enableDebug"); // Used exclusively for debugging securityUtility
3534

3635
public static enum KeyVersion {
3736
AES_V0("PBKDF2WithHmacSHA1", 84756, 128, new byte[] { -89, -94, -125, 57, 76, 90, -77, 79, 50, 21, 10, -98, 47, 23, 17, 56, -61, 46, 125, -128 }),
@@ -56,41 +55,21 @@ private KeyVersion(String alg, int iterations, int keyLength, byte[] salt) {
5655
this.salt = salt;
5756
}
5857

59-
private KeyHolder get(char[] keyChars) {
58+
private KeyHolder get(char[] keyChars) throws NoSuchAlgorithmException, InvalidKeySpecException {
6059
KeyHolder holder = _key.get();
6160
if (holder == null || !!!holder.matches(keyChars)) {
62-
try {
63-
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(alg);
64-
KeySpec aesKey = new PBEKeySpec(keyChars, salt, iterations, keyLength);
65-
byte[] data = keyFactory.generateSecret(aesKey).getEncoded();
66-
KeyHolder holder2 = new KeyHolder(keyChars, new SecretKeySpec(data, "AES"), new IvParameterSpec(data));
67-
_key.compareAndSet(holder, holder2);
68-
// Still use this holder for returns even if I do not end up caching it.
69-
holder = holder2;
70-
} catch (InvalidKeySpecException e) {
71-
if (DEBUG) {
72-
securityUtilDebug("InvalidKeySpecException received. Returning null", e);
73-
}
74-
return null;
75-
} catch (NoSuchAlgorithmException e) {
76-
if (DEBUG) {
77-
securityUtilDebug("InvalidKeySpecException received. Returning null", e);
78-
}
79-
return null;
80-
}
81-
61+
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(alg);
62+
KeySpec aesKey = new PBEKeySpec(keyChars, salt, iterations, keyLength);
63+
byte[] data = keyFactory.generateSecret(aesKey).getEncoded();
64+
KeyHolder holder2 = new KeyHolder(keyChars, new SecretKeySpec(data, "AES"), new IvParameterSpec(data));
65+
_key.compareAndSet(holder, holder2);
66+
// Still use this holder for returns even if I do not end up caching it.
67+
holder = holder2;
8268
}
83-
8469
return holder;
8570
}
8671
}
8772

88-
// Used exclusively for debugging securityUtility
89-
private static void securityUtilDebug(String message, Throwable throwable) {
90-
System.out.println("[DEBUG] " + message);
91-
throwable.printStackTrace(System.out); // Prints the exception stack trace
92-
}
93-
9473
private static class KeyHolder {
9574
private final char[] keyChars;
9675
private final Key key;
@@ -121,15 +100,13 @@ public IvParameterSpec getIv() {
121100
setKeyStringResolver(null);
122101
}
123102

124-
public static Key getKey(KeyVersion version, String key) {
125-
103+
public static Key getKey(KeyVersion version, String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
126104
KeyHolder holder = getHolder(version, key);
127-
128105
return holder.getKey();
129106
}
130107

131108
@Deprecated
132-
public static Key getKey(String key) {
109+
public static Key getKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
133110

134111
KeyHolder holder = getHolder(KeyVersion.AES_V0, key);
135112

@@ -141,9 +118,8 @@ public static Key getKey(String key) {
141118
* @param keyChars
142119
* @return
143120
*/
144-
private static KeyHolder getHolder(KeyVersion version, String key) {
121+
private static KeyHolder getHolder(KeyVersion version, String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
145122
char[] keyChars = _resolver.get().getKey(key == null ? "${wlp.password.encryption.key}" : key);
146-
147123
return version.get(keyChars);
148124
}
149125

@@ -167,7 +143,7 @@ public char[] getKey(String key) {
167143
* @param cryptoKey
168144
* @return
169145
*/
170-
public static IvParameterSpec getIV(KeyVersion version, String cryptoKey) {
146+
public static IvParameterSpec getIV(KeyVersion version, String cryptoKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
171147
if (version == KeyVersion.AES_V0) {
172148
return getHolder(version, cryptoKey).getIv();
173149
} else {
@@ -180,7 +156,7 @@ public static IvParameterSpec getIV(KeyVersion version, String cryptoKey) {
180156
* @return
181157
*/
182158
@Deprecated
183-
public static IvParameterSpec getIV(String cryptoKey) {
159+
public static IvParameterSpec getIV(String cryptoKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
184160
return getHolder(KeyVersion.AES_V0, cryptoKey).getIv();
185161
}
186-
}
162+
}

0 commit comments

Comments
 (0)