Skip to content

Commit

Permalink
[improve][security] Add load multiple certificates support in TrustMa…
Browse files Browse the repository at this point in the history
…nagerProxy (apache#14798)

Signed-off-by: Zixuan Liu <[email protected]>
  • Loading branch information
nodece authored Jul 13, 2022
1 parent 9c75904 commit 35037cd
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,13 @@
package org.apache.pulsar.common.util;

import io.netty.handler.ssl.SslContext;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
Expand All @@ -45,13 +42,13 @@
public class TrustManagerProxy extends X509ExtendedTrustManager {

private volatile X509ExtendedTrustManager trustManager;
private FileModifiedTimeUpdater certFile;
private final FileModifiedTimeUpdater certFile;

public TrustManagerProxy(String caCertFile, int refreshDurationSec, ScheduledExecutorService executor) {
this.certFile = new FileModifiedTimeUpdater(caCertFile);
try {
updateTrustManager();
} catch (IOException | CertificateException e) {
} catch (KeyManagementException | IOException | CertificateException e) {
log.warn("Failed to load cert {}, {}", certFile, e.getMessage());
throw new IllegalArgumentException(e);
} catch (NoSuchAlgorithmException | KeyStoreException e) {
Expand All @@ -71,19 +68,18 @@ private void updateTrustManagerSafely() {
}

private void updateTrustManager() throws CertificateException, KeyStoreException, NoSuchAlgorithmException,
FileNotFoundException, IOException {
CertificateFactory factory = CertificateFactory.getInstance("X.509");
try (InputStream inputStream = new FileInputStream(certFile.getFileName())) {
X509Certificate certificate = (X509Certificate) factory.generateCertificate(inputStream);
IOException, KeyManagementException {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
X509Certificate[] certificates = SecurityUtility.loadCertificatesFromPemFile(certFile.getFileName());
for (X509Certificate certificate : certificates) {
String alias = certificate.getSubjectX500Principal().getName();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null);
keyStore.setCertificateEntry(alias, certificate);
final TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
trustManager = (X509ExtendedTrustManager) trustManagerFactory.getTrustManagers()[0];
}
final TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
trustManager = (X509ExtendedTrustManager) trustManagerFactory.getTrustManagers()[0];
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.pulsar.common.util;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import com.google.common.io.Resources;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TrustManagerProxyTest {
@DataProvider(name = "caDataProvider")
public static Object[][] caDataProvider() {
return new Object[][]{
{"ca/multiple-ca.pem", 2},
{"ca/single-ca.pem", 1}
};
}

@Test(dataProvider = "caDataProvider")
public void testLoadCA(String path, int count) {
String caPath = Resources.getResource(path).getPath();

ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
try {
TrustManagerProxy trustManagerProxy =
new TrustManagerProxy(caPath, 120, scheduledExecutor);
X509Certificate[] x509Certificates = trustManagerProxy.getAcceptedIssuers();
assertNotNull(x509Certificates);
assertEquals(Arrays.stream(x509Certificates).count(), count);
} finally {
scheduledExecutor.shutdown();
}
}
}
36 changes: 36 additions & 0 deletions pulsar-common/src/test/resources/ca/multiple-ca.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIC8jCCAdqgAwIBAgIUPnoDe05/dkrbpa2vpmnp45e6/4UwDQYJKoZIhvcNAQEL
BQAwEDEOMAwGA1UEAxMFdGVzdDEwIBcNMjIwMzIyMDkxOTAwWhgPMjEyMjAzMjQw
OTE5MDBaMBAxDjAMBgNVBAMTBXRlc3QxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAvbd4hZAwrgShqrA6g7QKyXQw/4TvskSBT411XCu9+ZIvG4tEafUJ
CjuHv6AEAt8XN9DSNzVB64q/cOczskaOMa/MQd6Qe+peAiqUsFyu6vucQyCWOLz6
iuvjPyhuIL5ZYbh17CtXNZOn50BYzq95K4vcAvNUxq/HAGnAm2HegSujq4IMaVpU
gBE3OinUf6patbGqDDuPRUy/gw3I/+xkQcP9RxZqmbsvc6tw6ZpejBdCunCF9hxH
p1V70AqNlxUo7H2w7O7gSDU17gzq8kYoyyiJSLS4Wh1nDscpCQykcxYtS+Agb4VZ
GOYxWMyIBvhRHXLfPVSaYRKw5t5cVy4GjQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULlE62PqE/wu4x4BmUmnE5Xfw
8rowDQYJKoZIhvcNAQELBQADggEBAEVd7o4Gdm9jpsIFuq8879q3XTmdVvLFL5/6
g/AddloVeyznd6J1vP4n/4fcIskJ084SD1g8FXG21hOb4vQR06E1qWYhxgJJs7fz
kY3nInbmEWba4Sg7dHXL1KnKOCkhq25UlFF2sMI5BSyKwwAi1R7PKdbTFXZuwFL+
bKJIvegh+jawlFi1LbSjYYRTy4GgSE8f8/T0xVjqNjdxBnExEkV/dklUJgxck1b1
K7fRAeoB65tpO/jvYeoQGu1kJkUNmbJu8k1TbBJQm9AxR6OaE+ZKFCf3U5wqH3Ff
hvrO1utY5yvTUnZ2EMTBytH5cGQ+8zW9tm00AB8eimCb4360l/8=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIC+jCCAeKgAwIBAgIUEyTKRqhwRp7VqaWPm50zo+CWrt0wDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAxMJbG9jYWxob3N0MCAXDTIyMDMyMTA5NTkwMFoYDzIxMjIw
MzIzMDk1OTAwWjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDrVbbVOJwhdFzi5hueWKwqHQ8OKtWup8lsOIQXbpc0
T3/FPclF7Qo481SFBUH9Kg+kXJvxYS/sy/9VnoCq/UaUpaOZ6DQTM09bS9b1LOLM
EjXv9sMJ82ipQiwG/MOCGtuDHV++Hmf1lMej0pULL6WpBUhbIYWauiUWLlgLzc1u
v4JZcO/AuBl+tli49Af1ODGWQ4kJYESv27IDU0Jv+/HyE4fmm82vJEqAwjnjxmek
vsFpBvVK6dPUpTJ4hmG4pRrs4MzyxWBGi4PlWhka0LoT8pJ7gcykABToj3gt4Dmz
vVS1LoPq5ph5XgqE+8OHlIMaYIrG6fSxzFXQTyzp27pNAgMBAAGjQjBAMA4GA1Ud
DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR26y6V2jSvt5Dh
n2yaI0YW/nK2aTANBgkqhkiG9w0BAQsFAAOCAQEAxThI6kyDeKajNcnYP6urFO/d
7j/Yvhm1m/xsbg3Ou0iwJqygiJ+IC+jsVzA/tZE1TSX/Yn2KkGdc6vtZVTqESkSi
Gjxp36M1mhLKr/s4pspzSB+8pIOnhOBO2hcZ31DuWASv4AGpIT6XnuoK0KWaJvo8
Dwbv1D89m5E2WickT4G/QLtbd05Ens/5BrrWW9Lt3f1IxffRWuTBdM7D7a/fF3zF
PpMWCAwmDeDwB9fbyBMtXo+Hd+R1YoeO5X5f0F4HO6VcVo+AkUNxs7FETYAiAQXn
yUYS/bCWHY6eeb67siCLtt4FprkYHt4SQHwKU1V4YmoEE7O/YN9IBEEvKVJZSg==
-----END CERTIFICATE-----
19 changes: 19 additions & 0 deletions pulsar-common/src/test/resources/ca/single-ca.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIC8jCCAdqgAwIBAgIUPnoDe05/dkrbpa2vpmnp45e6/4UwDQYJKoZIhvcNAQEL
BQAwEDEOMAwGA1UEAxMFdGVzdDEwIBcNMjIwMzIyMDkxOTAwWhgPMjEyMjAzMjQw
OTE5MDBaMBAxDjAMBgNVBAMTBXRlc3QxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAvbd4hZAwrgShqrA6g7QKyXQw/4TvskSBT411XCu9+ZIvG4tEafUJ
CjuHv6AEAt8XN9DSNzVB64q/cOczskaOMa/MQd6Qe+peAiqUsFyu6vucQyCWOLz6
iuvjPyhuIL5ZYbh17CtXNZOn50BYzq95K4vcAvNUxq/HAGnAm2HegSujq4IMaVpU
gBE3OinUf6patbGqDDuPRUy/gw3I/+xkQcP9RxZqmbsvc6tw6ZpejBdCunCF9hxH
p1V70AqNlxUo7H2w7O7gSDU17gzq8kYoyyiJSLS4Wh1nDscpCQykcxYtS+Agb4VZ
GOYxWMyIBvhRHXLfPVSaYRKw5t5cVy4GjQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULlE62PqE/wu4x4BmUmnE5Xfw
8rowDQYJKoZIhvcNAQELBQADggEBAEVd7o4Gdm9jpsIFuq8879q3XTmdVvLFL5/6
g/AddloVeyznd6J1vP4n/4fcIskJ084SD1g8FXG21hOb4vQR06E1qWYhxgJJs7fz
kY3nInbmEWba4Sg7dHXL1KnKOCkhq25UlFF2sMI5BSyKwwAi1R7PKdbTFXZuwFL+
bKJIvegh+jawlFi1LbSjYYRTy4GgSE8f8/T0xVjqNjdxBnExEkV/dklUJgxck1b1
K7fRAeoB65tpO/jvYeoQGu1kJkUNmbJu8k1TbBJQm9AxR6OaE+ZKFCf3U5wqH3Ff
hvrO1utY5yvTUnZ2EMTBytH5cGQ+8zW9tm00AB8eimCb4360l/8=
-----END CERTIFICATE-----

0 comments on commit 35037cd

Please sign in to comment.