yubikey certifications!
This commit is contained in:
@@ -30,6 +30,8 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpCertifyOperation.PgpCertifyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
@@ -38,6 +40,8 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException
|
||||
import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
|
||||
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
|
||||
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
|
||||
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel.NfcSignOperationsBuilder;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
@@ -73,10 +77,6 @@ public class CertifyOperation extends BaseOperation {
|
||||
mProviderHelper.getCanonicalizedSecretKeyRing(parcel.mMasterKeyId);
|
||||
log.add(LogType.MSG_CRT_UNLOCK, 1);
|
||||
certificationKey = secretKeyRing.getSecretKey();
|
||||
if (certificationKey.getSecretKeyType() == SecretKeyType.DIVERT_TO_CARD) {
|
||||
log.add(LogType.MSG_CRT_ERROR_DIVERT, 2);
|
||||
return new CertifyResult(CertifyResult.RESULT_ERROR, log);
|
||||
}
|
||||
|
||||
// certification is always with the master key id, so use that one
|
||||
String passphrase = getCachedPassphrase(parcel.mMasterKeyId, parcel.mMasterKeyId);
|
||||
@@ -102,6 +102,8 @@ public class CertifyOperation extends BaseOperation {
|
||||
|
||||
int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0;
|
||||
|
||||
NfcSignOperationsBuilder allRequiredInput = new NfcSignOperationsBuilder(parcel.getSignatureTime());
|
||||
|
||||
// Work through all requested certifications
|
||||
for (CertifyAction action : parcel.mCertifyActions) {
|
||||
|
||||
@@ -122,28 +124,21 @@ public class CertifyOperation extends BaseOperation {
|
||||
CanonicalizedPublicKeyRing publicRing =
|
||||
mProviderHelper.getCanonicalizedPublicKeyRing(action.mMasterKeyId);
|
||||
|
||||
UncachedKeyRing certifiedKey = null;
|
||||
if (action.mUserIds != null) {
|
||||
log.add(LogType.MSG_CRT_CERTIFY_UIDS, 2, action.mUserIds.size(),
|
||||
KeyFormattingUtils.convertKeyIdToHex(action.mMasterKeyId));
|
||||
PgpCertifyOperation op = new PgpCertifyOperation();
|
||||
PgpCertifyResult result = op.certify(certificationKey, publicRing,
|
||||
log, 2, action, parcel.getSignatureData(), parcel.getSignatureTime());
|
||||
|
||||
certifiedKey = certificationKey.certifyUserIds(
|
||||
publicRing, action.mUserIds, null, null);
|
||||
}
|
||||
|
||||
if (action.mUserAttributes != null) {
|
||||
log.add(LogType.MSG_CRT_CERTIFY_UATS, 2, action.mUserAttributes.size(),
|
||||
KeyFormattingUtils.convertKeyIdToHex(action.mMasterKeyId));
|
||||
|
||||
certifiedKey = certificationKey.certifyUserAttributes(
|
||||
publicRing, action.mUserAttributes, null, null);
|
||||
}
|
||||
|
||||
if (certifiedKey == null) {
|
||||
if (!result.success()) {
|
||||
certifyError += 1;
|
||||
log.add(LogType.MSG_CRT_WARN_CERT_FAILED, 3);
|
||||
continue;
|
||||
}
|
||||
certifiedKeys.add(certifiedKey);
|
||||
if (result.nfcInputRequired()) {
|
||||
NfcOperationsParcel requiredInput = result.getRequiredInput();
|
||||
allRequiredInput.addAll(requiredInput);
|
||||
continue;
|
||||
}
|
||||
|
||||
certifiedKeys.add(result.getCertifiedRing());
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
certifyError += 1;
|
||||
@@ -152,6 +147,11 @@ public class CertifyOperation extends BaseOperation {
|
||||
|
||||
}
|
||||
|
||||
if ( ! allRequiredInput.isEmpty()) {
|
||||
log.add(LogType.MSG_CRT_NFC_RETURN, 1);
|
||||
return new CertifyResult(log, allRequiredInput.build());
|
||||
}
|
||||
|
||||
log.add(LogType.MSG_CRT_SAVING, 1);
|
||||
|
||||
// Check if we were cancelled
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.Intent;
|
||||
import android.os.Parcel;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel;
|
||||
import org.sufficientlysecure.keychain.ui.LogDisplayActivity;
|
||||
import org.sufficientlysecure.keychain.ui.LogDisplayFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
@@ -30,16 +31,19 @@ import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.Showable;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
|
||||
|
||||
public class CertifyResult extends OperationResult {
|
||||
|
||||
public class CertifyResult extends InputPendingResult {
|
||||
int mCertifyOk, mCertifyError, mUploadOk, mUploadError;
|
||||
|
||||
public CertifyResult(int result, OperationLog log) {
|
||||
super(result, log);
|
||||
}
|
||||
|
||||
public CertifyResult(OperationLog log, NfcOperationsParcel requiredInput) {
|
||||
super(log, requiredInput);
|
||||
}
|
||||
|
||||
public CertifyResult(int result, OperationLog log, int certifyOk, int certifyError, int uploadOk, int uploadError) {
|
||||
this(result, log);
|
||||
super(result, log);
|
||||
mCertifyOk = certifyOk;
|
||||
mCertifyError = certifyError;
|
||||
mUploadOk = uploadOk;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.sufficientlysecure.keychain.operations.results;
|
||||
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import org.sufficientlysecure.keychain.service.input.NfcOperationsParcel;
|
||||
|
||||
|
||||
public class InputPendingResult extends OperationResult {
|
||||
|
||||
// the fourth bit indicates a "data pending" result! (it's also a form of non-success)
|
||||
public static final int RESULT_PENDING = RESULT_ERROR + 8;
|
||||
|
||||
public static final int RESULT_PENDING_PASSPHRASE = RESULT_PENDING + 16;
|
||||
public static final int RESULT_PENDING_NFC = RESULT_PENDING + 32;
|
||||
|
||||
final NfcOperationsParcel mRequiredInput;
|
||||
final Long mKeyIdPassphraseNeeded;
|
||||
|
||||
public InputPendingResult(int result, OperationLog log) {
|
||||
super(result, log);
|
||||
mRequiredInput = null;
|
||||
mKeyIdPassphraseNeeded = null;
|
||||
}
|
||||
|
||||
public InputPendingResult(OperationLog log, NfcOperationsParcel requiredInput) {
|
||||
super(RESULT_PENDING_NFC, log);
|
||||
mRequiredInput = requiredInput;
|
||||
mKeyIdPassphraseNeeded = null;
|
||||
}
|
||||
|
||||
public InputPendingResult(OperationLog log, long keyIdPassphraseNeeded) {
|
||||
super(RESULT_PENDING_PASSPHRASE, log);
|
||||
mRequiredInput = null;
|
||||
mKeyIdPassphraseNeeded = keyIdPassphraseNeeded;
|
||||
}
|
||||
|
||||
public InputPendingResult(Parcel source) {
|
||||
super(source);
|
||||
mRequiredInput = source.readParcelable(getClass().getClassLoader());
|
||||
mKeyIdPassphraseNeeded = source.readInt() != 0 ? source.readLong() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeParcelable(mRequiredInput, 0);
|
||||
if (mKeyIdPassphraseNeeded != null) {
|
||||
dest.writeInt(1);
|
||||
dest.writeLong(mKeyIdPassphraseNeeded);
|
||||
} else {
|
||||
dest.writeInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPending() {
|
||||
return (mResult & RESULT_PENDING) == RESULT_PENDING;
|
||||
}
|
||||
|
||||
public boolean isNfcPending() {
|
||||
return (mResult & RESULT_PENDING_NFC) == RESULT_PENDING_NFC;
|
||||
}
|
||||
|
||||
public boolean isPassphrasePending() {
|
||||
return (mResult & RESULT_PENDING_PASSPHRASE) == RESULT_PENDING_PASSPHRASE;
|
||||
}
|
||||
|
||||
public NfcOperationsParcel getNfcOperationsParcel() {
|
||||
return mRequiredInput;
|
||||
}
|
||||
|
||||
public long getPassphraseKeyId() {
|
||||
return mKeyIdPassphraseNeeded;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -697,9 +697,9 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_CRT_ERROR_MASTER_NOT_FOUND (LogLevel.ERROR, R.string.msg_crt_error_master_not_found),
|
||||
MSG_CRT_ERROR_NOTHING (LogLevel.ERROR, R.string.msg_crt_error_nothing),
|
||||
MSG_CRT_ERROR_UNLOCK (LogLevel.ERROR, R.string.msg_crt_error_unlock),
|
||||
MSG_CRT_ERROR_DIVERT (LogLevel.ERROR, R.string.msg_crt_error_divert),
|
||||
MSG_CRT (LogLevel.START, R.string.msg_crt),
|
||||
MSG_CRT_MASTER_FETCH (LogLevel.DEBUG, R.string.msg_crt_master_fetch),
|
||||
MSG_CRT_NFC_RETURN (LogLevel.OK, R.string.msg_crt_nfc_return),
|
||||
MSG_CRT_SAVE (LogLevel.DEBUG, R.string.msg_crt_save),
|
||||
MSG_CRT_SAVING (LogLevel.DEBUG, R.string.msg_crt_saving),
|
||||
MSG_CRT_SUCCESS (LogLevel.OK, R.string.msg_crt_success),
|
||||
|
||||
@@ -31,6 +31,7 @@ public class SignEncryptResult extends OperationResult {
|
||||
|
||||
public static final int RESULT_PENDING = RESULT_ERROR + 8;
|
||||
|
||||
|
||||
public PgpSignEncryptResult getPending() {
|
||||
for (PgpSignEncryptResult sub : mResults) {
|
||||
if (sub.isPending()) {
|
||||
|
||||
Reference in New Issue
Block a user