diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-01-08 19:19:45 +0100 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-01-08 19:19:45 +0100 |
commit | 55530597dfc02453aaf211b80703553fe87ff8f5 (patch) | |
tree | b3e4b1caf1c8272fe64241a4c8ad64684870e26d | |
parent | 6fd44a0ec5fcf7d45042ca0eaaed4906ccfcdf12 (diff) | |
download | open-keychain-55530597dfc02453aaf211b80703553fe87ff8f5.tar.gz open-keychain-55530597dfc02453aaf211b80703553fe87ff8f5.tar.bz2 open-keychain-55530597dfc02453aaf211b80703553fe87ff8f5.zip |
Fix many problems with import from files
6 files changed, 101 insertions, 73 deletions
diff --git a/APG/res/values/strings.xml b/APG/res/values/strings.xml index 0b4f3c029..6aac04808 100644 --- a/APG/res/values/strings.xml +++ b/APG/res/values/strings.xml @@ -155,7 +155,8 @@ <string name="notValid">not valid</string> <string name="nKeyServers">%s key server(s)</string> <string name="fingerprint">Fingerprint:</string> - + <string name="secretKeyring">Secret Keyring:</string> + <!-- choice_lowerCase: capitalized first word, no punctuation --> <string name="choice_none">None</string> <string name="choice_signOnly">Sign only</string> diff --git a/APG/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java b/APG/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java index 5ed320764..35bbac08e 100644 --- a/APG/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java +++ b/APG/src/org/thialfihar/android/apg/helper/PGPConversionHelper.java @@ -137,16 +137,4 @@ public class PGPConversionHelper { } } - public static PGPKeyRing decodeKeyRing(InputStream is) throws IOException { - InputStream in = PGPUtil.getDecoderStream(is); - PGPObjectFactory objectFactory = new PGPObjectFactory(in); - Object obj = objectFactory.nextObject(); - - if (obj instanceof PGPKeyRing) { - return (PGPKeyRing) obj; - } - - return null; - } - } diff --git a/APG/src/org/thialfihar/android/apg/helper/PGPMain.java b/APG/src/org/thialfihar/android/apg/helper/PGPMain.java index 1e97b7ba4..5afc935ec 100644 --- a/APG/src/org/thialfihar/android/apg/helper/PGPMain.java +++ b/APG/src/org/thialfihar/android/apg/helper/PGPMain.java @@ -45,6 +45,7 @@ import org.spongycastle.openpgp.PGPPrivateKey; import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPPublicKeyRingCollection; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSignature; @@ -475,6 +476,13 @@ public class PGPMain { updateProgress(progress, R.string.progress_done, 100, 100); } + /** + * TODO: implement Id.return_value.updated as status when key already existed + * + * @param context + * @param keyring + * @return + */ public static int storeKeyRingInCache(Context context, PGPKeyRing keyring) { int status = Integer.MIN_VALUE; // out of bounds value (Id.return_value.*) try { @@ -543,21 +551,14 @@ public class PGPMain { PGPException, IOException { Bundle returnData = new Bundle(); - // if (type == Id.type.secret_key) { - // if (progress != null) - updateProgress(progress, R.string.progress_importingSecretKeys, 0, 100); - // progress.setProgress(R.string.progress_importingSecretKeys, 0, 100); - // } else { - // if (progress != null) - // progress.setProgress(R.string.progress_importingPublicKeys, 0, 100); - // } if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { throw new ApgGeneralException(context.getString(R.string.error_externalStorageNotReady)); } PositionAwareInputStream progressIn = new PositionAwareInputStream(data.getInputStream()); + // need to have access to the bufferedInput, so we can reuse it for the possible // PGPObject chunks after the first one, e.g. files with several consecutive ASCII // armour blocks @@ -566,35 +567,47 @@ public class PGPMain { int oldKeys = 0; int badKeys = 0; try { - PGPKeyRing keyring = PGPConversionHelper.decodeKeyRing(bufferedInput); - while (keyring != null) { - int status = Integer.MIN_VALUE; // out of bounds value - - // if this key is what we expect it to be, save it - // if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing) - // || (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) { - status = storeKeyRingInCache(context, keyring); - // } - - if (status == Id.return_value.error) { - throw new ApgGeneralException(context.getString(R.string.error_savingKeys)); - } - // update the counts to display to the user at the end - if (status == Id.return_value.updated) { - ++oldKeys; - } else if (status == Id.return_value.ok) { - ++newKeys; - } else if (status == Id.return_value.bad) { - ++badKeys; + // read all available blocks... (asc files can contain many blocks with BEGIN END) + while (bufferedInput.available() > 0) { + InputStream in = PGPUtil.getDecoderStream(bufferedInput); + PGPObjectFactory objectFactory = new PGPObjectFactory(in); + + // go through all objects in this block + Object obj; + while ((obj = objectFactory.nextObject()) != null) { + Log.d(Constants.TAG, "Found class: " + obj.getClass()); + + if (obj instanceof PGPKeyRing) { + PGPKeyRing keyring = (PGPKeyRing) obj; + + int status = Integer.MIN_VALUE; // out of bounds value + + status = storeKeyRingInCache(context, keyring); + + if (status == Id.return_value.error) { + throw new ApgGeneralException( + context.getString(R.string.error_savingKeys)); + } + + // update the counts to display to the user at the end + if (status == Id.return_value.updated) { + ++oldKeys; + } else if (status == Id.return_value.ok) { + ++newKeys; + } else if (status == Id.return_value.bad) { + ++badKeys; + } + + updateProgress(progress, + (int) (100 * progressIn.position() / data.getSize()), 100); + } else { + Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!"); + } } - - updateProgress(progress, (int) (100 * progressIn.position() / data.getSize()), 100); - - keyring = PGPConversionHelper.decodeKeyRing(bufferedInput); } - } catch (EOFException e) { - // nothing to do, we are done + } catch (Exception e) { + Log.e(Constants.TAG, "Exception on parsing key file!", e); } returnData.putInt(ApgIntentService.RESULT_IMPORT_ADDED, newKeys); @@ -658,7 +671,6 @@ public class PGPMain { if (secretKeyRing != null) { secretKeyRing.encode(outSec); } - ++numKeys; } outSec.close(); } diff --git a/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java b/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java index 84359f1da..2979fbc04 100644 --- a/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java +++ b/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java @@ -212,13 +212,12 @@ public class ImportKeysActivity extends SherlockFragmentActivity { @Override public void handleMessage(Message message) { if (message.what == FileDialogFragment.MESSAGE_OKAY) { - Log.d(Constants.TAG, "FileDialogFragment.MESSAGE_OKAY"); Bundle data = message.getData(); mImportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - - Log.d(Constants.TAG, "mImportFilename: " + mImportFilename); - mDeleteAfterImport = data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED); + + Log.d(Constants.TAG, "mImportFilename: " + mImportFilename); + Log.d(Constants.TAG, "mDeleteAfterImport: " + mDeleteAfterImport); loadKeyListFragment(); } diff --git a/APG/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java b/APG/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java index 513bb058e..4a9596743 100644 --- a/APG/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java +++ b/APG/src/org/thialfihar/android/apg/ui/dialog/FileDialogFragment.java @@ -127,8 +127,6 @@ public class FileDialogFragment extends DialogFragment { @Override public void onClick(DialogInterface dialog, int id) { - Log.d(Constants.TAG, "onclock"); - dismiss(); boolean checked = false; diff --git a/APG/src/org/thialfihar/android/apg/ui/widget/ImportKeysListLoader.java b/APG/src/org/thialfihar/android/apg/ui/widget/ImportKeysListLoader.java index 75a0ef06f..6a2947f94 100644 --- a/APG/src/org/thialfihar/android/apg/ui/widget/ImportKeysListLoader.java +++ b/APG/src/org/thialfihar/android/apg/ui/widget/ImportKeysListLoader.java @@ -20,12 +20,20 @@ import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import org.spongycastle.openpgp.PGPKeyRing; +import org.spongycastle.openpgp.PGPObjectFactory; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPPublicKeyRingCollection; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSecretKeyRingCollection; +import org.spongycastle.openpgp.PGPUtil; import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.helper.PGPConversionHelper; @@ -46,6 +54,8 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin public static final String MAP_ATTR_USER_ID = "user_id"; public static final String MAP_ATTR_FINGERPINT = "fingerprint"; + ArrayList<Map<String, String>> data = new ArrayList<Map<String, String>>(); + Context mContext; List<String> mItems; @@ -73,7 +83,9 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin } } - return generateListOfKeyrings(inputData); + generateListOfKeyrings(inputData); + + return data; } @Override @@ -105,36 +117,54 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin * @param keyringBytes * @return */ - private ArrayList<Map<String, String>> generateListOfKeyrings(InputData inputData) { - ArrayList<Map<String, String>> output = new ArrayList<Map<String, String>>(); - + private void generateListOfKeyrings(InputData inputData) { PositionAwareInputStream progressIn = new PositionAwareInputStream( inputData.getInputStream()); + // need to have access to the bufferedInput, so we can reuse it for the possible // PGPObject chunks after the first one, e.g. files with several consecutive ASCII // armour blocks BufferedInputStream bufferedInput = new BufferedInputStream(progressIn); try { - PGPKeyRing keyring = PGPConversionHelper.decodeKeyRing(bufferedInput); - while (keyring != null) { - String userId = PGPHelper.getMainUserId(keyring.getPublicKey()); - - String fingerprint = PGPHelper.convertFingerprintToHex(keyring.getPublicKey() - .getFingerprint()); - - Map<String, String> attrs = new HashMap<String, String>(); - attrs.put(MAP_ATTR_USER_ID, userId); - attrs.put(MAP_ATTR_FINGERPINT, mContext.getString(R.string.fingerprint) + "\n" - + fingerprint); - output.add(attrs); - keyring = PGPConversionHelper.decodeKeyRing(bufferedInput); + // read all available blocks... (asc files can contain many blocks with BEGIN END) + while (bufferedInput.available() > 0) { + InputStream in = PGPUtil.getDecoderStream(bufferedInput); + PGPObjectFactory objectFactory = new PGPObjectFactory(in); + + // go through all objects in this block + Object obj; + while ((obj = objectFactory.nextObject()) != null) { + Log.d(Constants.TAG, "Found class: " + obj.getClass()); + + if (obj instanceof PGPKeyRing) { + PGPKeyRing newKeyring = (PGPKeyRing) obj; + addToData(newKeyring); + } else { + Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!"); + } + } } } catch (Exception e) { - Log.e(Constants.TAG, "Exception", e); + Log.e(Constants.TAG, "Exception on parsing key file!", e); } + } + + private void addToData(PGPKeyRing keyring) { + String userId = PGPHelper.getMainUserId(keyring.getPublicKey()); + + if (keyring instanceof PGPSecretKeyRing) { + userId = mContext.getString(R.string.secretKeyring) + " " + userId; + } + + String fingerprint = PGPHelper.convertFingerprintToHex(keyring.getPublicKey() + .getFingerprint()); - return output; + Map<String, String> attrs = new HashMap<String, String>(); + attrs.put(MAP_ATTR_USER_ID, userId); + attrs.put(MAP_ATTR_FINGERPINT, mContext.getString(R.string.fingerprint) + "\n" + + fingerprint); + data.add(attrs); } } |