From 0505507d1df36a3c9e1d8524b9ee2d6b4ab25a84 Mon Sep 17 00:00:00 2001 From: Felix Prahl-Kamps Date: Mon, 27 May 2019 20:03:27 +0200 Subject: [PATCH] improve documentation --- .idea/inspectionProfiles/Project_Default.xml | 15 ------ .idea/misc.xml | 6 +++ .../lu/circl/mispbump/auxiliary/KeyValue.java | 5 ++ .../mispbump/auxiliary/PreferenceManager.java | 42 ++++++++++++++--- .../restful_client/MispRestClient.java | 8 +++- .../restful_client/MispRestService.java | 5 +- .../circl/mispbump/security/AESSecurity.java | 31 +++++++----- .../mispbump/security/KeyStoreWrapper.java | 47 +++++++++++++++++-- 8 files changed, 119 insertions(+), 40 deletions(-) delete mode 100644 .idea/inspectionProfiles/Project_Default.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 786a0ea..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 10467e7..08f9851 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/lu/circl/mispbump/auxiliary/KeyValue.java b/app/src/main/java/lu/circl/mispbump/auxiliary/KeyValue.java index fe9b2e9..b0e02e1 100644 --- a/app/src/main/java/lu/circl/mispbump/auxiliary/KeyValue.java +++ b/app/src/main/java/lu/circl/mispbump/auxiliary/KeyValue.java @@ -4,6 +4,11 @@ public class KeyValue { public K key; public V value; + /** + * Generates a generic key value pair. + * @param key key + * @param value value + */ public KeyValue(K key, V value) { this.key = key; this.value = value; diff --git a/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java b/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java index 1906186..1963166 100644 --- a/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java +++ b/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java @@ -5,10 +5,14 @@ import android.content.SharedPreferences; import com.google.gson.Gson; +import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; @@ -39,11 +43,12 @@ public class PreferenceManager { /** * Helper class to save and retrieve (sensitive) information to and from SharedPreferences. + * * @param context for accessing the SharedPreferences file. * @return singleton instance */ public static PreferenceManager getInstance(Context context) { - if(instance == null) { + if (instance == null) { instance = new PreferenceManager(context); } @@ -53,6 +58,7 @@ public class PreferenceManager { /** * Saves user infos from "users/view/me" (encrypted) + * * @param user */ public void setUserInfo(User user) { @@ -77,6 +83,7 @@ public class PreferenceManager { } /** + * Returns the user information if already stored and decrypts it. * * @return decrypted user info if any, else null */ @@ -110,6 +117,7 @@ public class PreferenceManager { /** * Save user org infos from "organisations/view/{orgId}" (encrypted) + * * @param organisation Object representation of json organisation information */ public void setUserOrgInfo(Organisation organisation) { @@ -135,12 +143,13 @@ public class PreferenceManager { } /** + * Returns the user organisation information if already stored and decrypts it. * * @return decrypted user org info if any, else null */ public Organisation getUserOrganisation() { - if(!preferences.contains(USER_ORG_INFOS)) { + if (!preferences.contains(USER_ORG_INFOS)) { return null; } @@ -167,7 +176,8 @@ public class PreferenceManager { /** - * Saves the encrypted auth key/automation key + * Encrypts the automation key and stores it in preferences. + * * @param automationKey */ public void setAutomationKey(String automationKey) { @@ -189,6 +199,11 @@ public class PreferenceManager { } } + /** + * Decrypts the stored automation key and returns it. + * + * @return the decr + */ public String getAutomationKey() { if (!preferences.contains(AUTOMATION_KEY)) { @@ -215,6 +230,9 @@ public class PreferenceManager { return ""; } + /** + * Delete the key to decrypt this entry and the entry itself. + */ public void clearAutomationKey() { // remove the key from KeyStore KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.AUTOMATION_ALIAS); @@ -227,8 +245,9 @@ public class PreferenceManager { /** - * Saves the encrypted URL of Misp Server - * @param serverUrl + * Encrypts the server url and stores it in preferences. + * + * @param serverUrl url of the corresponding misp instance */ public void setServerUrl(String serverUrl) { try { @@ -251,6 +270,11 @@ public class PreferenceManager { } } + /** + * Decrypts the stored server url and returns it + * + * @return decrypted misp instance url + */ public String getServerUrl() { if (!preferences.contains(SERVER_URL)) { @@ -278,6 +302,9 @@ public class PreferenceManager { return ""; } + /** + * Delete the key to decrypt this entry and the entry itself. + */ public void clearServerUrl() { // remove the key from KeyStore KeyStoreWrapper keyStoreWrapper = new KeyStoreWrapper(KeyStoreWrapper.SERVER_URL_ALIAS); @@ -291,7 +318,10 @@ public class PreferenceManager { /** * Set if credentials (authkey & server url) should be saved locally. + * * @param save enable or disable + * @deprecated currently not used because automation key is needed to do requests to your misp instance. + * If this should be an option in future: misp automation key would be needed on each sync process. */ public void setSaveCredentials(boolean save) { SharedPreferences.Editor editor = preferences.edit(); @@ -309,4 +339,4 @@ public class PreferenceManager { editor.clear(); editor.apply(); } -} +} \ No newline at end of file diff --git a/app/src/main/java/lu/circl/mispbump/restful_client/MispRestClient.java b/app/src/main/java/lu/circl/mispbump/restful_client/MispRestClient.java index da61799..92ec224 100644 --- a/app/src/main/java/lu/circl/mispbump/restful_client/MispRestClient.java +++ b/app/src/main/java/lu/circl/mispbump/restful_client/MispRestClient.java @@ -25,6 +25,10 @@ import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; +/** + * Implementation of the RetroFit2 Misp client. + * In order to conveniently use this api some wrapper interfaces are implemented to return the requested API endpoint as java object. + */ public class MispRestClient { // callbacks and interfaces @@ -81,7 +85,7 @@ public class MispRestClient { } /** - * For development only! + * NOTE: for development only! * Accepts all certificates so self signed certs are also accepted. * @return OkHttpClient which accepts all certificates */ @@ -343,4 +347,4 @@ public class MispRestClient { } }); } -} +} \ No newline at end of file diff --git a/app/src/main/java/lu/circl/mispbump/restful_client/MispRestService.java b/app/src/main/java/lu/circl/mispbump/restful_client/MispRestService.java index 5ae9f93..eeb7786 100644 --- a/app/src/main/java/lu/circl/mispbump/restful_client/MispRestService.java +++ b/app/src/main/java/lu/circl/mispbump/restful_client/MispRestService.java @@ -8,6 +8,9 @@ import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.Path; +/** + * RetroFit2 interface for communication with misp instances + */ public interface MispRestService { // user routes @@ -36,4 +39,4 @@ public interface MispRestService { @POST("servers/add") Call addServer(@Body MispServer server); -} +} \ No newline at end of file diff --git a/app/src/main/java/lu/circl/mispbump/security/AESSecurity.java b/app/src/main/java/lu/circl/mispbump/security/AESSecurity.java index 427f87d..052b599 100644 --- a/app/src/main/java/lu/circl/mispbump/security/AESSecurity.java +++ b/app/src/main/java/lu/circl/mispbump/security/AESSecurity.java @@ -18,6 +18,7 @@ public class AESSecurity { private static final String KEY_PAIR_ALGORITHM = "EC"; private static final int KEY_SIZE = 521; // 224 | 256 | 384 | 521 private static final String KEY_AGREEMENT_ALGORITHM = "ECDH"; + private static final String KEY_FACTORY_ALGORITHM = "EC"; private static AESSecurity instance; @@ -31,9 +32,9 @@ public class AESSecurity { initialize(); } - /*** - * Generates a public and a private key using an elliptic curve algorithm (256 bit) - * The private key is fed into the key agreement instance + /** + * Generates a public and a private key using an elliptic curve algorithm. + * The private key is fed into the key agreement instance. */ private void initialize() { @@ -52,9 +53,9 @@ public class AESSecurity { } } - /*** - * Generates a shared secret with a given public key - * @param publickey + /** + * Generates a shared secret and derives an initialisation vector from it. + * @param publickey public key of the sync partner */ public void setForeignPublicKey(PublicKey publickey) { @@ -72,6 +73,11 @@ public class AESSecurity { } } + /** + * + * @param data + * @return + */ public String encrypt(String data) { try { @@ -93,6 +99,11 @@ public class AESSecurity { return data; } + /** + * + * @param data + * @return + */ public String decrypt(String data) { try { Key key = generateKey(); @@ -119,9 +130,7 @@ public class AESSecurity { } private Key generateKey() { - return new SecretKeySpec(sharedSecret, ENCRYPT_ALGORITHM); - } public static String publicKeyToString(PublicKey key) { @@ -129,11 +138,10 @@ public class AESSecurity { } public static PublicKey publicKeyFromString(String key) { - try { byte[] input = Base64.decode(key, Base64.DEFAULT); - return KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(input)); + return KeyFactory.getInstance(KEY_FACTORY_ALGORITHM).generatePublic(new X509EncodedKeySpec(input)); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { e.printStackTrace(); @@ -143,12 +151,9 @@ public class AESSecurity { } public static AESSecurity getInstance() { - if(instance == null) { instance = new AESSecurity(); } - return instance; } } - diff --git a/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java b/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java index 1396fae..2af8db5 100644 --- a/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java +++ b/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java @@ -40,10 +40,17 @@ public class KeyStoreWrapper { private String KEYSTORE_ALIAS; + /** + * Wraps the android key store to easily encrypt and decrypt sensitive data. + * @param alias identifies a key store entry (see public static ALIAS variables). + */ public KeyStoreWrapper(String alias) { KEYSTORE_ALIAS = alias; } + /** + * @return wheter an entry for this alias already exists. + */ private boolean isInitialized() { try { KeyStore ks = KeyStore.getInstance(KEYSTORE_PROVIDER); @@ -66,6 +73,10 @@ public class KeyStoreWrapper { } + /** + * + * @return SecretKey associated with the given alias. + */ private SecretKey getStoredKey() { try { @@ -88,6 +99,10 @@ public class KeyStoreWrapper { return null; } + /** + * Generates a new key. + * @return the newly generated key. + */ private SecretKey generateKey() { try { @@ -117,7 +132,9 @@ public class KeyStoreWrapper { return null; } - + /** + * Deletes the key associated with the current alias. + */ public void deleteStoredKey() { try { KeyStore ks = KeyStore.getInstance(KEYSTORE_PROVIDER); @@ -134,6 +151,16 @@ public class KeyStoreWrapper { } } + /** + * Encrypt data with given algorithm and key associated with alias. + * @param data data to encrypt. + * @return encrypted data as String. + * @throws NoSuchPaddingException + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + * @throws BadPaddingException + * @throws IllegalBlockSizeException + */ public String encrypt(String data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { SecretKey secretKey; @@ -153,6 +180,17 @@ public class KeyStoreWrapper { return ivString + ":::" + encryptedDataString; } + /** + * Decrypts data with given algorithm and key associated with alias. + * @param input encrypted data. + * @return decrypted data as String. + * @throws NoSuchPaddingException + * @throws NoSuchAlgorithmException + * @throws InvalidAlgorithmParameterException + * @throws InvalidKeyException + * @throws BadPaddingException + * @throws IllegalBlockSizeException + */ public String decrypt(String input) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { // extract iv from save data @@ -169,7 +207,10 @@ public class KeyStoreWrapper { return new String(cipher.doFinal(data), StandardCharsets.UTF_8); } - + /** + * Removes all aliases and the associated keys. + * Note: all encrypted data cannot be decrypted anymore! + */ public static void deleteAllStoredKeys() { try { @@ -195,4 +236,4 @@ public class KeyStoreWrapper { e.printStackTrace(); } } -} +} \ No newline at end of file