implemented secret keys without passphrase

This commit is contained in:
Dominik 2012-04-13 16:54:50 +02:00
parent 4793cd1c25
commit 4eebeede2b
8 changed files with 98 additions and 55 deletions

View File

@ -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"

View File

@ -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>

View File

@ -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";
}
}

View File

@ -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();
}
}

View File

@ -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);
mDecryptString = getString(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();
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;
}
}