Skip to content

Commit 5b8edec

Browse files
authored
Merge pull request #2426 from kalaiyarasiganeshalingam/master
Add FIPS support
2 parents 9f7550d + 27bf20f commit 5b8edec

13 files changed

Lines changed: 213 additions & 64 deletions

File tree

modules/commons/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@
149149
<groupId>commons-pool</groupId>
150150
<artifactId>commons-pool</artifactId>
151151
</dependency>
152+
<dependency>
153+
<groupId>jaxen</groupId>
154+
<artifactId>jaxen</artifactId>
155+
</dependency>
152156
<dependency>
153157
<groupId>org.wso2.orbit.javax.activation</groupId>
154158
<artifactId>activation</artifactId>

modules/commons/src/main/java/org/apache/synapse/commons/crypto/CryptoUtil.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.synapse.commons.crypto;
1919

2020
import org.apache.axis2.AxisFault;
21+
import org.apache.commons.lang.StringUtils;
2122
import org.apache.commons.logging.Log;
2223
import org.apache.commons.logging.LogFactory;
2324
import org.wso2.securevault.CipherFactory;
@@ -43,6 +44,7 @@ public class CryptoUtil {
4344
private EncodeDecodeTypes inType = null;
4445
private EncodeDecodeTypes outType = null;
4546
private String algorithm = null;
47+
private static final String SECURITY_JCE_PROVIDER = "security.jce.provider";
4648

4749
/**
4850
* Public constructor
@@ -106,19 +108,7 @@ public void init(Properties secureVaultProperties) throws AxisFault {
106108
cipherInformation.setInType(null); //skipping decoding encoding in securevault
107109
cipherInformation.setOutType(null); //skipping decoding encoding in securevault
108110
if (provider != null && !provider.isEmpty()) {
109-
String providerClass;
110-
if (CryptoConstants.BOUNCY_CASTLE_PROVIDER.equals(provider)) {
111-
providerClass = "org.bouncycastle.jce.provider.BouncyCastleProvider";
112-
} else if (CryptoConstants.BOUNCY_CASTLE_FIPS_PROVIDER.equals(provider)) {
113-
providerClass = "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider";
114-
} else {
115-
throw new AxisFault("Unsupported JCE Provider: " + provider);
116-
}
117-
try {
118-
Security.addProvider((Provider) Class.forName(providerClass).getDeclaredConstructor().newInstance());
119-
} catch (Exception e) {
120-
throw new AxisFault("Error while initializing the JCE Provider: " + provider, e);
121-
}
111+
addProvider(provider);
122112
cipherInformation.setProvider(provider);
123113
//todo need to add other providers if there are any.
124114
}
@@ -148,4 +138,20 @@ public boolean isInitialized() {
148138
return isInitialized;
149139
}
150140

141+
private static void addProvider(String jceProvider) throws AxisFault {
142+
if (StringUtils.isEmpty(System.getProperty(SECURITY_JCE_PROVIDER))) {
143+
String providerClass;
144+
if (CryptoConstants.BOUNCY_CASTLE_FIPS_PROVIDER.equals(jceProvider)) {
145+
providerClass = "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider";
146+
} else {
147+
providerClass = "org.bouncycastle.jce.provider.BouncyCastleProvider";
148+
}
149+
try {
150+
Security.addProvider((Provider) Class.forName(providerClass).getDeclaredConstructor().newInstance());
151+
} catch (Exception e) {
152+
throw new AxisFault("Error while initializing the JCE provider: " + providerClass, e);
153+
}
154+
}
155+
}
156+
151157
}

modules/core/src/main/java/org/apache/synapse/message/store/impl/rabbitmq/RabbitMQStore.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ public class RabbitMQStore extends AbstractMessageStore {
8484
public static final String SSL_TRUSTSTORE_TYPE = "rabbitmq.connection.ssl.truststore.type";
8585
public static final String SSL_TRUSTSTORE_PASSWORD = "rabbitmq.connection.ssl.truststore.password";
8686
public static final String SSL_VERSION = "rabbitmq.connection.ssl.version";
87+
private static final String PKIX = "PKIX";
88+
private static final String JCE_PROVIDER = "security.jce.provider";
8789

8890
public static final String AMQ_PREFIX = "amq.";
8991

@@ -214,15 +216,14 @@ private void setSSL(boolean sslEnabled) {
214216
KeyStore ks = KeyStore.getInstance(keyStoreType);
215217
ks.load(new FileInputStream(keyStoreLocation), keyPassphrase);
216218

217-
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
219+
KeyManagerFactory kmf = KeyManagerFactory.getInstance(getKeyManagerType());
218220
kmf.init(ks, keyPassphrase);
219221

220222
char[] trustPassphrase = trustStorePassword.toCharArray();
221223
KeyStore tks = KeyStore.getInstance(trustStoreType);
222224
tks.load(new FileInputStream(trustStoreLocation), trustPassphrase);
223225

224-
TrustManagerFactory tmf = TrustManagerFactory
225-
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
226+
TrustManagerFactory tmf = TrustManagerFactory.getInstance(getTrustManagerType());
226227
tmf.init(tks);
227228

228229
SSLContext c = SSLContext.getInstance(sslVersion);
@@ -477,4 +478,20 @@ public MessageContext get(String messageId) {
477478
private String nameString() {
478479
return "Store [" + getName() + "]";
479480
}
481+
482+
private static String getTrustManagerType() {
483+
String provider = System.getProperty(JCE_PROVIDER);
484+
if (StringUtils.isNotEmpty(provider)) {
485+
return PKIX;
486+
}
487+
return TrustManagerFactory.getDefaultAlgorithm();
488+
}
489+
490+
private static String getKeyManagerType() {
491+
String provider = System.getProperty(JCE_PROVIDER);
492+
if (StringUtils.isNotEmpty(provider)) {
493+
return PKIX;
494+
}
495+
return KeyManagerFactory.getDefaultAlgorithm();
496+
}
480497
}

modules/core/src/main/java/org/apache/synapse/util/xpath/DecryptFunction.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.apache.synapse.util.xpath;
1717

18+
import org.apache.commons.lang.StringUtils;
1819
import org.apache.commons.logging.Log;
1920
import org.apache.commons.logging.LogFactory;
2021
import org.jaxen.Context;
@@ -44,7 +45,10 @@ public class DecryptFunction implements Function {
4445
private static final Log log = LogFactory.getLog(DecryptFunction.class);
4546
private static final String DEFAULT_ALGORITHM = "RSA";
4647
private static final String DEFAULT_KEYSTORE_TYPE = "JKS";
47-
private static Map<String, Cipher> cipherInstancesMap = new ConcurrentHashMap<>();
48+
private static final Map<String, Cipher> cipherInstancesMap = new ConcurrentHashMap<>();
49+
private static final String SECURITY_JCE_PROVIDER = "security.jce.provider";
50+
private static final String PRIMARY_KEY_STORE_TYPE_PROPERTY = "primary.key.type";
51+
public static final String BCFKS = "BCFKS";
4852

4953
@Override
5054
public Object call(Context context, List args) throws FunctionCallException {
@@ -62,7 +66,7 @@ public Object call(Context context, List args) throws FunctionCallException {
6266
String keyStore = StringFunction.evaluate(args.get(1), context.getNavigator());
6367
String keyStorePassword = StringFunction.evaluate(args.get(2), context.getNavigator());
6468
String keyStoreAlias = StringFunction.evaluate(args.get(3), context.getNavigator());
65-
return decrypt(encryptedText.getBytes(), keyStore, keyStorePassword, keyStoreAlias, DEFAULT_KEYSTORE_TYPE,
69+
return decrypt(encryptedText.getBytes(), keyStore, keyStorePassword, keyStoreAlias, getKeyType(),
6670
DEFAULT_ALGORITHM);
6771
}
6872
if (size == 5) {
@@ -132,4 +136,13 @@ private Cipher getCipherInstance(String algorithm) throws NoSuchPaddingException
132136
}
133137
return cipherInstance;
134138
}
139+
140+
private static String getKeyType() {
141+
String keyType = System.getProperty(PRIMARY_KEY_STORE_TYPE_PROPERTY);
142+
if (StringUtils.isNotEmpty(System.getProperty(SECURITY_JCE_PROVIDER))) {
143+
return StringUtils.isNotEmpty(keyType) ? keyType : BCFKS;
144+
} else {
145+
return StringUtils.isNotEmpty(keyType) ? keyType : DEFAULT_KEYSTORE_TYPE;
146+
}
147+
}
135148
}

modules/core/src/main/java/org/apache/synapse/util/xpath/EncryptFunction.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.apache.synapse.util.xpath;
1717

18+
import org.apache.commons.lang.StringUtils;
1819
import org.apache.commons.logging.Log;
1920
import org.apache.commons.logging.LogFactory;
2021
import org.jaxen.Context;
@@ -43,7 +44,10 @@ public class EncryptFunction implements Function {
4344
private static final Log log = LogFactory.getLog(EncryptFunction.class);
4445
private static final String DEFAULT_ALGORITHM = "RSA";
4546
private static final String DEFAULT_KEYSTORE_TYPE ="JKS";
46-
private static Map<String, Cipher> cipherInstancesMap = new ConcurrentHashMap<>();
47+
private static final Map<String, Cipher> cipherInstancesMap = new ConcurrentHashMap<>();
48+
private static final String SECURITY_JCE_PROVIDER = "security.jce.provider";
49+
private static final String PRIMARY_KEY_STORE_TYPE_PROPERTY = "primary.key.type";
50+
public static final String BCFKS = "BCFKS";
4751

4852
@Override
4953
public Object call(Context context, List args) throws FunctionCallException {
@@ -61,7 +65,7 @@ public Object call(Context context, List args) throws FunctionCallException {
6165
String keyStore = StringFunction.evaluate(args.get(1), context.getNavigator());
6266
String keyStorePassword = StringFunction.evaluate(args.get(2), context.getNavigator());
6367
String keyStoreAlias = StringFunction.evaluate(args.get(3), context.getNavigator());
64-
return encrypt(plainText.getBytes(), keyStore, keyStorePassword, keyStoreAlias, DEFAULT_KEYSTORE_TYPE,
68+
return encrypt(plainText.getBytes(), keyStore, keyStorePassword, keyStoreAlias, getKeyType(),
6569
DEFAULT_ALGORITHM);
6670
}
6771
if (size == 5) {
@@ -131,4 +135,13 @@ private Cipher getCipherInstance(String algorithm) throws NoSuchPaddingException
131135
}
132136
return cipherInstance;
133137
}
138+
139+
private static String getKeyType() {
140+
String keyType = System.getProperty(PRIMARY_KEY_STORE_TYPE_PROPERTY);
141+
if (StringUtils.isNotEmpty(System.getProperty(SECURITY_JCE_PROVIDER))) {
142+
return StringUtils.isNotEmpty(keyType) ? keyType : BCFKS;
143+
} else {
144+
return StringUtils.isNotEmpty(keyType) ? keyType : DEFAULT_KEYSTORE_TYPE;
145+
}
146+
}
134147
}

modules/extensions/src/main/java/org/apache/synapse/mediators/opa/OPAClient.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.apache.synapse.mediators.opa;
2020

2121
import org.apache.commons.httpclient.HttpStatus;
22+
import org.apache.commons.lang.StringUtils;
2223
import org.apache.commons.logging.Log;
2324
import org.apache.commons.logging.LogFactory;
2425
import org.apache.http.HttpEntity;
@@ -69,6 +70,10 @@ public class OPAClient {
6970
private int connectionTimeout = 30;
7071

7172
private CloseableHttpClient httpClient = null;
73+
private static final String PRIMARY_KEY_STORE_TYPE_PROPERTY = "primary.key.type";
74+
private static final String DEFAULT_KEYSTORE_TYPE ="JKS";
75+
private static final String SECURITY_JCE_PROVIDER = "security.jce.provider";
76+
public static final String BCFKS = "BCFKS";
7277

7378
public OPAClient(String url, Map<String, String> additionalParameters) throws OPASecurityException {
7479

@@ -191,7 +196,7 @@ private PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager
191196
String trustStoreLocation = System.getProperty(OPAConstants.TRUST_STORE_LOCATION_SYSTEM_PROPERTY);
192197
File trustStoreFile = new File(trustStoreLocation);
193198
try (InputStream localTrustStoreStream = new FileInputStream(trustStoreFile)) {
194-
KeyStore trustStore = KeyStore.getInstance("JKS");
199+
KeyStore trustStore = KeyStore.getInstance(getKeyType());
195200
trustStore.load(localTrustStoreStream, trustStorePassword);
196201
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(trustStore).build();
197202

@@ -251,4 +256,15 @@ public CloseableHttpClient createHttpClient(String url) throws OPASecurityExcept
251256

252257
return HttpClients.custom().setConnectionManager(pool).setDefaultRequestConfig(params).build();
253258
}
259+
260+
private static String getKeyType() {
261+
String keyType = System.getProperty(PRIMARY_KEY_STORE_TYPE_PROPERTY);
262+
if (StringUtils.isNotEmpty(keyType)) {
263+
return keyType;
264+
}
265+
if (System.getProperty(SECURITY_JCE_PROVIDER) != null) {
266+
return BCFKS;
267+
}
268+
return DEFAULT_KEYSTORE_TYPE;
269+
}
254270
}

modules/securevault/src/main/java/org/apache/synapse/securevault/definition/IdentityKeyStoreInformation.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.apache.synapse.securevault.definition;
2020

21+
import org.apache.commons.lang.StringUtils;
2122
import org.apache.synapse.securevault.secret.SecretInformation;
2223

2324
import javax.net.ssl.KeyManagerFactory;
@@ -30,6 +31,8 @@ public class IdentityKeyStoreInformation extends KeyStoreInformation {
3031

3132
/* Password for access private key*/
3233
private SecretInformation keyPasswordProvider;
34+
private static final String PKIX = "PKIX";
35+
private static final String JCE_PROVIDER = "security.jce.provider";
3336

3437
public void setKeyPasswordProvider(SecretInformation keyPasswordProvider) {
3538
this.keyPasswordProvider = keyPasswordProvider;
@@ -48,8 +51,7 @@ public KeyManagerFactory getIdentityKeyManagerFactoryInstance() {
4851
}
4952

5053
KeyStore keyStore = this.getIdentityKeyStore();
51-
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
52-
KeyManagerFactory.getDefaultAlgorithm());
54+
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(getManagerType());
5355
keyManagerFactory.init(keyStore, keyPasswordProvider.getResolvedSecret().toCharArray());
5456

5557
return keyManagerFactory;
@@ -72,4 +74,13 @@ public KeyStore getIdentityKeyStore() {
7274
public SecretInformation getKeyPasswordProvider() {
7375
return keyPasswordProvider;
7476
}
77+
78+
private static String getManagerType() {
79+
String provider = System.getProperty(JCE_PROVIDER);
80+
if (StringUtils.isNotEmpty(provider)) {
81+
return PKIX;
82+
} else {
83+
return KeyManagerFactory.getDefaultAlgorithm();
84+
}
85+
}
7586
}

modules/securevault/src/main/java/org/apache/synapse/securevault/definition/TrustKeyStoreInformation.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package org.apache.synapse.securevault.definition;
2020

21+
import org.apache.commons.lang.StringUtils;
22+
2123
import javax.net.ssl.TrustManagerFactory;
2224
import java.security.KeyStore;
2325

@@ -26,6 +28,9 @@
2628
*/
2729
public class TrustKeyStoreInformation extends KeyStoreInformation {
2830

31+
private static final String PKIX = "PKIX";
32+
private static final String JCE_PROVIDER = "security.jce.provider";
33+
2934
/**
3035
* Returns the TrustManagerFactory instance
3136
*
@@ -38,8 +43,7 @@ public TrustManagerFactory getTrustManagerFactoryInstance() {
3843
log.debug("Creating a TrustManagerFactory instance");
3944
}
4045
KeyStore trustStore = this.getTrustStore();
41-
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
42-
TrustManagerFactory.getDefaultAlgorithm());
46+
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(getManagerType());
4347
trustManagerFactory.init(trustStore);
4448

4549
return trustManagerFactory;
@@ -60,4 +64,11 @@ public KeyStore getTrustStore() {
6064

6165
}
6266

67+
private static String getManagerType() {
68+
String provider = System.getProperty(JCE_PROVIDER);
69+
if (StringUtils.isNotEmpty(provider)) {
70+
return PKIX;
71+
}
72+
return TrustManagerFactory.getDefaultAlgorithm();
73+
}
6374
}

modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/certificatevalidation/ocsp/OCSPVerifier.java

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.apache.synapse.transport.certificatevalidation.ocsp;
2020

21+
import org.apache.commons.lang.StringUtils;
2122
import org.apache.commons.logging.Log;
2223
import org.apache.commons.logging.LogFactory;
2324
import org.apache.http.HttpResponse;
@@ -27,6 +28,7 @@
2728
import org.apache.http.entity.ContentType;
2829
import org.apache.http.impl.client.CloseableHttpClient;
2930
import org.apache.http.impl.client.HttpClientBuilder;
31+
import org.apache.synapse.commons.crypto.CryptoConstants;
3032
import org.apache.synapse.transport.certificatevalidation.CertificateVerificationException;
3133
import org.apache.synapse.transport.certificatevalidation.Constants;
3234
import org.apache.synapse.transport.certificatevalidation.RevocationStatus;
@@ -79,7 +81,7 @@ public OCSPVerifier(OCSPCache cache) {
7981
public static final String ACCEPT_TYPE = "Accept";
8082
public static final String OCSP_REQUEST_TYPE = "application/ocsp-request";
8183
public static final String OCSP_RESPONSE_TYPE = "application/ocsp-response";
82-
84+
private static final String SECURITY_JCE_PROVIDER = "security.jce.provider";
8385

8486
/**
8587
* Gets the revocation status (Good, Revoked or Unknown) of the given peer certificate.
@@ -201,20 +203,7 @@ protected OCSPResp getOCSPResponce(String serviceUrl, OCSPReq request) throws Ce
201203
private OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber)
202204
throws CertificateVerificationException {
203205
String jceProvider = getPreferredJceProvider();
204-
String providerClass;
205-
if (jceProvider.equals(Constants.BOUNCY_CASTLE_PROVIDER)) {
206-
providerClass = "org.bouncycastle.jce.provider.BouncyCastleProvider";
207-
} else if (jceProvider.equals(Constants.BOUNCY_CASTLE_FIPS_PROVIDER)) {
208-
providerClass = "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider";
209-
} else {
210-
throw new CertificateVerificationException("Unsupported JCE provider: " + jceProvider);
211-
}
212-
try {
213-
Security.addProvider((Provider) Class.forName(providerClass).getDeclaredConstructor().newInstance());
214-
} catch (Exception e) {
215-
throw new CertificateVerificationException("Error while initializing the JCE provider: "
216-
+ providerClass, e);
217-
}
206+
addProvider(jceProvider);
218207

219208
try {
220209

@@ -299,4 +288,21 @@ private static String getPreferredJceProvider() {
299288
}
300289
return Constants.BOUNCY_CASTLE_PROVIDER;
301290
}
291+
292+
public static void addProvider(String jceProvider) throws CertificateVerificationException {
293+
if (StringUtils.isEmpty(System.getProperty(SECURITY_JCE_PROVIDER))) {
294+
String providerClass;
295+
if (CryptoConstants.BOUNCY_CASTLE_FIPS_PROVIDER.equals(jceProvider)) {
296+
providerClass = "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider";
297+
} else {
298+
providerClass = "org.bouncycastle.jce.provider.BouncyCastleProvider";
299+
}
300+
try {
301+
Security.addProvider((Provider) Class.forName(providerClass).getDeclaredConstructor().newInstance());
302+
} catch (Exception e) {
303+
throw new CertificateVerificationException("Error while initializing the JCE provider: " +
304+
providerClass, e);
305+
}
306+
}
307+
}
302308
}

0 commit comments

Comments
 (0)