1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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();
}
}
|