-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Method for extracting the added alias (#11503)
The approach used is very simple, the content of the alias is extracted and a new object representing a keystore is created only with that alias, this way it is possible to load only the desired alias and no more errors occur when we have multiple aliases in the keystore each with a password Related issue #11430
- Loading branch information
1 parent
5fdb596
commit 93b612e
Showing
4 changed files
with
169 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
http-netty/src/test/groovy/io/micronaut/http/netty/NettyTlsUtilsSpec.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package io.micronaut.http.netty | ||
|
||
import io.micronaut.http.ssl.SslConfiguration | ||
import spock.lang.Specification | ||
|
||
import javax.net.ssl.KeyManagerFactory | ||
import javax.net.ssl.X509KeyManager | ||
import java.security.KeyStore | ||
import java.security.cert.Certificate | ||
|
||
class NettyTlsUtilsSpec extends Specification { | ||
def "storeToFactory should return a KeyManagerFactory with only the selected alias"() { | ||
given: | ||
|
||
SslConfiguration sslConfig = Mock(SslConfiguration); | ||
SslConfiguration.KeyConfiguration keyConfiguration = Mock(SslConfiguration.KeyConfiguration); | ||
SslConfiguration.KeyStoreConfiguration keyStoreConfiguration = Mock(SslConfiguration.KeyStoreConfiguration); | ||
sslConfig.isPreferOpenssl() >> false | ||
sslConfig.getKey() >> keyConfiguration | ||
sslConfig.getKeyStore() >> keyStoreConfiguration | ||
keyConfiguration.getAlias() >> Optional.of("alias2") | ||
keyConfiguration.getPassword() >> Optional.of("passwordAlias2") | ||
|
||
String keystorePath = "src/test/resources/keystoreWithMultipleAlias.jks"; | ||
char[] keystorePassword = "password".toCharArray(); | ||
|
||
KeyStore rootKeyStore = KeyStore.getInstance("JKS"); | ||
try (FileInputStream fis = new FileInputStream(keystorePath)) { | ||
rootKeyStore.load(fis, keystorePassword); | ||
} | ||
|
||
when: | ||
KeyManagerFactory resultKeyStore = NettyTlsUtils.storeToFactory(sslConfig, rootKeyStore) | ||
|
||
then: | ||
resultKeyStore.getKeyManagers().size() == 1 | ||
def manager = (X509KeyManager) resultKeyStore.getKeyManagers().first() | ||
def certificate = manager.getCertificateChain("alias2") | ||
certificate[0].getSubjectX500Principal().toString() == "CN=localhost2, OU=Micronaut2, O=My Company, L=City, ST=State, C=BR"; | ||
} | ||
|
||
def "storeToFactory should throw a exception if selected alias not exists"() { | ||
given: | ||
|
||
SslConfiguration sslConfig = Mock(SslConfiguration); | ||
SslConfiguration.KeyConfiguration keyConfiguration = Mock(SslConfiguration.KeyConfiguration); | ||
SslConfiguration.KeyStoreConfiguration keyStoreConfiguration = Mock(SslConfiguration.KeyStoreConfiguration); | ||
sslConfig.isPreferOpenssl() >> false | ||
sslConfig.getKey() >> keyConfiguration | ||
sslConfig.getKeyStore() >> keyStoreConfiguration | ||
keyConfiguration.getAlias() >> Optional.of("alias5") | ||
keyConfiguration.getPassword() >> Optional.of("passwordAlias2") | ||
KeyStore keystore = KeyStore.getInstance("JKS"); | ||
keystore.load(null, null) | ||
keystore.containsAlias("any") >> false; | ||
|
||
when: | ||
NettyTlsUtils.storeToFactory(sslConfig, keystore) | ||
|
||
then: | ||
def e = thrown(IllegalArgumentException) | ||
e.message == "Alias alias5 not found in keystore" | ||
} | ||
|
||
def "storeToFactory should throw a exception if key of alias is null"() { | ||
given: | ||
|
||
SslConfiguration sslConfig = Mock(SslConfiguration); | ||
SslConfiguration.KeyConfiguration keyConfiguration = Mock(SslConfiguration.KeyConfiguration); | ||
SslConfiguration.KeyStoreConfiguration keyStoreConfiguration = Mock(SslConfiguration.KeyStoreConfiguration); | ||
sslConfig.isPreferOpenssl() >> false | ||
sslConfig.getKey() >> keyConfiguration | ||
sslConfig.getKeyStore() >> keyStoreConfiguration | ||
keyConfiguration.getAlias() >> Optional.of("any") | ||
keyConfiguration.getPassword() >> Optional.of("any") | ||
|
||
KeyStore keystore = KeyStore.getInstance("JKS"); | ||
keystore.load(null, null) | ||
keystore.containsAlias("any") >> false; | ||
keystore.setCertificateEntry("any", Mock(Certificate)) | ||
|
||
when: | ||
NettyTlsUtils.storeToFactory(sslConfig, keystore) | ||
|
||
then: | ||
def e = thrown(IllegalStateException) | ||
e.message == "There are no keys associated with the alias any" | ||
} | ||
|
||
def "storeToFactory should not extract alias if Keystore is null"() { | ||
given: | ||
|
||
SslConfiguration sslConfig = Mock(SslConfiguration); | ||
SslConfiguration.KeyConfiguration keyConfiguration = Mock(SslConfiguration.KeyConfiguration); | ||
SslConfiguration.KeyStoreConfiguration keyStoreConfiguration = Mock(SslConfiguration.KeyStoreConfiguration); | ||
sslConfig.isPreferOpenssl() >> false | ||
sslConfig.getKey() >> keyConfiguration | ||
sslConfig.getKeyStore() >> keyStoreConfiguration | ||
keyConfiguration.getAlias() >> Optional.of("any") | ||
keyConfiguration.getPassword() >> Optional.of("any") | ||
|
||
when: | ||
NettyTlsUtils.storeToFactory(sslConfig, null) | ||
|
||
then: | ||
0 * NettyTlsUtils.extractKeystoreAlias(_, _, _) | ||
} | ||
|
||
def "storeToFactory should not extract alias if alias is not defined"() { | ||
given: | ||
|
||
SslConfiguration sslConfig = Mock(SslConfiguration); | ||
SslConfiguration.KeyConfiguration keyConfiguration = Mock(SslConfiguration.KeyConfiguration); | ||
SslConfiguration.KeyStoreConfiguration keyStoreConfiguration = Mock(SslConfiguration.KeyStoreConfiguration); | ||
sslConfig.isPreferOpenssl() >> false | ||
sslConfig.getKey() >> keyConfiguration | ||
sslConfig.getKeyStore() >> keyStoreConfiguration | ||
keyConfiguration.getAlias() >> Optional.empty() | ||
keyConfiguration.getPassword() >> Optional.empty() | ||
keyStoreConfiguration.getPassword() >> Optional.of("any") | ||
|
||
KeyStore keystore = KeyStore.getInstance("JKS"); | ||
keystore.load(null, null) | ||
|
||
when: | ||
NettyTlsUtils.storeToFactory(sslConfig, keystore) | ||
|
||
then: | ||
0 * NettyTlsUtils.extractKeystoreAlias(_, _, _) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
## Commands used to generate keystore for testing | ||
|
||
**keystoreWithMultipleAlias.jks** | ||
|
||
```sh | ||
keytool -genkeypair -v -keystore keystoreWithMultipleAlias.jks -storetype JKS -alias alias1 -keyalg RSA -keysize 2048 -validity 36500 -dname "CN=localhost1, OU=Micronaut1, O=My Company, L=City, ST=State, C=BR" -storepass password -keypass passwordAlias1 | ||
keytool -genkeypair -v -keystore keystoreWithMultipleAlias.jks -storetype JKS -alias alias2 -keyalg RSA -keysize 2048 -validity 36500 -dname "CN=localhost2, OU=Micronaut2, O=My Company, L=City, ST=State, C=BR" -storepass password -keypass passwordAlias2 | ||
keytool -genkeypair -v -keystore keystoreWithMultipleAlias.jks -storetype JKS -alias alias3 -keyalg RSA -keysize 2048 -validity 36500 -dname "CN=localhost3, OU=Micronaut3, O=My Company, L=City, ST=State, C=BR" -storepass password -keypass passwordAlias3 | ||
``` |
Binary file not shown.