diff options
Diffstat (limited to 'src/org/apg/ui/ImportFromQRCodeActivity.java')
-rw-r--r-- | src/org/apg/ui/ImportFromQRCodeActivity.java | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/org/apg/ui/ImportFromQRCodeActivity.java b/src/org/apg/ui/ImportFromQRCodeActivity.java new file mode 100644 index 000000000..0d9209991 --- /dev/null +++ b/src/org/apg/ui/ImportFromQRCodeActivity.java @@ -0,0 +1,138 @@ +package org.apg.ui; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import org.apg.Apg; +import org.apg.Constants; +import org.apg.HkpKeyServer; +import org.apg.Id; +import org.apg.KeyServer.QueryException; +import org.spongycastle.openpgp.PGPKeyRing; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.apg.R; + +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); + + new IntentIntegrator(this).initiateScan(); + } + + 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(); + } +} |