verify downloaded key by comparing fingerprints

This commit is contained in:
Dominik Schürmann 2014-03-20 19:11:51 +01:00
parent 77365202e0
commit 0510e0e217

View File

@ -25,6 +25,7 @@ import android.os.Bundle;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.os.RemoteException; import android.os.RemoteException;
import org.spongycastle.openpgp.*; import org.spongycastle.openpgp.*;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
@ -692,11 +693,11 @@ public class KeychainIntentService extends IntentService
for (long masterKeyId : masterKeyIds) { for (long masterKeyId : masterKeyIds) {
if ((keyType == Id.type.public_key || keyType == Id.type.public_secret_key) if ((keyType == Id.type.public_key || keyType == Id.type.public_secret_key)
&& allPublicMasterKeyIds.contains(masterKeyId)) { && allPublicMasterKeyIds.contains(masterKeyId)) {
publicMasterKeyIds.add(masterKeyId); publicMasterKeyIds.add(masterKeyId);
} }
if ((keyType == Id.type.secret_key || keyType == Id.type.public_secret_key) if ((keyType == Id.type.secret_key || keyType == Id.type.public_secret_key)
&& allSecretMasterKeyIds.contains(masterKeyId)) { && allSecretMasterKeyIds.contains(masterKeyId)) {
secretMasterKeyIds.add(masterKeyId); secretMasterKeyIds.add(masterKeyId);
} }
} }
@ -745,49 +746,58 @@ public class KeychainIntentService extends IntentService
ArrayList<ImportKeysListEntry> entries = data.getParcelableArrayList(DOWNLOAD_KEY_LIST); ArrayList<ImportKeysListEntry> entries = data.getParcelableArrayList(DOWNLOAD_KEY_LIST);
String keyServer = data.getString(DOWNLOAD_KEY_SERVER); String keyServer = data.getString(DOWNLOAD_KEY_SERVER);
// TODO: add extra which requires fingerprint suport and force verification!
// only supported by newer sks keyserver versions
// this downloads the keys and places them into the ImportKeysListEntry entries // this downloads the keys and places them into the ImportKeysListEntry entries
HkpKeyServer server = new HkpKeyServer(keyServer); HkpKeyServer server = new HkpKeyServer(keyServer);
for (ImportKeysListEntry entry : entries) { for (ImportKeysListEntry entry : entries) {
byte[] downloadedKey = server.get(entry.getKeyIdHex()).getBytes(); // if available use complete fingerprint for get request
byte[] downloadedKeyBytes;
if (entry.getFingerPrintHex() != null) {
downloadedKeyBytes = server.get(entry.getFingerPrintHex()).getBytes();
} else {
downloadedKeyBytes = server.get(entry.getKeyIdHex()).getBytes();
}
/** // create PGPKeyRing object based on downloaded armored key
* TODO: copied from ImportKeysListLoader PGPKeyRing downloadedKey = null;
*
*
* this parses the downloaded key
*/
// 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
// armor blocks
BufferedInputStream bufferedInput = BufferedInputStream bufferedInput =
new BufferedInputStream(new ByteArrayInputStream(downloadedKey)); new BufferedInputStream(new ByteArrayInputStream(downloadedKeyBytes));
try { if (bufferedInput.available() > 0) {
InputStream in = PGPUtil.getDecoderStream(bufferedInput);
PGPObjectFactory objectFactory = new PGPObjectFactory(in);
// read all available blocks... (asc files can contain many blocks with BEGIN END) // get first object in block
while (bufferedInput.available() > 0) { Object obj;
InputStream in = PGPUtil.getDecoderStream(bufferedInput); if ((obj = objectFactory.nextObject()) != null) {
PGPObjectFactory objectFactory = new PGPObjectFactory(in); Log.d(Constants.TAG, "Found class: " + obj.getClass());
// go through all objects in this block if (obj instanceof PGPKeyRing) {
Object obj; downloadedKey = (PGPKeyRing) obj;
while ((obj = objectFactory.nextObject()) != null) { } else {
Log.d(Constants.TAG, "Found class: " + obj.getClass()); throw new PgpGeneralException("Object not recognized as PGPKeyRing!");
if (obj instanceof PGPKeyRing) {
PGPKeyRing newKeyring = (PGPKeyRing) obj;
entry.setBytes(newKeyring.getEncoded());
} else {
Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!");
}
} }
} }
} catch (Exception e) {
Log.e(Constants.TAG, "Exception on parsing key file!", e);
} }
// verify downloaded key by comparing fingerprints
if (entry.getFingerPrintHex() != null) {
String downloadedKeyFp = PgpKeyHelper.convertFingerprintToHex(downloadedKey.getPublicKey().getFingerprint(), false);
if (downloadedKeyFp.equals(entry.getFingerPrintHex())) {
Log.d(Constants.TAG, "fingerprint of downloaded key is the same as the requested fingerprint!");
} else {
throw new PgpGeneralException("fingerprint of downloaded key is NOT the same as the requested fingerprint!");
}
}
// save key bytes in entry object for doing the
// actual import afterwards
entry.setBytes(downloadedKey.getEncoded());
} }
Intent importIntent = new Intent(this, KeychainIntentService.class); Intent importIntent = new Intent(this, KeychainIntentService.class);
importIntent.setAction(ACTION_IMPORT_KEYRING); importIntent.setAction(ACTION_IMPORT_KEYRING);
Bundle importData = new Bundle(); Bundle importData = new Bundle();