aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java')
-rw-r--r--src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java b/src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java
new file mode 100644
index 000000000..b875f2eef
--- /dev/null
+++ b/src/org/thialfihar/android/apg/ImportFromQRCodeActivity.java
@@ -0,0 +1,133 @@
+package org.thialfihar.android.apg;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.spongycastle.openpgp.PGPKeyRing;
+import org.spongycastle.openpgp.PGPPublicKeyRing;
+import org.thialfihar.android.apg.KeyServer.QueryException;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Message;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+
+public class ImportFromQRCodeActivity extends BaseActivity {
+ private static final String TAG = "ImportFromQRCodeActivity";
+
+ private final Bundle status = new Bundle();
+ private final Message msg = new Message();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ IntentIntegrator.initiateScan(this);
+ }
+
+ private void importAndSign(final long keyId, final String expectedFingerprint) {
+ if (expectedFingerprint != null && expectedFingerprint.length() > 0) {
+
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ // TODO: display some sort of spinner here while the user waits
+
+ HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]); // TODO: there should be only 1
+ String encodedKey = server.get(keyId);
+
+ PGPKeyRing keyring = Apg.decodeKeyRing(new ByteArrayInputStream(encodedKey.getBytes()));
+ if (keyring != null && keyring instanceof PGPPublicKeyRing) {
+ PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
+
+ // make sure the fingerprints match before we cache this thing
+ String actualFingerprint = Apg.convertToHex(publicKeyRing.getPublicKey().getFingerprint());
+ if (expectedFingerprint.equals(actualFingerprint)) {
+ // store the signed key in our local cache
+ int retval = Apg.storeKeyRingInCache(publicKeyRing);
+ if (retval != Id.return_value.ok && retval != Id.return_value.updated) {
+ status.putString(Apg.EXTRA_ERROR, "Failed to store signed key in local cache");
+ } else {
+ Intent intent = new Intent(ImportFromQRCodeActivity.this, SignKeyActivity.class);
+ intent.putExtra(Apg.EXTRA_KEY_ID, keyId);
+ startActivityForResult(intent, Id.request.sign_key);
+ }
+ } else {
+ status.putString(Apg.EXTRA_ERROR, "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key.");
+ }
+ }
+ } catch (QueryException e) {
+ Log.e(TAG, "Failed to query KeyServer", e);
+ status.putString(Apg.EXTRA_ERROR, "Failed to query KeyServer");
+ status.putInt(Constants.extras.status, Id.message.done);
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to query KeyServer", e);
+ status.putString(Apg.EXTRA_ERROR, "Failed to query KeyServer");
+ status.putInt(Constants.extras.status, Id.message.done);
+ }
+ }
+ };
+
+ t.setName("KeyExchange Download Thread");
+ t.setDaemon(true);
+ t.start();
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case IntentIntegrator.REQUEST_CODE: {
+ boolean debug = true; // TODO: remove this!!!
+ IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
+ if (debug || (scanResult != null && scanResult.getFormatName() != null)) {
+ String[] bits = debug ? new String[] { "5993515643896327656", "0816 F68A 6816 68FB 01BF 2CA5 532D 3EB9 1E2F EDE8" } : scanResult.getContents().split(",");
+ if (bits.length != 2) {
+ return; // dont know how to handle this. Not a valid code
+ }
+
+ long keyId = Long.parseLong(bits[0]);
+ String expectedFingerprint = bits[1];
+
+ importAndSign(keyId, expectedFingerprint);
+
+ break;
+ }
+ }
+
+ case Id.request.sign_key: {
+ // signals the end of processing. Signature was either applied, or it wasnt
+ status.putInt(Constants.extras.status, Id.message.done);
+
+ msg.setData(status);
+ sendMessage(msg);
+
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+ }
+
+ @Override
+ public void doneCallback(Message msg) {
+ super.doneCallback(msg);
+
+ Bundle data = msg.getData();
+ String error = data.getString(Apg.EXTRA_ERROR);
+ if (error != null) {
+ Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ Toast.makeText(this, R.string.keySignSuccess, Toast.LENGTH_SHORT).show(); // TODO
+ finish();
+ }
+}