token-import: add logging
This commit is contained in:
parent
050aed1ef5
commit
363551723b
|
@ -0,0 +1,25 @@
|
||||||
|
package org.sufficientlysecure.keychain.operations.results;
|
||||||
|
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
|
||||||
|
|
||||||
|
public class GenericOperationResult extends OperationResult {
|
||||||
|
public GenericOperationResult(int result, OperationLog log) {
|
||||||
|
super(result, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericOperationResult(Parcel source) {
|
||||||
|
super(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<GenericOperationResult> CREATOR = new Creator<GenericOperationResult>() {
|
||||||
|
public GenericOperationResult createFromParcel(final Parcel source) {
|
||||||
|
return new GenericOperationResult(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericOperationResult[] newArray(final int size) {
|
||||||
|
return new GenericOperationResult[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -905,6 +905,36 @@ public abstract class OperationResult implements Parcelable {
|
||||||
MSG_BENCH_S2K_100MS_ITS (LogLevel.INFO, R.string.msg_bench_s2k_100ms_its),
|
MSG_BENCH_S2K_100MS_ITS (LogLevel.INFO, R.string.msg_bench_s2k_100ms_its),
|
||||||
MSG_BENCH_SUCCESS (LogLevel.OK, R.string.msg_bench_success),
|
MSG_BENCH_SUCCESS (LogLevel.OK, R.string.msg_bench_success),
|
||||||
|
|
||||||
|
MSG_RET_CURI_ERROR_IO (LogLevel.ERROR, R.string.msg_ret_curi_error_io),
|
||||||
|
MSG_RET_CURI_ERROR_NO_MATCH (LogLevel.ERROR, R.string.msg_ret_curi_error_no_match),
|
||||||
|
MSG_RET_CURI_ERROR_NOT_FOUND (LogLevel.ERROR, R.string.msg_ret_curi_error_not_found),
|
||||||
|
MSG_RET_CURI_FOUND (LogLevel.DEBUG, R.string.msg_ret_curi_found),
|
||||||
|
MSG_RET_CURI_MISMATCH (LogLevel.ERROR, R.string.msg_ret_curi_mismatch),
|
||||||
|
MSG_RET_CURI_OK (LogLevel.OK, R.string.msg_ret_curi_ok),
|
||||||
|
MSG_RET_CURI_OPEN (LogLevel.DEBUG, R.string.msg_ret_curi_open),
|
||||||
|
MSG_RET_CURI_START (LogLevel.START, R.string.msg_ret_curi_start),
|
||||||
|
MSG_RET_KS_ERROR_NOT_FOUND (LogLevel.ERROR, R.string.msg_ret_ks_error_not_found),
|
||||||
|
MSG_RET_KS_ERROR (LogLevel.ERROR, R.string.msg_ret_ks_error),
|
||||||
|
MSG_RET_KS_FP_MATCH (LogLevel.DEBUG, R.string.msg_ret_ks_fp_match),
|
||||||
|
MSG_RET_KS_FP_MISMATCH (LogLevel.ERROR, R.string.msg_ret_ks_fp_mismatch),
|
||||||
|
MSG_RET_KS_OK (LogLevel.OK, R.string.msg_ret_ks_ok),
|
||||||
|
MSG_RET_KS_START (LogLevel.START, R.string.msg_ret_ks_start),
|
||||||
|
MSG_RET_LOCAL_SEARCH(LogLevel.DEBUG, R.string.msg_ret_local_search),
|
||||||
|
MSG_RET_LOCAL_FP_MATCH (LogLevel.DEBUG, R.string.msg_ret_local_fp_match),
|
||||||
|
MSG_RET_LOCAL_FP_MISMATCH (LogLevel.ERROR, R.string.msg_ret_local_fp_mismatch),
|
||||||
|
MSG_RET_LOCAL_NOT_FOUND (LogLevel.ERROR, R.string.msg_ret_local_not_found),
|
||||||
|
MSG_RET_LOCAL_OK (LogLevel.OK, R.string.msg_ret_local_ok),
|
||||||
|
MSG_RET_LOCAL_SECRET (LogLevel.INFO, R.string.msg_ret_local_secret),
|
||||||
|
MSG_RET_LOCAL_START (LogLevel.START, R.string.msg_ret_local_start),
|
||||||
|
MSG_RET_URI_ERROR_NO_MATCH(LogLevel.ERROR, R.string.msg_ret_uri_error_no_match),
|
||||||
|
MSG_RET_URI_ERROR_FETCH (LogLevel.ERROR, R.string.msg_ret_uri_error_fetch),
|
||||||
|
MSG_RET_URI_ERROR_PARSE (LogLevel.ERROR, R.string.msg_ret_uri_error_parse),
|
||||||
|
MSG_RET_URI_FETCHING (LogLevel.DEBUG, R.string.msg_ret_uri_fetching),
|
||||||
|
MSG_RET_URI_OK (LogLevel.OK, R.string.msg_ret_uri_ok),
|
||||||
|
MSG_RET_URI_START (LogLevel.START, R.string.msg_ret_uri_start),
|
||||||
|
MSG_RET_URI_NULL (LogLevel.ERROR, R.string.msg_ret_uri_null),
|
||||||
|
MSG_RET_URI_TEST (LogLevel.DEBUG, R.string.msg_ret_uri_test),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
public final int mMsgId;
|
public final int mMsgId;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import android.support.v7.app.AlertDialog.Builder;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -39,6 +40,7 @@ import org.bouncycastle.util.encoders.Hex;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||||
|
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||||
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
|
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
||||||
|
@ -137,6 +139,19 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat
|
||||||
inflater.inflate(R.menu.token_setup, menu);
|
inflater.inflate(R.menu.token_setup, menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.view_log: {
|
||||||
|
presenter.onClickViewLog();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
@ -267,6 +282,13 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat
|
||||||
}).show();
|
}).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showDisplayLogActivity(OperationResult result) {
|
||||||
|
Intent intent = new Intent(getActivity(), LogDisplayActivity.class);
|
||||||
|
intent.putExtra(LogDisplayFragment.EXTRA_RESULT, result);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
|
@ -327,13 +349,13 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat
|
||||||
@Override
|
@Override
|
||||||
public void onCryptoOperationSuccess(ImportKeyResult result) {
|
public void onCryptoOperationSuccess(ImportKeyResult result) {
|
||||||
currentImportKeyringParcel = null;
|
currentImportKeyringParcel = null;
|
||||||
presenter.onImportSuccess();
|
presenter.onImportSuccess(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCryptoOperationError(ImportKeyResult result) {
|
public void onCryptoOperationError(ImportKeyResult result) {
|
||||||
currentImportKeyringParcel = null;
|
currentImportKeyringParcel = null;
|
||||||
presenter.onImportError();
|
presenter.onImportError(result);
|
||||||
}
|
}
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
|
@ -347,13 +369,13 @@ public class CreateSecurityTokenImportFragment extends Fragment implements Creat
|
||||||
@Override
|
@Override
|
||||||
public void onCryptoOperationSuccess(PromoteKeyResult result) {
|
public void onCryptoOperationSuccess(PromoteKeyResult result) {
|
||||||
currentPromoteKeyringParcel = null;
|
currentPromoteKeyringParcel = null;
|
||||||
presenter.onPromoteSuccess();
|
presenter.onPromoteSuccess(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCryptoOperationError(PromoteKeyResult result) {
|
public void onCryptoOperationError(PromoteKeyResult result) {
|
||||||
currentPromoteKeyringParcel = null;
|
currentPromoteKeyringParcel = null;
|
||||||
presenter.onPromoteError();
|
presenter.onPromoteError(result);
|
||||||
}
|
}
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,9 @@ import android.support.v4.app.LoaderManager;
|
||||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
|
|
||||||
|
import org.sufficientlysecure.keychain.operations.results.GenericOperationResult;
|
||||||
|
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||||
|
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||||
import org.sufficientlysecure.keychain.ui.CreateSecurityTokenImportFragment.StatusLine;
|
import org.sufficientlysecure.keychain.ui.CreateSecurityTokenImportFragment.StatusLine;
|
||||||
import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.ContentUriRetrievalLoader;
|
import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.ContentUriRetrievalLoader;
|
||||||
import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.KeyRetrievalResult;
|
import org.sufficientlysecure.keychain.ui.PublicKeyRetrievalLoader.KeyRetrievalResult;
|
||||||
|
@ -57,6 +60,7 @@ class CreateSecurityTokenImportPresenter {
|
||||||
private byte[] importKeyData;
|
private byte[] importKeyData;
|
||||||
private Long masterKeyId;
|
private Long masterKeyId;
|
||||||
|
|
||||||
|
private OperationLog log;
|
||||||
|
|
||||||
CreateSecurityTokenImportPresenter(Context context, byte[] tokenFingerprints, byte[] tokenAid,
|
CreateSecurityTokenImportPresenter(Context context, byte[] tokenFingerprints, byte[] tokenAid,
|
||||||
String tokenUserId, String tokenUrl, LoaderManager loaderManager) {
|
String tokenUserId, String tokenUrl, LoaderManager loaderManager) {
|
||||||
|
@ -75,6 +79,8 @@ class CreateSecurityTokenImportPresenter {
|
||||||
this.tokenFingerprints[i] = new byte[20];
|
this.tokenFingerprints[i] = new byte[20];
|
||||||
System.arraycopy(tokenFingerprints, i*20, this.tokenFingerprints[i], 0, 20);
|
System.arraycopy(tokenFingerprints, i*20, this.tokenFingerprints[i], 0, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.log = new OperationLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setView(CreateSecurityTokenImportMvpView view) {
|
public void setView(CreateSecurityTokenImportMvpView view) {
|
||||||
|
@ -153,6 +159,8 @@ class CreateSecurityTokenImportPresenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.add(data.getOperationResult(), 0);
|
||||||
|
|
||||||
if (data.isSuccess()) {
|
if (data.isSuccess()) {
|
||||||
processResult(data);
|
processResult(data);
|
||||||
} else {
|
} else {
|
||||||
|
@ -194,22 +202,30 @@ class CreateSecurityTokenImportPresenter {
|
||||||
view.operationImportKey(importKeyData);
|
view.operationImportKey(importKeyData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onImportSuccess() {
|
void onImportSuccess(OperationResult result) {
|
||||||
|
log.add(result, 0);
|
||||||
|
|
||||||
view.statusLineOk();
|
view.statusLineOk();
|
||||||
view.statusLineAdd(StatusLine.TOKEN_PROMOTE);
|
view.statusLineAdd(StatusLine.TOKEN_PROMOTE);
|
||||||
view.operationPromote(masterKeyId, tokenAid);
|
view.operationPromote(masterKeyId, tokenAid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onImportError() {
|
void onImportError(OperationResult result) {
|
||||||
|
log.add(result, 0);
|
||||||
|
|
||||||
view.statusLineError();
|
view.statusLineError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onPromoteSuccess() {
|
void onPromoteSuccess(OperationResult result) {
|
||||||
|
log.add(result, 0);
|
||||||
|
|
||||||
view.statusLineOk();
|
view.statusLineOk();
|
||||||
view.showActionViewKey();
|
view.showActionViewKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onPromoteError() {
|
void onPromoteError(OperationResult result) {
|
||||||
|
log.add(result, 0);
|
||||||
|
|
||||||
view.statusLineError();
|
view.statusLineError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +268,11 @@ class CreateSecurityTokenImportPresenter {
|
||||||
loaderManager.restartLoader(LOADER_CONTENT_URI, args, loaderCallbacks);
|
loaderManager.restartLoader(LOADER_CONTENT_URI, args, loaderCallbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onClickViewLog() {
|
||||||
|
OperationResult result = new GenericOperationResult(GenericOperationResult.RESULT_OK, log);
|
||||||
|
view.showDisplayLogActivity(result);
|
||||||
|
}
|
||||||
|
|
||||||
interface CreateSecurityTokenImportMvpView {
|
interface CreateSecurityTokenImportMvpView {
|
||||||
void statusLineAdd(StatusLine statusLine);
|
void statusLineAdd(StatusLine statusLine);
|
||||||
void statusLineOk();
|
void statusLineOk();
|
||||||
|
@ -271,5 +292,7 @@ class CreateSecurityTokenImportPresenter {
|
||||||
|
|
||||||
void showFileSelectDialog();
|
void showFileSelectDialog();
|
||||||
void showConfirmResetDialog();
|
void showConfirmResetDialog();
|
||||||
|
|
||||||
|
void showDisplayLogActivity(OperationResult result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,16 +33,22 @@ import android.util.Log;
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
import com.google.auto.value.AutoValue;
|
||||||
import okhttp3.Call;
|
import okhttp3.Call;
|
||||||
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.Request.Builder;
|
import okhttp3.Request.Builder;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
||||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverClient;
|
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverClient;
|
||||||
import org.sufficientlysecure.keychain.keyimport.KeyserverClient.QueryFailedException;
|
import org.sufficientlysecure.keychain.keyimport.KeyserverClient.QueryFailedException;
|
||||||
|
import org.sufficientlysecure.keychain.keyimport.KeyserverClient.QueryNotFoundException;
|
||||||
import org.sufficientlysecure.keychain.network.OkHttpClientFactory;
|
import org.sufficientlysecure.keychain.network.OkHttpClientFactory;
|
||||||
|
import org.sufficientlysecure.keychain.operations.results.GenericOperationResult;
|
||||||
|
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||||
|
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
|
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
|
||||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
||||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
||||||
import org.sufficientlysecure.keychain.provider.KeyRepository.NotFoundException;
|
import org.sufficientlysecure.keychain.provider.KeyRepository.NotFoundException;
|
||||||
|
@ -94,59 +100,102 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyRetrievalResult loadInBackground() {
|
public KeyRetrievalResult loadInBackground() {
|
||||||
|
OperationLog log = new OperationLog();
|
||||||
try {
|
try {
|
||||||
|
log.add(LogType.MSG_RET_LOCAL_START, 0);
|
||||||
|
|
||||||
// TODO check other fingerprints
|
// TODO check other fingerprints
|
||||||
long masterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(fingerprints[0]);
|
long masterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(fingerprints[0]);
|
||||||
|
log.add(LogType.MSG_RET_LOCAL_SEARCH, 1, KeyFormattingUtils.convertKeyIdToHex(masterKeyId));
|
||||||
CachedPublicKeyRing cachedPublicKeyRing = keyRepository.getCachedPublicKeyRing(masterKeyId);
|
CachedPublicKeyRing cachedPublicKeyRing = keyRepository.getCachedPublicKeyRing(masterKeyId);
|
||||||
|
|
||||||
|
if (!Arrays.equals(fingerprints[0], cachedPublicKeyRing.getFingerprint())) {
|
||||||
|
log.add(LogType.MSG_RET_LOCAL_FP_MISMATCH, 1);
|
||||||
|
return KeyRetrievalResult.createWithError(log);
|
||||||
|
} else {
|
||||||
|
log.add(LogType.MSG_RET_LOCAL_FP_MATCH, 1);
|
||||||
|
}
|
||||||
|
|
||||||
switch (cachedPublicKeyRing.getSecretKeyType(masterKeyId)) {
|
switch (cachedPublicKeyRing.getSecretKeyType(masterKeyId)) {
|
||||||
case PASSPHRASE:
|
case PASSPHRASE:
|
||||||
case PASSPHRASE_EMPTY: {
|
case PASSPHRASE_EMPTY: {
|
||||||
return KeyRetrievalResult.createWithMasterKeyIdAndSecretAvailable(masterKeyId);
|
log.add(LogType.MSG_RET_LOCAL_SECRET, 1);
|
||||||
|
log.add(LogType.MSG_RET_LOCAL_OK, 1);
|
||||||
|
return KeyRetrievalResult.createWithMasterKeyIdAndSecretAvailable(log, masterKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
case GNU_DUMMY:
|
case GNU_DUMMY:
|
||||||
case DIVERT_TO_CARD:
|
case DIVERT_TO_CARD:
|
||||||
case UNAVAILABLE: {
|
case UNAVAILABLE: {
|
||||||
return KeyRetrievalResult.createWithMasterKeyId(masterKeyId);
|
log.add(LogType.MSG_RET_LOCAL_OK, 1);
|
||||||
|
return KeyRetrievalResult.createWithMasterKeyId(log, masterKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
throw new IllegalStateException("Unhandled SecretKeyType!");
|
throw new IllegalStateException("Unhandled SecretKeyType!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (NotFoundException e) {
|
} catch (PgpKeyNotFoundException | NotFoundException e) {
|
||||||
return KeyRetrievalResult.createWithError();
|
log.add(LogType.MSG_RET_LOCAL_NOT_FOUND, 1);
|
||||||
|
return KeyRetrievalResult.createWithError(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class UriKeyRetrievalLoader extends PublicKeyRetrievalLoader {
|
public static class UriKeyRetrievalLoader extends PublicKeyRetrievalLoader {
|
||||||
byte[][] fingerprints;
|
byte[][] fingerprints;
|
||||||
String yubikeyUri;
|
String tokenUri;
|
||||||
|
|
||||||
public UriKeyRetrievalLoader(Context context, String yubikeyUri, byte[][] fingerprints) {
|
public UriKeyRetrievalLoader(Context context, String tokenUri, byte[][] fingerprints) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
this.yubikeyUri = yubikeyUri;
|
this.tokenUri = tokenUri;
|
||||||
this.fingerprints = fingerprints;
|
this.fingerprints = fingerprints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyRetrievalResult loadInBackground() {
|
public KeyRetrievalResult loadInBackground() {
|
||||||
|
OperationLog log = new OperationLog();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Call call = OkHttpClientFactory.getSimpleClient().newCall(new Builder().url(yubikeyUri).build());
|
log.add(LogType.MSG_RET_URI_START, 0);
|
||||||
|
if (tokenUri == null) {
|
||||||
|
log.add(LogType.MSG_RET_URI_NULL, 1);
|
||||||
|
return KeyRetrievalResult.createWithError(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.add(LogType.MSG_RET_URI_FETCHING, 1, tokenUri);
|
||||||
|
|
||||||
|
HttpUrl httpUrl = HttpUrl.parse(tokenUri);
|
||||||
|
if (httpUrl == null) {
|
||||||
|
log.add(LogType.MSG_RET_URI_ERROR_PARSE, 1);
|
||||||
|
return KeyRetrievalResult.createWithError(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
Call call = OkHttpClientFactory.getSimpleClient().newCall(new Builder().url(httpUrl).build());
|
||||||
Response execute = call.execute();
|
Response execute = call.execute();
|
||||||
if (execute.isSuccessful()) {
|
if (!execute.isSuccessful()) {
|
||||||
UncachedKeyRing keyRing = UncachedKeyRing.decodeFromData(execute.body().bytes());
|
log.add(LogType.MSG_RET_URI_ERROR_FETCH, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
IteratorWithIOThrow<UncachedKeyRing> uncachedKeyRingIterator = UncachedKeyRing.fromStream(
|
||||||
|
new BufferedInputStream(execute.body().byteStream()));
|
||||||
|
while (uncachedKeyRingIterator.hasNext()) {
|
||||||
|
UncachedKeyRing keyRing = uncachedKeyRingIterator.next();
|
||||||
|
log.add(LogType.MSG_RET_URI_TEST, 1, KeyFormattingUtils.convertKeyIdToHex(keyRing.getMasterKeyId()));
|
||||||
if (Arrays.equals(fingerprints[0], keyRing.getFingerprint())) {
|
if (Arrays.equals(fingerprints[0], keyRing.getFingerprint())) {
|
||||||
return KeyRetrievalResult.createWithKeyringdata(keyRing.getMasterKeyId(), keyRing.getEncoded());
|
log.add(LogType.MSG_RET_URI_OK, 1);
|
||||||
|
return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException | PgpGeneralException e) {
|
|
||||||
|
log.add(LogType.MSG_RET_URI_ERROR_NO_MATCH, 1);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.add(LogType.MSG_RET_URI_ERROR_FETCH, 1);
|
||||||
Log.e(Constants.TAG, "error retrieving key from uri", e);
|
Log.e(Constants.TAG, "error retrieving key from uri", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return KeyRetrievalResult.createWithError();
|
return KeyRetrievalResult.createWithError(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,26 +210,37 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyRetrievalResult loadInBackground() {
|
public KeyRetrievalResult loadInBackground() {
|
||||||
|
OperationLog log = new OperationLog();
|
||||||
|
|
||||||
HkpKeyserverAddress preferredKeyserver = Preferences.getPreferences(getContext()).getPreferredKeyserver();
|
HkpKeyserverAddress preferredKeyserver = Preferences.getPreferences(getContext()).getPreferredKeyserver();
|
||||||
ParcelableProxy parcelableProxy = Preferences.getPreferences(getContext()).getParcelableProxy();
|
ParcelableProxy parcelableProxy = Preferences.getPreferences(getContext()).getParcelableProxy();
|
||||||
|
|
||||||
HkpKeyserverClient keyserverClient = HkpKeyserverClient.fromHkpKeyserverAddress(preferredKeyserver);
|
HkpKeyserverClient keyserverClient = HkpKeyserverClient.fromHkpKeyserverAddress(preferredKeyserver);
|
||||||
|
|
||||||
if (true) {
|
|
||||||
return KeyRetrievalResult.createWithError();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String keyString =
|
log.add(LogType.MSG_RET_KS_START, 0);
|
||||||
keyserverClient.get("0x" + KeyFormattingUtils.convertFingerprintToHex(fingerprint), parcelableProxy);
|
|
||||||
|
String keyString = keyserverClient.get(
|
||||||
|
"0x" + KeyFormattingUtils.convertFingerprintToHex(fingerprint), parcelableProxy);
|
||||||
UncachedKeyRing keyRing = UncachedKeyRing.decodeFromData(keyString.getBytes());
|
UncachedKeyRing keyRing = UncachedKeyRing.decodeFromData(keyString.getBytes());
|
||||||
|
|
||||||
return KeyRetrievalResult.createWithKeyringdata(keyRing.getMasterKeyId(), keyRing.getEncoded());
|
if (!Arrays.equals(fingerprint, keyRing.getFingerprint())) {
|
||||||
|
log.add(LogType.MSG_RET_KS_FP_MISMATCH, 1);
|
||||||
|
return KeyRetrievalResult.createWithError(log);
|
||||||
|
} else {
|
||||||
|
log.add(LogType.MSG_RET_KS_FP_MATCH, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.add(LogType.MSG_RET_KS_OK, 1);
|
||||||
|
return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded());
|
||||||
|
} catch (QueryNotFoundException e) {
|
||||||
|
log.add(LogType.MSG_RET_KS_ERROR_NOT_FOUND, 1);
|
||||||
} catch (QueryFailedException | IOException | PgpGeneralException e) {
|
} catch (QueryFailedException | IOException | PgpGeneralException e) {
|
||||||
|
log.add(LogType.MSG_RET_KS_ERROR, 1);
|
||||||
Log.e(Constants.TAG, "error retrieving key from keyserver", e);
|
Log.e(Constants.TAG, "error retrieving key from keyserver", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return KeyRetrievalResult.createWithError();
|
return KeyRetrievalResult.createWithError(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,25 +259,37 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyRetrievalResult loadInBackground() {
|
public KeyRetrievalResult loadInBackground() {
|
||||||
|
OperationLog log = new OperationLog();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
log.add(LogType.MSG_RET_CURI_START, 0);
|
||||||
|
|
||||||
|
log.add(LogType.MSG_RET_CURI_OPEN, 1, uri.toString());
|
||||||
InputStream is = contentResolver.openInputStream(uri);
|
InputStream is = contentResolver.openInputStream(uri);
|
||||||
if (is == null) {
|
if (is == null) {
|
||||||
return KeyRetrievalResult.createWithError();
|
log.add(LogType.MSG_RET_CURI_ERROR_NOT_FOUND, 1);
|
||||||
|
return KeyRetrievalResult.createWithError(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorWithIOThrow<UncachedKeyRing> uncachedKeyRingIterator = UncachedKeyRing.fromStream(
|
IteratorWithIOThrow<UncachedKeyRing> uncachedKeyRingIterator = UncachedKeyRing.fromStream(
|
||||||
new BufferedInputStream(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()));
|
||||||
if (Arrays.equals(fingerprint, keyRing.getFingerprint())) {
|
if (Arrays.equals(fingerprint, keyRing.getFingerprint())) {
|
||||||
return KeyRetrievalResult.createWithKeyringdata(keyRing.getMasterKeyId(), keyRing.getEncoded());
|
log.add(LogType.MSG_RET_CURI_OK, 1);
|
||||||
|
return KeyRetrievalResult.createWithKeyringdata(log, keyRing.getMasterKeyId(), keyRing.getEncoded());
|
||||||
|
} else {
|
||||||
|
log.add(LogType.MSG_RET_CURI_MISMATCH, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log.add(LogType.MSG_RET_CURI_ERROR_NO_MATCH, 1);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(Constants.TAG, "error retrieving key from keyserver", e);
|
Log.e(Constants.TAG, "error reading keyring from file", e);
|
||||||
|
log.add(LogType.MSG_RET_CURI_ERROR_IO, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return KeyRetrievalResult.createWithError();
|
return KeyRetrievalResult.createWithError(log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,6 +315,8 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
|
||||||
|
|
||||||
@AutoValue
|
@AutoValue
|
||||||
static abstract class KeyRetrievalResult {
|
static abstract class KeyRetrievalResult {
|
||||||
|
abstract GenericOperationResult getOperationResult();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
abstract Long getMasterKeyId();
|
abstract Long getMasterKeyId();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -253,20 +327,28 @@ public abstract class PublicKeyRetrievalLoader extends AsyncTaskLoader<KeyRetrie
|
||||||
return getMasterKeyId() != null || getKeyData() != null;
|
return getMasterKeyId() != null || getKeyData() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static KeyRetrievalResult createWithError() {
|
static KeyRetrievalResult createWithError(OperationLog log) {
|
||||||
return new AutoValue_PublicKeyRetrievalLoader_KeyRetrievalResult(null, null, false);
|
return new AutoValue_PublicKeyRetrievalLoader_KeyRetrievalResult(
|
||||||
|
new GenericOperationResult(GenericOperationResult.RESULT_ERROR, log),
|
||||||
|
null, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static KeyRetrievalResult createWithKeyringdata(long masterKeyId, byte[] keyringData) {
|
static KeyRetrievalResult createWithKeyringdata(OperationLog log, long masterKeyId, byte[] keyringData) {
|
||||||
return new AutoValue_PublicKeyRetrievalLoader_KeyRetrievalResult(masterKeyId, keyringData, false);
|
return new AutoValue_PublicKeyRetrievalLoader_KeyRetrievalResult(
|
||||||
|
new GenericOperationResult(GenericOperationResult.RESULT_OK, log),
|
||||||
|
masterKeyId, keyringData, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static KeyRetrievalResult createWithMasterKeyIdAndSecretAvailable(long masterKeyId) {
|
static KeyRetrievalResult createWithMasterKeyIdAndSecretAvailable(OperationLog log, long masterKeyId) {
|
||||||
return new AutoValue_PublicKeyRetrievalLoader_KeyRetrievalResult(masterKeyId, null, true);
|
return new AutoValue_PublicKeyRetrievalLoader_KeyRetrievalResult(
|
||||||
|
new GenericOperationResult(GenericOperationResult.RESULT_OK, log),
|
||||||
|
masterKeyId, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static KeyRetrievalResult createWithMasterKeyId(long masterKeyId) {
|
static KeyRetrievalResult createWithMasterKeyId(OperationLog log, long masterKeyId) {
|
||||||
return new AutoValue_PublicKeyRetrievalLoader_KeyRetrievalResult(masterKeyId, null, false);
|
return new AutoValue_PublicKeyRetrievalLoader_KeyRetrievalResult(
|
||||||
|
new GenericOperationResult(GenericOperationResult.RESULT_OK, log),
|
||||||
|
masterKeyId, null, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1938,4 +1938,34 @@
|
||||||
<string name="token_status_token_ok">Ready for use!</string>
|
<string name="token_status_token_ok">Ready for use!</string>
|
||||||
<string name="token_status_view_key">View Key</string>
|
<string name="token_status_view_key">View Key</string>
|
||||||
|
|
||||||
|
<string name="msg_ret_curi_error_io">"Error reading data!"</string>
|
||||||
|
<string name="msg_ret_curi_error_no_match">"No matching key found"</string>
|
||||||
|
<string name="msg_ret_curi_error_not_found">"Couldn't open file!"</string>
|
||||||
|
<string name="msg_ret_curi_found">"Found key: %s"</string>
|
||||||
|
<string name="msg_ret_curi_mismatch">"Key doesn't match"</string>
|
||||||
|
<string name="msg_ret_curi_ok">"Key found"</string>
|
||||||
|
<string name="msg_ret_curi_open">"Opening Uri: %s"</string>
|
||||||
|
<string name="msg_ret_curi_start">"Loading key from file or document…"</string>
|
||||||
|
<string name="msg_ret_ks_error">"Unknown error searching for key!"</string>
|
||||||
|
<string name="msg_ret_ks_error_not_found">"Key not found"</string>
|
||||||
|
<string name="msg_ret_ks_fp_match">"Retrieved key's fingerprint matches"</string>
|
||||||
|
<string name="msg_ret_ks_fp_mismatch">"Retrieved key's fingerprint doesn't match!"</string>
|
||||||
|
<string name="msg_ret_ks_ok">"Key found"</string>
|
||||||
|
<string name="msg_ret_ks_start">"Looking for key on keyservers…"</string>
|
||||||
|
<string name="msg_ret_local_search">"Searching for key: %s"</string>
|
||||||
|
<string name="msg_ret_local_fp_match">"Local key's fingerprint matches"</string>
|
||||||
|
<string name="msg_ret_local_fp_mismatch">"Local key's fingerprint doesn't match!"</string>
|
||||||
|
<string name="msg_ret_local_not_found">"No key found"</string>
|
||||||
|
<string name="msg_ret_local_ok">"Key found"</string>
|
||||||
|
<string name="msg_ret_local_secret">"Local key contains secret key material"</string>
|
||||||
|
<string name="msg_ret_local_start">"Looking for key in local key list…"</string>
|
||||||
|
<string name="msg_ret_uri_error_fetch">"Unknown error fetching Uri!"</string>
|
||||||
|
<string name="msg_ret_uri_error_parse">"Token Uri is malformed!"</string>
|
||||||
|
<string name="msg_ret_uri_error_no_match">"No matching key found at Uri"</string>
|
||||||
|
<string name="msg_ret_uri_fetching">"Fetching Uri: %s"</string>
|
||||||
|
<string name="msg_ret_uri_ok">"Key found"</string>
|
||||||
|
<string name="msg_ret_uri_start">"Looking for key at token Uri…"</string>
|
||||||
|
<string name="msg_ret_uri_null">"No Uri saved on Security Token"</string>
|
||||||
|
<string name="msg_ret_uri_test">"Checking if found key matches: %s"</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue