diff --git a/org_apg/src/org/thialfihar/android/apg/Apg.java b/org_apg/src/org/thialfihar/android/apg/Apg.java index d702f6883..6d966324a 100644 --- a/org_apg/src/org/thialfihar/android/apg/Apg.java +++ b/org_apg/src/org/thialfihar/android/apg/Apg.java @@ -399,29 +399,26 @@ public class Apg { PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() .setProvider("SC").build(passPhrase.toCharArray()); - PGPSecretKeyRing secKeyRing = null; + PGPKeyRingGenerator ringGen = null; if (masterSecretKey == null) { // build keyRing with only this one master key in it! - PGPKeyRingGenerator ringGen = new PGPKeyRingGenerator( - PGPSignature.DEFAULT_CERTIFICATION, keyPair, "", sha1Calc, null, null, - certificationSignerBuilder, keyEncryptor); - - secKeyRing = ringGen.generateSecretKeyRing(); + ringGen = new PGPKeyRingGenerator(PGPSignature.DEFAULT_CERTIFICATION, keyPair, "", + sha1Calc, null, null, certificationSignerBuilder, keyEncryptor); } else { PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey(); PGPPrivateKey masterPrivateKey = masterSecretKey.extractPrivateKey(keyDecryptor); PGPKeyPair masterKeyPair = new PGPKeyPair(masterPublicKey, masterPrivateKey); // build keyRing with master key and new key as subkey (certified by masterkey) - PGPKeyRingGenerator ringGen = new PGPKeyRingGenerator( - PGPSignature.DEFAULT_CERTIFICATION, masterKeyPair, "", sha1Calc, null, null, - certificationSignerBuilder, keyEncryptor); + ringGen = new PGPKeyRingGenerator(PGPSignature.DEFAULT_CERTIFICATION, masterKeyPair, + "", sha1Calc, null, null, certificationSignerBuilder, keyEncryptor); ringGen.addSubKey(keyPair); - secKeyRing = ringGen.generateSecretKeyRing(); } + PGPSecretKeyRing secKeyRing = ringGen.generateSecretKeyRing(); + return secKeyRing; } diff --git a/org_apg/src/org/thialfihar/android/apg/service/ApgHandler.java b/org_apg/src/org/thialfihar/android/apg/service/ApgHandler.java index fe848fb68..90353976b 100644 --- a/org_apg/src/org/thialfihar/android/apg/service/ApgHandler.java +++ b/org_apg/src/org/thialfihar/android/apg/service/ApgHandler.java @@ -41,6 +41,7 @@ public class ApgHandler extends Handler { // generate key results public static final String NEW_KEY = "new_key"; + public static final String NEW_KEY2 = "new_key2"; Activity mActivity; diff --git a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java index b7b2b24bc..a52bcb927 100644 --- a/org_apg/src/org/thialfihar/android/apg/service/ApgService.java +++ b/org_apg/src/org/thialfihar/android/apg/service/ApgService.java @@ -22,6 +22,7 @@ import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.thialfihar.android.apg.Apg; import org.thialfihar.android.apg.Constants; +import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.ProgressDialogUpdater; import org.thialfihar.android.apg.util.Utils; @@ -64,6 +65,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater { // possible ints for EXTRA_ACTION public static final int ACTION_SAVE_KEYRING = 1; public static final int ACTION_GENERATE_KEY = 2; + public static final int ACTION_GENERATE_DEFAULT_RSA_KEYS = 3; Messenger mMessenger; @@ -162,6 +164,31 @@ public class ApgService extends IntentService implements ProgressDialogUpdater { break; + case ACTION_GENERATE_DEFAULT_RSA_KEYS: + // generate one RSA 2048 key for signing and one subkey for encrypting! + try { + String passphrase = data.getString(PASSPHRASE); + + // Operation + PGPSecretKeyRing masterKeyRing = Apg.createKey(this, Id.choice.algorithm.rsa, 2048, + passphrase, null); + + PGPSecretKeyRing subKeyRing = Apg.createKey(this, Id.choice.algorithm.rsa, 2048, + passphrase, masterKeyRing.getSecretKey()); + + // Output + Bundle resultData = new Bundle(); + resultData.putByteArray(ApgHandler.NEW_KEY, + Utils.PGPSecretKeyRingToBytes(masterKeyRing)); + resultData.putByteArray(ApgHandler.NEW_KEY2, + Utils.PGPSecretKeyRingToBytes(subKeyRing)); + sendMessageToHandler(ApgHandler.MESSAGE_OKAY, null, resultData); + } catch (Exception e) { + Log.e(Constants.TAG, "Creating initial key failed: +" + e); + } + + break; + default: break; } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java index dc102ce12..822eb28d2 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java @@ -58,6 +58,7 @@ import android.widget.LinearLayout; import android.widget.Toast; import android.widget.CompoundButton.OnCheckedChangeListener; +import java.util.Iterator; import java.util.Vector; public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseActivity { @@ -66,8 +67,8 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA private PGPSecretKeyRing mKeyRing = null; - private SectionView mUserIds; - private SectionView mKeys; + private SectionView mUserIdsView; + private SectionView mKeysView; private String mCurrentPassPhrase = null; private String mNewPassPhrase = null; @@ -77,6 +78,11 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA private CheckBox mNoPassphrase; private ProgressDialogFragment mSavingDialog; + private ProgressDialogFragment mGeneratingDialog; + + Vector mUserIds; + Vector mKeys; + Vector mKeysUsages; @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -131,9 +137,9 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase); mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase); - Vector userIds = new Vector(); - Vector keys = new Vector(); - Vector keysUsages = new Vector(); + mUserIds = new Vector(); + mKeys = new Vector(); + mKeysUsages = new Vector(); // Catch Intents opened from other apps mIntent = getIntent(); @@ -150,7 +156,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA // if userId is given, prefill the fields if (extras.containsKey(Apg.EXTRA_USER_IDS)) { Log.d(Constants.TAG, "UserIds are given!"); - userIds.add(extras.getString(Apg.EXTRA_USER_IDS)); + mUserIds.add(extras.getString(Apg.EXTRA_USER_IDS)); } // if no passphrase is given @@ -169,25 +175,62 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA .getBoolean(Apg.EXTRA_GENERATE_DEFAULT_KEYS); if (generateDefaultKeys) { -// // generate a RSA 2048 key for encryption and signing! -// try { -// PGPSecretKey masterKey = Apg.createKey(this, Id.choice.algorithm.rsa, -// 2048, mCurrentPassPhrase, null); -// -// // add new masterKey to keys array, which is then added to view -// keys.add(masterKey); -// keysUsages.add(Id.choice.usage.sign_only); -// -// PGPSecretKey subKey = Apg.createKey(this, Id.choice.algorithm.rsa, -// 2048, mCurrentPassPhrase, masterKey); -// -// keys.add(subKey); -// keysUsages.add(Id.choice.usage.encrypt_only); -// } catch (Exception e) { -// Log.e(Constants.TAG, "Creating initial key failed: +" + e); -// } - } + // Send all information needed to service generate keys in other thread + Intent intent = new Intent(this, ApgService.class); + intent.putExtra(ApgService.EXTRA_ACTION, + ApgService.ACTION_GENERATE_DEFAULT_RSA_KEYS); + // fill values for this action + Bundle data = new Bundle(); + data.putString(ApgService.PASSPHRASE, mCurrentPassPhrase); + + intent.putExtra(ApgService.EXTRA_DATA, data); + + // show progress dialog + mGeneratingDialog = ProgressDialogFragment.newInstance( + R.string.progress_generating, ProgressDialog.STYLE_SPINNER); + + // Message is received after generating is done in ApgService + ApgHandler saveHandler = new ApgHandler(this, mGeneratingDialog) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == ApgHandler.MESSAGE_OKAY) { + // get new key from data bundle returned from service + Bundle data = message.getData(); + PGPSecretKeyRing masterKeyRing = Utils + .BytesToPGPSecretKeyRing(data + .getByteArray(ApgHandler.NEW_KEY)); + PGPSecretKeyRing subKeyRing = Utils + .BytesToPGPSecretKeyRing(data + .getByteArray(ApgHandler.NEW_KEY2)); + + // add master key + Iterator masterIt = masterKeyRing.getSecretKeys(); + mKeys.add(masterIt.next()); + mKeysUsages.add(Id.choice.usage.sign_only); + + // add sub key + Iterator subIt = subKeyRing.getSecretKeys(); + subIt.next(); // masterkey + mKeys.add(subIt.next()); + mKeysUsages.add(Id.choice.usage.encrypt_only); + + buildLayout(); + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(ApgService.EXTRA_MESSENGER, messenger); + + mGeneratingDialog.show(getSupportFragmentManager(), "dialog"); + + // start service with intent + startService(intent); + } } } } else if (Apg.Intent.EDIT_KEY.equals(mIntent.getAction())) { @@ -217,14 +260,14 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA masterKey = Apg.getMasterKey(mKeyRing); for (PGPSecretKey key : new IterableIterator( mKeyRing.getSecretKeys())) { - keys.add(key); - keysUsages.add(-1); // get usage when view is created + mKeys.add(key); + mKeysUsages.add(-1); // get usage when view is created } } if (masterKey != null) { for (String userId : new IterableIterator( masterKey.getUserIDs())) { - userIds.add(userId); + mUserIds.add(userId); } } } @@ -255,27 +298,35 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA } }); + buildLayout(); + } + + /** + * Build layout based on mUserId, mKeys and mKeysUsages Vectors. It creates Views for every user + * id and key. + */ + private void buildLayout() { // Build layout based on given userIds and keys LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout container = (LinearLayout) findViewById(R.id.edit_key_container); - mUserIds = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); - mUserIds.setType(Id.type.user_id); - mUserIds.setUserIds(userIds); - container.addView(mUserIds); - mKeys = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); - mKeys.setType(Id.type.key); - mKeys.setKeys(keys, keysUsages); - container.addView(mKeys); + mUserIdsView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); + mUserIdsView.setType(Id.type.user_id); + mUserIdsView.setUserIds(mUserIds); + container.addView(mUserIdsView); + mKeysView = (SectionView) inflater.inflate(R.layout.edit_key_section, container, false); + mKeysView.setType(Id.type.key); + mKeysView.setKeys(mKeys, mKeysUsages); + container.addView(mKeysView); updatePassPhraseButtonText(); } private long getMasterKeyId() { - if (mKeys.getEditors().getChildCount() == 0) { + if (mKeysView.getEditors().getChildCount() == 0) { return 0; } - return ((KeyEditor) mKeys.getEditors().getChildAt(0)).getValue().getKeyID(); + return ((KeyEditor) mKeysView.getEditors().getChildAt(0)).getValue().getKeyID(); } public boolean isPassphraseSet() { @@ -362,13 +413,12 @@ public class EditKeyActivity extends SherlockFragmentActivity { // extends BaseA data.putString(ApgService.CURRENT_PASSPHRASE, mCurrentPassPhrase); data.putString(ApgService.NEW_PASSPHRASE, mNewPassPhrase); - data.putSerializable(ApgService.USER_IDS, getUserIds(mUserIds)); + data.putSerializable(ApgService.USER_IDS, getUserIds(mUserIdsView)); - Vector keys = getKeys(mKeys); - byte[] keysBytes = Utils.PGPSecretKeyListToBytes(keys); - data.putByteArray(ApgService.KEYS, keysBytes); + Vector keys = getKeys(mKeysView); + data.putByteArray(ApgService.KEYS, Utils.PGPSecretKeyListToBytes(keys)); - data.putSerializable(ApgService.KEYS_USAGES, getKeysUsages(mKeys)); + data.putSerializable(ApgService.KEYS_USAGES, getKeysUsages(mKeysView)); data.putLong(ApgService.MASTER_KEY_ID, getMasterKeyId());