diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java index 2a04db189..7b87371ad 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/Constants.java @@ -143,7 +143,6 @@ public final class Constants { public static final String SYNC_KEYSERVER = "syncKeyserver"; public static final String ENABLE_WIFI_SYNC_ONLY = "enableWifiSyncOnly"; // other settings - public static final String EXPERIMENTAL_ENABLE_WORD_CONFIRM = "experimentalEnableWordConfirm"; public static final String EXPERIMENTAL_ENABLE_LINKED_IDENTITIES = "experimentalEnableLinkedIdentities"; public static final String EXPERIMENTAL_ENABLE_KEYBASE = "experimentalEnableKeybase"; public static final String EXPERIMENTAL_USB_ALLOW_UNTESTED = "experimentalUsbAllowUntested"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/experimental/BitInputStream.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/experimental/BitInputStream.java deleted file mode 100644 index 111e0b366..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/experimental/BitInputStream.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) Andreas Jakl - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.experimental; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; - -/** - * The BitInputStream allows reading individual bits from a - * general Java InputStream. - * Like the various Stream-classes from Java, the BitInputStream - * has to be created based on another Input stream. It provides - * a function to read the next bit from the stream, as well as to read multiple - * bits at once and write the resulting data into an integer value. - *

- * source: http://developer.nokia.com/Community/Wiki/Bit_Input/Output_Stream_utility_classes_for_efficient_data_transfer - */ -public class BitInputStream { - /** - * The Java InputStream this class is working on. - */ - private InputStream iIs; - - /** - * The buffer containing the currently processed - * byte of the input stream. - */ - private int iBuffer; - - /** - * Next bit of the current byte value that the user will - * get. If it's 8, the next bit will be read from the - * next byte of the InputStream. - */ - private int iNextBit = 8; - - /** - * Create a new bit input stream based on an existing Java InputStream. - * - * @param aIs the input stream this class should read the bits from. - */ - public BitInputStream(InputStream aIs) { - iIs = aIs; - } - - /** - * Read a specified number of bits and return them combined as - * an integer value. The bits are written to the integer - * starting at the highest bit ( << aNumberOfBits ), going down - * to the lowest bit ( << 0 ) - * - * @param aNumberOfBits defines how many bits to read from the stream. - * @return integer value containing the bits read from the stream. - * @throws IOException - */ - synchronized public int readBits(final int aNumberOfBits, boolean stuffIfEnd) - throws IOException { - int value = 0; - for (int i = aNumberOfBits - 1; i >= 0; i--) { - value |= (readBit(stuffIfEnd) << i); - } - return value; - } - - synchronized public int available() { - try { - return (8 - iNextBit) + iIs.available() * 8; // bytestream to bitstream available - } catch (Exception e) { - return 0; - } - } - - /** - * Read the next bit from the stream. - * - * @return 0 if the bit is 0, 1 if the bit is 1. - * @throws IOException - */ - synchronized public int readBit(boolean stuffIfEnd) throws IOException { - if (iIs == null) - throw new IOException("Already closed"); - - if (iNextBit == 8) { - iBuffer = iIs.read(); - - if (iBuffer == -1) { - if (stuffIfEnd) { - return 1; - } else { - throw new EOFException(); - } - } - - iNextBit = 0; - } - - int bit = iBuffer & (1 << iNextBit); - iNextBit++; - - bit = (bit == 0) ? 0 : 1; - - return bit; - } - - /** - * Close the underlying input stream. - * - * @throws IOException - */ - public void close() throws IOException { - iIs.close(); - iIs = null; - } -} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/experimental/SentenceConfirm.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/experimental/SentenceConfirm.java deleted file mode 100644 index 0374d878c..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/experimental/SentenceConfirm.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2015 Dominik Schürmann - * Copyright (C) 2014 Jake McGinty (Open Whisper Systems) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.experimental; - -import android.content.Context; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.util.Log; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - -/** - * From https://github.com/mcginty/TextSecure/tree/mnemonic-poem - */ -public class SentenceConfirm { - Context context; - List n, vi, vt, adj, adv, p, art; - - public SentenceConfirm(Context context) { - this.context = context; - try { - n = readFile(R.raw.fp_sentence_nouns); - vi = readFile(R.raw.fp_sentence_verbs_i); - vt = readFile(R.raw.fp_sentence_verbs_t); - adj = readFile(R.raw.fp_sentence_adjectives); - adv = readFile(R.raw.fp_sentence_adverbs); - p = readFile(R.raw.fp_sentence_prepositions); - art = readFile(R.raw.fp_sentence_articles); - } catch (IOException e) { - Log.e(Constants.TAG, "Reading sentence files failed", e); - } - } - - List readFile(int resId) throws IOException { - if (context.getApplicationContext() == null) { - throw new AssertionError("app context can't be null"); - } - - BufferedReader in = new BufferedReader(new InputStreamReader( - context.getApplicationContext() - .getResources() - .openRawResource(resId))); - List words = new ArrayList<>(); - String word = in.readLine(); - while (word != null) { - words.add(word); - word = in.readLine(); - } - in.close(); - return words; - } - - public String fromBytes(final byte[] bytes, int desiredBytes) throws IOException { - BitInputStream bin = new BitInputStream(new ByteArrayInputStream(bytes)); - EntropyString fingerprint = new EntropyString(); - - while (fingerprint.getBits() < (desiredBytes * 8)) { - if (!fingerprint.isEmpty()) { - fingerprint.append("\n\n"); - } - try { - fingerprint.append(getSentence(bin)); - } catch (IOException e) { - Log.e(Constants.TAG, "IOException when creating the sentence"); - throw e; - } - } - return fingerprint.toString(); - } - - /** - * Grab a word for a list of them using the necessary bits to choose from a BitInputStream - * - * @param words the list of words to select from - * @param bin the bit input stream to encode from - * @return A Pair of the word and the number of bits consumed from the stream - */ - private EntropyString getWord(List words, BitInputStream bin) throws IOException { - final int neededBits = log(words.size(), 2); - Log.d(Constants.TAG, "need: " + neededBits + " bits of entropy"); - Log.d(Constants.TAG, "available: " + bin.available() + " bits"); - if (neededBits > bin.available()) { - Log.d(Constants.TAG, "stuffed with " + (neededBits - bin.available()) + " ones!"); - } - int bits = bin.readBits(neededBits, true); - Log.d(Constants.TAG, "got word " + words.get(bits) + " with " + neededBits + " bits of entropy"); - return new EntropyString(words.get(bits), neededBits); - } - - private EntropyString getNounPhrase(BitInputStream bits) throws IOException { - final EntropyString phrase = new EntropyString(); - phrase.append(getWord(art, bits)).append(" "); - if (bits.readBit(true) != 0) { - phrase.append(getWord(adj, bits)).append(" "); - } - phrase.incBits(); - - phrase.append(getWord(n, bits)); - Log.d(Constants.TAG, "got phrase " + phrase + " with " + phrase.getBits() + " bits of entropy"); - return phrase; - } - - EntropyString getSentence(BitInputStream bits) throws IOException { - final EntropyString sentence = new EntropyString(); - sentence.append(getNounPhrase(bits)); // Subject - if (bits.readBit(true) != 0) { - sentence.append(" ").append(getWord(vt, bits)); // Transitive verb - sentence.append(" ").append(getNounPhrase(bits)); // Object of transitive verb - } else { - sentence.append(" ").append(getWord(vi, bits)); // Intransitive verb - } - sentence.incBits(); - - if (bits.readBit(true) != 0) { - sentence.append(" ").append(getWord(adv, bits)); // Adverb - } - - sentence.incBits(); - if (bits.readBit(true) != 0) { - sentence.append(" ").append(getWord(p, bits)); // Preposition - sentence.append(" ").append(getNounPhrase(bits)); // Object of preposition - } - sentence.incBits(); - Log.d(Constants.TAG, "got sentence '" + sentence + "' with " + sentence.getBits() + " bits of entropy"); - - // uppercase first character, end with dot (without increasing the bits) - sentence.getBuilder().replace(0, 1, - Character.toString(Character.toUpperCase(sentence.getBuilder().charAt(0)))); - sentence.getBuilder().append("."); - - return sentence; - } - - public static class EntropyString { - private StringBuilder builder; - private int bits; - - public EntropyString(String phrase, int bits) { - this.builder = new StringBuilder(phrase); - this.bits = bits; - } - - public EntropyString() { - this("", 0); - } - - public StringBuilder getBuilder() { - return builder; - } - - public boolean isEmpty() { - return builder.length() == 0; - } - - public EntropyString append(EntropyString phrase) { - builder.append(phrase); - bits += phrase.getBits(); - return this; - } - - public EntropyString append(String string) { - builder.append(string); - return this; - } - - public int getBits() { - return bits; - } - - public void setBits(int bits) { - this.bits = bits; - } - - public void incBits() { - bits += 1; - } - - @Override - public String toString() { - return builder.toString(); - } - } - - private static int log(int x, int base) { - return (int) (Math.log(x) / Math.log(base)); - } - -} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java index c5528e40b..016ab5f3c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java @@ -30,8 +30,6 @@ public class CertifyFingerprintActivity extends BaseActivity { protected Uri mDataUri; - public static final String EXTRA_ENABLE_WORD_CONFIRM = "enable_word_confirm"; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -42,7 +40,6 @@ public class CertifyFingerprintActivity extends BaseActivity { finish(); return; } - boolean enableWordConfirm = getIntent().getBooleanExtra(EXTRA_ENABLE_WORD_CONFIRM, false); setFullScreenDialogClose(new View.OnClickListener() { @Override @@ -53,7 +50,7 @@ public class CertifyFingerprintActivity extends BaseActivity { Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); - startFragment(savedInstanceState, mDataUri, enableWordConfirm); + startFragment(savedInstanceState, mDataUri); } @Override @@ -61,7 +58,7 @@ public class CertifyFingerprintActivity extends BaseActivity { setContentView(R.layout.certify_fingerprint_activity); } - private void startFragment(Bundle savedInstanceState, Uri dataUri, boolean enableWordConfirm) { + private void startFragment(Bundle savedInstanceState, Uri dataUri) { // However, if we're being restored from a previous state, // then we don't need to do anything and should return or else // we could end up with overlapping fragments. @@ -70,7 +67,7 @@ public class CertifyFingerprintActivity extends BaseActivity { } // Create an instance of the fragment - CertifyFingerprintFragment frag = CertifyFingerprintFragment.newInstance(dataUri, enableWordConfirm); + CertifyFingerprintFragment frag = CertifyFingerprintFragment.newInstance(dataUri); // Add the fragment to the 'fragment_container' FrameLayout // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java index 5ca39964b..6811a13f7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java @@ -35,7 +35,6 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.experimental.SentenceConfirm; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; @@ -50,7 +49,6 @@ public class CertifyFingerprintFragment extends LoaderFragment implements static final int REQUEST_CERTIFY = 1; public static final String ARG_DATA_URI = "uri"; - public static final String ARG_ENABLE_PHRASES_CONFIRM = "enable_word_confirm"; private TextView mActionYes; private TextView mFingerprint; @@ -60,16 +58,14 @@ public class CertifyFingerprintFragment extends LoaderFragment implements private static final int LOADER_ID_UNIFIED = 0; private Uri mDataUri; - private boolean mEnablePhrasesConfirm; /** * Creates new instance of this fragment */ - public static CertifyFingerprintFragment newInstance(Uri dataUri, boolean enablePhrasesConfirm) { + public static CertifyFingerprintFragment newInstance(Uri dataUri) { CertifyFingerprintFragment frag = new CertifyFingerprintFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_DATA_URI, dataUri); - args.putBoolean(ARG_ENABLE_PHRASES_CONFIRM, enablePhrasesConfirm); frag.setArguments(args); @@ -114,13 +110,6 @@ public class CertifyFingerprintFragment extends LoaderFragment implements getActivity().finish(); return; } - mEnablePhrasesConfirm = getArguments().getBoolean(ARG_ENABLE_PHRASES_CONFIRM); - - if (mEnablePhrasesConfirm) { - mIntro.setText(R.string.certify_fingerprint_text_phrases); - mHeader.setText(R.string.section_phrases); - mActionYes.setText(R.string.btn_match_phrases); - } loadData(dataUri); } @@ -169,11 +158,7 @@ public class CertifyFingerprintFragment extends LoaderFragment implements if (data.moveToFirst()) { byte[] fingerprintBlob = data.getBlob(INDEX_UNIFIED_FINGERPRINT); - if (mEnablePhrasesConfirm) { - displayWordConfirm(fingerprintBlob); - } else { - displayHexConfirm(fingerprintBlob); - } + displayHexConfirm(fingerprintBlob); break; } @@ -188,20 +173,6 @@ public class CertifyFingerprintFragment extends LoaderFragment implements mFingerprint.setText(KeyFormattingUtils.formatFingerprint(fingerprint)); } - private void displayWordConfirm(byte[] fingerprintBlob) { - String fingerprint; - try { - fingerprint = new SentenceConfirm(getActivity()).fromBytes(fingerprintBlob, 20); - } catch (IOException e) { - fingerprint = "-"; - Log.e(Constants.TAG, "Problem when creating sentence!", e); - } - - mFingerprint.setTextSize(18); - mFingerprint.setTypeface(Typeface.DEFAULT, Typeface.BOLD); - mFingerprint.setText(fingerprint); - } - /** * This is called when the last Cursor provided to onLoadFinished() above is about to be closed. * We need to make sure we are no longer using it. diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java index 0e9df8c4a..324da4e91 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java @@ -375,11 +375,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements return true; } case R.id.menu_key_view_certify_fingerprint: { - certifyFingerprint(mDataUri, false); - return true; - } - case R.id.menu_key_view_certify_fingerprint_word: { - certifyFingerprint(mDataUri, true); + certifyFingerprint(mDataUri); return true; } } @@ -396,9 +392,6 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint); certifyFingerprint.setVisible(!mIsSecret && !mIsVerified && !mIsExpired && !mIsRevoked); - MenuItem certifyFingerprintWord = menu.findItem(R.id.menu_key_view_certify_fingerprint_word); - certifyFingerprintWord.setVisible(!mIsSecret && !mIsVerified && !mIsExpired && !mIsRevoked - && Preferences.getPreferences(this).getExperimentalEnableWordConfirm()); return true; } @@ -471,10 +464,9 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements startActivityForResult(scanQrCode, REQUEST_QR_FINGERPRINT); } - private void certifyFingerprint(Uri dataUri, boolean enableWordConfirm) { + private void certifyFingerprint(Uri dataUri) { Intent intent = new Intent(this, CertifyFingerprintActivity.class); intent.setData(dataUri); - intent.putExtra(CertifyFingerprintActivity.EXTRA_ENABLE_WORD_CONFIRM, enableWordConfirm); startActivityForResult(intent, REQUEST_CERTIFY); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java index 8983452a7..3e9d3d7bf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java @@ -400,10 +400,6 @@ public class Preferences { // experimental prefs - public boolean getExperimentalEnableWordConfirm() { - return mSharedPreferences.getBoolean(Pref.EXPERIMENTAL_ENABLE_WORD_CONFIRM, false); - } - public boolean getExperimentalEnableLinkedIdentities() { return mSharedPreferences.getBoolean(Pref.EXPERIMENTAL_ENABLE_LINKED_IDENTITIES, false); } diff --git a/OpenKeychain/src/main/res/menu/key_view.xml b/OpenKeychain/src/main/res/menu/key_view.xml index e16b3a152..54fc1020e 100644 --- a/OpenKeychain/src/main/res/menu/key_view.xml +++ b/OpenKeychain/src/main/res/menu/key_view.xml @@ -40,10 +40,4 @@ android:visible="false" app:showAsAction="never" /> - - diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 8b053f59d..c50a93087 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -66,7 +66,6 @@ "Key" "Keyserver" "Fingerprint" - "Phrases" "Encrypt" "Decrypt/Verify" "Current expiry" @@ -88,7 +87,6 @@ "Back" "No" "Fingerprints match" - "Phrases match" "Encrypt/sign and share text" "Encrypt/sign and copy text" "Encrypt/sign and paste text" @@ -224,8 +222,6 @@ "Warning" "These features are not yet finished or results of user experience/security research. Thus, don't rely on their security and please don't report issues you encounter!" - "Confirmation with phrases" - "Confirm keys with phrases instead of hexadecimal fingerprints" "Linked Identities" "Link keys to Twitter, GitHub, websites or DNS (similar to keybase.io but decentralized)" "Keybase.io proofs" @@ -1503,7 +1499,6 @@ "Identities for " "The keys you are importing contain “identities”: names and email addresses. Select exactly those for confirmation which match what you expected." "Compare the fingerprint, character by character, with the one displayed on your partner’s device." - "Compare these phrases with the ones displayed on your partner’s device." "Revocation Reason" "Type" "Key not found!" diff --git a/OpenKeychain/src/main/res/xml/experimental_preferences.xml b/OpenKeychain/src/main/res/xml/experimental_preferences.xml index 1e922063e..e557f06e6 100644 --- a/OpenKeychain/src/main/res/xml/experimental_preferences.xml +++ b/OpenKeychain/src/main/res/xml/experimental_preferences.xml @@ -5,13 +5,6 @@ android:summary="@string/label_experimental_settings_desc_summary" android:title="@string/label_experimental_settings_desc_title" /> - -