Skip to content

Commit

Permalink
revert: "feat: add a new API for getting the cert chain using securit…
Browse files Browse the repository at this point in the history
…y service (#1260)" (#1324)

This reverts commit c4cfe2b.
  • Loading branch information
jbutler authored Sep 28, 2022
1 parent 7cc4e68 commit dcf97bc
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 153 deletions.
49 changes: 3 additions & 46 deletions src/main/java/com/aws/greengrass/security/SecurityService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.aws.greengrass.deployment.DeviceConfiguration;
import com.aws.greengrass.logging.api.Logger;
import com.aws.greengrass.logging.impl.LogManager;
import com.aws.greengrass.security.exceptions.CertificateChainLoadingException;
import com.aws.greengrass.security.exceptions.KeyLoadingException;
import com.aws.greengrass.security.exceptions.MqttConnectionProviderException;
import com.aws.greengrass.security.exceptions.ServiceProviderConflictException;
Expand Down Expand Up @@ -43,14 +42,12 @@
import javax.inject.Inject;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.X509KeyManager;

public final class SecurityService {
private static final Logger logger = LogManager.getLogger(SecurityService.class);
private static final String KEY_TYPE = "keyType";
private static final String KEY_URI = "keyUri";
private static final String CERT_URI = "certificateUri";
private static final String KEY_ALIAS = "private-key";

// retry 3 times with exponential backoff, start with 200ms,
// if service still not available, pop exception to the caller
Expand Down Expand Up @@ -152,11 +149,11 @@ public void deregisterMqttConnectionProvider(MqttConnectionSpi mqttProvider) {
/**
* Get JSSE KeyManagers, used for https TLS handshake.
*
* @param privateKeyUri private key URI
* @param privateKeyUri private key URI
* @param certificateUri certificate URI
* @return KeyManagers that manage the specified private key
* @throws ServiceUnavailableException if crypto key provider service is unavailable
* @throws KeyLoadingException if crypto key provider service fails to load key
* @throws KeyLoadingException if crypto key provider service fails to load key
*/
public KeyManager[] getKeyManagers(URI privateKeyUri, URI certificateUri)
throws ServiceUnavailableException, KeyLoadingException {
Expand All @@ -166,46 +163,6 @@ public KeyManager[] getKeyManagers(URI privateKeyUri, URI certificateUri)
return provider.getKeyManagers(privateKeyUri, certificateUri);
}

/**
* Get certificate chain using private and certificate URIs.
*
* @param privateKeyUri private key URI
* @param certificateUri certificate URI
* @return X509Certificate list that corresponds to the given private key and certificate URIs
* @throws ServiceUnavailableException if crypto key provider service is unavailable
* @throws KeyLoadingException if crypto key provider service fails to load key
* @throws CertificateChainLoadingException if no certificate chain is found
*/
public X509Certificate[] getCertificateChain(URI privateKeyUri, URI certificateUri)
throws CertificateChainLoadingException, ServiceUnavailableException, KeyLoadingException {
logger.atTrace().kv(KEY_URI, privateKeyUri).kv(CERT_URI, certificateUri)
.log("Getting the certificate chain using private key and certificate URIs");
CryptoKeySpi provider = selectCryptoKeyProvider(privateKeyUri);
KeyManager[] km = provider.getKeyManagers(privateKeyUri, certificateUri);

if (km.length != 1 || !(km[0] instanceof X509KeyManager)) {
throw new CertificateChainLoadingException("Unable to find the X509 key manager instance to get the "
+ "certificate chain using the private key and certificate URIs");
}

X509KeyManager x509KeyManager = (X509KeyManager) km[0];
KeyPair keyPair = provider.getKeyPair(privateKeyUri, certificateUri);
String[] aliases = x509KeyManager.getClientAliases(keyPair.getPublic().getAlgorithm(), null);
if (aliases == null) {
throw new CertificateChainLoadingException("Unable to find aliases in the key manager with the given "
+ "private key and certificate URIs");
}
for (String alias : aliases) {
if (x509KeyManager.getPrivateKey(alias).equals(keyPair.getPrivate())) {
return x509KeyManager.getCertificateChain(alias);
}
}

throw new CertificateChainLoadingException("Unable to get the certificate chain using the private key and "
+ "certificate URIs");
}


/**
* Get JCA KeyPair, used for Secret manager.
*
Expand Down Expand Up @@ -355,7 +312,7 @@ public KeyManager[] getKeyManagers(URI privateKeyUri, URI certificateUri)

KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null);
keyStore.setKeyEntry(KEY_ALIAS, privateKey, null, certificateChain.toArray(new Certificate[0]));
keyStore.setKeyEntry("private-key", privateKey, null, certificateChain.toArray(new Certificate[0]));

KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
Expand Down

This file was deleted.

91 changes: 4 additions & 87 deletions src/test/java/com/aws/greengrass/security/SecurityServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import com.aws.greengrass.config.CaseInsensitiveString;
import com.aws.greengrass.config.Topic;
import com.aws.greengrass.deployment.DeviceConfiguration;
import com.aws.greengrass.security.exceptions.*;
import com.aws.greengrass.security.exceptions.KeyLoadingException;
import com.aws.greengrass.security.exceptions.MqttConnectionProviderException;
import com.aws.greengrass.security.exceptions.ServiceProviderConflictException;
import com.aws.greengrass.security.exceptions.ServiceUnavailableException;
import com.aws.greengrass.testcommons.testutilities.GGExtension;
import com.aws.greengrass.util.EncryptionUtilsTest;
import org.hamcrest.collection.IsMapContaining;
Expand All @@ -26,10 +29,6 @@

import java.net.URI;
import java.nio.file.Path;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.X509KeyManager;

Expand All @@ -38,9 +37,7 @@
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -348,84 +345,4 @@ void GIVEN_key_and_cert_uri_WHEN_get_mqtt_builder_from_default_THEN_succeed() th
assertThat(builder, IsNull.notNullValue());
}
}

@Test
void GIVEN_key_and_cert_uri_WHEN_get_cert_chain_THEN_return_cert_chain()
throws Exception {
URI keyUri = new URI("pkcs11:object=key-label");
URI certificateUri = new URI("file:///path/to/certificate");
KeyManager[] mockKeyManagers = {mock(X509KeyManager.class)};
X509KeyManager x509KeyManager = (X509KeyManager) mockKeyManagers[0];
KeyPair mockKeyPair = mock(KeyPair.class);
String[] aliases = {"test"};
PrivateKey mockPrivateKey = mock(PrivateKey.class);
X509Certificate[] x509Certificates = new X509Certificate[1];
when(mockKeyProvider.getKeyManagers(keyUri, certificateUri)).thenReturn(mockKeyManagers);
when(mockKeyProvider.getKeyPair(keyUri, certificateUri)).thenReturn(mockKeyPair);
when(mockKeyPair.getPublic()).thenReturn(mock(PublicKey.class));
when(mockKeyPair.getPrivate()).thenReturn(mockPrivateKey);
when(mockKeyProvider.supportedKeyType()).thenReturn("PKCS11");
when(x509KeyManager.getClientAliases(any(), any())).thenReturn(aliases);
when(x509KeyManager.getPrivateKey(aliases[0])).thenReturn(mockPrivateKey);
when(x509KeyManager.getCertificateChain("test")).thenReturn(x509Certificates);

service.registerCryptoKeyProvider(mockKeyProvider);
X509Certificate[] certs = service.getCertificateChain(keyUri, certificateUri);
assertEquals(certs, x509Certificates);
}

@Test
void GIVEN_key_and_cert_uri_WHEN_getCertificateChain_multipleKeyManagers_THEN_throw_exception()
throws Exception {
URI keyUri = new URI("pkcs11:object=key-label");
URI certificateUri = new URI("file:///path/to/certificate");
KeyManager[] mockKeyManagers = {mock(X509KeyManager.class), mock(X509KeyManager.class)};
when(mockKeyProvider.getKeyManagers(keyUri, certificateUri)).thenReturn(mockKeyManagers);
when(mockKeyProvider.supportedKeyType()).thenReturn("PKCS11");
service.registerCryptoKeyProvider(mockKeyProvider);
assertThrows(CertificateChainLoadingException.class, ()->{
service.getCertificateChain(keyUri, certificateUri);
});
}

@Test
void GIVEN_key_and_cert_uri_WHEN_getCertificateChain_noMatchingAlias_THEN_throw_exception()
throws Exception {
URI keyUri = new URI("pkcs11:object=key-label");
URI certificateUri = new URI("file:///path/to/certificate");
KeyManager[] mockKeyManagers = {mock(X509KeyManager.class)};
X509KeyManager x509KeyManager = (X509KeyManager) mockKeyManagers[0];
KeyPair mockKeyPair = mock(KeyPair.class);
String[] aliases = {"test"};
when(mockKeyProvider.supportedKeyType()).thenReturn("PKCS11");
when(mockKeyProvider.getKeyManagers(keyUri, certificateUri)).thenReturn(mockKeyManagers);
when(mockKeyProvider.getKeyPair(keyUri, certificateUri)).thenReturn(mockKeyPair);
when(mockKeyPair.getPublic()).thenReturn(mock(PublicKey.class));
when(mockKeyPair.getPrivate()).thenReturn(mock(PrivateKey.class));
when(x509KeyManager.getPrivateKey(aliases[0])).thenReturn(mock(PrivateKey.class));
when(x509KeyManager.getClientAliases(any(), any())).thenReturn(aliases);

service.registerCryptoKeyProvider(mockKeyProvider);
assertThrows(CertificateChainLoadingException.class, ()->{
service.getCertificateChain(keyUri, certificateUri);
});
}

@Test
void GIVEN_key_and_cert_uri_WHEN_getCertificateChain_noAliases_THEN_throw_exception()
throws Exception {
URI keyUri = new URI("pkcs11:object=key-label");
URI certificateUri = new URI("file:///path/to/certificate");
KeyManager[] mockKeyManagers = {mock(X509KeyManager.class)};
KeyPair mockKeyPair = mock(KeyPair.class);
when(mockKeyProvider.getKeyManagers(keyUri, certificateUri)).thenReturn(mockKeyManagers);
when(mockKeyProvider.getKeyPair(keyUri, certificateUri)).thenReturn(mockKeyPair);
when(mockKeyProvider.supportedKeyType()).thenReturn("PKCS11");
when(mockKeyPair.getPublic()).thenReturn(mock(PublicKey.class));
when(((X509KeyManager) mockKeyManagers[0]).getClientAliases(any(), any())).thenReturn(null);
service.registerCryptoKeyProvider(mockKeyProvider);
assertThrows(CertificateChainLoadingException.class, ()->{
service.getCertificateChain(keyUri, certificateUri);
});
}
}

0 comments on commit dcf97bc

Please sign in to comment.