Proof of concept: protected text

pull/209/head
M66B 2 years ago
parent 8ebc9245d8
commit 98c3599d0b

@ -37,7 +37,9 @@ import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.QuoteSpan;
import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.util.Base64;
import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.Menu;
@ -56,9 +58,16 @@ import androidx.preference.PreferenceManager;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.util.List;
import java.util.concurrent.ExecutorService;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
@ -113,6 +122,7 @@ public class EditTextCompose extends FixedEditText {
int order = 1000;
menu.add(Menu.CATEGORY_SECONDARY, R.string.title_insert_brackets, order++, context.getString(R.string.title_insert_brackets));
menu.add(Menu.CATEGORY_SECONDARY, R.string.title_insert_quotes, order++, context.getString(R.string.title_insert_quotes));
menu.add(Menu.CATEGORY_SECONDARY, R.string.title_protect_text, order++, context.getString(R.string.title_protect_text));
} catch (Throwable ex) {
Log.e(ex);
}
@ -137,6 +147,8 @@ public class EditTextCompose extends FixedEditText {
return surround("(", ")");
else if (id == R.string.title_insert_quotes)
return surround("\"", "\"");
else if (id == R.string.title_protect_text)
return protect();
}
return false;
}
@ -166,6 +178,81 @@ public class EditTextCompose extends FixedEditText {
}
return selection;
}
private boolean protect() {
Editable edit = getText();
int start = getSelectionStart();
int end = getSelectionEnd();
boolean selection = (edit != null && start >= 0 && start < end);
if (selection)
executor.submit(new Runnable() {
@Override
public void run() {
try {
String password = "FairEmail";
String text = HtmlHelper.toHtml((Spanned) edit.subSequence(start, end), context);
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16]; // 128 bits
random.nextBytes(salt);
byte[] iv = new byte[12]; // 96 bites
random.nextBytes(iv);
// Iterations = 120,000; Keylength = 256 bits = 32 bytes
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 120000, 256);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
SecretKey key = skf.generateSecret(spec);
// Authentication tag length = 128 bits = 16 bytes
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv);
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
byte[] cipherText = cipher.doFinal(text.getBytes());
ByteBuffer out = ByteBuffer.allocate(1 + salt.length + iv.length + cipherText.length);
out.put((byte) 1); //version
out.put(salt);
out.put(iv);
out.put(cipherText);
String fragment = Base64.encodeToString(out.array(), Base64.URL_SAFE | Base64.NO_WRAP);
post(new Runnable() {
@Override
public void run() {
try {
if (getSelectionStart() != start || getSelectionEnd() != end)
return;
String title = context.getString(R.string.title_decrypt);
String url = "https://email.faircode.eu/decrypt/#" + fragment;
edit.delete(start, end);
edit.insert(start, title);
edit.setSpan(new URLSpan(url), start, start + title.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
setSelection(start + title.length());
} catch (Throwable ex) {
Log.e(ex);
}
}
});
} catch (Throwable ex) {
Log.e(ex);
post(new Runnable() {
@Override
public void run() {
ToastEx.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
}
});
}
}
});
return selection;
}
});
setCustomInsertionActionModeCallback(new ActionMode.Callback() {

@ -1954,6 +1954,7 @@
<string name="title_select_block">Select block</string>
<string name="title_insert_brackets">Bracket</string>
<string name="title_insert_quotes">Quote</string>
<string name="title_protect_text">Protect</string>
<string name="title_add">Add</string>
<string name="title_browse">Open with</string>
<string name="title_info">Info</string>

Loading…
Cancel
Save