token-import: match fingerprints of subkeys

This commit is contained in:
Vincent Breitmoser
2017-09-11 14:21:47 +02:00
parent a1b049993f
commit 10eeb5672b
3 changed files with 35 additions and 28 deletions

View File

@@ -171,6 +171,22 @@ public class UncachedKeyRing {
} }
public boolean containsKeyWithAnyFingerprint(byte[]... expectedFingerprints) {
Iterator<UncachedPublicKey> publicKeys = getPublicKeys();
while (publicKeys.hasNext()) {
UncachedPublicKey publicKey = publicKeys.next();
for (byte[] expectedFingerprint : expectedFingerprints) {
if (Arrays.equals(expectedFingerprint, publicKey.getFingerprint())) {
return true;
}
}
}
return false;
}
public static IteratorWithIOThrow<UncachedKeyRing> fromStream(InputStream rawStream) { public static IteratorWithIOThrow<UncachedKeyRing> fromStream(InputStream rawStream) {
final InputStream stream = rawStream.markSupported() ? rawStream: new BufferedInputStream(rawStream); final InputStream stream = rawStream.markSupported() ? rawStream: new BufferedInputStream(rawStream);

View File

@@ -211,9 +211,9 @@ class ManageSecurityTokenPresenter implements ManageSecurityTokenMvpPresenter {
case LOADER_URI: case LOADER_URI:
return new UriKeyRetrievalLoader(context, tokenInfo.getUrl(), tokenInfo.getAllFingerprints()); return new UriKeyRetrievalLoader(context, tokenInfo.getUrl(), tokenInfo.getAllFingerprints());
case LOADER_KEYSERVER: case LOADER_KEYSERVER:
return new KeyserverRetrievalLoader(context, tokenInfo.getFingerprintSign()); return new KeyserverRetrievalLoader(context, tokenInfo.getAllFingerprints());
case LOADER_CONTENT_URI: case LOADER_CONTENT_URI:
return new ContentUriRetrievalLoader(context, tokenInfo.getFingerprintSign(), return new ContentUriRetrievalLoader(context, tokenInfo.getAllFingerprints(),
args.<Uri>getParcelable(ARG_CONTENT_URI)); args.<Uri>getParcelable(ARG_CONTENT_URI));
} }
throw new IllegalArgumentException("called with unknown loader id!"); throw new IllegalArgumentException("called with unknown loader id!");

View File

@@ -18,10 +18,8 @@
package org.sufficientlysecure.keychain.ui.token; package org.sufficientlysecure.keychain.ui.token;
import java.io.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
@@ -66,9 +64,13 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
private KeyRetrievalResult cachedResult; private KeyRetrievalResult cachedResult;
protected final byte[][] fingerprints;
private PublicKeyRetrievalLoader(Context context) {
private PublicKeyRetrievalLoader(Context context, byte[][] fingerprints) {
super(context); super(context);
this.fingerprints = fingerprints;
} }
@Override @Override
@@ -91,12 +93,10 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
static class LocalKeyLookupLoader extends PublicKeyRetrievalLoader { static class LocalKeyLookupLoader extends PublicKeyRetrievalLoader {
private final KeyRepository keyRepository; private final KeyRepository keyRepository;
private final byte[][] fingerprints;
LocalKeyLookupLoader(Context context, byte[][] fingerprints) { LocalKeyLookupLoader(Context context, byte[][] fingerprints) {
super(context); super(context, fingerprints);
this.fingerprints = fingerprints;
this.keyRepository = KeyRepository.createDatabaseInteractor(context); this.keyRepository = KeyRepository.createDatabaseInteractor(context);
} }
@@ -156,14 +156,12 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
} }
static class UriKeyRetrievalLoader extends PublicKeyRetrievalLoader { static class UriKeyRetrievalLoader extends PublicKeyRetrievalLoader {
private final byte[][] fingerprints;
private final String tokenUri; private final String tokenUri;
UriKeyRetrievalLoader(Context context, String tokenUri, byte[][] fingerprints) { UriKeyRetrievalLoader(Context context, String tokenUri, byte[][] fingerprints) {
super(context); super(context, fingerprints);
this.tokenUri = tokenUri; this.tokenUri = tokenUri;
this.fingerprints = fingerprints;
} }
@Override @Override
@@ -192,11 +190,11 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
} }
IteratorWithIOThrow<UncachedKeyRing> uncachedKeyRingIterator = UncachedKeyRing.fromStream( IteratorWithIOThrow<UncachedKeyRing> uncachedKeyRingIterator = UncachedKeyRing.fromStream(
new BufferedInputStream(execute.body().byteStream())); execute.body().byteStream());
while (uncachedKeyRingIterator.hasNext()) { while (uncachedKeyRingIterator.hasNext()) {
UncachedKeyRing keyRing = uncachedKeyRingIterator.next(); UncachedKeyRing keyRing = uncachedKeyRingIterator.next();
log.add(LogType.MSG_RET_URI_TEST, 1, KeyFormattingUtils.convertKeyIdToHex(keyRing.getMasterKeyId())); log.add(LogType.MSG_RET_URI_TEST, 1, KeyFormattingUtils.convertKeyIdToHex(keyRing.getMasterKeyId()));
if (Arrays.equals(fingerprints[0], keyRing.getFingerprint())) { if (keyRing.containsKeyWithAnyFingerprint(fingerprints)) {
log.add(LogType.MSG_RET_URI_OK, 1); log.add(LogType.MSG_RET_URI_OK, 1);
return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded()); return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded());
} }
@@ -213,12 +211,8 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
} }
static class KeyserverRetrievalLoader extends PublicKeyRetrievalLoader { static class KeyserverRetrievalLoader extends PublicKeyRetrievalLoader {
private final byte[] fingerprint; KeyserverRetrievalLoader(Context context, byte[][] fingerprints) {
super(context, fingerprints);
KeyserverRetrievalLoader(Context context, byte[] fingerprint) {
super(context);
this.fingerprint = fingerprint;
} }
@Override @Override
@@ -234,10 +228,10 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
log.add(LogType.MSG_RET_KS_START, 0); log.add(LogType.MSG_RET_KS_START, 0);
String keyString = keyserverClient.get( String keyString = keyserverClient.get(
"0x" + KeyFormattingUtils.convertFingerprintToHex(fingerprint), parcelableProxy); "0x" + KeyFormattingUtils.convertFingerprintToHex(fingerprints[0]), parcelableProxy);
UncachedKeyRing keyRing = UncachedKeyRing.decodeFromData(keyString.getBytes()); UncachedKeyRing keyRing = UncachedKeyRing.decodeFromData(keyString.getBytes());
if (!Arrays.equals(fingerprint, keyRing.getFingerprint())) { if (!keyRing.containsKeyWithAnyFingerprint(fingerprints)) {
log.add(LogType.MSG_RET_KS_FP_MISMATCH, 1); log.add(LogType.MSG_RET_KS_FP_MISMATCH, 1);
return KeyRetrievalResult.createWithError(log); return KeyRetrievalResult.createWithError(log);
} else { } else {
@@ -259,13 +253,11 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
static class ContentUriRetrievalLoader extends PublicKeyRetrievalLoader { static class ContentUriRetrievalLoader extends PublicKeyRetrievalLoader {
private final ContentResolver contentResolver; private final ContentResolver contentResolver;
private final byte[] fingerprint;
private final Uri uri; private final Uri uri;
ContentUriRetrievalLoader(Context context, byte[] fingerprint, Uri uri) { ContentUriRetrievalLoader(Context context, byte[][] fingerprints, Uri uri) {
super(context); super(context, fingerprints);
this.fingerprint = fingerprint;
this.uri = uri; this.uri = uri;
this.contentResolver = context.getContentResolver(); this.contentResolver = context.getContentResolver();
} }
@@ -284,12 +276,11 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
return KeyRetrievalResult.createWithError(log); return KeyRetrievalResult.createWithError(log);
} }
IteratorWithIOThrow<UncachedKeyRing> uncachedKeyRingIterator = UncachedKeyRing.fromStream( IteratorWithIOThrow<UncachedKeyRing> uncachedKeyRingIterator = UncachedKeyRing.fromStream(is);
new BufferedInputStream(is));
while (uncachedKeyRingIterator.hasNext()) { while (uncachedKeyRingIterator.hasNext()) {
UncachedKeyRing keyRing = uncachedKeyRingIterator.next(); UncachedKeyRing keyRing = uncachedKeyRingIterator.next();
log.add(LogType.MSG_RET_CURI_FOUND, 1, KeyFormattingUtils.convertKeyIdToHex(keyRing.getMasterKeyId())); log.add(LogType.MSG_RET_CURI_FOUND, 1, KeyFormattingUtils.convertKeyIdToHex(keyRing.getMasterKeyId()));
if (Arrays.equals(fingerprint, keyRing.getFingerprint())) { if (keyRing.containsKeyWithAnyFingerprint(fingerprints)) {
log.add(LogType.MSG_RET_CURI_OK, 1); log.add(LogType.MSG_RET_CURI_OK, 1);
return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded()); return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded());
} else { } else {