aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPiotr Jaszczyk <piotr.jaszczyk@nokia.com>2019-05-30 13:04:36 +0200
committerPiotr Jaszczyk <piotr.jaszczyk@nokia.com>2019-06-03 15:51:17 +0200
commit086e8381d8235db912d935def6491ef321c75a9b (patch)
tree178c0bbe29b56b50a2d322f56d722bbb2e975df7 /security
parent7e893708bbdc36698a5d90502b318a5fd4f3be21 (diff)
Update dependencies and enhance crypt-password lib
Change-Id: I7fe56e43d7ff0ac9b50708a6abe2163f7ddf8904 Issue-ID: DCAEGEN2-1542 Signed-off-by: Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
Diffstat (limited to 'security')
-rw-r--r--security/crypt-password/pom.xml98
-rw-r--r--security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CharsFromStreamReader.java62
-rw-r--r--security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CryptPassword.java33
-rw-r--r--security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/DecodePassword.java34
-rw-r--r--security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/EncodePassword.java76
-rw-r--r--security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/ExitCode.java31
-rw-r--r--security/crypt-password/src/test/java/org/onap/dcaegen2/services/sdk/security/CharsFromStreamReaderTest.java57
-rw-r--r--security/crypt-password/src/test/java/org/onap/dcaegen2/services/sdk/security/CryptPasswordTest.java55
8 files changed, 364 insertions, 82 deletions
diff --git a/security/crypt-password/pom.xml b/security/crypt-password/pom.xml
index 2e37c151..299aced7 100644
--- a/security/crypt-password/pom.xml
+++ b/security/crypt-password/pom.xml
@@ -1,52 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <groupId>org.onap.dcaegen2.services.sdk.security</groupId>
- <artifactId>dcaegen2-services-sdk-security</artifactId>
- <version>1.2.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.dcaegen2.services.sdk.security</groupId>
+ <artifactId>dcaegen2-services-sdk-security</artifactId>
+ <version>1.2.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
- <groupId>org.onap.dcaegen2.services.sdk.security.crypt</groupId>
- <artifactId>crypt-password</artifactId>
+ <groupId>org.onap.dcaegen2.services.sdk.security.crypt</groupId>
+ <artifactId>crypt-password</artifactId>
- <name>Security :: Crypt Password</name>
- <description>DMaaP Security Module</description>
- <packaging>jar</packaging>
+ <name>Security :: Crypt Password</name>
+ <description>DMaaP Security Module</description>
+ <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-crypto</artifactId>
- <version>3.1.0.RELEASE</version>
- </dependency>
- </dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-crypto</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
<build>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>3.2.1</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <transformers>
- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.onap.dcaegen2.services.sdk.security.DecodePassword</mainClass>
- </transformer>
- </transformers>
- </configuration>
- </execution>
- </executions>
- </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>3.2.1</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <transformers>
+ <transformer
+ implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.onap.dcaegen2.services.sdk.security.EncodePassword</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
diff --git a/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CharsFromStreamReader.java b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CharsFromStreamReader.java
new file mode 100644
index 00000000..1ea18cc7
--- /dev/null
+++ b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CharsFromStreamReader.java
@@ -0,0 +1,62 @@
+/*
+ * ============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;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.CharBuffer;
+
+final class CharsFromStreamReader {
+
+ public static final int END_OF_STREAM = -1;
+ private final int maxLength;
+
+ CharsFromStreamReader(int maxLength) {
+ this.maxLength = maxLength;
+ }
+
+ CharSequence readPasswordFromStdIn() throws IOException {
+ try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
+ return readPassword(bufferedReader);
+ }
+ }
+
+ CharSequence readPassword(BufferedReader bufferedReader) throws IOException {
+ final CharBuffer charBuffer = CharBuffer.allocate(maxLength);
+ if (readAllChars(charBuffer, bufferedReader)) {
+ charBuffer.flip();
+ return charBuffer.asReadOnlyBuffer();
+ } else {
+ throw new IOException(
+ "Input exceeds maximum supported length of " + maxLength + " characters");
+ }
+ }
+
+ private boolean readAllChars(CharBuffer charBuffer, BufferedReader bufferedReader) throws IOException {
+ int readChars = 0;
+ while (readChars != END_OF_STREAM && charBuffer.remaining() > 0) {
+ readChars = bufferedReader.read(charBuffer);
+ }
+ // true when all characters were read
+ return readChars == -1;
+ }
+}
diff --git a/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CryptPassword.java b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CryptPassword.java
index 6ca78a01..4b16c9e2 100644
--- a/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CryptPassword.java
+++ b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/CryptPassword.java
@@ -21,15 +21,32 @@ package org.onap.dcaegen2.services.sdk.security;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-public class CryptPassword {
+/**
+ * Class for encoding passwords using BCrypt algorithm.
+ */
+public final class CryptPassword {
- private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+ private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
- public String decode(String arg) {
- return encoder.encode(arg);
- }
+ /**
+ * Encode the raw password.
+ *
+ * @param rawPassword raw password to be encoded
+ * @return encoded password
+ */
+ public String encode(CharSequence rawPassword) {
+ return encoder.encode(rawPassword);
+ }
- public boolean matches(String rawPassword, String encodedPassword){
- return encoder.matches(rawPassword,encodedPassword);
- }
+ /**
+ * Verify the encoded password matches the submitted raw password. Returns true if the passwords match, false if
+ * they do not.
+ *
+ * @param rawPassword the raw password to encode and match
+ * @param encodedPassword the encoded password to compare with
+ * @return true if the raw password, after encoding, matches the encoded password
+ */
+ public boolean matches(CharSequence rawPassword, String encodedPassword) {
+ return encoder.matches(rawPassword, encodedPassword);
+ }
}
diff --git a/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/DecodePassword.java b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/DecodePassword.java
deleted file mode 100644
index 85412eb6..00000000
--- a/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/DecodePassword.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * DCAEGEN2-SERVICES-SDK
- * ================================================================================
- * Copyright (C) 2018 NOKIA Intellectual Property. 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;
-
-class DecodePassword {
-
- private static CryptPassword cryptPassword = new CryptPassword();
-
- public static void main(String[] args) {
-
- try {
- System.out.println(cryptPassword.decode(args[0]));
- }catch(Exception e){
- System.out.println("Param to crypt is required !");
- }
- }
-}
diff --git a/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/EncodePassword.java b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/EncodePassword.java
new file mode 100644
index 00000000..77843816
--- /dev/null
+++ b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/EncodePassword.java
@@ -0,0 +1,76 @@
+/*
+ * ============LICENSE_START=======================================================
+ * DCAEGEN2-SERVICES-SDK
+ * ================================================================================
+ * Copyright (C) 2018 NOKIA Intellectual Property. 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;
+
+import java.io.IOException;
+
+class EncodePassword {
+
+ private static final int MAX_PASSWORD_LENGTH = 64 * 1024;
+ private static final int ARGS_LENGTH_PASSWORD_PROVIDED = 1;
+ private CryptPassword cryptPassword = new CryptPassword();
+ private CharsFromStreamReader charsFromStreamReader = new CharsFromStreamReader(MAX_PASSWORD_LENGTH);
+
+ public static void main(String[] args) {
+ new EncodePassword().run(args);
+ }
+
+ public void run(String[] args) {
+ try {
+ encodeRawInput(readPassword(args));
+ } catch (IOException ex) {
+ printErrorAndExit(ExitCode.IO_ERROR, "Error while reading the password: " + ex.getMessage());
+ }
+ }
+
+ private void encodeRawInput(CharSequence rawPassword) {
+ if (rawPassword == null || rawPassword.length() == 0) {
+ printErrorAndExit(ExitCode.INVALID_PASSWORD, "Password cannot be empty");
+ } else {
+ printWarningIfContainsEndlChars(rawPassword);
+ printResult(cryptPassword.encode(rawPassword));
+ }
+ }
+
+ private void printWarningIfContainsEndlChars(CharSequence rawPassword) {
+ if (rawPassword.chars().anyMatch(ch -> ch == '\n' || ch == '\r')) {
+ printWarning("Warning: Password contains end of lines characters.");
+ }
+ }
+
+ private CharSequence readPassword(String[] args) throws IOException {
+ return args.length >= ARGS_LENGTH_PASSWORD_PROVIDED
+ ? args[0]
+ : charsFromStreamReader.readPasswordFromStdIn();
+ }
+
+ private void printWarning(String msg) {
+ System.err.println(msg);
+ }
+
+ private void printErrorAndExit(ExitCode exitCode, String msg) {
+ System.err.println(msg);
+ System.exit(exitCode.value);
+ }
+
+ private void printResult(String encodedPassword) {
+ System.out.println(encodedPassword);
+ }
+}
diff --git a/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/ExitCode.java b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/ExitCode.java
new file mode 100644
index 00000000..51141eed
--- /dev/null
+++ b/security/crypt-password/src/main/java/org/onap/dcaegen2/services/sdk/security/ExitCode.java
@@ -0,0 +1,31 @@
+/*
+ * ============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;
+
+enum ExitCode {
+ INVALID_PASSWORD(1), IO_ERROR(2);
+
+ final int value;
+
+ ExitCode(int value) {
+ this.value = value;
+ }
+} \ No newline at end of file
diff --git a/security/crypt-password/src/test/java/org/onap/dcaegen2/services/sdk/security/CharsFromStreamReaderTest.java b/security/crypt-password/src/test/java/org/onap/dcaegen2/services/sdk/security/CharsFromStreamReaderTest.java
new file mode 100644
index 00000000..2cfaa291
--- /dev/null
+++ b/security/crypt-password/src/test/java/org/onap/dcaegen2/services/sdk/security/CharsFromStreamReaderTest.java
@@ -0,0 +1,57 @@
+/*
+ * ============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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import org.junit.jupiter.api.Test;
+
+class CharsFromStreamReaderTest {
+ private static final int MAX_LENGTH = 6;
+ private final CharsFromStreamReader cut = new CharsFromStreamReader(MAX_LENGTH);
+
+ @Test
+ void readPasswordShouldThrowExceptionWhenInputExceedsMaxLength() throws IOException {
+ try (BufferedReader input = new BufferedReader(new StringReader("very long password"))) {
+ assertThatThrownBy(() -> cut.readPassword(input))
+ .isInstanceOf(IOException.class)
+ .hasMessageContaining(Integer.toString(MAX_LENGTH));
+ }
+ }
+
+
+ @Test
+ void readPasswordShouldReturnThePassword() throws IOException {
+ // given
+ final String givenPass = "pass";
+ BufferedReader input = new BufferedReader(new StringReader(givenPass));
+
+ // when
+ final CharSequence result = cut.readPassword(input);
+
+ // then
+ assertThat(result.toString()).isEqualTo(givenPass);
+ }
+} \ No newline at end of file
diff --git a/security/crypt-password/src/test/java/org/onap/dcaegen2/services/sdk/security/CryptPasswordTest.java b/security/crypt-password/src/test/java/org/onap/dcaegen2/services/sdk/security/CryptPasswordTest.java
new file mode 100644
index 00000000..debd9afb
--- /dev/null
+++ b/security/crypt-password/src/test/java/org/onap/dcaegen2/services/sdk/security/CryptPasswordTest.java
@@ -0,0 +1,55 @@
+/*
+ * ============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;
+
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class CryptPasswordTest {
+
+ private final CryptPassword cut = new CryptPassword();
+
+ @Test
+ void encodedPasswordShouldMatchTheInput() {
+ final String rawPasswd = "some.strong.password";
+ final String result = cut.encode(rawPasswd);
+
+ assertThat(cut.matches(rawPasswd, result)).isTrue();
+ }
+
+ @Test
+ void testCompatibility() {
+ final String rawPasswd = "some.strong.password";
+ final String encodedWithPreviousVersion = "$2a$10$LpP1jatprzTm9c4gX.jx7.k3.sa7Nm2aI7pe3hY/n6ZSo6g1Zye4K";
+
+ assertThat(cut.matches(rawPasswd, encodedWithPreviousVersion)).isTrue();
+ }
+
+ @Test
+ void differentPasswordShouldNotMatchTheInput() {
+ final String rawPasswd = "some.strong.password";
+ final String result = cut.encode("different.password");
+
+ assertThat(cut.matches(rawPasswd, result)).isFalse();
+ }
+} \ No newline at end of file