From e4642ab5744bc875fa46cd225c98bd6d52fc4b15 Mon Sep 17 00:00:00 2001 From: Patryk Milewski Date: Mon, 22 Oct 2018 08:20:17 +0200 Subject: [PATCH 1/6] Added Authorization Server logic as Manager Module Added http client implementation based on Apache Http Added wrapers for session token, credentials and secret Added Reader implementation for reading data stored in storage Took 11 hours 56 minutes --- Manager/pom.xml | 27 ++ .../manager/common/http/ApacheHttpClient.java | 58 +++++ .../common/http/ApacheSecuredHttpClient.java | 20 ++ .../manager/common/http/HttpClient.java | 24 ++ .../common/{ => interfaces}/Destroyable.java | 2 +- .../manager/common/readers/Reader.java | 52 ++++ .../manager/common/readers/StringReader.java | 56 +++++ .../common/readers/WalletUUIDReader.java | 46 ++++ .../manager/common/wrappers/ByteWrapper.java | 17 +- .../manager/common/wrappers/Credentials.java | 13 + .../manager/common/wrappers/Secret.java | 28 +++ .../manager/common/wrappers/Token.java | 30 +++ .../manager/cryptography/common/Password.java | 2 +- .../cryptography/crypto/CryptoObject.java | 12 +- .../crypto/algorithms/AESParams.java | 2 +- .../exceptions/DecryptionException.java | 26 ++ .../manager/modules/ExampleModule.java | 4 +- .../manager/modules/Module.java | 230 ++++-------------- .../modules/authorizationserver/APIKeys.java | 22 ++ .../AuthorizationServerAPI.java | 164 +++++++++++++ .../AuthorizationServerConf.java | 28 +++ .../AuthorizationServerModule.java | 108 ++++++++ .../authorizationserver/RequestException.java | 15 ++ .../manager/session/SessionToken.java | 2 +- .../cryptography/crypto/AESObjectsTests.java | 17 +- .../cryptography/crypto/RSAObjectsTests.java | 13 +- .../authorizationserver/AuthServerTests.java | 29 +++ 27 files changed, 828 insertions(+), 219 deletions(-) create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheHttpClient.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheSecuredHttpClient.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/http/HttpClient.java rename Manager/src/main/java/io/raspberrywallet/manager/common/{ => interfaces}/Destroyable.java (51%) create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/readers/Reader.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/readers/StringReader.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/readers/WalletUUIDReader.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Credentials.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Secret.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Token.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/APIKeys.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerConf.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/RequestException.java create mode 100644 Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java diff --git a/Manager/pom.xml b/Manager/pom.xml index a1b8cd2..2cccbcb 100644 --- a/Manager/pom.xml +++ b/Manager/pom.xml @@ -102,6 +102,33 @@ ${jackson.version} + + + org.apache.httpcomponents + httpclient + 4.5.6 + + + + + org.apache.httpcomponents + fluent-hc + 4.5.6 + + + + + org.json + json + 20180813 + + + com.exadatum.xsuite.xmaven + bash-maven-plugin + 1.0.7 + test + + diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheHttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheHttpClient.java new file mode 100644 index 0000000..1df79ec --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheHttpClient.java @@ -0,0 +1,58 @@ +package io.raspberrywallet.manager.common.http; + +import org.apache.commons.lang.NotImplementedException; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.fluent.Form; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicHeader; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ApacheHttpClient extends HttpClient { + + private String host; + private Header[] defaultHeaders; + + public ApacheHttpClient(String host, Form defaultHeaders) { + this.host = host; + this.defaultHeaders = toHeadersArray(defaultHeaders); + } + + @Override + public HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException { + org.apache.http.client.HttpClient client = HttpClients.createDefault(); + + JSONObject jsonObject = convert(body); + StringEntity stringEntity = new StringEntity(jsonObject.toString()); + + HttpPost httpRequest = new HttpPost(endpoint); + httpRequest.setEntity(stringEntity); + httpRequest.setHeaders(defaultHeaders); + + return client.execute(httpRequest); + } + + @Override + public HttpResponse sendGETRequest(Form body, String endpoint) { + throw new NotImplementedException(); + } + + private Header[] toHeadersArray(Form form) { + List list = form.build(); + List
result = new ArrayList<>(list.size()); + list.forEach(nameValuePair -> { + BasicHeader basicHeader = new BasicHeader(nameValuePair.getName(), nameValuePair.getValue()); + result.add(basicHeader); + }); + + Header[] headers = new Header[result.size()]; + return result.toArray(headers); + } +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheSecuredHttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheSecuredHttpClient.java new file mode 100644 index 0000000..0fca90f --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheSecuredHttpClient.java @@ -0,0 +1,20 @@ +package io.raspberrywallet.manager.common.http; + +import org.apache.commons.lang.NotImplementedException; +import org.apache.http.HttpResponse; +import org.apache.http.client.fluent.Form; + +import java.io.IOException; + +public class ApacheSecuredHttpClient extends HttpClient { + + @Override + public HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException { + throw new NotImplementedException(); + } + + @Override + public HttpResponse sendGETRequest(Form body, String endpoint) { + throw new NotImplementedException(); + } +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/HttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/HttpClient.java new file mode 100644 index 0000000..4b9c809 --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/http/HttpClient.java @@ -0,0 +1,24 @@ +package io.raspberrywallet.manager.common.http; + +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.fluent.Form; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.List; + +public abstract class HttpClient { + + public abstract HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException; + + public abstract HttpResponse sendGETRequest(Form body, String endpoint); + + JSONObject convert(Form body) { + List keyValuesList = body.build(); + JSONObject convertedJson = new JSONObject(); + keyValuesList.forEach(pair -> convertedJson.put(pair.getName(), pair.getValue())); + return convertedJson; + } + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/Destroyable.java b/Manager/src/main/java/io/raspberrywallet/manager/common/interfaces/Destroyable.java similarity index 51% rename from Manager/src/main/java/io/raspberrywallet/manager/common/Destroyable.java rename to Manager/src/main/java/io/raspberrywallet/manager/common/interfaces/Destroyable.java index 1ffaf33..bbeab14 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/Destroyable.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/interfaces/Destroyable.java @@ -1,4 +1,4 @@ -package io.raspberrywallet.manager.common; +package io.raspberrywallet.manager.common.interfaces; public interface Destroyable { diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/readers/Reader.java b/Manager/src/main/java/io/raspberrywallet/manager/common/readers/Reader.java new file mode 100644 index 0000000..24bbfec --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/readers/Reader.java @@ -0,0 +1,52 @@ +package io.raspberrywallet.manager.common.readers; + +import org.apache.commons.lang.SerializationUtils; + +import java.io.IOException; +import java.io.Serializable; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; + +abstract class Reader { + + final static String WALLET_DIR = "/opt/wallet/"; + + private Path pathToFile; + + abstract String getFilePath(); + + T read() { + try { + return (T)SerializationUtils.deserialize(Files.readAllBytes(pathToFile)); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + void write(T input) { + if (pathToFile == null) + readFilePath(); + + try { + byte[] serializedData = SerializationUtils.serialize(input); + Files.write(pathToFile, serializedData, + StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING ); + } catch (IOException e) { + e.printStackTrace(); + } + } + + boolean fileExists() { + if (pathToFile == null) + readFilePath(); + + return Files.exists(pathToFile); + } + + private void readFilePath() { + pathToFile = Paths.get(getFilePath()); + } +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/readers/StringReader.java b/Manager/src/main/java/io/raspberrywallet/manager/common/readers/StringReader.java new file mode 100644 index 0000000..585a8b5 --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/readers/StringReader.java @@ -0,0 +1,56 @@ +package io.raspberrywallet.manager.common.readers; + +import lombok.Getter; +import lombok.Setter; +import lombok.Synchronized; + +import java.security.SecureRandom; + +public class StringReader extends Reader { + + private final SecureRandom secureRandom = new SecureRandom(); + + @Getter + @Setter + private int stringSizeInBytes = 16; + + private final String filePath; + + private String value; + + public StringReader(String filePath) { + this.filePath = WALLET_DIR + filePath; + } + + /** + * Get String from file, or if it does not exists, + * then get random String and save it to file. + * @return String read from file or randomly generated with SecureRandom. + */ + @Synchronized + public String get() { + if (value != null) + return value; + + if (fileExists()) { + value = read(); + return value; + } + + value = getRandomString(); + write(value); + return value; + } + + private String getRandomString() { + byte[] randomBytes = new byte[stringSizeInBytes]; + secureRandom.nextBytes(randomBytes); + return new String(randomBytes); + } + + @Override + String getFilePath() { + return filePath; + } + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/readers/WalletUUIDReader.java b/Manager/src/main/java/io/raspberrywallet/manager/common/readers/WalletUUIDReader.java new file mode 100644 index 0000000..504a638 --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/readers/WalletUUIDReader.java @@ -0,0 +1,46 @@ +package io.raspberrywallet.manager.common.readers; + +import lombok.Synchronized; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.UUID; + +public class WalletUUIDReader extends Reader { + + private final static String UUID_FILE_NAME = "wallet.uuid"; + private final static WalletUUIDReader INSTANCE = new WalletUUIDReader(); + + private UUID walletUUID; + + private WalletUUIDReader() {} + + public static WalletUUIDReader getInstance() { + return INSTANCE; + } + + @Synchronized + public UUID get() { + if (walletUUID != null) + return walletUUID; + + if (fileExists()) { + walletUUID = read(); + return walletUUID; + } + + walletUUID = UUID.randomUUID(); + write(walletUUID); + return walletUUID; + } + + @Override + String getFilePath() { + return WALLET_DIR + UUID_FILE_NAME; + } + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/ByteWrapper.java b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/ByteWrapper.java index 70f4efa..bb23b12 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/ByteWrapper.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/ByteWrapper.java @@ -1,20 +1,21 @@ package io.raspberrywallet.manager.common.wrappers; +import io.raspberrywallet.manager.common.ArrayDestroyer; +import io.raspberrywallet.manager.common.interfaces.Destroyable; +import lombok.Getter; + import java.io.Serializable; import java.util.Arrays; -public class ByteWrapper implements Serializable { +public class ByteWrapper implements Serializable, Destroyable { + @Getter private byte[] data; public ByteWrapper(byte[] data) { this.data = data; } - public byte[] getData() { - return data; - } - @Override public int hashCode() { return Arrays.hashCode(data); @@ -31,4 +32,10 @@ public boolean equals(Object other) { ByteWrapper otherCasted = (ByteWrapper)other; return this.hashCode() == otherCasted.hashCode(); } + + @Override + public void destroy() { + ArrayDestroyer.destroy(data); + } + } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Credentials.java b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Credentials.java new file mode 100644 index 0000000..e38377b --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Credentials.java @@ -0,0 +1,13 @@ +package io.raspberrywallet.manager.common.wrappers; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class Credentials { + + private String name; + private String password; + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Secret.java b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Secret.java new file mode 100644 index 0000000..56e1c90 --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Secret.java @@ -0,0 +1,28 @@ +package io.raspberrywallet.manager.common.wrappers; + +import io.raspberrywallet.manager.common.interfaces.Destroyable; + +import java.util.Base64; + +public class Secret implements Destroyable { + + private ByteWrapper byteWrapper; + + public byte[] getData() { + return byteWrapper.getData(); + } + + public Secret(byte[] data) { + byte[] dataConverted = Base64.getEncoder().encode(data); + byteWrapper = new ByteWrapper(dataConverted); + } + + public byte[] decode() { + return Base64.getDecoder().decode(byteWrapper.getData()); + } + + @Override + public void destroy() { + byteWrapper.destroy(); + } +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Token.java b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Token.java new file mode 100644 index 0000000..5c1540b --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Token.java @@ -0,0 +1,30 @@ +package io.raspberrywallet.manager.common.wrappers; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import java.time.LocalDate; + +@AllArgsConstructor +@Getter +@EqualsAndHashCode +public class Token { + + @EqualsAndHashCode.Include + private String data; + + /** + * Since different UUID tokens couldn't have the same UUID, + * then even with different expiration date they are the same. + */ + @EqualsAndHashCode.Exclude + private LocalDate expirationDate; + + public boolean isExpired() { + if (expirationDate.compareTo(LocalDate.now()) < 0) + return true; + else + return false; + } +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/common/Password.java b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/common/Password.java index e89d90a..5b21c48 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/common/Password.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/common/Password.java @@ -1,7 +1,7 @@ package io.raspberrywallet.manager.cryptography.common; import io.raspberrywallet.manager.common.ArrayDestroyer; -import io.raspberrywallet.manager.common.Destroyable; +import io.raspberrywallet.manager.common.interfaces.Destroyable; public class Password implements Destroyable { diff --git a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/CryptoObject.java b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/CryptoObject.java index f39fb9f..4ce2c7f 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/CryptoObject.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/CryptoObject.java @@ -27,7 +27,7 @@ public class CryptoObject { * @throws EncryptionException If there is any error with encryption, then it's caught and thrown as * EncryptionException, with original or custom error message. */ - public AESEncryptedObject encrypt(E object, Password password) throws EncryptionException { + public static AESEncryptedObject encrypt(E object, Password password) throws EncryptionException { AESCipherParams aesCipherParams = new AESCipherParams(); try { @@ -52,7 +52,7 @@ public AESEncryptedObject encrypt(E object, Password * @throws EncryptionException If there is any error with encryption, then it's caught and thrown as * EncryptionException, with original or custom error message. */ - public RSAEncryptedObject encrypt(E object, PublicKey publicKey) throws EncryptionException { + public static RSAEncryptedObject encrypt(E object, PublicKey publicKey) throws EncryptionException { RSACipherParams rsaCipherParams = new RSACipherParams(); try { Cipher cipher = rsaCipherParams.getEncryptCipher(publicKey); @@ -64,7 +64,7 @@ public RSAEncryptedObject encrypt(E object, PublicKe } } - private byte[] encrypt(Serializable object, Cipher cipher) throws BadPaddingException, IllegalBlockSizeException { + private static byte[] encrypt(Serializable object, Cipher cipher) throws BadPaddingException, IllegalBlockSizeException { byte[] serializedObject = SerializationUtils.serialize(object); return cipher.doFinal(serializedObject); } @@ -81,7 +81,7 @@ private byte[] encrypt(Serializable object, Cipher cipher) throws BadPaddingExce * @throws DecryptionException If there is any error in decryption, then it is caught and thrown as * DecryptionException, with it's original or custom message. */ - public E decrypt(AESEncryptedObject object, Password password) throws DecryptionException { + public static E decrypt(AESEncryptedObject object, Password password) throws DecryptionException { if (!object.isEncrypted()) throw new DecryptionException("Given object is not encrypted."); @@ -105,7 +105,7 @@ public E decrypt(AESEncryptedObject object, Password * @throws DecryptionException If there is any error in decryption, then it is caught and thrown as * DecryptionException, with it's original or custom message. */ - public E decrypt(RSAEncryptedObject object, PrivateKey privateKey) throws DecryptionException { + public static E decrypt(RSAEncryptedObject object, PrivateKey privateKey) throws DecryptionException { if(!object.isEncrypted()) throw new DecryptionException("Given object is not encrypted."); @@ -119,7 +119,7 @@ public E decrypt(RSAEncryptedObject object, PrivateK } } - private E decrypt(EncryptedObject object, Cipher cipher) throws BadPaddingException, IllegalBlockSizeException { + private static E decrypt(EncryptedObject object, Cipher cipher) throws BadPaddingException, IllegalBlockSizeException { byte[] decryptedObject = cipher.doFinal(object.getSerializedObject()); return object.getOriginalObject(decryptedObject); } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/algorithms/AESParams.java b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/algorithms/AESParams.java index f7532d1..2448282 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/algorithms/AESParams.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/algorithms/AESParams.java @@ -4,7 +4,7 @@ class AESParams extends AlgorithmParams { private final static String HASH_ALGORITHM_NAME = "PBKDF2WithHmacSHA1"; - private final static int KEY_HASH_ITERATIONS_AMOUNT = 65536; + private final static int KEY_HASH_ITERATIONS_AMOUNT = 16000; AESParams() { algorithmName = "AES"; diff --git a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/exceptions/DecryptionException.java b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/exceptions/DecryptionException.java index 6bd5c40..ec76ec6 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/exceptions/DecryptionException.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/exceptions/DecryptionException.java @@ -1,7 +1,21 @@ package io.raspberrywallet.manager.cryptography.crypto.exceptions; +import lombok.Getter; + public class DecryptionException extends Exception { + @Getter + private static final int NO_DATA = -1; + + @Getter + private static final int BAD_KEY = -2; + + private int code; + + public DecryptionException(int code) { + this.code = code; + } + public DecryptionException(String message) { super(message); } @@ -9,4 +23,16 @@ public DecryptionException(String message) { public DecryptionException(Throwable throwable) { super(throwable); } + + @Override + public String getMessage() { + switch (code) { + case NO_DATA: + return "-1: No paylaod data specified."; + case BAD_KEY: + return "-2: Wrong key provided for decryption."; + default: + return "-3: Unknown error."; + } + } } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/ExampleModule.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/ExampleModule.java index 430aee2..3fc08d1 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/ExampleModule.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/ExampleModule.java @@ -1,5 +1,7 @@ package io.raspberrywallet.manager.modules; +import io.raspberrywallet.manager.cryptography.crypto.exceptions.DecryptionException; + public class ExampleModule extends Module { @Override @@ -50,7 +52,7 @@ public byte[] encrypt(byte[] data) { */ @Override public byte[] decrypt(byte[] payload) throws DecryptionException { - if (payload == null) throw new Module.DecryptionException(Module.DecryptionException.NO_DATA); + if (payload == null) throw new DecryptionException(DecryptionException.getNO_DATA()); byte[] r = payload.clone(); diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/Module.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/Module.java index 6244fc3..938d5bc 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/Module.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/Module.java @@ -1,19 +1,44 @@ package io.raspberrywallet.manager.modules; +import io.raspberrywallet.manager.common.ArrayDestroyer; +import io.raspberrywallet.manager.common.interfaces.Destroyable; +import io.raspberrywallet.manager.cryptography.crypto.exceptions.DecryptionException; +import io.raspberrywallet.manager.cryptography.crypto.exceptions.EncryptionException; +import lombok.Getter; +import lombok.Setter; import org.jetbrains.annotations.Nullable; +import org.json.JSONObject; import java.util.HashMap; import java.util.Map; -public abstract class Module { - - /* - * Module info formatted as JSON. - * */ +public abstract class Module implements Destroyable { + + private static final int STATUS_OK = 200; + private static final int STATUS_TIMEOUT = 432; + private static final int STATUS_WAITING = 100; + + private byte[] payload; + private int status = STATUS_WAITING; + + @Setter + @Getter + private String statusString = "null"; + + private byte[] decryptedValue; + private HashMap input = new HashMap<>(); + + /** + * Returns module info. + * @return Info formatted as JSONObject casted to string. + */ @Override public String toString() { - return "{\"id\":\"" + getId() + "\", \"status\":\"" + getStatusString() + "\"}"; + JSONObject idAndStatus = new JSONObject(); + idAndStatus.put("id", getId()).put("status", getStatusString()); + return idAndStatus.toString(); + } public abstract String getDescription(); @@ -24,32 +49,16 @@ public io.raspberrywallet.module.Module asServerModule() { } /** - * Check if needed interaction (User-Module) has been completed - * + * Check if needed interaction (User-Module) has been completed. * @return true, if we are ready to decrypt */ public abstract boolean check(); - /** - * decrypt payload and set the results. - * Method called from CheckRunnable - */ - private synchronized void process(byte[] payload) { - try { - decryptedValue = decrypt(payload); - this.status = Module.STATUS_OK; - this.statusString = "OK: 200: Decrypted keypart"; - } catch (DecryptionException de) { - this.status = de.getCode(); - this.statusString = "Error: " + de.getMessage(); - } - } - /** * @param keyPart - unencrypted key part * @return encrypted payload */ - public abstract byte[] encrypt(byte[] keyPart); + public abstract byte[] encrypt(byte[] keyPart) throws EncryptionException; /** * @param payload - encrypted payload @@ -69,45 +78,10 @@ private synchronized void process(byte[] payload) { @Nullable public abstract String getHtmlUi(); - /** - * Returns status of the module to show to the user - * - * @return message - */ - public String getStatusString() { - return statusString == null ? "null" : statusString; - } - - /** - * Manager uses this to start the Module after register() - */ - public void start() { - checkThread = new Thread(checkRunnable.enable().setSleepTime(100)); - checkThread.start(); - } - /** - * Setting the status message for the user - * - * @param status - new status - */ - void setStatusString(String status) { - this.statusString = status; - } - public String getId() { return this.getClass().getName(); } - private static final int STATUS_OK = 200; - private static final int STATUS_TIMEOUT = 432; - private static final int STATUS_WAITING = 100; - - private byte[] payload; - private int status = STATUS_WAITING; - private String statusString; - private byte[] decryptedValue; - private HashMap input = new HashMap<>(); - public void newSession() { input.clear(); register(); @@ -125,153 +99,35 @@ public byte[] getResult() throws DecryptionException { if (getStatus() != STATUS_OK) throw new DecryptionException(getStatus()); else return decryptedValue; } - - private Thread checkThread; - - private class CheckRunnable implements Runnable { - - private boolean run = false; - private long sleepTime = 1000; - private long timeout = 3000; - private long startTime; - - CheckRunnable stop() { - run = false; - return this; - } - - CheckRunnable enable() { - run = true; - return this; - } - - CheckRunnable setSleepTime(long sleep) { - sleepTime = sleep; - return this; - } - - public CheckRunnable setTimeout(long tout) { - timeout = tout; - return this; - } - - public void run() { - startTime = System.currentTimeMillis(); - while (run) { - - if (check()) { - process(payload); - run = false; - } - - if (System.currentTimeMillis() - startTime > timeout && status == STATUS_WAITING) { - run = false; - status = STATUS_TIMEOUT; - statusString = "Timed out waiting for Module interaction."; - } - } - try { - Thread.sleep(sleepTime); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - private CheckRunnable checkRunnable = new CheckRunnable(); - - /* - * Used when everything has been completed, both in "cancel" and "done" cases. - * Override this to be sure everything else is cleaned. - * Manager should call this. - * */ - public void destroy() { - - //Stopping the wait thread - checkRunnable.stop(); - try { - //Joining - checkThread.join(checkRunnable.sleepTime * 2); - } catch (Exception e) { - e.printStackTrace(); - } finally { - //Clearing the RAM - synchronized (this) { - zeroFill(); - } - } - } - - - /* - * Fill everything with "zeroes" - */ - private synchronized void zeroFill() { - if (decryptedValue != null) { - for (int i = 0; i < decryptedValue.length; ++i) - decryptedValue[i] = (byte) (i % 120); - } - if (payload != null) { - for (int i = 0; i < payload.length; ++i) - payload[i] = (byte) (i % 60); - } - } - - public class DecryptionException extends Throwable { - - static final int NO_DATA = -1; - static final int BAD_KEY = -2; - static final int UNKNOWN = -3; - - private int code; - - DecryptionException(int code) { - this.code = code; - } - - int getCode() { - return this.code; - } - - public String getMessage() { - switch (code) { - case NO_DATA: - return "-1: No paylaod data specified."; - case BAD_KEY: - return "-2: Wrong key provided for decryption."; - case UNKNOWN: - return "-3: Unknown error."; - } - return "??: This is an error LOL."; - } - - } - - + /** * Sets input for this Module from user - * * @param key - key of the parameter * @param value - value of the parameter */ public void setInput(String key, String value) { input.put(key, value); } - + /** * Sets inputs for this Module from user + * @param inputs Map with key-value inputs. */ public void setInputs(Map inputs) { input.putAll(inputs); } + @Override + public void destroy() { + ArrayDestroyer.destroy(decryptedValue); + } + /** * Checks if user has submitted any input - * * @param key - key of the parameter * @return - if key exists */ - protected boolean hasInput(String key) { + boolean hasInput(String key) { return input.containsKey(key); } @@ -281,7 +137,7 @@ protected boolean hasInput(String key) { * @param key - parameter key * @return - value of the parameter */ - protected String getInput(String key) { + String getInput(String key) { return input.get(key); } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/APIKeys.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/APIKeys.java new file mode 100644 index 0000000..b309a46 --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/APIKeys.java @@ -0,0 +1,22 @@ +package io.raspberrywallet.manager.modules.authorizationserver; + +enum APIKeys { + + WALLETUUID("walletUUID"), + PASSWORD("password"), + SECRET("secret"), + TOKEN("token"), + SESSION_LENGTH("sessionLength"); + + String val; + + APIKeys(String val) { + this.val = val; + } + + @Override + public String toString() { + return val; + } + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java new file mode 100644 index 0000000..0ae82ba --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java @@ -0,0 +1,164 @@ +package io.raspberrywallet.manager.modules.authorizationserver; + +import io.raspberrywallet.manager.common.wrappers.Credentials; +import io.raspberrywallet.manager.common.wrappers.Secret; +import io.raspberrywallet.manager.common.wrappers.Token; +import io.raspberrywallet.manager.common.http.ApacheHttpClient; +import io.raspberrywallet.manager.common.http.HttpClient; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.fluent.Form; +import org.apache.http.util.EntityUtils; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +import java.io.IOException; +import java.time.LocalDate; + +class AuthorizationServerAPI { + + private AuthorizationServerConf configuration; + private Credentials credentials; + + private HttpClient httpClient; + private Form preparedCredentials; + + private Token token; + private Boolean isRegisteredFlag, isLoggedInFlag; + + AuthorizationServerAPI(AuthorizationServerConf configuration, Credentials credentials) { + this.configuration = configuration; + Form defaultHeaders = Form.form() + .add(HttpHeaders.CONTENT_TYPE, "application/json") + .add("charset", "UTF-8"); + + this.credentials = credentials; + preparedCredentials = Form.form() + .add(APIKeys.WALLETUUID.val, credentials.getName()) + .add(APIKeys.PASSWORD.val, credentials.getPassword()); + + httpClient = new ApacheHttpClient(configuration.getHost(), defaultHeaders); + } + + Token login(int sessionLength) throws RequestException { + Form requestBody = Form.form() + .add(APIKeys.WALLETUUID.val, credentials.getName()) + .add(APIKeys.PASSWORD.val, credentials.getPassword()) + .add(APIKeys.SESSION_LENGTH.val, Integer.toString(sessionLength)); + + return login(requestBody); + } + + Token login() throws RequestException { + return login(preparedCredentials); + } + + private Token login(Form requestBody) throws RequestException { + try { + HttpResponse httpResponse = executeRequest(requestBody, configuration.getLoginEndpoint()); + String token = EntityUtils.toString(httpResponse.getEntity()); + return new Token(token, LocalDate.MAX); + } catch (IOException e) { + throw new RequestException(e); + } + } + + boolean logout() throws RequestException { + HttpResponse response = executeRequest(preparedCredentials, configuration.getLogoutEndpoint()); + isLoggedInFlag = !handleResponse(response); + return isLoggedInFlag; + } + + boolean register() throws RequestException { + HttpResponse response = executeRequest(preparedCredentials, configuration.getRegisterEndpoint()); + return handleResponse(response); + } + + boolean isRegistered() throws RequestException { + if (isRegisteredFlag != null) + return isRegisteredFlag; + + Form requestBody = Form.form() + .add(APIKeys.WALLETUUID.val, credentials.getName()); + + HttpResponse response = executeRequest(requestBody, configuration.getWalletExistsEndpoint()); + isRegisteredFlag = handleResponse(response); + return isRegisteredFlag; + } + + Secret getSecret() throws RequestException { + registerAndLogin(); + + Form requestBody = Form.form() + .add(APIKeys.WALLETUUID.val, credentials.getName()) + .add(APIKeys.TOKEN.val, token.getData()); + + try { + HttpResponse httpResponse = executeRequest(requestBody, configuration.getGetSecretEndpoint()); + String secret = EntityUtils.toString(httpResponse.getEntity()); + return new Secret(secret.getBytes()); + } catch (IOException e) { + throw new RequestException(e); + } + } + + /** + * Since this method is not needed right now, it will not be implemented. + * @param secret empty + * @return empty + */ + boolean setSecret(Secret secret) { + throw new NotImplementedException(); + } + + void overwriteSecret(Secret secret) throws RequestException { + registerAndLogin(); + + Form requestBody = Form.form() + .add(APIKeys.WALLETUUID.val, credentials.getName()) + .add(APIKeys.TOKEN.val, token.getData()) + .add(APIKeys.SECRET.val, new String(secret.getData())); + + HttpResponse response = executeRequest(requestBody, configuration.getOverwriteEndpoint()); + handleResponse(response); + } + + private HttpResponse executeRequest(Form body, String endpoint) throws RequestException { + try { + return httpClient.sendPOSTRequest(body, endpoint); + } catch (IOException e) { + throw new RequestException(e); + } + } + + private boolean handleResponse(HttpResponse response) throws RequestException { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) + throw new RequestException("Request failed with error code: " + statusCode); + + return true; + } + + private void registerAndLogin() throws RequestException { + if (!isRegisteredCheck()) + register(); + + if (!isLoggedIn()) + token = login(); + } + + private boolean isRegisteredCheck() throws RequestException { + if (isRegisteredFlag == null || !isRegisteredFlag) + isRegisteredFlag = isRegistered(); + + return isRegisteredFlag; + } + + private boolean isLoggedIn() { + if (token == null || token.isExpired()) + return false; + else + return true; + } + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerConf.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerConf.java new file mode 100644 index 0000000..3ea1dde --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerConf.java @@ -0,0 +1,28 @@ +package io.raspberrywallet.manager.modules.authorizationserver; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +@AllArgsConstructor +class AuthorizationServerConf { + + AuthorizationServerConf() {} + + private String host = "http://localhost"; + private int port = 8080; + + private String address = host + ":" + port; + + private String loginEndpoint = address + "/authorization/login"; + private String logoutEndpoint = address + "/authorization/logout"; + private String registerEndpoint = address + "/authorization/register"; + private String setSecretEndpoint = address + "/authorization/secret/set"; + private String getSecretEndpoint = address + "/authorization/secret/get"; + private String overwriteEndpoint = address + "/authorization/secret/overwrite"; + private String walletExistsEndpoint = address + "/authorization/exists"; + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java new file mode 100644 index 0000000..cc2db08 --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java @@ -0,0 +1,108 @@ +package io.raspberrywallet.manager.modules.authorizationserver; + +import io.raspberrywallet.manager.common.readers.StringReader; +import io.raspberrywallet.manager.common.wrappers.ByteWrapper; +import io.raspberrywallet.manager.common.wrappers.Credentials; +import io.raspberrywallet.manager.common.wrappers.Secret; +import io.raspberrywallet.manager.cryptography.common.Password; +import io.raspberrywallet.manager.cryptography.crypto.AESEncryptedObject; +import io.raspberrywallet.manager.cryptography.crypto.CryptoObject; +import io.raspberrywallet.manager.cryptography.crypto.exceptions.DecryptionException; +import io.raspberrywallet.manager.cryptography.crypto.exceptions.EncryptionException; +import io.raspberrywallet.manager.modules.Module; +import io.raspberrywallet.manager.common.readers.WalletUUIDReader; +import org.apache.commons.lang.SerializationUtils; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; + +public class AuthorizationServerModule extends Module { + + // todo refactor it to take filename from conf, to avoid file collisions for multiple modules + private final String encryptionPasswordFilename = "serverPassword.key"; + private Password encryptionPassword; + + private final WalletUUIDReader walletUUIDReader = WalletUUIDReader.getInstance(); + private final UUID walletUUID = walletUUIDReader.get(); + //todo change it to read data from conf yml + private Credentials serverCredentials = new Credentials(walletUUID.toString(), "123"); + + private final AuthorizationServerAPI serverAPI; + + //todo move this to correct method in Module interface + public void initialize() { + String rawPassword = new StringReader(encryptionPasswordFilename).get(); + encryptionPassword = new Password(rawPassword.toCharArray()); + } + + public AuthorizationServerModule() { + serverAPI = new AuthorizationServerAPI(new AuthorizationServerConf(), serverCredentials); + initialize(); + } + + public AuthorizationServerModule(String host, int port) { + AuthorizationServerConf configuration = AuthorizationServerConf.builder().host(host).port(port).build(); + serverAPI = new AuthorizationServerAPI(configuration, serverCredentials); + initialize(); + } + + public AuthorizationServerModule(AuthorizationServerConf configuration) { + serverAPI = new AuthorizationServerAPI(configuration, serverCredentials); + initialize(); + } + + @Override + public String getDescription() { + return "This module is authenticating user with external authorization server."; + } + + @Override + public boolean check() { + return false; + } + + @Override + public byte[] encrypt(byte[] keyPart) throws EncryptionException { + AESEncryptedObject encryptedKeyPart = + CryptoObject.encrypt(new ByteWrapper(keyPart), encryptionPassword); + + byte[] serializedEncryptedKey = SerializationUtils.serialize(encryptedKeyPart); + Secret secret = new Secret(serializedEncryptedKey); + try { + serverAPI.overwriteSecret(secret); + } catch (RequestException e) { + throw new EncryptionException("Failed to save encrypted key part on server."); + } + + // since storing encrypted key part is external server logic + // we just return empty byte array, because it's not important + return new byte[1]; + } + + @Override + public byte[] decrypt(byte[] payload) throws DecryptionException { + try { + Secret encryptedSecret = serverAPI.getSecret(); + AESEncryptedObject deserializedEncryptedSecret = + (AESEncryptedObject)SerializationUtils.deserialize(encryptedSecret.getData()); + + return CryptoObject.decrypt(deserializedEncryptedSecret, encryptionPassword) + .getData(); + + } catch (RequestException e) { + throw new DecryptionException(e.getMessage()); + } + } + + @Override + public void register() { + + } + + @Nullable + @Override + public String getHtmlUi() { + return null; + } + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/RequestException.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/RequestException.java new file mode 100644 index 0000000..b97147b --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/RequestException.java @@ -0,0 +1,15 @@ +package io.raspberrywallet.manager.modules.authorizationserver; + +import java.io.IOException; + +class RequestException extends Exception { + + RequestException(String msg) { + super(msg); + } + + RequestException(IOException e) { + super(e); + } + +} \ No newline at end of file diff --git a/Manager/src/main/java/io/raspberrywallet/manager/session/SessionToken.java b/Manager/src/main/java/io/raspberrywallet/manager/session/SessionToken.java index 0bf1d3e..51e4672 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/session/SessionToken.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/session/SessionToken.java @@ -2,7 +2,7 @@ import io.raspberrywallet.manager.Configuration; import io.raspberrywallet.manager.common.ArrayDestroyer; -import io.raspberrywallet.manager.common.Destroyable; +import io.raspberrywallet.manager.common.interfaces.Destroyable; import java.security.SecureRandom; import java.util.Date; diff --git a/Manager/src/test/java/io/raspberrywallet/manager/cryptography/crypto/AESObjectsTests.java b/Manager/src/test/java/io/raspberrywallet/manager/cryptography/crypto/AESObjectsTests.java index 3c8bd05..4bce316 100644 --- a/Manager/src/test/java/io/raspberrywallet/manager/cryptography/crypto/AESObjectsTests.java +++ b/Manager/src/test/java/io/raspberrywallet/manager/cryptography/crypto/AESObjectsTests.java @@ -19,7 +19,6 @@ public class AESObjectsTests { private static final int randomObjectsAmount = 52; private static final Password defaultPassword = new Password("TestPassword123!@##$%".toCharArray()); - private static CryptoObject cryptoObject = new CryptoObject(); private static Random random = new Random(); private static byte[][] arrayOfRandomSizeObjects; private static Password[] arrayOfRandomPasswords; @@ -47,10 +46,10 @@ void WhenEncrypting_DataDecryptedWithDifferentPasswordDoesThrowException() { ByteWrapper wrappedData = new ByteWrapper(getRandomData()); Password randomPassword = getRandomPassword(); try { - AESEncryptedObject encryptedObject = cryptoObject.encrypt(wrappedData, defaultPassword); + AESEncryptedObject encryptedObject = CryptoObject.encrypt(wrappedData, defaultPassword); assertThrows(DecryptionException.class, () -> { - ByteWrapper decryptedObject = cryptoObject.decrypt(encryptedObject, randomPassword); + ByteWrapper decryptedObject = CryptoObject.decrypt(encryptedObject, randomPassword); }); } catch (EncryptionException e) { @@ -62,8 +61,8 @@ void WhenEncrypting_DataDecryptedWithDifferentPasswordDoesThrowException() { void ObjectDoesNotChange_WhenEncryptedAndDecrypted() { ByteWrapper wrappedData = new ByteWrapper(getRandomData()); try { - AESEncryptedObject encryptedObject = cryptoObject.encrypt(wrappedData, defaultPassword); - ByteWrapper decryptedObject = cryptoObject.decrypt(encryptedObject, defaultPassword); + AESEncryptedObject encryptedObject = CryptoObject.encrypt(wrappedData, defaultPassword); + ByteWrapper decryptedObject = CryptoObject.decrypt(encryptedObject, defaultPassword); assertEquals(wrappedData, decryptedObject); } catch (EncryptionException | DecryptionException e) { @@ -78,10 +77,10 @@ void WhenEncryptingObjectsWithRandomSize_DataEqualsAndEncryptedObjectsChanges() byte[] serializedWrappedData = SerializationUtils.serialize(data); try { - AESEncryptedObject encryptedObject = cryptoObject.encrypt(data, defaultPassword); + AESEncryptedObject encryptedObject = CryptoObject.encrypt(data, defaultPassword); assertFalse(Arrays.areEqual(encryptedObject.getSerializedObject(), serializedWrappedData)); - ByteWrapper decryptObject = cryptoObject.decrypt(encryptedObject, defaultPassword); + ByteWrapper decryptObject = CryptoObject.decrypt(encryptedObject, defaultPassword); assertEquals(decryptObject, data); } catch (EncryptionException e) { @@ -101,10 +100,10 @@ void WhenEncryptingObjectsWithRandomPassword_DataEqualsAndNotExceptionsAreThrown byte[] serializedData = SerializationUtils.serialize(data); try { - AESEncryptedObject encryptedObject = cryptoObject.encrypt(data, arrayOfRandomPasswords[i]); + AESEncryptedObject encryptedObject = CryptoObject.encrypt(data, arrayOfRandomPasswords[i]); assertFalse(Arrays.areEqual(serializedData, encryptedObject.getSerializedObject())); - ByteWrapper decryptObject = cryptoObject.decrypt(encryptedObject, arrayOfRandomPasswords[i]); + ByteWrapper decryptObject = CryptoObject.decrypt(encryptedObject, arrayOfRandomPasswords[i]); assertEquals(decryptObject, data); } catch (EncryptionException e) { diff --git a/Manager/src/test/java/io/raspberrywallet/manager/cryptography/crypto/RSAObjectsTests.java b/Manager/src/test/java/io/raspberrywallet/manager/cryptography/crypto/RSAObjectsTests.java index 55b2ea5..35b3324 100644 --- a/Manager/src/test/java/io/raspberrywallet/manager/cryptography/crypto/RSAObjectsTests.java +++ b/Manager/src/test/java/io/raspberrywallet/manager/cryptography/crypto/RSAObjectsTests.java @@ -20,7 +20,6 @@ public class RSAObjectsTests { private static final RSACipherParams RSA_CIPHER_PARAMS = new RSACipherParams(); private static final KeyPair defaultKeyPair = RSA_CIPHER_PARAMS.getKeyPairDefault(); - private static final CryptoObject cryptoObject = new CryptoObject(); private static final Random random = new Random(); private static byte[][] arrayOfRandomData; @@ -43,10 +42,10 @@ void WhenEncryptingData_DataEqualsAfterDecryptionAndNotExceptionIsThrown() { byte[] serializedData = SerializationUtils.serialize(data); try { - RSAEncryptedObject encryptedObject = cryptoObject.encrypt(data, defaultKeyPair.getPublic()); + RSAEncryptedObject encryptedObject = CryptoObject.encrypt(data, defaultKeyPair.getPublic()); assertFalse(Arrays.equals(encryptedObject.getSerializedObject(), serializedData)); - ByteWrapper decryptedObject = cryptoObject.decrypt(encryptedObject, defaultKeyPair.getPrivate()); + ByteWrapper decryptedObject = CryptoObject.decrypt(encryptedObject, defaultKeyPair.getPrivate()); assertEquals(decryptedObject, data); } catch (EncryptionException e) { @@ -63,10 +62,10 @@ void WhenEncryptingRandomData_DataEqualsAfterDecryption() { byte[] serializedData = SerializationUtils.serialize(data); try { - RSAEncryptedObject encryptedObject = cryptoObject.encrypt(data, defaultKeyPair.getPublic()); + RSAEncryptedObject encryptedObject = CryptoObject.encrypt(data, defaultKeyPair.getPublic()); assertFalse(Arrays.equals(encryptedObject.getSerializedObject(), serializedData)); - ByteWrapper decryptedObject = cryptoObject.decrypt(encryptedObject, defaultKeyPair.getPrivate()); + ByteWrapper decryptedObject = CryptoObject.decrypt(encryptedObject, defaultKeyPair.getPrivate()); assertEquals(decryptedObject, data); } catch (EncryptionException e) { @@ -83,10 +82,10 @@ void WhenDecryptingDataWithWrongKey_ExceptionIsThrown() { KeyPair newKeyPair = RSA_CIPHER_PARAMS.getKeyPairDefault(); try { - RSAEncryptedObject encryptedObject = cryptoObject.encrypt(data, defaultKeyPair.getPublic()); + RSAEncryptedObject encryptedObject = CryptoObject.encrypt(data, defaultKeyPair.getPublic()); assertThrows(DecryptionException.class, () -> { - ByteWrapper decryptedObject = cryptoObject.decrypt(encryptedObject, newKeyPair.getPrivate()); + ByteWrapper decryptedObject = CryptoObject.decrypt(encryptedObject, newKeyPair.getPrivate()); }); } catch (EncryptionException e) { diff --git a/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java b/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java new file mode 100644 index 0000000..a8f3e38 --- /dev/null +++ b/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java @@ -0,0 +1,29 @@ +package io.raspberrywallet.manager.modules.authorizationserver; + + +import io.raspberrywallet.manager.cryptography.crypto.exceptions.DecryptionException; +import io.raspberrywallet.manager.cryptography.crypto.exceptions.EncryptionException; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class AuthServerTests { + + private AuthorizationServerModule module = new AuthorizationServerModule(); + private byte[] encryptionData = "secret data".getBytes(); + + @Test + public void WalletEncryptionAndDecryptionWorks() { + try { + byte[] ignored = module.encrypt(encryptionData); + byte[] decryptedData = module.decrypt(ignored); + assertTrue(Arrays.equals(decryptedData, encryptionData)); + } catch (EncryptionException | DecryptionException e) { + fail(e.getMessage()); + } + } + +} From 5b3835eaeab5111bac7bbd9e917ec54dadf82360 Mon Sep 17 00:00:00 2001 From: Patryk Milewski Date: Thu, 25 Oct 2018 21:36:29 +0200 Subject: [PATCH 2/6] Fixed all problmes, fully working version There are still missing some method implementations of abstract Module class Took 1 hour 36 minutes --- .../manager/common/wrappers/Base64Secret.java | 12 +++++++ .../manager/common/wrappers/Secret.java | 21 ++++++++---- .../cryptography/crypto/EncryptedObject.java | 2 ++ .../AuthorizationServerAPI.java | 34 +++++++++++++------ .../AuthorizationServerModule.java | 23 ++++++++----- .../authorizationserver/AuthServerTests.java | 28 +++++++++++++-- 6 files changed, 93 insertions(+), 27 deletions(-) create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Base64Secret.java diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Base64Secret.java b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Base64Secret.java new file mode 100644 index 0000000..74346d9 --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Base64Secret.java @@ -0,0 +1,12 @@ +package io.raspberrywallet.manager.common.wrappers; + +import java.util.Base64; + +public class Base64Secret extends Secret { + + public Base64Secret(byte[] data) { + byte[] dataConverted = Base64.getEncoder().encode(data); + byteWrapper = new ByteWrapper(dataConverted); + } + +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Secret.java b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Secret.java index 56e1c90..be45d33 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Secret.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Secret.java @@ -6,23 +6,30 @@ public class Secret implements Destroyable { - private ByteWrapper byteWrapper; + ByteWrapper byteWrapper; public byte[] getData() { return byteWrapper.getData(); } - public Secret(byte[] data) { - byte[] dataConverted = Base64.getEncoder().encode(data); - byteWrapper = new ByteWrapper(dataConverted); - } + Secret() {} - public byte[] decode() { - return Base64.getDecoder().decode(byteWrapper.getData()); + /** + * Warning, this constructor assumes, that given data is encoded in Base64 + * @param base64Data base64 encoded data + */ + public Secret(String base64Data) { + byte[] decodedData = Base64.getDecoder().decode(base64Data); + byteWrapper = new ByteWrapper(decodedData); } @Override public void destroy() { byteWrapper.destroy(); } + + @Override + public int hashCode() { + return byteWrapper.hashCode(); + } } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/EncryptedObject.java b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/EncryptedObject.java index 6bd35f0..970841e 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/EncryptedObject.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/cryptography/crypto/EncryptedObject.java @@ -9,6 +9,8 @@ public abstract class EncryptedObject implements Serializable { + private static final long serializationUUID = 63465294432588745L; + private byte[] serializedObject; CipherParams cipherParams; private boolean isEncrypted; diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java index 0ae82ba..0452a7a 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java @@ -5,12 +5,12 @@ import io.raspberrywallet.manager.common.wrappers.Token; import io.raspberrywallet.manager.common.http.ApacheHttpClient; import io.raspberrywallet.manager.common.http.HttpClient; +import org.apache.commons.lang.NotImplementedException; import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.fluent.Form; import org.apache.http.util.EntityUtils; -import sun.reflect.generics.reflectiveObjects.NotImplementedException; import java.io.IOException; import java.time.LocalDate; @@ -82,11 +82,24 @@ boolean isRegistered() throws RequestException { .add(APIKeys.WALLETUUID.val, credentials.getName()); HttpResponse response = executeRequest(requestBody, configuration.getWalletExistsEndpoint()); - isRegisteredFlag = handleResponse(response); - return isRegisteredFlag; + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode == HttpStatus.SC_OK) { + isRegisteredFlag = true; + return true; + } + if (statusCode == HttpStatus.SC_NOT_FOUND) { + isRegisteredFlag = false; + return false; + } else + throw new RequestException("Request failed with error code: " + statusCode); } - Secret getSecret() throws RequestException { + /** + * + * @return Base64 encoded secret + * @throws RequestException + */ + String getSecret() throws RequestException { registerAndLogin(); Form requestBody = Form.form() @@ -95,8 +108,7 @@ Secret getSecret() throws RequestException { try { HttpResponse httpResponse = executeRequest(requestBody, configuration.getGetSecretEndpoint()); - String secret = EntityUtils.toString(httpResponse.getEntity()); - return new Secret(secret.getBytes()); + return EntityUtils.toString(httpResponse.getEntity()); } catch (IOException e) { throw new RequestException(e); } @@ -111,13 +123,13 @@ boolean setSecret(Secret secret) { throw new NotImplementedException(); } - void overwriteSecret(Secret secret) throws RequestException { + void overwriteSecret(String secret) throws RequestException { registerAndLogin(); Form requestBody = Form.form() .add(APIKeys.WALLETUUID.val, credentials.getName()) .add(APIKeys.TOKEN.val, token.getData()) - .add(APIKeys.SECRET.val, new String(secret.getData())); + .add(APIKeys.SECRET.val, secret); HttpResponse response = executeRequest(requestBody, configuration.getOverwriteEndpoint()); handleResponse(response); @@ -141,10 +153,12 @@ private boolean handleResponse(HttpResponse response) throws RequestException { private void registerAndLogin() throws RequestException { if (!isRegisteredCheck()) - register(); + isRegisteredFlag = register(); - if (!isLoggedIn()) + if (!isLoggedIn()) { token = login(); + isLoggedInFlag = true; + } } private boolean isRegisteredCheck() throws RequestException { diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java index cc2db08..872c8af 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java @@ -3,7 +3,6 @@ import io.raspberrywallet.manager.common.readers.StringReader; import io.raspberrywallet.manager.common.wrappers.ByteWrapper; import io.raspberrywallet.manager.common.wrappers.Credentials; -import io.raspberrywallet.manager.common.wrappers.Secret; import io.raspberrywallet.manager.cryptography.common.Password; import io.raspberrywallet.manager.cryptography.crypto.AESEncryptedObject; import io.raspberrywallet.manager.cryptography.crypto.CryptoObject; @@ -14,6 +13,7 @@ import org.apache.commons.lang.SerializationUtils; import org.jetbrains.annotations.Nullable; +import java.util.Base64; import java.util.UUID; public class AuthorizationServerModule extends Module { @@ -63,13 +63,14 @@ public boolean check() { @Override public byte[] encrypt(byte[] keyPart) throws EncryptionException { - AESEncryptedObject encryptedKeyPart = + AESEncryptedObject encryptedSecret = CryptoObject.encrypt(new ByteWrapper(keyPart), encryptionPassword); - byte[] serializedEncryptedKey = SerializationUtils.serialize(encryptedKeyPart); - Secret secret = new Secret(serializedEncryptedKey); + byte[] serializedSecret = SerializationUtils.serialize(encryptedSecret); + String serializedAndEncodedSecret = Base64.getEncoder().encodeToString(serializedSecret); + try { - serverAPI.overwriteSecret(secret); + serverAPI.overwriteSecret(serializedAndEncodedSecret); } catch (RequestException e) { throw new EncryptionException("Failed to save encrypted key part on server."); } @@ -82,9 +83,11 @@ public byte[] encrypt(byte[] keyPart) throws EncryptionException { @Override public byte[] decrypt(byte[] payload) throws DecryptionException { try { - Secret encryptedSecret = serverAPI.getSecret(); + String encodedSecret = serverAPI.getSecret(); + byte[] decodedSecret = Base64.getDecoder().decode(encodedSecret); + AESEncryptedObject deserializedEncryptedSecret = - (AESEncryptedObject)SerializationUtils.deserialize(encryptedSecret.getData()); + (AESEncryptedObject)SerializationUtils.deserialize(decodedSecret); return CryptoObject.decrypt(deserializedEncryptedSecret, encryptionPassword) .getData(); @@ -102,7 +105,11 @@ public void register() { @Nullable @Override public String getHtmlUi() { - return null; + StringBuilder html = new StringBuilder(); + html.append(""); + html.append("
"); + html.append(""); + return html.toString(); } } diff --git a/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java b/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java index a8f3e38..29c1cb5 100644 --- a/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java +++ b/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java @@ -7,20 +7,44 @@ import java.util.Arrays; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue; class AuthServerTests { private AuthorizationServerModule module = new AuthorizationServerModule(); - private byte[] encryptionData = "secret data".getBytes(); @Test public void WalletEncryptionAndDecryptionWorks() { + byte[] encryptionData = "secret data".getBytes(); + byte[] ignored = new byte[1]; + try { - byte[] ignored = module.encrypt(encryptionData); + module.encrypt(encryptionData); byte[] decryptedData = module.decrypt(ignored); + assertTrue(Arrays.equals(decryptedData, encryptionData)); + + } catch (EncryptionException | DecryptionException e) { + fail(e.getMessage()); + } + } + + @Test + public void MultipleEncryptionAndDecryptionOperationWorks() { + byte[] encryptionData = "secret data".getBytes(); + byte[] differentEncryptionData = "different secret data".getBytes(); + byte[] ignored = new byte[1]; + + try { + module.encrypt(encryptionData); + module.encrypt(differentEncryptionData); + byte[] decryptedData = module.decrypt(ignored); + + assertTrue(Arrays.equals(differentEncryptionData, decryptedData)); + assertFalse(Arrays.equals(encryptionData, decryptedData)); + } catch (EncryptionException | DecryptionException e) { fail(e.getMessage()); } From 16f13ddd582989aca249882a55c7b8be7af49372 Mon Sep 17 00:00:00 2001 From: Patryk Milewski Date: Thu, 25 Oct 2018 23:47:34 +0200 Subject: [PATCH 3/6] Merged with current master Changed storing secret logic for authorization server module, now Server is storing encryption key, that is used for key part encryption input from manager Not working version, needs some debugging Took 1 hour 25 minutes --- .../io/raspberrywallet/manager/Manager.java | 5 +- .../manager/modules/Module.java | 9 +- .../AuthorizationServerAPI.java | 75 +++++++----- .../AuthorizationServerConf.java | 1 + .../AuthorizationServerModule.java | 109 ++++++++++-------- .../authorizationserver/AuthServerTests.java | 42 ++++--- 6 files changed, 146 insertions(+), 95 deletions(-) diff --git a/Manager/src/main/java/io/raspberrywallet/manager/Manager.java b/Manager/src/main/java/io/raspberrywallet/manager/Manager.java index 5cfaf59..386dbdd 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/Manager.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/Manager.java @@ -7,6 +7,7 @@ import io.raspberrywallet.WalletStatus; import io.raspberrywallet.manager.bitcoin.Bitcoin; import io.raspberrywallet.manager.cryptography.crypto.exceptions.DecryptionException; +import io.raspberrywallet.manager.cryptography.crypto.exceptions.EncryptionException; import io.raspberrywallet.manager.cryptography.sharedsecret.shamir.Shamir; import io.raspberrywallet.manager.cryptography.sharedsecret.shamir.ShamirException; import io.raspberrywallet.manager.cryptography.sharedsecret.shamir.ShamirKey; @@ -144,10 +145,10 @@ public void restoreFromBackupPhrase(@NotNull List mnemonicCode, Map inputs) { * @param key - key of the parameter * @return - if key exists */ - boolean hasInput(String key) { + protected boolean hasInput(String key) { return input.containsKey(key); } @@ -119,7 +120,7 @@ boolean hasInput(String key) { * @return - value of the parameter */ @Nullable - String getInput(String key) { + protected String getInput(String key) { return input.get(key); } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java index 0452a7a..0370af9 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java @@ -18,29 +18,22 @@ class AuthorizationServerAPI { private AuthorizationServerConf configuration; - private Credentials credentials; private HttpClient httpClient; - private Form preparedCredentials; private Token token; private Boolean isRegisteredFlag, isLoggedInFlag; - AuthorizationServerAPI(AuthorizationServerConf configuration, Credentials credentials) { + AuthorizationServerAPI(AuthorizationServerConf configuration) { this.configuration = configuration; Form defaultHeaders = Form.form() .add(HttpHeaders.CONTENT_TYPE, "application/json") .add("charset", "UTF-8"); - this.credentials = credentials; - preparedCredentials = Form.form() - .add(APIKeys.WALLETUUID.val, credentials.getName()) - .add(APIKeys.PASSWORD.val, credentials.getPassword()); - httpClient = new ApacheHttpClient(configuration.getHost(), defaultHeaders); } - Token login(int sessionLength) throws RequestException { + Token login(Credentials credentials, int sessionLength) throws RequestException { Form requestBody = Form.form() .add(APIKeys.WALLETUUID.val, credentials.getName()) .add(APIKeys.PASSWORD.val, credentials.getPassword()) @@ -49,13 +42,17 @@ Token login(int sessionLength) throws RequestException { return login(requestBody); } - Token login() throws RequestException { - return login(preparedCredentials); + Token login(Credentials credentials) throws RequestException { + return login(credentials, 1800); } private Token login(Form requestBody) throws RequestException { try { HttpResponse httpResponse = executeRequest(requestBody, configuration.getLoginEndpoint()); + int statusCode = httpResponse.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) + throw new RequestException("Request failed with error code: " + statusCode); + String token = EntityUtils.toString(httpResponse.getEntity()); return new Token(token, LocalDate.MAX); } catch (IOException e) { @@ -63,18 +60,26 @@ private Token login(Form requestBody) throws RequestException { } } - boolean logout() throws RequestException { - HttpResponse response = executeRequest(preparedCredentials, configuration.getLogoutEndpoint()); + boolean logout(Credentials credentials) throws RequestException { + Form body = Form.form() + .add(APIKeys.WALLETUUID.val, credentials.getName()) + .add(APIKeys.TOKEN.val, token.getData()); + + HttpResponse response = executeRequest(body, configuration.getLogoutEndpoint()); isLoggedInFlag = !handleResponse(response); return isLoggedInFlag; } - boolean register() throws RequestException { - HttpResponse response = executeRequest(preparedCredentials, configuration.getRegisterEndpoint()); + boolean register(Credentials credentials) throws RequestException { + Form body = Form.form() + .add(APIKeys.WALLETUUID.val, credentials.getName()) + .add(APIKeys.PASSWORD.val, credentials.getPassword()); + + HttpResponse response = executeRequest(body, configuration.getRegisterEndpoint()); return handleResponse(response); } - boolean isRegistered() throws RequestException { + boolean isRegistered(Credentials credentials) throws RequestException { if (isRegisteredFlag != null) return isRegisteredFlag; @@ -99,8 +104,8 @@ boolean isRegistered() throws RequestException { * @return Base64 encoded secret * @throws RequestException */ - String getSecret() throws RequestException { - registerAndLogin(); + String getSecret(Credentials credentials) throws RequestException { + registerAndLogin(credentials); Form requestBody = Form.form() .add(APIKeys.WALLETUUID.val, credentials.getName()) @@ -123,8 +128,8 @@ boolean setSecret(Secret secret) { throw new NotImplementedException(); } - void overwriteSecret(String secret) throws RequestException { - registerAndLogin(); + void overwriteSecret(Credentials credentials, String secret) throws RequestException { + registerAndLogin(credentials); Form requestBody = Form.form() .add(APIKeys.WALLETUUID.val, credentials.getName()) @@ -135,6 +140,22 @@ void overwriteSecret(String secret) throws RequestException { handleResponse(response); } + boolean secretIsSet(Credentials credentials) throws RequestException { + Form requestBody = Form.form() + .add(APIKeys.WALLETUUID.val, credentials.getName()) + .add(APIKeys.TOKEN.val, token.getData()); + + HttpResponse response = executeRequest(requestBody, configuration.getIsSecretSetEndpoint()); + + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode == HttpStatus.SC_OK) + return true; + if (statusCode == HttpStatus.SC_NOT_FOUND) + return false; + else + throw new RequestException("Request failed with error code: " + statusCode); + } + private HttpResponse executeRequest(Form body, String endpoint) throws RequestException { try { return httpClient.sendPOSTRequest(body, endpoint); @@ -151,24 +172,24 @@ private boolean handleResponse(HttpResponse response) throws RequestException { return true; } - private void registerAndLogin() throws RequestException { - if (!isRegisteredCheck()) - isRegisteredFlag = register(); + public void registerAndLogin(Credentials credentials) throws RequestException { + if (!isRegisteredCheck(credentials)) + isRegisteredFlag = register(credentials); if (!isLoggedIn()) { - token = login(); + token = login(credentials); isLoggedInFlag = true; } } - private boolean isRegisteredCheck() throws RequestException { + private boolean isRegisteredCheck(Credentials credentials) throws RequestException { if (isRegisteredFlag == null || !isRegisteredFlag) - isRegisteredFlag = isRegistered(); + isRegisteredFlag = isRegistered(credentials); return isRegisteredFlag; } - private boolean isLoggedIn() { + boolean isLoggedIn() { if (token == null || token.isExpired()) return false; else diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerConf.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerConf.java index 3ea1dde..e758360 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerConf.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerConf.java @@ -24,5 +24,6 @@ class AuthorizationServerConf { private String getSecretEndpoint = address + "/authorization/secret/get"; private String overwriteEndpoint = address + "/authorization/secret/overwrite"; private String walletExistsEndpoint = address + "/authorization/exists"; + private String isSecretSetEndpoint = address + "/authorization/secret/exists"; } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java index 872c8af..4268c41 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java @@ -1,6 +1,5 @@ package io.raspberrywallet.manager.modules.authorizationserver; -import io.raspberrywallet.manager.common.readers.StringReader; import io.raspberrywallet.manager.common.wrappers.ByteWrapper; import io.raspberrywallet.manager.common.wrappers.Credentials; import io.raspberrywallet.manager.cryptography.common.Password; @@ -14,41 +13,37 @@ import org.jetbrains.annotations.Nullable; import java.util.Base64; +import java.util.Random; import java.util.UUID; public class AuthorizationServerModule extends Module { - // todo refactor it to take filename from conf, to avoid file collisions for multiple modules - private final String encryptionPasswordFilename = "serverPassword.key"; - private Password encryptionPassword; + private final static int PASSWORD_SIZE_IN_BYTES = 32; private final WalletUUIDReader walletUUIDReader = WalletUUIDReader.getInstance(); private final UUID walletUUID = walletUUIDReader.get(); + //todo change it to read data from conf yml private Credentials serverCredentials = new Credentials(walletUUID.toString(), "123"); private final AuthorizationServerAPI serverAPI; - //todo move this to correct method in Module interface - public void initialize() { - String rawPassword = new StringReader(encryptionPasswordFilename).get(); - encryptionPassword = new Password(rawPassword.toCharArray()); - } + private Random random = new Random(); public AuthorizationServerModule() { - serverAPI = new AuthorizationServerAPI(new AuthorizationServerConf(), serverCredentials); - initialize(); + super("Please enter username and password for external server."); + serverAPI = new AuthorizationServerAPI(new AuthorizationServerConf()); } public AuthorizationServerModule(String host, int port) { + super("Please enter username and password for external server."); AuthorizationServerConf configuration = AuthorizationServerConf.builder().host(host).port(port).build(); - serverAPI = new AuthorizationServerAPI(configuration, serverCredentials); - initialize(); + serverAPI = new AuthorizationServerAPI(configuration); } public AuthorizationServerModule(AuthorizationServerConf configuration) { - serverAPI = new AuthorizationServerAPI(configuration, serverCredentials); - initialize(); + super("Please enter username and password for external server."); + serverAPI = new AuthorizationServerAPI(configuration); } @Override @@ -58,58 +53,82 @@ public String getDescription() { @Override public boolean check() { - return false; + if (hasInput("password")) { + try { + String password = getInput("password"); + serverCredentials = new Credentials(walletUUID.toString(), password); + initialize(); + } catch (RequestException e) { + return false; + } + return true; + } + else return serverCredentials != null; } - @Override - public byte[] encrypt(byte[] keyPart) throws EncryptionException { - AESEncryptedObject encryptedSecret = - CryptoObject.encrypt(new ByteWrapper(keyPart), encryptionPassword); + + private void initialize() throws RequestException { + if (!serverAPI.isRegistered(serverCredentials)) + serverAPI.register(serverCredentials); - byte[] serializedSecret = SerializationUtils.serialize(encryptedSecret); - String serializedAndEncodedSecret = Base64.getEncoder().encodeToString(serializedSecret); - - try { - serverAPI.overwriteSecret(serializedAndEncodedSecret); - } catch (RequestException e) { - throw new EncryptionException("Failed to save encrypted key part on server."); - } + if (!serverAPI.isLoggedIn()) + serverAPI.login(serverCredentials); + + if (!serverAPI.secretIsSet(serverCredentials)) + serverAPI.overwriteSecret(serverCredentials, getRandomString()); + } - // since storing encrypted key part is external server logic - // we just return empty byte array, because it's not important - return new byte[1]; + private String getRandomString() { + byte[] randomBytes = new byte[PASSWORD_SIZE_IN_BYTES]; + random.nextBytes(randomBytes); + return new String(randomBytes); } @Override - public byte[] decrypt(byte[] payload) throws DecryptionException { + public byte[] encrypt(byte[] payload) throws EncryptionException { try { - String encodedSecret = serverAPI.getSecret(); - byte[] decodedSecret = Base64.getDecoder().decode(encodedSecret); + initialize(); - AESEncryptedObject deserializedEncryptedSecret = - (AESEncryptedObject)SerializationUtils.deserialize(decodedSecret); + String encodedSecret = serverAPI.getSecret(serverCredentials); + Password password = new Password(Base64.getDecoder().decode(encodedSecret)); - return CryptoObject.decrypt(deserializedEncryptedSecret, encryptionPassword) - .getData(); + AESEncryptedObject encryptedSecret = + CryptoObject.encrypt(new ByteWrapper(payload), password); + + return SerializationUtils.serialize(encodedSecret); } catch (RequestException e) { - throw new DecryptionException(e.getMessage()); + throw new EncryptionException(e.getMessage()); } } @Override - public void register() { + public byte[] decrypt(byte[] keyPart) throws DecryptionException { + try { + String encodedSecret = serverAPI.getSecret(serverCredentials); + Password password = new Password(Base64.getDecoder().decode(encodedSecret)); + AESEncryptedObject deserializedKeyPart = + (AESEncryptedObject) SerializationUtils.deserialize(keyPart); + + return CryptoObject.decrypt(deserializedKeyPart, password).getData(); + + } catch (RequestException e) { + throw new DecryptionException(e.getMessage()); + } } + /** + * There is no need to take actions before next encryption/decryption + * operations, so there is no point in implementing this method. + */ + @Override + public void register() {} + @Nullable @Override public String getHtmlUi() { - StringBuilder html = new StringBuilder(); - html.append(""); - html.append("
"); - html.append(""); - return html.toString(); + return ""; } } diff --git a/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java b/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java index 29c1cb5..4235d3d 100644 --- a/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java +++ b/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java @@ -3,26 +3,39 @@ import io.raspberrywallet.manager.cryptography.crypto.exceptions.DecryptionException; import io.raspberrywallet.manager.cryptography.crypto.exceptions.EncryptionException; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.Arrays; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue; class AuthServerTests { - private AuthorizationServerModule module = new AuthorizationServerModule(); + private byte[] encryptionData = "secret data".getBytes(); + private byte[] differentEncryptionData = "different secret data".getBytes(); + + private AuthorizationServerModule module; + + @BeforeEach + void initializeModule() { + module = new AuthorizationServerModule(); + module.setInput("password", "abadziaba123"); + } @Test - public void WalletEncryptionAndDecryptionWorks() { - byte[] encryptionData = "secret data".getBytes(); - byte[] ignored = new byte[1]; + void AuthorizationServerModuleInitializesCorrectly() { + assertTrue(module.check()); + } + @Test + void WalletEncryptionAndDecryptionWorks() { try { - module.encrypt(encryptionData); - byte[] decryptedData = module.decrypt(ignored); + assertTrue(module.check()); + + byte[] data = module.encrypt(encryptionData); + byte[] decryptedData = module.decrypt(data); assertTrue(Arrays.equals(decryptedData, encryptionData)); @@ -32,18 +45,13 @@ public void WalletEncryptionAndDecryptionWorks() { } @Test - public void MultipleEncryptionAndDecryptionOperationWorks() { - byte[] encryptionData = "secret data".getBytes(); - byte[] differentEncryptionData = "different secret data".getBytes(); - byte[] ignored = new byte[1]; - + void MultipleEncryptionAndDecryptionOperationWorks() { try { - module.encrypt(encryptionData); - module.encrypt(differentEncryptionData); - byte[] decryptedData = module.decrypt(ignored); + byte[] firstEncryptedData = module.encrypt(encryptionData); + assertTrue(Arrays.equals(encryptionData, module.decrypt(firstEncryptedData))); - assertTrue(Arrays.equals(differentEncryptionData, decryptedData)); - assertFalse(Arrays.equals(encryptionData, decryptedData)); + byte[] secondEncryptedData = module.encrypt(differentEncryptionData); + assertTrue(Arrays.equals(differentEncryptionData, module.decrypt(secondEncryptedData))); } catch (EncryptionException | DecryptionException e) { fail(e.getMessage()); From 598326d56dacf4cd78f4e8724d71daaecd01ff60 Mon Sep 17 00:00:00 2001 From: Patryk Milewski Date: Fri, 26 Oct 2018 14:30:33 +0200 Subject: [PATCH 4/6] The code is passing tests, functionally working Took 35 minutes --- .../manager/common/wrappers/Credentials.java | 10 +++++-- .../manager/common/wrappers/Token.java | 13 ++++---- .../AuthorizationServerAPI.java | 30 +++++++------------ .../AuthorizationServerModule.java | 9 ++++-- .../authorizationserver/AuthServerTests.java | 2 ++ 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Credentials.java b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Credentials.java index e38377b..a03f578 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Credentials.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Credentials.java @@ -3,11 +3,17 @@ import lombok.AllArgsConstructor; import lombok.Getter; -@Getter +import java.util.Base64; + @AllArgsConstructor +@Getter public class Credentials { private String name; private String password; - + + public String getPasswordBase64() { + return Base64.getEncoder().encodeToString(password.getBytes()); + } + } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Token.java b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Token.java index 5c1540b..ac87193 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Token.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/wrappers/Token.java @@ -4,7 +4,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; -import java.time.LocalDate; +import java.time.LocalDateTime; @AllArgsConstructor @Getter @@ -19,12 +19,13 @@ public class Token { * then even with different expiration date they are the same. */ @EqualsAndHashCode.Exclude - private LocalDate expirationDate; + private LocalDateTime expirationDate; + + public Token(String data, int sessionLength) { + this(data, LocalDateTime.now().plusSeconds(sessionLength)); + } public boolean isExpired() { - if (expirationDate.compareTo(LocalDate.now()) < 0) - return true; - else - return false; + return expirationDate.compareTo(LocalDateTime.now()) < 0; } } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java index 0370af9..3ec0245 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java @@ -13,7 +13,6 @@ import org.apache.http.util.EntityUtils; import java.io.IOException; -import java.time.LocalDate; class AuthorizationServerAPI { @@ -33,28 +32,28 @@ class AuthorizationServerAPI { httpClient = new ApacheHttpClient(configuration.getHost(), defaultHeaders); } - Token login(Credentials credentials, int sessionLength) throws RequestException { + void login(Credentials credentials, int sessionLength) throws RequestException { Form requestBody = Form.form() .add(APIKeys.WALLETUUID.val, credentials.getName()) - .add(APIKeys.PASSWORD.val, credentials.getPassword()) + .add(APIKeys.PASSWORD.val, credentials.getPasswordBase64()) .add(APIKeys.SESSION_LENGTH.val, Integer.toString(sessionLength)); - return login(requestBody); + login(requestBody, sessionLength); } - Token login(Credentials credentials) throws RequestException { - return login(credentials, 1800); + void login(Credentials credentials) throws RequestException { + login(credentials, 1800); } - private Token login(Form requestBody) throws RequestException { + private void login(Form requestBody, int sessionLength) throws RequestException { try { HttpResponse httpResponse = executeRequest(requestBody, configuration.getLoginEndpoint()); int statusCode = httpResponse.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) throw new RequestException("Request failed with error code: " + statusCode); - String token = EntityUtils.toString(httpResponse.getEntity()); - return new Token(token, LocalDate.MAX); + String tokenString = EntityUtils.toString(httpResponse.getEntity()); + token = new Token(tokenString, sessionLength); } catch (IOException e) { throw new RequestException(e); } @@ -73,7 +72,7 @@ boolean logout(Credentials credentials) throws RequestException { boolean register(Credentials credentials) throws RequestException { Form body = Form.form() .add(APIKeys.WALLETUUID.val, credentials.getName()) - .add(APIKeys.PASSWORD.val, credentials.getPassword()); + .add(APIKeys.PASSWORD.val, credentials.getPasswordBase64()); HttpResponse response = executeRequest(body, configuration.getRegisterEndpoint()); return handleResponse(response); @@ -105,8 +104,6 @@ boolean isRegistered(Credentials credentials) throws RequestException { * @throws RequestException */ String getSecret(Credentials credentials) throws RequestException { - registerAndLogin(credentials); - Form requestBody = Form.form() .add(APIKeys.WALLETUUID.val, credentials.getName()) .add(APIKeys.TOKEN.val, token.getData()); @@ -129,8 +126,6 @@ boolean setSecret(Secret secret) { } void overwriteSecret(Credentials credentials, String secret) throws RequestException { - registerAndLogin(credentials); - Form requestBody = Form.form() .add(APIKeys.WALLETUUID.val, credentials.getName()) .add(APIKeys.TOKEN.val, token.getData()) @@ -177,7 +172,7 @@ public void registerAndLogin(Credentials credentials) throws RequestException { isRegisteredFlag = register(credentials); if (!isLoggedIn()) { - token = login(credentials); + login(credentials); isLoggedInFlag = true; } } @@ -190,10 +185,7 @@ private boolean isRegisteredCheck(Credentials credentials) throws RequestExcepti } boolean isLoggedIn() { - if (token == null || token.isExpired()) - return false; - else - return true; + return token != null && !token.isExpired(); } } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java index 4268c41..dc55581 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerModule.java @@ -74,8 +74,11 @@ private void initialize() throws RequestException { if (!serverAPI.isLoggedIn()) serverAPI.login(serverCredentials); - if (!serverAPI.secretIsSet(serverCredentials)) - serverAPI.overwriteSecret(serverCredentials, getRandomString()); + if (!serverAPI.secretIsSet(serverCredentials)) { + String randomSecret = getRandomString(); + String encodedSecret = Base64.getEncoder().encodeToString(randomSecret.getBytes()); + serverAPI.overwriteSecret(serverCredentials, encodedSecret); + } } private String getRandomString() { @@ -95,7 +98,7 @@ public byte[] encrypt(byte[] payload) throws EncryptionException { AESEncryptedObject encryptedSecret = CryptoObject.encrypt(new ByteWrapper(payload), password); - return SerializationUtils.serialize(encodedSecret); + return SerializationUtils.serialize(encryptedSecret); } catch (RequestException e) { throw new EncryptionException(e.getMessage()); diff --git a/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java b/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java index 4235d3d..722cd03 100644 --- a/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java +++ b/Manager/src/test/java/io/raspberrywallet/manager/modules/authorizationserver/AuthServerTests.java @@ -47,6 +47,8 @@ void WalletEncryptionAndDecryptionWorks() { @Test void MultipleEncryptionAndDecryptionOperationWorks() { try { + assertTrue(module.check()); + byte[] firstEncryptedData = module.encrypt(encryptionData); assertTrue(Arrays.equals(encryptionData, module.decrypt(firstEncryptedData))); From 45009c463511458da4ee5d6f8e966bf0f3fd1f3b Mon Sep 17 00:00:00 2001 From: Patryk Milewski Date: Mon, 29 Oct 2018 12:37:19 +0100 Subject: [PATCH 5/6] Renamed HttpClient classes to ApacheHttpClient Removed unused StringReader class Removed unused host parameter from HttpClients constructors Changed access modifiers from protected to public in Module class Took 42 minutes --- .../manager/common/http/ApacheHttpClient.java | 52 +++-------------- .../manager/common/http/HttpClient.java | 24 -------- ...ava => SecuredApacheApacheHttpClient.java} | 2 +- .../http/UnsecuredApacheApacheHttpClient.java | 56 +++++++++++++++++++ .../manager/common/readers/StringReader.java | 56 ------------------- .../manager/modules/Module.java | 6 +- .../AuthorizationServerAPI.java | 6 +- 7 files changed, 72 insertions(+), 130 deletions(-) delete mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/http/HttpClient.java rename Manager/src/main/java/io/raspberrywallet/manager/common/http/{ApacheSecuredHttpClient.java => SecuredApacheApacheHttpClient.java} (88%) create mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecuredApacheApacheHttpClient.java delete mode 100644 Manager/src/main/java/io/raspberrywallet/manager/common/readers/StringReader.java diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheHttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheHttpClient.java index 1df79ec..68a7c33 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheHttpClient.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheHttpClient.java @@ -1,58 +1,24 @@ package io.raspberrywallet.manager.common.http; -import org.apache.commons.lang.NotImplementedException; -import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.fluent.Form; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicHeader; import org.json.JSONObject; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -public class ApacheHttpClient extends HttpClient { - - private String host; - private Header[] defaultHeaders; - - public ApacheHttpClient(String host, Form defaultHeaders) { - this.host = host; - this.defaultHeaders = toHeadersArray(defaultHeaders); - } +public abstract class ApacheHttpClient { + + public abstract HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException; - @Override - public HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException { - org.apache.http.client.HttpClient client = HttpClients.createDefault(); - - JSONObject jsonObject = convert(body); - StringEntity stringEntity = new StringEntity(jsonObject.toString()); - - HttpPost httpRequest = new HttpPost(endpoint); - httpRequest.setEntity(stringEntity); - httpRequest.setHeaders(defaultHeaders); - - return client.execute(httpRequest); - } + public abstract HttpResponse sendGETRequest(Form body, String endpoint); - @Override - public HttpResponse sendGETRequest(Form body, String endpoint) { - throw new NotImplementedException(); + JSONObject convert(Form body) { + List keyValuesList = body.build(); + JSONObject convertedJson = new JSONObject(); + keyValuesList.forEach(pair -> convertedJson.put(pair.getName(), pair.getValue())); + return convertedJson; } - private Header[] toHeadersArray(Form form) { - List list = form.build(); - List
result = new ArrayList<>(list.size()); - list.forEach(nameValuePair -> { - BasicHeader basicHeader = new BasicHeader(nameValuePair.getName(), nameValuePair.getValue()); - result.add(basicHeader); - }); - - Header[] headers = new Header[result.size()]; - return result.toArray(headers); - } } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/HttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/HttpClient.java deleted file mode 100644 index 4b9c809..0000000 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/http/HttpClient.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.raspberrywallet.manager.common.http; - -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.fluent.Form; -import org.json.JSONObject; - -import java.io.IOException; -import java.util.List; - -public abstract class HttpClient { - - public abstract HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException; - - public abstract HttpResponse sendGETRequest(Form body, String endpoint); - - JSONObject convert(Form body) { - List keyValuesList = body.build(); - JSONObject convertedJson = new JSONObject(); - keyValuesList.forEach(pair -> convertedJson.put(pair.getName(), pair.getValue())); - return convertedJson; - } - -} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheSecuredHttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/SecuredApacheApacheHttpClient.java similarity index 88% rename from Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheSecuredHttpClient.java rename to Manager/src/main/java/io/raspberrywallet/manager/common/http/SecuredApacheApacheHttpClient.java index 0fca90f..747c7f8 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/http/ApacheSecuredHttpClient.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/http/SecuredApacheApacheHttpClient.java @@ -6,7 +6,7 @@ import java.io.IOException; -public class ApacheSecuredHttpClient extends HttpClient { +public class SecuredApacheApacheHttpClient extends ApacheHttpClient { @Override public HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException { diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecuredApacheApacheHttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecuredApacheApacheHttpClient.java new file mode 100644 index 0000000..1868567 --- /dev/null +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecuredApacheApacheHttpClient.java @@ -0,0 +1,56 @@ +package io.raspberrywallet.manager.common.http; + +import org.apache.commons.lang.NotImplementedException; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.fluent.Form; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicHeader; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class UnsecuredApacheApacheHttpClient extends ApacheHttpClient { + + private Header[] defaultHeaders; + + public UnsecuredApacheApacheHttpClient(Form defaultHeaders) { + this.defaultHeaders = toHeadersArray(defaultHeaders); + } + + @Override + public HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException { + org.apache.http.client.HttpClient client = HttpClients.createDefault(); + + JSONObject jsonObject = convert(body); + StringEntity stringEntity = new StringEntity(jsonObject.toString()); + + HttpPost httpRequest = new HttpPost(endpoint); + httpRequest.setEntity(stringEntity); + httpRequest.setHeaders(defaultHeaders); + + return client.execute(httpRequest); + } + + @Override + public HttpResponse sendGETRequest(Form body, String endpoint) { + throw new NotImplementedException(); + } + + private Header[] toHeadersArray(Form form) { + List list = form.build(); + List
result = new ArrayList<>(list.size()); + list.forEach(nameValuePair -> { + BasicHeader basicHeader = new BasicHeader(nameValuePair.getName(), nameValuePair.getValue()); + result.add(basicHeader); + }); + + Header[] headers = new Header[result.size()]; + return result.toArray(headers); + } +} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/readers/StringReader.java b/Manager/src/main/java/io/raspberrywallet/manager/common/readers/StringReader.java deleted file mode 100644 index 585a8b5..0000000 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/readers/StringReader.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.raspberrywallet.manager.common.readers; - -import lombok.Getter; -import lombok.Setter; -import lombok.Synchronized; - -import java.security.SecureRandom; - -public class StringReader extends Reader { - - private final SecureRandom secureRandom = new SecureRandom(); - - @Getter - @Setter - private int stringSizeInBytes = 16; - - private final String filePath; - - private String value; - - public StringReader(String filePath) { - this.filePath = WALLET_DIR + filePath; - } - - /** - * Get String from file, or if it does not exists, - * then get random String and save it to file. - * @return String read from file or randomly generated with SecureRandom. - */ - @Synchronized - public String get() { - if (value != null) - return value; - - if (fileExists()) { - value = read(); - return value; - } - - value = getRandomString(); - write(value); - return value; - } - - private String getRandomString() { - byte[] randomBytes = new byte[stringSizeInBytes]; - secureRandom.nextBytes(randomBytes); - return new String(randomBytes); - } - - @Override - String getFilePath() { - return filePath; - } - -} diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/Module.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/Module.java index 2d5b1e2..7bb2721 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/Module.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/Module.java @@ -82,7 +82,7 @@ public String getStatusString() { * * @param status - new status */ - protected void setStatusString(@NotNull String status) { + public void setStatusString(@NotNull String status) { this.statusString = status; } @@ -109,7 +109,7 @@ public void setInputs(Map inputs) { * @param key - key of the parameter * @return - if key exists */ - protected boolean hasInput(String key) { + public boolean hasInput(String key) { return input.containsKey(key); } @@ -120,7 +120,7 @@ protected boolean hasInput(String key) { * @return - value of the parameter */ @Nullable - protected String getInput(String key) { + public String getInput(String key) { return input.get(key); } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java index 3ec0245..aba3314 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java @@ -3,8 +3,8 @@ import io.raspberrywallet.manager.common.wrappers.Credentials; import io.raspberrywallet.manager.common.wrappers.Secret; import io.raspberrywallet.manager.common.wrappers.Token; +import io.raspberrywallet.manager.common.http.UnsecuredApacheApacheHttpClient; import io.raspberrywallet.manager.common.http.ApacheHttpClient; -import io.raspberrywallet.manager.common.http.HttpClient; import org.apache.commons.lang.NotImplementedException; import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; @@ -18,7 +18,7 @@ class AuthorizationServerAPI { private AuthorizationServerConf configuration; - private HttpClient httpClient; + private ApacheHttpClient httpClient; private Token token; private Boolean isRegisteredFlag, isLoggedInFlag; @@ -29,7 +29,7 @@ class AuthorizationServerAPI { .add(HttpHeaders.CONTENT_TYPE, "application/json") .add("charset", "UTF-8"); - httpClient = new ApacheHttpClient(configuration.getHost(), defaultHeaders); + httpClient = new UnsecuredApacheApacheHttpClient(defaultHeaders); } void login(Credentials credentials, int sessionLength) throws RequestException { From f1be534093c9400df6043b255824d089326a376c Mon Sep 17 00:00:00 2001 From: Patryk Milewski Date: Mon, 29 Oct 2018 14:55:19 +0100 Subject: [PATCH 6/6] Fixed class names Took 24 minutes --- ...pacheHttpClient.java => SecureApacheApacheHttpClient.java} | 2 +- ...cheHttpClient.java => UnsecureApacheApacheHttpClient.java} | 4 ++-- .../modules/authorizationserver/AuthorizationServerAPI.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename Manager/src/main/java/io/raspberrywallet/manager/common/http/{SecuredApacheApacheHttpClient.java => SecureApacheApacheHttpClient.java} (88%) rename Manager/src/main/java/io/raspberrywallet/manager/common/http/{UnsecuredApacheApacheHttpClient.java => UnsecureApacheApacheHttpClient.java} (92%) diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/SecuredApacheApacheHttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/SecureApacheApacheHttpClient.java similarity index 88% rename from Manager/src/main/java/io/raspberrywallet/manager/common/http/SecuredApacheApacheHttpClient.java rename to Manager/src/main/java/io/raspberrywallet/manager/common/http/SecureApacheApacheHttpClient.java index 747c7f8..a963a1f 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/http/SecuredApacheApacheHttpClient.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/http/SecureApacheApacheHttpClient.java @@ -6,7 +6,7 @@ import java.io.IOException; -public class SecuredApacheApacheHttpClient extends ApacheHttpClient { +public class SecureApacheApacheHttpClient extends ApacheHttpClient { @Override public HttpResponse sendPOSTRequest(Form body, String endpoint) throws IOException { diff --git a/Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecuredApacheApacheHttpClient.java b/Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecureApacheApacheHttpClient.java similarity index 92% rename from Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecuredApacheApacheHttpClient.java rename to Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecureApacheApacheHttpClient.java index 1868567..c445313 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecuredApacheApacheHttpClient.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/common/http/UnsecureApacheApacheHttpClient.java @@ -15,11 +15,11 @@ import java.util.ArrayList; import java.util.List; -public class UnsecuredApacheApacheHttpClient extends ApacheHttpClient { +public class UnsecureApacheApacheHttpClient extends ApacheHttpClient { private Header[] defaultHeaders; - public UnsecuredApacheApacheHttpClient(Form defaultHeaders) { + public UnsecureApacheApacheHttpClient(Form defaultHeaders) { this.defaultHeaders = toHeadersArray(defaultHeaders); } diff --git a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java index aba3314..698ec45 100644 --- a/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java +++ b/Manager/src/main/java/io/raspberrywallet/manager/modules/authorizationserver/AuthorizationServerAPI.java @@ -3,7 +3,7 @@ import io.raspberrywallet.manager.common.wrappers.Credentials; import io.raspberrywallet.manager.common.wrappers.Secret; import io.raspberrywallet.manager.common.wrappers.Token; -import io.raspberrywallet.manager.common.http.UnsecuredApacheApacheHttpClient; +import io.raspberrywallet.manager.common.http.UnsecureApacheApacheHttpClient; import io.raspberrywallet.manager.common.http.ApacheHttpClient; import org.apache.commons.lang.NotImplementedException; import org.apache.http.HttpHeaders; @@ -29,7 +29,7 @@ class AuthorizationServerAPI { .add(HttpHeaders.CONTENT_TYPE, "application/json") .add("charset", "UTF-8"); - httpClient = new UnsecuredApacheApacheHttpClient(defaultHeaders); + httpClient = new UnsecureApacheApacheHttpClient(defaultHeaders); } void login(Credentials credentials, int sessionLength) throws RequestException {