mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-05 08:45:08 -05:00
implemented secret keys without passphrase
This commit is contained in:
parent
4793cd1c25
commit
4eebeede2b
@ -25,15 +25,14 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:fillViewport="true"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp" >
|
||||
android:fillViewport="true" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="4dp" >
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -98,7 +98,7 @@
|
||||
<string name="menu_keyServer">Key Server</string>
|
||||
<string name="menu_updateKey">Update</string>
|
||||
<string name="menu_exportKeyToServer">Export To Server</string>
|
||||
<string name="menu_share">Share</string>
|
||||
<string name="menu_share">Share with QR Code</string>
|
||||
<string name="menu_scanQRCode">Scan QR Code</string>
|
||||
<string name="menu_signKey">Sign Key</string>
|
||||
|
||||
|
@ -27,6 +27,7 @@ import org.apg.ui.widget.KeyEditor;
|
||||
import org.apg.ui.widget.SectionView;
|
||||
import org.apg.ui.widget.UserIdEditor;
|
||||
import org.apg.util.IterableIterator;
|
||||
import org.apg.util.Utils;
|
||||
import org.spongycastle.bcpg.ArmoredInputStream;
|
||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
@ -155,6 +156,7 @@ public class Apg {
|
||||
public static final String EXTRA_BINARY = "binary";
|
||||
public static final String EXTRA_KEY_SERVERS = "keyServers";
|
||||
public static final String EXTRA_EXPECTED_FINGERPRINT = "expectedFingerprint";
|
||||
public static final String EXTRA_NO_PASSPHRASE = "noPassphrase";
|
||||
|
||||
public static final String AUTHORITY = DataProvider.AUTHORITY;
|
||||
|
||||
@ -374,18 +376,6 @@ public class Apg {
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
private static long getNumDaysBetween(GregorianCalendar first, GregorianCalendar second) {
|
||||
GregorianCalendar tmp = new GregorianCalendar();
|
||||
tmp.setTime(first.getTime());
|
||||
long numDays = (second.getTimeInMillis() - first.getTimeInMillis()) / 1000 / 86400;
|
||||
tmp.add(Calendar.DAY_OF_MONTH, (int) numDays);
|
||||
while (tmp.before(second)) {
|
||||
tmp.add(Calendar.DAY_OF_MONTH, 1);
|
||||
++numDays;
|
||||
}
|
||||
return numDays;
|
||||
}
|
||||
|
||||
public static void buildSecretKey(Activity context, SectionView userIdsView,
|
||||
SectionView keysView, String oldPassPhrase, String newPassPhrase,
|
||||
ProgressDialogUpdater progress) throws Apg.GeneralException, NoSuchProviderException,
|
||||
@ -509,7 +499,7 @@ public class Apg {
|
||||
GregorianCalendar creationDate = new GregorianCalendar();
|
||||
creationDate.setTime(getCreationDate(masterKey));
|
||||
GregorianCalendar expiryDate = keyEditor.getExpiryDate();
|
||||
long numDays = getNumDaysBetween(creationDate, expiryDate);
|
||||
long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
|
||||
if (numDays <= 0) {
|
||||
throw new GeneralException(
|
||||
context.getString(R.string.error_expiryMustComeAfterCreation));
|
||||
@ -517,8 +507,10 @@ public class Apg {
|
||||
hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
if (progress != null) {
|
||||
progress.setProgress(R.string.progress_buildingMasterKeyRing, 30, 100);
|
||||
}
|
||||
|
||||
PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
|
||||
masterKeyPair, mainUserId, PGPEncryptedData.CAST5, newPassPhrase.toCharArray(),
|
||||
hashedPacketsGen.generate(), unhashedPacketsGen.generate(), new SecureRandom(),
|
||||
@ -558,7 +550,7 @@ public class Apg {
|
||||
GregorianCalendar creationDate = new GregorianCalendar();
|
||||
creationDate.setTime(getCreationDate(masterKey));
|
||||
GregorianCalendar expiryDate = keyEditor.getExpiryDate();
|
||||
long numDays = getNumDaysBetween(creationDate, expiryDate);
|
||||
long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
|
||||
if (numDays <= 0) {
|
||||
throw new GeneralException(
|
||||
context.getString(R.string.error_expiryMustComeAfterCreation));
|
||||
@ -2202,7 +2194,7 @@ public class Apg {
|
||||
return false;
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
// unpossible!
|
||||
// impossible!
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2216,7 +2208,7 @@ public class Apg {
|
||||
VERSION = pi.versionName;
|
||||
return VERSION;
|
||||
} catch (NameNotFoundException e) {
|
||||
// unpossible!
|
||||
// impossible!
|
||||
return "0.0.0";
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
@ -86,7 +87,7 @@ public class AskForSecretKeyPassPhrase {
|
||||
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
activity.removeDialog(Id.dialog.pass_phrase);
|
||||
String passPhrase = "" + input.getText();
|
||||
String passPhrase = input.getText().toString();
|
||||
long keyId;
|
||||
if (secretKey != null) {
|
||||
try {
|
||||
@ -116,6 +117,23 @@ public class AskForSecretKeyPassPhrase {
|
||||
}
|
||||
});
|
||||
|
||||
// check if the key has no passphrase
|
||||
if (secretKey != null) {
|
||||
try {
|
||||
Log.d("APG", "check if key has no passphrase...");
|
||||
PGPPrivateKey testKey = secretKey.extractPrivateKey("".toCharArray(),
|
||||
new BouncyCastleProvider());
|
||||
if (testKey != null) {
|
||||
Log.d("APG", "Key has no passphrase!");
|
||||
|
||||
cb.passPhraseCallback(secretKey.getKeyID(), null);
|
||||
|
||||
return null;
|
||||
}
|
||||
} catch (PGPException e) {
|
||||
|
||||
}
|
||||
}
|
||||
return alert.create();
|
||||
}
|
||||
}
|
||||
|
@ -118,16 +118,12 @@ public class DecryptActivity extends BaseActivity {
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
if (mDecryptEnabled) {
|
||||
menu.add(1, Id.menu.option.decrypt, 0, mDecryptString)
|
||||
// .setIcon(R.drawable.ic_menu_encrypt)
|
||||
.setShowAsAction(
|
||||
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
menu.add(1, Id.menu.option.decrypt, 0, mDecryptString).setShowAsAction(
|
||||
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
}
|
||||
if (mReplyEnabled) {
|
||||
menu.add(1, Id.menu.option.reply, 1, mReplyString)
|
||||
// .setIcon(R.drawable.ic_menu_decrypt)
|
||||
.setShowAsAction(
|
||||
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
menu.add(1, Id.menu.option.reply, 1, mReplyString).setShowAsAction(
|
||||
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -275,9 +271,8 @@ public class DecryptActivity extends BaseActivity {
|
||||
// replace non breakable spaces
|
||||
textData = textData.replaceAll("\\xa0", " ");
|
||||
mMessage.setText(textData);
|
||||
|
||||
mDecryptString = getString(R.string.btn_verify);
|
||||
// mDecryptButton.setText(R.string.btn_verify);
|
||||
|
||||
// build new action bar
|
||||
invalidateOptionsMenu();
|
||||
} else {
|
||||
@ -399,8 +394,6 @@ public class DecryptActivity extends BaseActivity {
|
||||
|
||||
if (mSource.getCurrentView().getId() == R.id.sourceMessage
|
||||
&& (mMessage.getText().length() > 0 || mData != null || mContentUri != null)) {
|
||||
// mDecryptButton.performClick();
|
||||
// TODO: why was it performClick()???
|
||||
decryptClicked();
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.view.LayoutInflater;
|
||||
@ -49,7 +48,6 @@ import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.Toast;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
|
||||
@ -72,6 +70,8 @@ public class EditKeyActivity extends BaseActivity {
|
||||
|
||||
private Button mChangePassPhrase;
|
||||
|
||||
private CheckBox mNoPassphrase;
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
menu.add(1, Id.menu.option.cancel, 0, R.string.btn_doNotSave).setShowAsAction(
|
||||
@ -152,6 +152,14 @@ public class EditKeyActivity extends BaseActivity {
|
||||
if (extras.containsKey(Apg.EXTRA_USER_IDS)) {
|
||||
userIds.add(extras.getString(Apg.EXTRA_USER_IDS));
|
||||
}
|
||||
|
||||
// if userId is given, prefill the fields
|
||||
if (extras.containsKey(Apg.EXTRA_NO_PASSPHRASE)) {
|
||||
boolean noPassphrase = extras.getBoolean(Apg.EXTRA_NO_PASSPHRASE);
|
||||
if (noPassphrase) {
|
||||
mCurrentPassPhrase = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase);
|
||||
@ -162,12 +170,15 @@ public class EditKeyActivity extends BaseActivity {
|
||||
});
|
||||
|
||||
// disable passphrase when no passphrase checkobox is checked!
|
||||
final CheckBox noPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
|
||||
noPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
|
||||
mNoPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if (isChecked) {
|
||||
// remove passphrase
|
||||
mNewPassPhrase = null;
|
||||
|
||||
mChangePassPhrase.setVisibility(View.GONE);
|
||||
} else {
|
||||
mChangePassPhrase.setVisibility(View.VISIBLE);
|
||||
@ -194,6 +205,12 @@ public class EditKeyActivity extends BaseActivity {
|
||||
mCurrentPassPhrase = "";
|
||||
}
|
||||
|
||||
if (mCurrentPassPhrase.equals("")) {
|
||||
// check "no passphrase" checkbox and remove button
|
||||
mNoPassphrase.setChecked(true);
|
||||
mChangePassPhrase.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
updatePassPhraseButtonText();
|
||||
}
|
||||
|
||||
@ -204,9 +221,15 @@ public class EditKeyActivity extends BaseActivity {
|
||||
return ((KeyEditor) mKeys.getEditors().getChildAt(0)).getValue().getKeyID();
|
||||
}
|
||||
|
||||
public boolean havePassPhrase() {
|
||||
return (!mCurrentPassPhrase.equals(""))
|
||||
|| (mNewPassPhrase != null && !mNewPassPhrase.equals(""));
|
||||
public boolean isPassphraseSet() {
|
||||
if (mNoPassphrase.isChecked()) {
|
||||
return true;
|
||||
} else if ((!mCurrentPassPhrase.equals(""))
|
||||
|| (mNewPassPhrase != null && !mNewPassPhrase.equals(""))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -215,7 +238,7 @@ public class EditKeyActivity extends BaseActivity {
|
||||
case Id.dialog.new_pass_phrase: {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
||||
|
||||
if (havePassPhrase()) {
|
||||
if (isPassphraseSet()) {
|
||||
alert.setTitle(R.string.title_changePassPhrase);
|
||||
} else {
|
||||
alert.setTitle(R.string.title_setPassPhrase);
|
||||
@ -266,7 +289,7 @@ public class EditKeyActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
private void saveClicked() {
|
||||
if (!havePassPhrase()) {
|
||||
if (!isPassphraseSet()) {
|
||||
Toast.makeText(this, R.string.setAPassPhrase, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
@ -333,7 +356,7 @@ public class EditKeyActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
private void updatePassPhraseButtonText() {
|
||||
mChangePassPhrase.setText(havePassPhrase() ? R.string.btn_changePassPhrase
|
||||
mChangePassPhrase.setText(isPassphraseSet() ? R.string.btn_changePassPhrase
|
||||
: R.string.btn_setPassPhrase);
|
||||
}
|
||||
}
|
||||
|
@ -49,15 +49,13 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
menu.add(3, Id.menu.option.search, 0, R.string.menu_search)
|
||||
.setIcon(R.drawable.ic_menu_search)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
menu.add(1, Id.menu.option.create, 1, R.string.menu_createKey)
|
||||
.setShowAsAction(
|
||||
MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
menu.add(0, Id.menu.option.import_keys, 2, R.string.menu_importKeys)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
menu.add(0, Id.menu.option.export_keys, 3, R.string.menu_exportKeys)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
.setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
menu.add(1, Id.menu.option.create, 1, R.string.menu_createKey).setShowAsAction(
|
||||
MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
menu.add(0, Id.menu.option.import_keys, 2, R.string.menu_importKeys).setShowAsAction(
|
||||
MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
menu.add(0, Id.menu.option.export_keys, 3, R.string.menu_exportKeys).setShowAsAction(
|
||||
MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -114,7 +112,6 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
||||
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
|
||||
.getGroupId(mSelectedItem);
|
||||
String msg = keyId + "," + Apg.getFingerPrint(keyId);
|
||||
;
|
||||
|
||||
new IntentIntegrator(this).shareText(msg);
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package org.apg.util;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@ -51,4 +53,23 @@ public class Utils {
|
||||
return stream.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number if days between two dates
|
||||
*
|
||||
* @param first
|
||||
* @param second
|
||||
* @return number of days
|
||||
*/
|
||||
public static long getNumDaysBetween(GregorianCalendar first, GregorianCalendar second) {
|
||||
GregorianCalendar tmp = new GregorianCalendar();
|
||||
tmp.setTime(first.getTime());
|
||||
long numDays = (second.getTimeInMillis() - first.getTimeInMillis()) / 1000 / 86400;
|
||||
tmp.add(Calendar.DAY_OF_MONTH, (int) numDays);
|
||||
while (tmp.before(second)) {
|
||||
tmp.add(Calendar.DAY_OF_MONTH, 1);
|
||||
++numDays;
|
||||
}
|
||||
return numDays;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user