summaryrefslogtreecommitdiffstats
path: root/security/ssl/src
diff options
context:
space:
mode:
Diffstat (limited to 'security/ssl/src')
-rw-r--r--security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/KeyStoreTypes.java61
-rw-r--r--security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeys.java6
-rw-r--r--security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeysStore.java53
-rw-r--r--security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SslFactory.java70
-rw-r--r--security/ssl/src/test/java/org/onap/dcaegen2/services/sdk/security/ssl/KeyStoreTypesTest.java76
5 files changed, 237 insertions, 29 deletions
diff --git a/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/KeyStoreTypes.java b/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/KeyStoreTypes.java
new file mode 100644
index 00000000..61e551e6
--- /dev/null
+++ b/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/KeyStoreTypes.java
@@ -0,0 +1,61 @@
+/*
+ * ============LICENSE_START====================================
+ * DCAEGEN2-SERVICES-SDK
+ * =========================================================
+ * Copyright (C) 2019 Nokia. All rights reserved.
+ * =========================================================
+ * Licensed 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.
+ * ============LICENSE_END=====================================
+ */
+
+package org.onap.dcaegen2.services.sdk.security.ssl;
+
+import io.vavr.collection.HashSet;
+import io.vavr.collection.Set;
+import io.vavr.control.Option;
+import java.nio.file.Path;
+
+/**
+ * @author <a href="mailto:piotr.jaszczyk@nokia.com">Piotr Jaszczyk</a>
+ * @since 1.1.1
+ */
+final class KeyStoreTypes {
+ static final String TYPE_JKS = "jks";
+ static final String TYPE_PKCS12 = "pkcs12";
+ private static final Set<String> JKS_EXTENSIONS = HashSet.of(TYPE_JKS);
+ private static final Set<String> PKCS12_EXTENSIONS = HashSet.of(TYPE_PKCS12, "p12");
+
+ private KeyStoreTypes() {}
+
+ static Option<String> inferTypeFromExtension(Path filePath) {
+ return extension(filePath.toString())
+ .flatMap(KeyStoreTypes::typeForExtension);
+ }
+
+ private static Option<String> extension(String filePath) {
+ final int dotIndex = filePath.lastIndexOf('.');
+ return dotIndex < 0 || dotIndex + 1 >= filePath.length()
+ ? Option.none()
+ : Option.of(filePath.substring(dotIndex + 1).toLowerCase());
+ }
+
+ private static Option<String> typeForExtension(String extension) {
+ if (JKS_EXTENSIONS.contains(extension)) {
+ return Option.of(TYPE_JKS);
+ } else if (PKCS12_EXTENSIONS.contains(extension)) {
+ return Option.of(TYPE_PKCS12);
+ } else {
+ return Option.none();
+ }
+ }
+}
diff --git a/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeys.java b/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeys.java
index 05c3c470..244e33c8 100644
--- a/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeys.java
+++ b/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeys.java
@@ -20,7 +20,6 @@
package org.onap.dcaegen2.services.sdk.security.ssl;
-import java.nio.file.Path;
import org.immutables.value.Value;
/**
@@ -29,9 +28,10 @@ import org.immutables.value.Value;
*/
@Value.Immutable
public interface SecurityKeys {
- Path keyStore();
+
+ SecurityKeysStore keyStore();
Password keyStorePassword();
- Path trustStore();
+ SecurityKeysStore trustStore();
Password trustStorePassword();
}
diff --git a/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeysStore.java b/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeysStore.java
new file mode 100644
index 00000000..0ebfc451
--- /dev/null
+++ b/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SecurityKeysStore.java
@@ -0,0 +1,53 @@
+/*
+ * ============LICENSE_START====================================
+ * DCAEGEN2-SERVICES-SDK
+ * =========================================================
+ * Copyright (C) 2019 Nokia. All rights reserved.
+ * =========================================================
+ * Licensed 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.
+ * ============LICENSE_END=====================================
+ */
+
+package org.onap.dcaegen2.services.sdk.security.ssl;
+
+import java.nio.file.Path;
+import org.immutables.value.Value;
+
+/**
+ * @author <a href="mailto:piotr.jaszczyk@nokia.com">Piotr Jaszczyk</a>
+ * @since 1.1.1
+ */
+@Value.Immutable
+public interface SecurityKeysStore {
+ /**
+ * Stores the file path of the key store. It should contain data in format specified by {@link #type()}.
+ *
+ * @return key store path
+ */
+ @Value.Parameter
+ Path path();
+
+ /**
+ * Type of the key store. Can be anything supported by the JVM, eg. {@code jks} or {@code pkcs12}.
+ *
+ * If not set it will be guessed from the {@link #path()}. {@link IllegalStateException} will be thrown if it will
+ * not be possible.
+ *
+ * @return key store type
+ */
+ @Value.Default
+ default String type() {
+ return KeyStoreTypes.inferTypeFromExtension(path())
+ .getOrElseThrow(() -> new IllegalStateException("Could not determine key store type by file name"));
+ }
+}
diff --git a/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SslFactory.java b/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SslFactory.java
index 15739eb6..1f3f4cfd 100644
--- a/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SslFactory.java
+++ b/security/ssl/src/main/java/org/onap/dcaegen2/services/sdk/security/ssl/SslFactory.java
@@ -36,54 +36,72 @@ import javax.net.ssl.TrustManagerFactory;
public class SslFactory {
/**
- * Function for creating secure ssl context.
+ * Creates Netty SSL <em>client</em> context using provided security keys.
*
* @param keys - Security keys to be used
* @return configured SSL context
*/
- public Try<SslContext> createSecureContext(final SecurityKeys keys) {
- final Try<KeyManagerFactory> keyManagerFactory =
- keyManagerFactory(keys.keyStore(), keys.keyStorePassword());
- final Try<TrustManagerFactory> trustManagerFactory =
- trustManagerFactory(keys.trustStore(), keys.trustStorePassword());
+ public Try<SslContext> createSecureClientContext(final SecurityKeys keys) {
+ return Try.success(SslContextBuilder.forClient())
+ .flatMap(ctx -> keyManagerFactory(keys).map(ctx::keyManager))
+ .flatMap(ctx -> trustManagerFactory(keys).map(ctx::trustManager))
+ .mapTry(SslContextBuilder::build);
+ }
+ /**
+ * Creates Netty SSL <em>server</em> context using provided security keys.
+ *
+ * @param keys - Security keys to be used
+ * @return configured SSL context
+ */
+ public Try<SslContext> createSecureServerContext(final SecurityKeys keys) {
+ return keyManagerFactory(keys)
+ .map(SslContextBuilder::forServer)
+ .flatMap(ctx -> trustManagerFactory(keys).map(ctx::trustManager))
+ .mapTry(SslContextBuilder::build);
+ }
+
+ /**
+ * Function for creating insecure SSL context.
+ *
+ * @return configured insecure ssl context
+ * @deprecated Do not use in production. Will trust anyone.
+ */
+ @Deprecated
+ public Try<SslContext> createInsecureClientContext() {
return Try.success(SslContextBuilder.forClient())
- .flatMap(ctx -> keyManagerFactory.map(ctx::keyManager))
- .flatMap(ctx -> trustManagerFactory.map(ctx::trustManager))
+ .map(ctx -> ctx.trustManager(InsecureTrustManagerFactory.INSTANCE))
.mapTry(SslContextBuilder::build);
}
- private Try<KeyManagerFactory> keyManagerFactory(Path path, Password password) {
+ private Try<TrustManagerFactory> trustManagerFactory(SecurityKeys keys) {
+ return trustManagerFactory(keys.trustStore(), keys.trustStorePassword());
+ }
+
+ private Try<KeyManagerFactory> keyManagerFactory(SecurityKeys keys) {
+ return keyManagerFactory(keys.keyStore(), keys.keyStorePassword());
+ }
+
+ private Try<KeyManagerFactory> keyManagerFactory(SecurityKeysStore store, Password password) {
return password.useChecked(passwordChars -> {
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- kmf.init(loadKeyStoreFromFile(path, passwordChars), passwordChars);
+ kmf.init(loadKeyStoreFromFile(store, passwordChars), passwordChars);
return kmf;
});
}
- private Try<TrustManagerFactory> trustManagerFactory(Path path, Password password) {
+ private Try<TrustManagerFactory> trustManagerFactory(SecurityKeysStore store, Password password) {
return password.useChecked(passwordChars -> {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- tmf.init(loadKeyStoreFromFile(path, passwordChars));
+ tmf.init(loadKeyStoreFromFile(store, passwordChars));
return tmf;
});
}
- private KeyStore loadKeyStoreFromFile(Path path, char[] keyStorePassword)
+ private KeyStore loadKeyStoreFromFile(SecurityKeysStore store, char[] keyStorePassword)
throws GeneralSecurityException, IOException {
- KeyStore ks = KeyStore.getInstance("pkcs12");
- ks.load(Files.newInputStream(path, StandardOpenOption.READ), keyStorePassword);
+ KeyStore ks = KeyStore.getInstance(store.type());
+ ks.load(Files.newInputStream(store.path(), StandardOpenOption.READ), keyStorePassword);
return ks;
}
-
- /**
- * Function for creating insecure ssl context.
- *
- * @return configured insecure ssl context
- */
- public Try<SslContext> createInsecureContext() {
- return Try.success(SslContextBuilder.forClient())
- .map(ctx -> ctx.trustManager(InsecureTrustManagerFactory.INSTANCE))
- .mapTry(SslContextBuilder::build);
- }
}
diff --git a/security/ssl/src/test/java/org/onap/dcaegen2/services/sdk/security/ssl/KeyStoreTypesTest.java b/security/ssl/src/test/java/org/onap/dcaegen2/services/sdk/security/ssl/KeyStoreTypesTest.java
new file mode 100644
index 00000000..ab2aa773
--- /dev/null
+++ b/security/ssl/src/test/java/org/onap/dcaegen2/services/sdk/security/ssl/KeyStoreTypesTest.java
@@ -0,0 +1,76 @@
+/*
+ * ============LICENSE_START====================================
+ * DCAEGEN2-SERVICES-SDK
+ * =========================================================
+ * Copyright (C) 2019 Nokia. All rights reserved.
+ * =========================================================
+ * Licensed 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.
+ * ============LICENSE_END=====================================
+ */
+
+package org.onap.dcaegen2.services.sdk.security.ssl;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.vavr.control.Option;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author <a href="mailto:piotr.jaszczyk@nokia.com">Piotr Jaszczyk</a>
+ * @since February 2019
+ */
+class KeyStoreTypesTest {
+
+ @Test
+ void guessType_shouldReturnExtension_forP12() {
+ final Option<String> result = callGuessTypeWithFileName("file.p12");
+ assertThat(result.get()).isEqualTo(KeyStoreTypes.TYPE_PKCS12);
+ }
+
+ @Test
+ void guessType_shouldReturnExtension_forPkcs12() {
+ final Option<String> result = callGuessTypeWithFileName("file.pkcs12");
+ assertThat(result.get()).isEqualTo(KeyStoreTypes.TYPE_PKCS12);
+ }
+
+ @Test
+ void guessType_shouldReturnExtension_forJks() {
+ final Option<String> result = callGuessTypeWithFileName("file.jks");
+ assertThat(result.get()).isEqualTo(KeyStoreTypes.TYPE_JKS);
+ }
+
+ @Test
+ void guessType_shouldReturnExtension_ignoringCase() {
+ final Option<String> result = callGuessTypeWithFileName("file.PKCS12");
+ assertThat(result.get()).isEqualTo(KeyStoreTypes.TYPE_PKCS12);
+ }
+
+ @Test
+ void guessType_shouldReturnNone_whenFileDoesNotHaveExtension() {
+ final Option<String> result = callGuessTypeWithFileName("file");
+ assertThat(result.isEmpty()).isTrue();
+ }
+
+ @Test
+ void guessType_shouldReturnNone_whenFileEndsWithDot() {
+ final Option<String> result = callGuessTypeWithFileName("file.");
+ assertThat(result.isEmpty()).isTrue();
+ }
+
+ private Option<String> callGuessTypeWithFileName(String fileName) {
+ final Path path = Paths.get("/", "tmp", fileName);
+ return KeyStoreTypes.inferTypeFromExtension(path);
+ }
+} \ No newline at end of file