mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-19 18:18:05 +01:00
Allow HTTP clients to trust multiple certificates to support certificate rollover
This commit is contained in:
committed by
Jon Chambers
parent
a41d047f58
commit
0120a85c39
@@ -13,6 +13,7 @@ import javax.validation.constraints.NotNull;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import java.util.List;
|
||||
|
||||
public class SecureBackupServiceConfiguration {
|
||||
|
||||
@@ -24,9 +25,9 @@ public class SecureBackupServiceConfiguration {
|
||||
@JsonProperty
|
||||
private String uri;
|
||||
|
||||
@NotBlank
|
||||
@NotEmpty
|
||||
@JsonProperty
|
||||
private String backupCaCertificate;
|
||||
private List<@NotBlank String> backupCaCertificates;
|
||||
|
||||
@NotNull
|
||||
@Valid
|
||||
@@ -52,12 +53,12 @@ public class SecureBackupServiceConfiguration {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setBackupCaCertificate(final String backupCaCertificate) {
|
||||
this.backupCaCertificate = backupCaCertificate;
|
||||
public void setBackupCaCertificates(final List<String> backupCaCertificates) {
|
||||
this.backupCaCertificates = backupCaCertificates;
|
||||
}
|
||||
|
||||
public String getBackupCaCertificate() {
|
||||
return backupCaCertificate;
|
||||
public List<String> getBackupCaCertificates() {
|
||||
return backupCaCertificates;
|
||||
}
|
||||
|
||||
public CircuitBreakerConfiguration getCircuitBreakerConfiguration() {
|
||||
|
||||
@@ -13,6 +13,7 @@ import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import java.util.List;
|
||||
|
||||
public class SecureStorageServiceConfiguration {
|
||||
|
||||
@@ -24,9 +25,9 @@ public class SecureStorageServiceConfiguration {
|
||||
@JsonProperty
|
||||
private String uri;
|
||||
|
||||
@NotBlank
|
||||
@NotEmpty
|
||||
@JsonProperty
|
||||
private String storageCaCertificate;
|
||||
private List<@NotBlank String> storageCaCertificates;
|
||||
|
||||
@NotNull
|
||||
@Valid
|
||||
@@ -52,12 +53,12 @@ public class SecureStorageServiceConfiguration {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setStorageCaCertificate(final String certificatePem) {
|
||||
this.storageCaCertificate = certificatePem;
|
||||
public void setStorageCaCertificates(final List<String> certificatePem) {
|
||||
this.storageCaCertificates = certificatePem;
|
||||
}
|
||||
|
||||
public String getStorageCaCertificate() {
|
||||
return storageCaCertificate;
|
||||
public List<String> getStorageCaCertificates() {
|
||||
return storageCaCertificates;
|
||||
}
|
||||
|
||||
public CircuitBreakerConfiguration getCircuitBreakerConfiguration() {
|
||||
|
||||
@@ -135,7 +135,7 @@ public class FaultTolerantHttpClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withTrustedServerCertificate(final String certificatePem) throws CertificateException {
|
||||
public Builder withTrustedServerCertificates(final String... certificatePem) throws CertificateException {
|
||||
this.trustStore = CertificateUtil.buildKeyStoreForPem(certificatePem);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SecureBackupClient {
|
||||
.withExecutor(executor)
|
||||
.withName("secure-backup")
|
||||
.withSecurityProtocol(FaultTolerantHttpClient.SECURITY_PROTOCOL_TLS_1_2)
|
||||
.withTrustedServerCertificate(configuration.getBackupCaCertificate())
|
||||
.withTrustedServerCertificates(configuration.getBackupCaCertificates().toArray(new String[0]))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class SecureStorageClient {
|
||||
.withExecutor(executor)
|
||||
.withName("secure-storage")
|
||||
.withSecurityProtocol(FaultTolerantHttpClient.SECURITY_PROTOCOL_TLS_1_3)
|
||||
.withTrustedServerCertificate(configuration.getStorageCaCertificate())
|
||||
.withTrustedServerCertificates(configuration.getStorageCaCertificates().toArray(new String[0]))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,33 +15,37 @@ import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
public class CertificateUtil {
|
||||
public static KeyStore buildKeyStoreForPem(final String caCertificatePem) throws CertificateException
|
||||
{
|
||||
try {
|
||||
X509Certificate certificate = getCertificate(caCertificatePem);
|
||||
|
||||
if (certificate == null) {
|
||||
throw new CertificateException("No certificate found in parsing!");
|
||||
}
|
||||
public static KeyStore buildKeyStoreForPem(final String... caCertificatePems) throws CertificateException {
|
||||
try {
|
||||
final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null);
|
||||
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null);
|
||||
keyStore.setCertificateEntry("ca", certificate);
|
||||
return keyStore;
|
||||
} catch (IOException | KeyStoreException ex) {
|
||||
throw new CertificateException(ex);
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
throw new AssertionError(ex);
|
||||
for (int i = 0; i < caCertificatePems.length; i++) {
|
||||
final X509Certificate certificate = getCertificate(caCertificatePems[i]);
|
||||
|
||||
if (certificate == null) {
|
||||
throw new CertificateException("No certificate found in parsing!");
|
||||
}
|
||||
}
|
||||
|
||||
public static X509Certificate getCertificate(final String certificatePem) throws CertificateException {
|
||||
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
keyStore.setCertificateEntry("ca-" + i, certificate);
|
||||
}
|
||||
|
||||
try (final ByteArrayInputStream pemInputStream = new ByteArrayInputStream(certificatePem.getBytes())) {
|
||||
return (X509Certificate) certificateFactory.generateCertificate(pemInputStream);
|
||||
} catch (IOException e) {
|
||||
throw new CertificateException(e);
|
||||
}
|
||||
return keyStore;
|
||||
} catch (IOException | KeyStoreException ex) {
|
||||
throw new CertificateException(ex);
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
throw new AssertionError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static X509Certificate getCertificate(final String certificatePem) throws CertificateException {
|
||||
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
|
||||
try (final ByteArrayInputStream pemInputStream = new ByteArrayInputStream(certificatePem.getBytes())) {
|
||||
return (X509Certificate) certificateFactory.generateCertificate(pemInputStream);
|
||||
} catch (IOException e) {
|
||||
throw new CertificateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user