Skip to content

Commit 9db1ffb

Browse files
committed
Add Nullability to spring-security-crypto
Closes gh-17533
1 parent bc4ec39 commit 9db1ffb

22 files changed

+237
-37
lines changed

crypto/spring-security-crypto.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
plugins {
2+
id 'security-nullability'
3+
}
4+
15
apply plugin: 'io.spring.convention.spring-module'
26

37
dependencies {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2002-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
@NullMarked
18+
package org.springframework.security.crypto.argon2;
19+
20+
import org.jspecify.annotations.NullMarked;

crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,9 @@ public class BCrypt {
210210
static final int MAX_LOG_ROUNDS = 31;
211211

212212
// Expanded Blowfish key
213-
private int P[];
213+
private int P[] = new int[0];
214214

215-
private int S[];
215+
private int S[] = new int[0];
216216

217217
/**
218218
* Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note

crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import org.apache.commons.logging.Log;
2424
import org.apache.commons.logging.LogFactory;
25+
import org.jspecify.annotations.Nullable;
2526

2627
import org.springframework.security.crypto.password.PasswordEncoder;
2728

@@ -43,7 +44,7 @@ public class BCryptPasswordEncoder implements PasswordEncoder {
4344

4445
private final BCryptVersion version;
4546

46-
private final SecureRandom random;
47+
private final @Nullable SecureRandom random;
4748

4849
public BCryptPasswordEncoder() {
4950
this(-1);
@@ -67,15 +68,15 @@ public BCryptPasswordEncoder(BCryptVersion version) {
6768
* @param version the version of bcrypt, can be 2a,2b,2y
6869
* @param random the secure random instance to use
6970
*/
70-
public BCryptPasswordEncoder(BCryptVersion version, SecureRandom random) {
71+
public BCryptPasswordEncoder(BCryptVersion version, @Nullable SecureRandom random) {
7172
this(version, -1, random);
7273
}
7374

7475
/**
7576
* @param strength the log rounds to use, between 4 and 31
7677
* @param random the secure random instance to use
7778
*/
78-
public BCryptPasswordEncoder(int strength, SecureRandom random) {
79+
public BCryptPasswordEncoder(int strength, @Nullable SecureRandom random) {
7980
this(BCryptVersion.$2A, strength, random);
8081
}
8182

@@ -92,7 +93,7 @@ public BCryptPasswordEncoder(BCryptVersion version, int strength) {
9293
* @param strength the log rounds to use, between 4 and 31
9394
* @param random the secure random instance to use
9495
*/
95-
public BCryptPasswordEncoder(BCryptVersion version, int strength, SecureRandom random) {
96+
public BCryptPasswordEncoder(BCryptVersion version, int strength, @Nullable SecureRandom random) {
9697
if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) {
9798
throw new IllegalArgumentException("Bad strength");
9899
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2002-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
@NullMarked
18+
package org.springframework.security.crypto.bcrypt;
19+
20+
import org.jspecify.annotations.NullMarked;

crypto/src/main/java/org/springframework/security/crypto/codec/Utf8.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.nio.charset.Charset;
2323
import java.nio.charset.StandardCharsets;
2424

25+
import org.jspecify.annotations.Nullable;
26+
2527
/**
2628
* UTF-8 Charset encoder/decoder.
2729
* <p>
@@ -39,7 +41,7 @@ private Utf8() {
3941
/**
4042
* Get the bytes of the String in UTF-8 encoded form.
4143
*/
42-
public static byte[] encode(CharSequence string) {
44+
public static byte[] encode(@Nullable CharSequence string) {
4345
try {
4446
ByteBuffer bytes = CHARSET.newEncoder().encode(CharBuffer.wrap(string));
4547
byte[] bytesCopy = new byte[bytes.limit()];

crypto/src/main/java/org/springframework/security/crypto/codec/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Internal codec classes. Only intended for use within the framework.
1919
*/
20+
@NullMarked
2021
package org.springframework.security.crypto.codec;
22+
23+
import org.jspecify.annotations.NullMarked;

crypto/src/main/java/org/springframework/security/crypto/encrypt/AesBytesEncryptor.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import javax.crypto.spec.PBEKeySpec;
2626
import javax.crypto.spec.SecretKeySpec;
2727

28+
import org.jspecify.annotations.Nullable;
29+
2830
import org.springframework.security.crypto.codec.Hex;
2931
import org.springframework.security.crypto.keygen.BytesKeyGenerator;
3032
import org.springframework.security.crypto.keygen.KeyGenerators;
@@ -81,7 +83,7 @@ public AesBytesEncryptor(String password, CharSequence salt) {
8183
* @param salt the hex-encoded salt value
8284
* @param ivGenerator the generator used to generate the initialization vector
8385
*/
84-
public AesBytesEncryptor(String password, CharSequence salt, BytesKeyGenerator ivGenerator) {
86+
public AesBytesEncryptor(String password, CharSequence salt, @Nullable BytesKeyGenerator ivGenerator) {
8587
this(password, salt, ivGenerator, CipherAlgorithm.CBC);
8688
}
8789

@@ -95,7 +97,8 @@ public AesBytesEncryptor(String password, CharSequence salt, BytesKeyGenerator i
9597
* @param ivGenerator the generator used to generate the initialization vector
9698
* @param alg the {@link CipherAlgorithm} to be used
9799
*/
98-
public AesBytesEncryptor(String password, CharSequence salt, BytesKeyGenerator ivGenerator, CipherAlgorithm alg) {
100+
public AesBytesEncryptor(String password, CharSequence salt, @Nullable BytesKeyGenerator ivGenerator,
101+
CipherAlgorithm alg) {
99102
this(CipherUtils.newSecretKey("PBKDF2WithHmacSHA1",
100103
new PBEKeySpec(password.toCharArray(), Hex.decode(salt), 1024, 256)), ivGenerator, alg);
101104
}
@@ -108,7 +111,7 @@ public AesBytesEncryptor(String password, CharSequence salt, BytesKeyGenerator i
108111
* {@link CipherAlgorithm}
109112
* @param alg the {@link CipherAlgorithm} to be used
110113
*/
111-
public AesBytesEncryptor(SecretKey secretKey, BytesKeyGenerator ivGenerator, CipherAlgorithm alg) {
114+
public AesBytesEncryptor(SecretKey secretKey, @Nullable BytesKeyGenerator ivGenerator, CipherAlgorithm alg) {
112115
this.secretKey = new SecretKeySpec(secretKey.getEncoded(), "AES");
113116
this.alg = alg;
114117
this.encryptor = alg.createCipher();

crypto/src/main/java/org/springframework/security/crypto/encrypt/CipherUtils.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import javax.crypto.spec.PBEKeySpec;
3333
import javax.crypto.spec.PBEParameterSpec;
3434

35+
import org.jspecify.annotations.Nullable;
36+
3537
/**
3638
* Static helper for working with the Cipher API.
3739
*
@@ -109,7 +111,8 @@ static void initCipher(Cipher cipher, int mode, SecretKey secretKey, byte[] salt
109111
/**
110112
* Initializes the Cipher for use.
111113
*/
112-
static void initCipher(Cipher cipher, int mode, SecretKey secretKey, AlgorithmParameterSpec parameterSpec) {
114+
static void initCipher(Cipher cipher, int mode, SecretKey secretKey,
115+
@Nullable AlgorithmParameterSpec parameterSpec) {
113116
try {
114117
if (parameterSpec != null) {
115118
cipher.init(mode, secretKey, parameterSpec);

crypto/src/main/java/org/springframework/security/crypto/encrypt/KeyStoreKeyFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.security.interfaces.RSAPrivateCrtKey;
2626
import java.security.spec.RSAPublicKeySpec;
2727

28+
import org.jspecify.annotations.Nullable;
29+
2830
import org.springframework.core.io.Resource;
2931
import org.springframework.util.StringUtils;
3032

@@ -39,7 +41,7 @@ public class KeyStoreKeyFactory {
3941

4042
private final char[] password;
4143

42-
private KeyStore store;
44+
private @Nullable KeyStore store;
4345

4446
private final Object lock = new Object();
4547

0 commit comments

Comments
 (0)