Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor BouncyCastleProvider to BouncyCastleFipsProvider #2693

Merged
merged 1 commit into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ext {
// Versions shared between multiple dependencies
versions.aspectJVersion = "1.9.4"
versions.apacheDsVersion = "2.0.0.AM27"
versions.bouncyCastleVersion = "1.77"
versions.bouncyCastleVersion = "1.0.2.4"
versions.hamcrestVersion = "2.2"
versions.springBootVersion = "2.7.18"
versions.springFrameworkVersion = "5.3.31"
Expand Down Expand Up @@ -43,8 +43,8 @@ libraries.apacheDsProtocolLdap = "org.apache.directory.server:apacheds-protocol-
libraries.apacheLdapApi = "org.apache.directory.api:api-ldap-model:2.1.5"
libraries.aspectJRt = "org.aspectj:aspectjrt"
libraries.aspectJWeaver = "org.aspectj:aspectjweaver"
libraries.bouncyCastlePkix = "org.bouncycastle:bcpkix-jdk18on:${versions.bouncyCastleVersion}"
libraries.bouncyCastleProv = "org.bouncycastle:bcprov-jdk18on:${versions.bouncyCastleVersion}"
libraries.bouncyCastlePkix = "org.bouncycastle:bcpkix-fips:1.0.7"
libraries.bouncyCastleProv = "org.bouncycastle:bc-fips:${versions.bouncyCastleVersion}"
libraries.braveInstrumentationSpringWebmvc = "io.zipkin.brave:brave-instrumentation-spring-webmvc:${versions.braveVersion}"
libraries.braveContextSlf4j = "io.zipkin.brave:brave-context-slf4j:${versions.braveVersion}"
libraries.commonsIo = "commons-io:commons-io:2.15.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.cloudfoundry.identity.uaa.cypto;

import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.PasswordBasedDeriver;
import org.bouncycastle.crypto.PasswordConverter;
import org.bouncycastle.crypto.fips.FipsPBKD;
import org.bouncycastle.crypto.fips.FipsSHS;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.bouncycastle.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -12,8 +14,6 @@
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

public class EncryptionService {
Expand All @@ -40,7 +40,7 @@ public byte[] encrypt(String plaintext) throws EncryptionServiceException {

SecretKey key = new SecretKeySpec(generateKey(newSalt), CIPHER);

Cipher myCipher = Cipher.getInstance(CIPHERSCHEME);
Cipher myCipher = Cipher.getInstance(CIPHERSCHEME, BouncyCastleFipsProvider.PROVIDER_NAME);
byte[] newNonce = generateRandomArray(GCM_IV_NONCE_SIZE_BYTES);

GCMParameterSpec spec = new GCMParameterSpec(GCM_AUTHENTICATION_TAG_SIZE_BITS, newNonce);
Expand Down Expand Up @@ -84,9 +84,12 @@ private byte[] generateRandomArray(int sizeInBytes) {
}

private byte[] generateKey(byte[] salt) {
PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());

gen.init(this.passphrase.getBytes(StandardCharsets.UTF_8), salt, PBKDF2_ITERATIONS);
return ((KeyParameter) gen.generateDerivedParameters(AES_KEY_LENGTH_BITS)).getKey();
PasswordBasedDeriver<FipsPBKD.Parameters> gen = new FipsPBKD.DeriverFactory().createDeriver(
FipsPBKD.PBKDF2.using(FipsSHS.Algorithm.SHA256_HMAC,
PasswordConverter.UTF8.convert(this.passphrase.toCharArray()))
.withIterationCount(PBKDF2_ITERATIONS)
.withSalt(salt)
);
return gen.deriveKey(PasswordBasedDeriver.KeyType.CIPHER, (AES_KEY_LENGTH_BITS + 7) / 8);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.ECDSASigner;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.bc.BouncyCastleFIPSProviderSingleton;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.JWKParameterNames;
import com.nimbusds.jose.jwk.OctetSequenceKey;
Expand Down Expand Up @@ -81,6 +82,7 @@ public KeyInfo(String keyId, String signingKey, String keyUrl, String sigAlg, St
}
this.verifierCertificate = getValidX509Certificate(signingCert);
this.verifierKey = JsonWebKey.pemEncodePublicKey(keyPair.getPublic()).orElse(null);
this.signer.getJCAContext().setProvider(BouncyCastleFIPSProviderSingleton.getInstance());
} else {
jwk = new OctetSequenceKey.Builder(signingKey.getBytes()).build();
algorithm = Optional.ofNullable(sigAlg).orElse(JWSAlgorithm.HS256.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.KeyLengthException;
import com.nimbusds.jose.crypto.bc.BouncyCastleFIPSProviderSingleton;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
Expand Down Expand Up @@ -257,7 +258,7 @@ private JWTClaimsSet validateClientJWToken(JWT jwtAssertion, JWKSet jwkSet) {
ConfigurableJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
jwtProcessor.setJWSKeySelector(keySelector);
jwtProcessor.setJWTClaimsSetVerifier(new DefaultJWTClaimsVerifier<>(null, null));

jwtProcessor.getJWSVerifierFactory().getJCAContext().setProvider(BouncyCastleFIPSProviderSingleton.getInstance());
try {
return jwtProcessor.process(jwtAssertion, null);
} catch (BadJWSException | BadJWTException jwtException) { // signature failed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
Expand All @@ -20,6 +21,8 @@
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import static org.cloudfoundry.identity.uaa.oauth.jwt.JwtAlgorithms.DEFAULT_RSA;

public class KeyWithCert {
private X509Certificate certificate;
private PrivateKey privateKey;
Expand Down Expand Up @@ -53,16 +56,8 @@ public PrivateKey getPrivateKey() {
private boolean keysMatch(PublicKey publicKey, PrivateKey privateKey) {
byte[] data = {42};

String privateKeyAlgorithm = privateKey.getAlgorithm();
String publicKeyAlgorithm = publicKey.getAlgorithm();

if (privateKeyAlgorithm.equals("EC")) {
privateKeyAlgorithm = "ECDSA";
}

if (publicKeyAlgorithm.equals("EC")) {
publicKeyAlgorithm = "ECDSA";
}
String privateKeyAlgorithm = getJavaAlgorithm(privateKey.getAlgorithm());
String publicKeyAlgorithm = getJavaAlgorithm(publicKey.getAlgorithm());

try {
Signature sig = Signature.getInstance(privateKeyAlgorithm);
Expand All @@ -81,10 +76,19 @@ private boolean keysMatch(PublicKey publicKey, PrivateKey privateKey) {
}
}

private static String getJavaAlgorithm(String publicKeyAlgorithm) {
if ("EC".equals(publicKeyAlgorithm)) {
publicKeyAlgorithm = "ECDSA";
} else if ("RSA".equals(publicKeyAlgorithm)) {
publicKeyAlgorithm = DEFAULT_RSA;
}
return publicKeyAlgorithm;
}

private PrivateKey loadPrivateKey(String encodedPrivateKey, String passphrase) throws CertificateException {
PrivateKey privateKey = null;
try (PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(encodedPrivateKey.getBytes())))) {
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleFipsProvider.PROVIDER_NAME);

Object object = pemParser.readObject();

Expand Down Expand Up @@ -116,7 +120,7 @@ private X509Certificate loadCertificate(String encodedCertificate) throws Certif
try (PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(encodedCertificate.getBytes())))) {
Object object = pemParser.readObject();
if (object instanceof X509CertificateHolder) {
certificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate((X509CertificateHolder) object);
certificate = new JcaX509CertificateConverter().setProvider(BouncyCastleFipsProvider.PROVIDER_NAME).getCertificate((X509CertificateHolder) object);
} else {
throw new CertificateException("Unsupported certificate type, not an X509CertificateHolder.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@


public class SocketUtils {
private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;
private static final String BC = org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider.PROVIDER_NAME;

public static X509Certificate getSelfCertificate(KeyPair keyPair, String organisation, String orgUnit, String commonName, Date issueDate,
long validForSeconds,
String signatureAlgorithm)
throws CertificateException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, NoSuchProviderException {
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Security.addProvider(new org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider());

X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);
builder.addRDN(BCStyle.OU, orgUnit);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.cloudfoundry.identity.uaa.config;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.cloudfoundry.identity.uaa.annotations.WithDatabaseContext;
import org.cloudfoundry.identity.uaa.impl.config.IdentityZoneConfigurationBootstrap;
import org.cloudfoundry.identity.uaa.login.Prompt;
Expand Down Expand Up @@ -94,7 +94,7 @@ void configureProvisioning(@Autowired JdbcTemplate jdbcTemplate) throws SQLExcep
bootstrap.setValidator(validator);

//For the SamlTestUtils keys we are using.
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleFipsProvider());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
*******************************************************************************/
package org.cloudfoundry.identity.uaa.login;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;

import java.security.Security;

public class AddBcProvider {

static {
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleFipsProvider());
}

public static void noop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.cloudfoundry.identity.uaa.annotations.WithDatabaseContext;
import org.cloudfoundry.identity.uaa.cypto.EncryptionKeyService;
import org.cloudfoundry.identity.uaa.cypto.EncryptionServiceException;
Expand Down Expand Up @@ -54,6 +55,7 @@ class JdbcUserGoogleMfaCredentialsProvisioningTest {

@BeforeAll
static void key() {
Security.addProvider(new BouncyCastleFipsProvider());
Security.setProperty("crypto.policy", "unlimited");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public void setup() {
MockHttpServletRequest request = new MockHttpServletRequest();
ServletRequestAttributes attrs = new ServletRequestAttributes(request);
RequestContextHolder.setRequestAttributes(attrs);
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Security.addProvider(new org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider());

userAuthentication = mock(UaaAuthentication.class);
granter = new Saml2TokenGranter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/
package org.cloudfoundry.identity.uaa.provider.saml;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opensaml.DefaultBootstrap;
Expand All @@ -30,7 +30,7 @@ public class SamlConfigurationBeanTest {

@BeforeClass
public static void initVM() throws Exception {
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleFipsProvider());
DefaultBootstrap.bootstrap();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.cloudfoundry.identity.uaa.provider.saml;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.cloudfoundry.identity.uaa.saml.SamlKey;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.cloudfoundry.identity.uaa.zone.MultitenancyFixture;
Expand Down Expand Up @@ -169,7 +169,7 @@ public class SamlKeyManagerFactoryTests {
@BeforeAll
static void addBCProvider() {
try {
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleFipsProvider());
} catch (SecurityException e) {
e.printStackTrace();
System.err.println("Ignoring provider error, may already be added.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.cloudfoundry.identity.uaa.provider.saml;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.cloudfoundry.identity.uaa.provider.saml.idp.SamlTestUtils;
import org.cloudfoundry.identity.uaa.saml.SamlKey;
import org.cloudfoundry.identity.uaa.extensions.PollutionPreventionExtension;
Expand Down Expand Up @@ -49,7 +49,7 @@ public class ZoneAwareMetadataGeneratorTests {

@BeforeAll
static void bootstrap() throws Exception {
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleFipsProvider());
DefaultBootstrap.bootstrap();
NamedKeyInfoGeneratorManager keyInfoGeneratorManager = Configuration.getGlobalSecurityConfiguration().getKeyInfoGeneratorManager();
keyInfoGeneratorManager.getManager(SAMLConstants.SAML_METADATA_KEY_INFO_GENERATOR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
*******************************************************************************/
package org.cloudfoundry.identity.uaa.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.DecoderException;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.junit.BeforeClass;
import org.junit.Test;

Expand All @@ -26,7 +25,7 @@ public class KeyWithCertTest {

@BeforeClass
public static void addProvider() {
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleFipsProvider());
}

public static final String key = "-----BEGIN RSA PRIVATE KEY-----\n" +
Expand Down Expand Up @@ -183,7 +182,7 @@ public static void addProvider() {
"y9mayfAcKPti4MbPR6ADAo9NxKbdsZjA138=\n" +
"-----END PRIVATE KEY-----\n";

@Test(expected = DecoderException.class)
@Test(expected = CertificateException.class)
public void testInvalidCert() throws Exception {
new KeyWithCert(key, password, invalidCert);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*******************************************************************************/
package org.cloudfoundry.identity.uaa.zone;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.cloudfoundry.identity.uaa.saml.SamlKey;
import org.junit.After;
import org.junit.Before;
Expand Down Expand Up @@ -202,7 +202,7 @@ public GeneralIdentityZoneConfigurationValidatorTests(IdentityZoneValidator.Mode
@BeforeClass
public static void addBCProvider() {
try {
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleFipsProvider());
} catch (SecurityException e) {
e.printStackTrace();
System.err.println("Ignoring provider error, may already be added.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<property name="targetClass" value="java.security.Security"/>
<property name="targetMethod" value="addProvider"/>
<property name="arguments">
<bean class="org.bouncycastle.jce.provider.BouncyCastleProvider"/>
<bean class="org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider"/>
</property>
</bean>

Expand Down
Loading