perform fingerprint check after canonicalization (OKC-01-009)
This commit is contained in:
@@ -254,17 +254,6 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have an expected fingerprint, make sure it matches
|
|
||||||
if (entry.mExpectedFingerprint != null) {
|
|
||||||
if (!key.containsSubkey(entry.mExpectedFingerprint)) {
|
|
||||||
log.add(LogType.MSG_IMPORT_FINGERPRINT_ERROR, 2);
|
|
||||||
badKeys += 1;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
log.add(LogType.MSG_IMPORT_FINGERPRINT_OK, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Another check if we have been cancelled
|
// Another check if we have been cancelled
|
||||||
if (checkCancelled()) {
|
if (checkCancelled()) {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
@@ -283,7 +272,7 @@ public class ImportOperation extends BaseOperation<ImportKeyringParcel> {
|
|||||||
} else {
|
} else {
|
||||||
result = mProviderHelper.savePublicKeyRing(key,
|
result = mProviderHelper.savePublicKeyRing(key,
|
||||||
new ProgressScaler(progressable, (int) (position * progSteps),
|
new ProgressScaler(progressable, (int) (position * progSteps),
|
||||||
(int) ((position + 1) * progSteps), 100));
|
(int) ((position + 1) * progSteps), 100), entry.mExpectedFingerprint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result.success()) {
|
if (!result.success()) {
|
||||||
|
|||||||
@@ -289,6 +289,8 @@ public abstract class OperationResult implements Parcelable {
|
|||||||
MSG_IP_ERROR_IO_EXC (LogLevel.ERROR, R.string.msg_ip_error_io_exc),
|
MSG_IP_ERROR_IO_EXC (LogLevel.ERROR, R.string.msg_ip_error_io_exc),
|
||||||
MSG_IP_ERROR_OP_EXC (LogLevel.ERROR, R.string.msg_ip_error_op_exc),
|
MSG_IP_ERROR_OP_EXC (LogLevel.ERROR, R.string.msg_ip_error_op_exc),
|
||||||
MSG_IP_ERROR_REMOTE_EX (LogLevel.ERROR, R.string.msg_ip_error_remote_ex),
|
MSG_IP_ERROR_REMOTE_EX (LogLevel.ERROR, R.string.msg_ip_error_remote_ex),
|
||||||
|
MSG_IP_FINGERPRINT_ERROR (LogLevel.ERROR, R.string.msg_ip_fingerprint_error),
|
||||||
|
MSG_IP_FINGERPRINT_OK (LogLevel.INFO, R.string.msg_ip_fingerprint_ok),
|
||||||
MSG_IP_INSERT_KEYRING (LogLevel.DEBUG, R.string.msg_ip_insert_keyring),
|
MSG_IP_INSERT_KEYRING (LogLevel.DEBUG, R.string.msg_ip_insert_keyring),
|
||||||
MSG_IP_INSERT_SUBKEYS (LogLevel.DEBUG, R.string.msg_ip_insert_keys),
|
MSG_IP_INSERT_SUBKEYS (LogLevel.DEBUG, R.string.msg_ip_insert_keys),
|
||||||
MSG_IP_PREPARE (LogLevel.DEBUG, R.string.msg_ip_prepare),
|
MSG_IP_PREPARE (LogLevel.DEBUG, R.string.msg_ip_prepare),
|
||||||
@@ -712,8 +714,6 @@ public abstract class OperationResult implements Parcelable {
|
|||||||
MSG_IMPORT_KEYSERVER (LogLevel.DEBUG, R.string.msg_import_keyserver),
|
MSG_IMPORT_KEYSERVER (LogLevel.DEBUG, R.string.msg_import_keyserver),
|
||||||
MSG_IMPORT_MERGE (LogLevel.DEBUG, R.string.msg_import_merge),
|
MSG_IMPORT_MERGE (LogLevel.DEBUG, R.string.msg_import_merge),
|
||||||
MSG_IMPORT_MERGE_ERROR (LogLevel.ERROR, R.string.msg_import_merge_error),
|
MSG_IMPORT_MERGE_ERROR (LogLevel.ERROR, R.string.msg_import_merge_error),
|
||||||
MSG_IMPORT_FINGERPRINT_ERROR (LogLevel.ERROR, R.string.msg_import_fingerprint_error),
|
|
||||||
MSG_IMPORT_FINGERPRINT_OK (LogLevel.DEBUG, R.string.msg_import_fingerprint_ok),
|
|
||||||
MSG_IMPORT_ERROR (LogLevel.ERROR, R.string.msg_import_error),
|
MSG_IMPORT_ERROR (LogLevel.ERROR, R.string.msg_import_error),
|
||||||
MSG_IMPORT_ERROR_IO (LogLevel.ERROR, R.string.msg_import_error_io),
|
MSG_IMPORT_ERROR_IO (LogLevel.ERROR, R.string.msg_import_error_io),
|
||||||
MSG_IMPORT_PARTIAL (LogLevel.ERROR, R.string.msg_import_partial),
|
MSG_IMPORT_PARTIAL (LogLevel.ERROR, R.string.msg_import_partial),
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package org.sufficientlysecure.keychain.pgp;
|
|||||||
import org.spongycastle.openpgp.PGPKeyRing;
|
import org.spongycastle.openpgp.PGPKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPPublicKey;
|
import org.spongycastle.openpgp.PGPPublicKey;
|
||||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||||
|
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -28,6 +29,7 @@ import java.io.OutputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
@@ -152,4 +154,14 @@ public abstract class CanonicalizedKeyRing extends KeyRing {
|
|||||||
return getRing().getEncoded();
|
return getRing().getEncoded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean containsSubkey(String expectedFingerprint) {
|
||||||
|
for (CanonicalizedPublicKey key : publicKeyIterator()) {
|
||||||
|
if (KeyFormattingUtils.convertFingerprintToHex(
|
||||||
|
key.getFingerprint()).equalsIgnoreCase(expectedFingerprint)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,17 +216,6 @@ public class UncachedKeyRing implements Serializable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsSubkey(String expectedFingerprint) {
|
|
||||||
Iterator<PGPPublicKey> it = mRing.getPublicKeys();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
if (KeyFormattingUtils.convertFingerprintToHex(
|
|
||||||
it.next().getFingerprint()).equalsIgnoreCase(expectedFingerprint)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IteratorWithIOThrow<E> {
|
public interface IteratorWithIOThrow<E> {
|
||||||
public boolean hasNext() throws IOException;
|
public boolean hasNext() throws IOException;
|
||||||
public E next() throws IOException;
|
public E next() throws IOException;
|
||||||
|
|||||||
@@ -878,7 +878,7 @@ public class ProviderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing keyRing) {
|
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing keyRing) {
|
||||||
return savePublicKeyRing(keyRing, new ProgressScaler());
|
return savePublicKeyRing(keyRing, new ProgressScaler(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -887,7 +887,7 @@ public class ProviderHelper {
|
|||||||
* This is a high level method, which takes care of merging all new information into the old and
|
* This is a high level method, which takes care of merging all new information into the old and
|
||||||
* keep public and secret keyrings in sync.
|
* keep public and secret keyrings in sync.
|
||||||
*/
|
*/
|
||||||
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing publicRing, Progressable progress) {
|
public SaveKeyringResult savePublicKeyRing(UncachedKeyRing publicRing, Progressable progress, String expectedFingerprint) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
long masterKeyId = publicRing.getMasterKeyId();
|
long masterKeyId = publicRing.getMasterKeyId();
|
||||||
@@ -960,6 +960,17 @@ public class ProviderHelper {
|
|||||||
canSecretRing = null;
|
canSecretRing = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If we have an expected fingerprint, make sure it matches
|
||||||
|
if (expectedFingerprint != null) {
|
||||||
|
if (!canPublicRing.containsSubkey(expectedFingerprint)) {
|
||||||
|
log(LogType.MSG_IP_FINGERPRINT_ERROR);
|
||||||
|
return new SaveKeyringResult(SaveKeyringResult.RESULT_ERROR, mLog, null);
|
||||||
|
} else {
|
||||||
|
log(LogType.MSG_IP_FINGERPRINT_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int result = saveCanonicalizedPublicKeyRing(canPublicRing, progress, canSecretRing != null);
|
int result = saveCanonicalizedPublicKeyRing(canPublicRing, progress, canSecretRing != null);
|
||||||
|
|
||||||
// Save the saved keyring (if any)
|
// Save the saved keyring (if any)
|
||||||
|
|||||||
@@ -826,6 +826,8 @@
|
|||||||
<string name="msg_ip_error_op_exc">"Operation failed due to database error"</string>
|
<string name="msg_ip_error_op_exc">"Operation failed due to database error"</string>
|
||||||
<string name="msg_ip_error_remote_ex">"Operation failed due to internal error"</string>
|
<string name="msg_ip_error_remote_ex">"Operation failed due to internal error"</string>
|
||||||
<string name="msg_ip">"Importing public keyring %s"</string>
|
<string name="msg_ip">"Importing public keyring %s"</string>
|
||||||
|
<string name="msg_ip_fingerprint_error">"Fingerprint of importing key does not match expected!"</string>
|
||||||
|
<string name="msg_ip_fingerprint_ok">"Fingerprint check OK"</string>
|
||||||
<string name="msg_ip_insert_keyring">"Encoding keyring data"</string>
|
<string name="msg_ip_insert_keyring">"Encoding keyring data"</string>
|
||||||
<string name="msg_ip_insert_keys">"Parsing keys"</string>
|
<string name="msg_ip_insert_keys">"Parsing keys"</string>
|
||||||
<string name="msg_ip_prepare">"Preparing database operations"</string>
|
<string name="msg_ip_prepare">"Preparing database operations"</string>
|
||||||
@@ -1281,8 +1283,6 @@
|
|||||||
<string name="msg_import_fetch_keyserver">"Retrieving from keyserver: %s"</string>
|
<string name="msg_import_fetch_keyserver">"Retrieving from keyserver: %s"</string>
|
||||||
<string name="msg_import_fetch_keyserver_ok">"Key retrieval successful"</string>
|
<string name="msg_import_fetch_keyserver_ok">"Key retrieval successful"</string>
|
||||||
<string name="msg_import_keyserver">"Using keyserver %s"</string>
|
<string name="msg_import_keyserver">"Using keyserver %s"</string>
|
||||||
<string name="msg_import_fingerprint_error">"Fingerprint of fetched key didn't match expected!"</string>
|
|
||||||
<string name="msg_import_fingerprint_ok">"Fingerprint check OK"</string>
|
|
||||||
<string name="msg_import_merge">"Merging retrieved data"</string>
|
<string name="msg_import_merge">"Merging retrieved data"</string>
|
||||||
<string name="msg_import_merge_error">"Error merging retrieved data!"</string>
|
<string name="msg_import_merge_error">"Error merging retrieved data!"</string>
|
||||||
<string name="msg_import_error">"Import operation failed!"</string>
|
<string name="msg_import_error">"Import operation failed!"</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user