Skip to content

Commit 3478296

Browse files
authored
SANTUARIO-606 - Avoid creating the SecureRandom in XMLSecurityConstants (#218)
during class initialization
1 parent fa63d6f commit 3478296

1 file changed

Lines changed: 27 additions & 12 deletions

File tree

src/main/java/org/apache/xml/security/stax/ext/XMLSecurityConstants.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
import jakarta.xml.bind.JAXBException;
2323
import jakarta.xml.bind.Unmarshaller;
2424

25+
import java.security.AccessController;
2526
import java.security.NoSuchAlgorithmException;
27+
import java.security.PrivilegedAction;
2628
import java.security.SecureRandom;
2729

2830
import javax.xml.datatype.DatatypeConfigurationException;
@@ -43,19 +45,13 @@ public class XMLSecurityConstants {
4345
public static final XMLOutputFactory xmlOutputFactory;
4446
public static final XMLOutputFactory xmlOutputFactoryNonRepairingNs;
4547

46-
private static final SecureRandom SECURE_RANDOM;
48+
private static volatile SecureRandom SECURE_RANDOM;
49+
private static final Object SECURE_RANDOM_LOCK = new Object();
4750
private static final String RANDOM_ALGORITHM_KEY = "org.apache.xml.security.securerandom.algorithm";
4851
private static JAXBContext jaxbContext;
4952
private static Schema schema;
5053

5154
static {
52-
try {
53-
String PrngAlgorithm = System.getProperty(RANDOM_ALGORITHM_KEY);
54-
SECURE_RANDOM = PrngAlgorithm != null ? SecureRandom.getInstance(PrngAlgorithm) : new SecureRandom();
55-
} catch (NoSuchAlgorithmException e) {
56-
throw new RuntimeException(e);
57-
}
58-
5955
try {
6056
datatypeFactory = DatatypeFactory.newInstance();
6157
} catch (DatatypeConfigurationException e) {
@@ -73,17 +69,36 @@ protected XMLSecurityConstants() {
7369
}
7470

7571
/**
76-
* Generate bytes of the given length using the supplied algorithm in RANDOM_ALGORITHM_KEY or,
77-
* if not specified, use SecureRandom instance from default constructor. The SecureRandom
72+
* Generate bytes of the given length using the algorithm supplied in {@value #RANDOM_ALGORITHM_KEY} or,
73+
* if not specified, use a {@code SecureRandom} instance from default constructor. The {@code SecureRandom}
7874
* instance that backs this method is cached for efficiency.
7975
*
80-
* @return a byte array of the given length
76+
* @return a new byte array of the given length
8177
* @throws XMLSecurityException
8278
*/
8379
public static byte[] generateBytes(int length) throws XMLSecurityException {
80+
81+
SecureRandom rnd = SECURE_RANDOM;
82+
if (rnd == null) {
83+
synchronized (SECURE_RANDOM_LOCK) {
84+
rnd = SECURE_RANDOM;
85+
if (rnd == null) {
86+
try {
87+
final String prngAlgorithm = AccessController.doPrivileged(
88+
(PrivilegedAction<String>) () -> System.getProperty(RANDOM_ALGORITHM_KEY));
89+
SECURE_RANDOM = rnd = prngAlgorithm != null
90+
? SecureRandom.getInstance(prngAlgorithm)
91+
: new SecureRandom();
92+
} catch (NoSuchAlgorithmException e) {
93+
throw new RuntimeException(e);
94+
}
95+
}
96+
}
97+
}
98+
8499
try {
85100
byte[] temp = new byte[length];
86-
SECURE_RANDOM.nextBytes(temp);
101+
rnd.nextBytes(temp);
87102
return temp;
88103
} catch (Exception ex) {
89104
throw new XMLSecurityException(ex);

0 commit comments

Comments
 (0)