use autovalue for SaveKeyringParcel

This commit is contained in:
Vincent Breitmoser
2017-05-23 02:23:03 +02:00
parent 147e4dbee7
commit d58f1bd225
26 changed files with 816 additions and 812 deletions

View File

@@ -179,12 +179,12 @@ public final class Constants {
/**
* Default key configuration: 3072 bit RSA (certify, sign, encrypt)
*/
public static void addDefaultSubkeys(SaveKeyringParcel saveKeyringParcel) {
saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA,
public static void addDefaultSubkeys(SaveKeyringParcel.Builder builder) {
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA,
3072, null, KeyFlags.CERTIFY_OTHER, 0L));
saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA,
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA,
3072, null, KeyFlags.SIGN_DATA, 0L));
saveKeyringParcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA,
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA,
3072, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L));
}

View File

@@ -88,13 +88,13 @@ public class EditKeyOperation extends BaseReadWriteOperation<SaveKeyringParcel>
new PgpKeyOperation(new ProgressScaler(mProgressable, 10, 60, 100), mCancelled);
// If a key id is specified, fetch and edit
if (saveParcel.mMasterKeyId != null) {
if (saveParcel.getMasterKeyId() != null) {
try {
log.add(LogType.MSG_ED_FETCHING, 1,
KeyFormattingUtils.convertKeyIdToHex(saveParcel.mMasterKeyId));
KeyFormattingUtils.convertKeyIdToHex(saveParcel.getMasterKeyId()));
CanonicalizedSecretKeyRing secRing =
mKeyRepository.getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
mKeyRepository.getCanonicalizedSecretKeyRing(saveParcel.getMasterKeyId());
modifyResult = keyOperations.modifySecretKeyRing(secRing, cryptoInput, saveParcel);
if (modifyResult.isPending()) {
@@ -133,7 +133,7 @@ public class EditKeyOperation extends BaseReadWriteOperation<SaveKeyringParcel>
// It's a success, so this must be non-null now
UncachedKeyRing ring = modifyResult.getRing();
if (saveParcel.isUpload()) {
if (saveParcel.isShouldUpload()) {
byte[] keyringBytes;
try {
UncachedKeyRing publicKeyRing = ring.extractPublicKeyRing();
@@ -154,7 +154,7 @@ public class EditKeyOperation extends BaseReadWriteOperation<SaveKeyringParcel>
if (uploadResult.isPending()) {
return new EditKeyResult(log, uploadResult);
} else if (!uploadResult.success() && saveParcel.isUploadAtomic()) {
} else if (!uploadResult.success() && saveParcel.isShouldUploadAtomic()) {
// if atomic, update fail implies edit operation should also fail and not save
return new EditKeyResult(log, RequiredInputParcel.createRetryUploadOperation(), cryptoInput);
}

View File

@@ -71,17 +71,18 @@ public class RevokeOperation extends BaseReadWriteOperation<RevokeKeyringParcel>
return new RevokeResult(RevokeResult.RESULT_ERROR, log, masterKeyId);
}
SaveKeyringParcel saveKeyringParcel =
new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint());
SaveKeyringParcel.Builder saveKeyringParcel =
SaveKeyringParcel.buildChangeKeyringParcel(masterKeyId, keyRing.getFingerprint());
// all revoke operations are made atomic as of now
saveKeyringParcel.setUpdateOptions(revokeKeyringParcel.isShouldUpload(), true,
revokeKeyringParcel.getKeyserver());
saveKeyringParcel.mRevokeSubKeys.add(masterKeyId);
saveKeyringParcel.addRevokeSubkey(masterKeyId);
EditKeyResult revokeAndUploadResult = new EditKeyOperation(mContext,
mKeyWritableRepository, mProgressable, mCancelled).execute(saveKeyringParcel, cryptoInputParcel);
mKeyWritableRepository, mProgressable, mCancelled).execute(
saveKeyringParcel.build(), cryptoInputParcel);
if (revokeAndUploadResult.isPending()) {
return revokeAndUploadResult;

View File

@@ -29,10 +29,10 @@ import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.spec.ECGenParameterSpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -80,6 +80,7 @@ import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.service.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Builder;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
@@ -287,23 +288,23 @@ public class PgpKeyOperation {
progress(R.string.progress_building_key, 0);
indent += 1;
if (saveParcel.mAddSubKeys.isEmpty()) {
if (saveParcel.getAddSubKeys().isEmpty()) {
log.add(LogType.MSG_CR_ERROR_NO_MASTER, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (saveParcel.mAddUserIds.isEmpty()) {
if (saveParcel.getAddUserIds().isEmpty()) {
log.add(LogType.MSG_CR_ERROR_NO_USER_ID, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
SubkeyAdd add = saveParcel.mAddSubKeys.remove(0);
if ((add.getFlags() & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) {
SubkeyAdd certificationKey = saveParcel.getAddSubKeys().get(0);
if ((certificationKey.getFlags() & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) {
log.add(LogType.MSG_CR_ERROR_NO_CERTIFY, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (add.getExpiry() == null) {
if (certificationKey.getExpiry() == null) {
log.add(LogType.MSG_CR_ERROR_NULL_EXPIRY, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
@@ -311,7 +312,7 @@ public class PgpKeyOperation {
Date creationTime = new Date();
subProgressPush(10, 30);
PGPKeyPair keyPair = createKey(add, creationTime, log, indent);
PGPKeyPair keyPair = createKey(certificationKey, creationTime, log, indent);
subProgressPop();
// return null if this failed (an error will already have been logged by createKey)
@@ -337,9 +338,14 @@ public class PgpKeyOperation {
PGPSecretKeyRing sKR = new PGPSecretKeyRing(
masterSecretKey.getEncoded(), new JcaKeyFingerprintCalculator());
// Remove certification key from remaining SaveKeyringParcel
Builder builder = SaveKeyringParcel.buildUpon(saveParcel);
builder.getMutableAddSubKeys().remove(certificationKey);
saveParcel = builder.build();
subProgressPush(50, 100);
CryptoInputParcel cryptoInput = CryptoInputParcel.createCryptoInputParcel(creationTime, new Passphrase(""));
return internal(sKR, masterSecretKey, add.getFlags(), add.getExpiry(), cryptoInput, saveParcel, log, indent);
return internal(sKR, masterSecretKey, certificationKey.getFlags(), certificationKey.getExpiry(), cryptoInput, saveParcel, log, indent);
} catch (PGPException e) {
log.add(LogType.MSG_CR_ERROR_INTERNAL_PGP, indent);
@@ -394,7 +400,7 @@ public class PgpKeyOperation {
progress(R.string.progress_building_key, 0);
// Make sure this is called with a proper SaveKeyringParcel
if (saveParcel.mMasterKeyId == null || saveParcel.mMasterKeyId != wsKR.getMasterKeyId()) {
if (saveParcel.getMasterKeyId() == null || saveParcel.getMasterKeyId() != wsKR.getMasterKeyId()) {
log.add(LogType.MSG_MF_ERROR_KEYID, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
@@ -404,75 +410,29 @@ public class PgpKeyOperation {
PGPSecretKey masterSecretKey = sKR.getSecretKey();
// Make sure the fingerprint matches
if (saveParcel.mFingerprint == null || !Arrays.equals(saveParcel.mFingerprint,
if (saveParcel.getFingerprint() == null || !Arrays.equals(saveParcel.getFingerprint(),
masterSecretKey.getPublicKey().getFingerprint())) {
log.add(LogType.MSG_MF_ERROR_FINGERPRINT, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (saveParcel.isEmpty()) {
if (isParcelEmpty(saveParcel)) {
log.add(LogType.MSG_MF_ERROR_NOOP, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
// Ensure we don't have multiple keys for the same slot.
boolean hasSign = false;
boolean hasEncrypt = false;
boolean hasAuth = false;
for (SaveKeyringParcel.SubkeyChange change : new ArrayList<>(saveParcel.mChangeSubKeys)) {
if (change.getMoveKeyToSecurityToken()) {
// If this is a moveKeyToSecurityToken operation, see if it was completed: look for a hash
// matching the given subkey ID in cryptoData.
byte[] subKeyId = new byte[8];
ByteBuffer buf = ByteBuffer.wrap(subKeyId);
buf.putLong(change.getSubKeyId()).rewind();
saveParcel = parseSecurityTokenSerialNumberIntoSubkeyChanges(cryptoInput, saveParcel);
byte[] serialNumber = cryptoInput.getCryptoData().get(buf);
if (serialNumber != null) {
saveParcel.addOrReplaceSubkeyChange(
SubkeyChange.createSecurityTokenSerialNo(change.getSubKeyId(), serialNumber));
}
}
if (change.getMoveKeyToSecurityToken()) {
// Pending moveKeyToSecurityToken operation. Need to make sure that we don't have multiple
// subkeys pending for the same slot.
CanonicalizedSecretKey wsK = wsKR.getSecretKey(change.getSubKeyId());
if ((wsK.canSign() || wsK.canCertify())) {
if (hasSign) {
log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
} else {
hasSign = true;
}
} else if ((wsK.canEncrypt())) {
if (hasEncrypt) {
log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
} else {
hasEncrypt = true;
}
} else if ((wsK.canAuthenticate())) {
if (hasAuth) {
log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
} else {
hasAuth = true;
}
} else {
log.add(LogType.MSG_MF_ERROR_INVALID_FLAGS_FOR_KEYTOCARD, indent + 1);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
}
if (!checkCapabilitiesAreUnique(wsKR, saveParcel, log, indent)) {
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (isDummy(masterSecretKey) && ! saveParcel.isRestrictedOnly()) {
if (isDummy(masterSecretKey) && ! isParcelRestrictedOnly(saveParcel)) {
log.add(LogType.MSG_EK_ERROR_DUMMY, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
if (isDummy(masterSecretKey) || saveParcel.isRestrictedOnly()) {
if (isDummy(masterSecretKey) || isParcelRestrictedOnly(saveParcel)) {
log.add(LogType.MSG_MF_RESTRICTED_MODE, indent);
return internalRestricted(sKR, saveParcel, log, indent + 1);
}
@@ -496,6 +456,70 @@ public class PgpKeyOperation {
}
private SaveKeyringParcel parseSecurityTokenSerialNumberIntoSubkeyChanges(CryptoInputParcel cryptoInput,
SaveKeyringParcel saveParcel) {
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildUpon(saveParcel);
for (SubkeyChange change : saveParcel.getChangeSubKeys()) {
if (change.getMoveKeyToSecurityToken()) {
// If this is a moveKeyToSecurityToken operation, see if it was completed: look for a hash
// matching the given subkey ID in cryptoData.
byte[] subKeyId = new byte[8];
ByteBuffer buf = ByteBuffer.wrap(subKeyId);
buf.putLong(change.getSubKeyId()).rewind();
byte[] serialNumber = cryptoInput.getCryptoData().get(buf);
if (serialNumber != null) {
builder.addOrReplaceSubkeyChange(
SubkeyChange.createSecurityTokenSerialNo(change.getSubKeyId(), serialNumber));
}
}
}
saveParcel = builder.build();
return saveParcel;
}
private boolean checkCapabilitiesAreUnique(CanonicalizedSecretKeyRing wsKR, SaveKeyringParcel saveParcel,
OperationLog log, int indent) {
boolean hasSign = false;
boolean hasEncrypt = false;
boolean hasAuth = false;
for (SubkeyChange change : saveParcel.getChangeSubKeys()) {
if (change.getMoveKeyToSecurityToken()) {
// Pending moveKeyToSecurityToken operation. Need to make sure that we don't have multiple
// subkeys pending for the same slot.
CanonicalizedSecretKey wsK = wsKR.getSecretKey(change.getSubKeyId());
if ((wsK.canSign() || wsK.canCertify())) {
if (hasSign) {
log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
return false;
} else {
hasSign = true;
}
} else if ((wsK.canEncrypt())) {
if (hasEncrypt) {
log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
return false;
} else {
hasEncrypt = true;
}
} else if ((wsK.canAuthenticate())) {
if (hasAuth) {
log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
return false;
} else {
hasAuth = true;
}
} else {
log.add(LogType.MSG_MF_ERROR_INVALID_FLAGS_FOR_KEYTOCARD, indent + 1);
return false;
}
}
}
return true;
}
private PgpEditKeyResult internal(PGPSecretKeyRing sKR, PGPSecretKey masterSecretKey,
int masterKeyFlags, long masterKeyExpiry,
CryptoInputParcel cryptoInput,
@@ -549,10 +573,11 @@ public class PgpKeyOperation {
// 2a. Add certificates for new user ids
subProgressPush(15, 23);
for (int i = 0; i < saveParcel.mAddUserIds.size(); i++) {
String changePrimaryUserId = saveParcel.getChangePrimaryUserId();
for (int i = 0; i < saveParcel.getAddUserIds().size(); i++) {
progress(R.string.progress_modify_adduid, (i - 1) * (100 / saveParcel.mAddUserIds.size()));
String userId = saveParcel.mAddUserIds.get(i);
progress(R.string.progress_modify_adduid, (i - 1) * (100 / saveParcel.getAddUserIds().size()));
String userId = saveParcel.getAddUserIds().get(i);
log.add(LogType.MSG_MF_UID_ADD, indent, userId);
if ("".equals(userId)) {
@@ -583,8 +608,8 @@ public class PgpKeyOperation {
}
// if it's supposed to be primary, we can do that here as well
boolean isPrimary = saveParcel.mChangePrimaryUserId != null
&& userId.equals(saveParcel.mChangePrimaryUserId);
boolean isPrimary = changePrimaryUserId != null
&& userId.equals(changePrimaryUserId);
// generate and add new certificate
try {
PGPSignature cert = generateUserIdSignature(
@@ -601,10 +626,10 @@ public class PgpKeyOperation {
// 2b. Add certificates for new user ids
subProgressPush(23, 32);
for (int i = 0; i < saveParcel.mAddUserAttribute.size(); i++) {
progress(R.string.progress_modify_adduat, (i - 1) * (100 / saveParcel.mAddUserAttribute.size()));
WrappedUserAttribute attribute = saveParcel.mAddUserAttribute.get(i);
List<WrappedUserAttribute> addUserAttributes = saveParcel.getAddUserAttribute();
for (int i = 0; i < addUserAttributes.size(); i++) {
progress(R.string.progress_modify_adduat, (i - 1) * (100 / addUserAttributes.size()));
WrappedUserAttribute attribute = addUserAttributes.get(i);
switch (attribute.getType()) {
// the 'none' type must not succeed
@@ -637,10 +662,10 @@ public class PgpKeyOperation {
// 2c. Add revocations for revoked user ids
subProgressPush(32, 40);
for (int i = 0; i < saveParcel.mRevokeUserIds.size(); i++) {
progress(R.string.progress_modify_revokeuid, (i - 1) * (100 / saveParcel.mRevokeUserIds.size()));
String userId = saveParcel.mRevokeUserIds.get(i);
List<String> revokeUserIds = saveParcel.getRevokeUserIds();
for (int i = 0, j = revokeUserIds.size(); i < j; i++) {
progress(R.string.progress_modify_revokeuid, (i - 1) * (100 / revokeUserIds.size()));
String userId = revokeUserIds.get(i);
log.add(LogType.MSG_MF_UID_REVOKE, indent, userId);
// Make sure the user id exists (yes these are 10 LoC in Java!)
@@ -672,12 +697,12 @@ public class PgpKeyOperation {
subProgressPop();
// 3. If primary user id changed, generate new certificates for both old and new
if (saveParcel.mChangePrimaryUserId != null) {
if (changePrimaryUserId != null) {
progress(R.string.progress_modify_primaryuid, 40);
// keep track if we actually changed one
boolean ok = false;
log.add(LogType.MSG_MF_UID_PRIMARY, indent, saveParcel.mChangePrimaryUserId);
log.add(LogType.MSG_MF_UID_PRIMARY, indent, changePrimaryUserId);
indent += 1;
// we work on the modifiedPublicKey here, to respect new or newly revoked uids
@@ -718,7 +743,7 @@ public class PgpKeyOperation {
// we definitely should not update certifications of revoked keys, so just leave it.
if (isRevoked) {
// revoked user ids cannot be primary!
if (userId.equals(saveParcel.mChangePrimaryUserId)) {
if (userId.equals(changePrimaryUserId)) {
log.add(LogType.MSG_MF_ERROR_REVOKED_PRIMARY, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
@@ -729,7 +754,7 @@ public class PgpKeyOperation {
if (currentCert.getHashedSubPackets() != null
&& currentCert.getHashedSubPackets().isPrimaryUserID()) {
// if it's the one we want, just leave it as is
if (userId.equals(saveParcel.mChangePrimaryUserId)) {
if (userId.equals(changePrimaryUserId)) {
ok = true;
continue;
}
@@ -755,7 +780,7 @@ public class PgpKeyOperation {
// if we are here, this is not currently a primary user id
// if it should be
if (userId.equals(saveParcel.mChangePrimaryUserId)) {
if (userId.equals(changePrimaryUserId)) {
// add shiny new primary user id certificate
log.add(LogType.MSG_MF_PRIMARY_NEW, indent);
modifiedPublicKey = PGPPublicKey.removeCertification(
@@ -803,10 +828,11 @@ public class PgpKeyOperation {
// 4a. For each subkey change, generate new subkey binding certificate
subProgressPush(50, 60);
for (int i = 0; i < saveParcel.mChangeSubKeys.size(); i++) {
List<SubkeyChange> changeSubKeys = saveParcel.getChangeSubKeys();
for (int i = 0, j = changeSubKeys.size(); i < j; i++) {
progress(R.string.progress_modify_subkeychange, (i-1) * (100 / saveParcel.mChangeSubKeys.size()));
SaveKeyringParcel.SubkeyChange change = saveParcel.mChangeSubKeys.get(i);
progress(R.string.progress_modify_subkeychange, (i-1) * (100 / changeSubKeys.size()));
SaveKeyringParcel.SubkeyChange change = changeSubKeys.get(i);
log.add(LogType.MSG_MF_SUBKEY_CHANGE,
indent, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId()));
@@ -944,10 +970,10 @@ public class PgpKeyOperation {
// 4b. For each subkey revocation, generate new subkey revocation certificate
subProgressPush(60, 65);
for (int i = 0; i < saveParcel.mRevokeSubKeys.size(); i++) {
progress(R.string.progress_modify_subkeyrevoke, (i-1) * (100 / saveParcel.mRevokeSubKeys.size()));
long revocation = saveParcel.mRevokeSubKeys.get(i);
List<Long> revokeSubKeys = saveParcel.getRevokeSubKeys();
for (int i = 0, j = revokeSubKeys.size(); i < j; i++) {
progress(R.string.progress_modify_subkeyrevoke, (i-1) * (100 / revokeSubKeys.size()));
long revocation = revokeSubKeys.get(i);
log.add(LogType.MSG_MF_SUBKEY_REVOKE,
indent, KeyFormattingUtils.convertKeyIdToHex(revocation));
@@ -976,16 +1002,16 @@ public class PgpKeyOperation {
// 5. Generate and add new subkeys
subProgressPush(70, 90);
for (int i = 0; i < saveParcel.mAddSubKeys.size(); i++) {
List<SubkeyAdd> addSubKeys = saveParcel.getAddSubKeys();
for (int i = 0, j = addSubKeys.size(); i < j; i++) {
// Check if we were cancelled - again. This operation is expensive so we do it each loop.
if (checkCancelled()) {
log.add(LogType.MSG_OPERATION_CANCELLED, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_CANCELLED, log, null);
}
progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size()));
SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i);
progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / addSubKeys.size()));
SaveKeyringParcel.SubkeyAdd add = addSubKeys.get(i);
log.add(LogType.MSG_MF_SUBKEY_NEW, indent,
KeyFormattingUtils.getAlgorithmInfo(add.getAlgorithm(), add.getKeySize(), add.getCurve()) );
@@ -1006,8 +1032,8 @@ public class PgpKeyOperation {
// generate a new secret key (privkey only for now)
subProgressPush(
(i-1) * (100 / saveParcel.mAddSubKeys.size()),
i * (100 / saveParcel.mAddSubKeys.size())
(i-1) * (100 / addSubKeys.size()),
i * (100 / addSubKeys.size())
);
PGPKeyPair keyPair = createKey(add, cryptoInput.getSignatureTime(), log, indent);
subProgressPop();
@@ -1060,13 +1086,13 @@ public class PgpKeyOperation {
}
// 6. If requested, change passphrase
if (saveParcel.getChangeUnlockParcel() != null) {
if (saveParcel.getNewUnlock() != null) {
progress(R.string.progress_modify_passphrase, 90);
log.add(LogType.MSG_MF_PASSPHRASE, indent);
indent += 1;
sKR = applyNewPassphrase(sKR, masterPublicKey, cryptoInput.getPassphrase(),
saveParcel.getChangeUnlockParcel().getNewPassphrase(), log, indent);
saveParcel.getNewUnlock().getNewPassphrase(), log, indent);
if (sKR == null) {
// The error has been logged above, just return a bad state
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
@@ -1076,21 +1102,21 @@ public class PgpKeyOperation {
}
// 7. if requested, change PIN and/or Admin PIN on security token
if (saveParcel.mSecurityTokenPin != null) {
if (saveParcel.getSecurityTokenPin() != null) {
progress(R.string.progress_modify_pin, 90);
log.add(LogType.MSG_MF_PIN, indent);
indent += 1;
nfcKeyToCardOps.setPin(saveParcel.mSecurityTokenPin);
nfcKeyToCardOps.setPin(saveParcel.getSecurityTokenPin());
indent -= 1;
}
if (saveParcel.mSecurityTokenAdminPin != null) {
if (saveParcel.getSecurityTokenAdminPin() != null) {
progress(R.string.progress_modify_admin_pin, 90);
log.add(LogType.MSG_MF_ADMIN_PIN, indent);
indent += 1;
nfcKeyToCardOps.setAdminPin(saveParcel.mSecurityTokenAdminPin);
nfcKeyToCardOps.setAdminPin(saveParcel.getSecurityTokenAdminPin());
indent -= 1;
}
@@ -1141,7 +1167,7 @@ public class PgpKeyOperation {
progress(R.string.progress_modify, 0);
// Make sure the saveParcel includes only operations available without passphrase!
if (!saveParcel.isRestrictedOnly()) {
if (!isParcelRestrictedOnly(saveParcel)) {
log.add(LogType.MSG_MF_ERROR_RESTRICTED, indent);
return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
}
@@ -1155,10 +1181,10 @@ public class PgpKeyOperation {
// The only operation we can do here:
// 4a. Strip secret keys, or change their protection mode (stripped/divert-to-card)
subProgressPush(50, 60);
for (int i = 0; i < saveParcel.mChangeSubKeys.size(); i++) {
progress(R.string.progress_modify_subkeychange, (i - 1) * (100 / saveParcel.mChangeSubKeys.size()));
SaveKeyringParcel.SubkeyChange change = saveParcel.mChangeSubKeys.get(i);
List<SubkeyChange> changeSubKeys = saveParcel.getChangeSubKeys();
for (int i = 0, j = changeSubKeys.size(); i < j; i++) {
progress(R.string.progress_modify_subkeychange, (i - 1) * (100 / changeSubKeys.size()));
SaveKeyringParcel.SubkeyChange change = changeSubKeys.get(i);
log.add(LogType.MSG_MF_SUBKEY_CHANGE,
indent, KeyFormattingUtils.convertKeyIdToHex(change.getSubKeyId()));
@@ -1700,4 +1726,31 @@ public class PgpKeyOperation {
return true;
}
/** Returns true iff this parcel does not contain any operations which require a passphrase. */
private static boolean isParcelRestrictedOnly(SaveKeyringParcel saveKeyringParcel) {
if (saveKeyringParcel.getNewUnlock() != null
|| !saveKeyringParcel.getAddUserIds().isEmpty()
|| !saveKeyringParcel.getAddUserAttribute().isEmpty()
|| !saveKeyringParcel.getAddSubKeys().isEmpty()
|| saveKeyringParcel.getChangePrimaryUserId() != null
|| !saveKeyringParcel.getRevokeUserIds().isEmpty()
|| !saveKeyringParcel.getRevokeSubKeys().isEmpty()) {
return false;
}
for (SubkeyChange change : saveKeyringParcel.getChangeSubKeys()) {
if (change.getRecertify() || change.getFlags() != null || change.getExpiry() != null
|| change.getMoveKeyToSecurityToken()) {
return false;
}
}
return true;
}
private static boolean isParcelEmpty(SaveKeyringParcel saveKeyringParcel) {
return isParcelRestrictedOnly(saveKeyringParcel) && saveKeyringParcel.getChangeSubKeys().isEmpty();
}
}

View File

@@ -86,7 +86,7 @@ public class ECKeyFormat extends KeyFormat {
}
}
public void addToSaveKeyringParcel(SaveKeyringParcel keyring, int keyFlags) {
public void addToSaveKeyringParcel(SaveKeyringParcel.Builder builder, int keyFlags) {
final X9ECParameters params = NISTNamedCurves.getByOID(mECCurveOID);
final ECCurve curve = params.getCurve();
@@ -107,7 +107,6 @@ public class ECKeyFormat extends KeyFormat {
throw new IllegalArgumentException("Unsupported curve " + mECCurveOID);
}
keyring.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(algo,
curve.getFieldSize(), scurve, keyFlags, 0L));
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(algo, curve.getFieldSize(), scurve, keyFlags, 0L));
}
}

View File

@@ -94,6 +94,6 @@ public abstract class KeyFormat {
throw new IllegalArgumentException("Unsupported Algorithm id " + t);
}
public abstract void addToSaveKeyringParcel(SaveKeyringParcel keyring, int keyFlags);
public abstract void addToSaveKeyringParcel(SaveKeyringParcel.Builder builder, int keyFlags);
}

View File

@@ -86,8 +86,8 @@ public class RSAKeyFormat extends KeyFormat {
}
}
public void addToSaveKeyringParcel(SaveKeyringParcel keyring, int keyFlags) {
keyring.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA,
public void addToSaveKeyringParcel(SaveKeyringParcel.Builder builder, int keyFlags) {
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(SaveKeyringParcel.Algorithm.RSA,
mModulusLength, null, keyFlags, 0L));
}
}

View File

@@ -18,18 +18,20 @@
package org.sufficientlysecure.keychain.service;
import android.os.Parcel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.google.auto.value.AutoValue;
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver;
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import org.sufficientlysecure.keychain.util.Passphrase;
import java.io.Serializable;
import java.util.ArrayList;
/**
* This class is a a transferable representation for a collection of changes
* to be done on a keyring.
@@ -45,107 +47,183 @@ import java.util.ArrayList;
* error in any included operation (for example revocation of a non-existent
* subkey) will cause the operation as a whole to fail.
*/
public class SaveKeyringParcel implements Parcelable {
@AutoValue
public abstract class SaveKeyringParcel implements Parcelable {
// the master key id to be edited. if this is null, a new one will be created
public Long mMasterKeyId;
@Nullable
public abstract Long getMasterKeyId();
// the key fingerprint, for safety. MUST be null for a new key.
public byte[] mFingerprint;
@Nullable
public abstract byte[] getFingerprint();
public ArrayList<String> mAddUserIds;
public ArrayList<WrappedUserAttribute> mAddUserAttribute;
public ArrayList<SubkeyAdd> mAddSubKeys;
public abstract List<String> getAddUserIds();
public abstract List<WrappedUserAttribute> getAddUserAttribute();
public abstract List<SubkeyAdd> getAddSubKeys();
public ArrayList<SubkeyChange> mChangeSubKeys;
public String mChangePrimaryUserId;
public abstract List<SubkeyChange> getChangeSubKeys();
@Nullable
public abstract String getChangePrimaryUserId();
public ArrayList<String> mRevokeUserIds;
public ArrayList<Long> mRevokeSubKeys;
public abstract List<String> getRevokeUserIds();
public abstract List<Long> getRevokeSubKeys();
// if these are non-null, PINs will be changed on the token
public Passphrase mSecurityTokenPin;
public Passphrase mSecurityTokenAdminPin;
@Nullable
public abstract Passphrase getSecurityTokenPin();
@Nullable
public abstract Passphrase getSecurityTokenAdminPin();
// private because they have to be set together with setUpdateOptions
private boolean mUpload;
private boolean mUploadAtomic;
private ParcelableHkpKeyserver mKeyserver;
public abstract boolean isShouldUpload();
public abstract boolean isShouldUploadAtomic();
@Nullable
public abstract ParcelableHkpKeyserver getUploadKeyserver();
// private because we have to set other details like key id
private ChangeUnlockParcel mNewUnlock;
@Nullable
public abstract ChangeUnlockParcel getNewUnlock();
public SaveKeyringParcel() {
reset();
public static Builder buildNewKeyringParcel() {
return new AutoValue_SaveKeyringParcel.Builder()
.setShouldUpload(false)
.setShouldUploadAtomic(false);
}
public SaveKeyringParcel(long masterKeyId, byte[] fingerprint) {
this();
mMasterKeyId = masterKeyId;
mFingerprint = fingerprint;
public static Builder buildChangeKeyringParcel(long masterKeyId, byte[] fingerprint) {
return buildNewKeyringParcel()
.setMasterKeyId(masterKeyId)
.setFingerprint(fingerprint);
}
public void reset() {
mNewUnlock = null;
mAddUserIds = new ArrayList<>();
mAddUserAttribute = new ArrayList<>();
mAddSubKeys = new ArrayList<>();
mChangePrimaryUserId = null;
mChangeSubKeys = new ArrayList<>();
mRevokeUserIds = new ArrayList<>();
mRevokeSubKeys = new ArrayList<>();
mSecurityTokenPin = null;
mSecurityTokenAdminPin = null;
mUpload = false;
mUploadAtomic = false;
mKeyserver = null;
abstract Builder toBuilder();
public static Builder buildUpon(SaveKeyringParcel saveKeyringParcel) {
SaveKeyringParcel.Builder builder = saveKeyringParcel.toBuilder();
builder.addUserIds.addAll(saveKeyringParcel.getAddUserIds());
builder.revokeUserIds.addAll(saveKeyringParcel.getRevokeUserIds());
builder.addUserAttribute.addAll(saveKeyringParcel.getAddUserAttribute());
builder.addSubKeys.addAll(saveKeyringParcel.getAddSubKeys());
builder.changeSubKeys.addAll(saveKeyringParcel.getChangeSubKeys());
builder.revokeSubKeys.addAll(saveKeyringParcel.getRevokeSubKeys());
return builder;
}
public void setUpdateOptions(boolean upload, boolean uploadAtomic, ParcelableHkpKeyserver keyserver) {
mUpload = upload;
mUploadAtomic = uploadAtomic;
mKeyserver = keyserver;
}
@AutoValue.Builder
public static abstract class Builder {
private ArrayList<String> addUserIds = new ArrayList<>();
private ArrayList<String> revokeUserIds = new ArrayList<>();
private ArrayList<WrappedUserAttribute> addUserAttribute = new ArrayList<>();
private ArrayList<SubkeyAdd> addSubKeys = new ArrayList<>();
private ArrayList<SubkeyChange> changeSubKeys = new ArrayList<>();
private ArrayList<Long> revokeSubKeys = new ArrayList<>();
public void setNewUnlock(ChangeUnlockParcel parcel) {
mNewUnlock = parcel;
}
public ChangeUnlockParcel getChangeUnlockParcel() {
return mNewUnlock;
}
public abstract Builder setChangePrimaryUserId(String changePrimaryUserId);
public abstract Builder setSecurityTokenPin(Passphrase securityTokenPin);
public abstract Builder setSecurityTokenAdminPin(Passphrase securityTokenAdminPin);
public abstract Builder setNewUnlock(ChangeUnlockParcel newUnlock);
public boolean isUpload() {
return mUpload;
}
public abstract Long getMasterKeyId();
public abstract byte[] getFingerprint();
public abstract String getChangePrimaryUserId();
public boolean isUploadAtomic() {
return mUploadAtomic;
}
public ParcelableHkpKeyserver getUploadKeyserver() {
return mKeyserver;
}
public boolean isEmpty() {
return isRestrictedOnly() && mChangeSubKeys.isEmpty();
}
/** Returns true iff this parcel does not contain any operations which require a passphrase. */
public boolean isRestrictedOnly() {
if (mNewUnlock != null || !mAddUserIds.isEmpty() || !mAddUserAttribute.isEmpty()
|| !mAddSubKeys.isEmpty() || mChangePrimaryUserId != null || !mRevokeUserIds.isEmpty()
|| !mRevokeSubKeys.isEmpty()) {
return false;
public ArrayList<SubkeyAdd> getMutableAddSubKeys() {
return addSubKeys;
}
public ArrayList<String> getMutableAddUserIds() {
return addUserIds;
}
public ArrayList<Long> getMutableRevokeSubKeys() {
return revokeSubKeys;
}
public ArrayList<String> getMutableRevokeUserIds() {
return revokeUserIds;
}
for (SubkeyChange change : mChangeSubKeys) {
if (change.getRecertify() || change.getFlags() != null || change.getExpiry() != null
|| change.getMoveKeyToSecurityToken()) {
return false;
abstract Builder setMasterKeyId(Long masterKeyId);
abstract Builder setFingerprint(byte[] fingerprint);
abstract Builder setAddUserIds(List<String> addUserIds);
abstract Builder setAddUserAttribute(List<WrappedUserAttribute> addUserAttribute);
abstract Builder setAddSubKeys(List<SubkeyAdd> addSubKeys);
abstract Builder setChangeSubKeys(List<SubkeyChange> changeSubKeys);
abstract Builder setRevokeUserIds(List<String> revokeUserIds);
abstract Builder setRevokeSubKeys(List<Long> revokeSubKeys);
abstract Builder setShouldUpload(boolean upload);
abstract Builder setShouldUploadAtomic(boolean uploadAtomic);
abstract Builder setUploadKeyserver(ParcelableHkpKeyserver keyserver);
public void setUpdateOptions(boolean upload, boolean uploadAtomic, ParcelableHkpKeyserver keyserver) {
setShouldUpload(upload);
setShouldUploadAtomic(uploadAtomic);
setUploadKeyserver(keyserver);
}
public void addSubkeyAdd(SubkeyAdd subkeyAdd) {
addSubKeys.add(subkeyAdd);
}
public void addUserId(String userId) {
addUserIds.add(userId);
}
public void addRevokeSubkey(long masterKeyId) {
revokeSubKeys.add(masterKeyId);
}
public void removeRevokeSubkey(long keyId) {
revokeSubKeys.remove(keyId);
}
public void addRevokeUserId(String userId) {
revokeUserIds.add(userId);
}
public void removeRevokeUserId(String userId) {
revokeUserIds.remove(userId);
}
public void addOrReplaceSubkeyChange(SubkeyChange newChange) {
SubkeyChange foundSubkeyChange = getSubkeyChange(newChange.getSubKeyId());
if (foundSubkeyChange != null) {
changeSubKeys.remove(foundSubkeyChange);
}
changeSubKeys.add(newChange);
}
return true;
public void removeSubkeyChange(SubkeyChange change) {
changeSubKeys.remove(change);
}
public SubkeyChange getSubkeyChange(long keyId) {
if (changeSubKeys == null) {
return null;
}
for (SubkeyChange subkeyChange : changeSubKeys) {
if (subkeyChange.getSubKeyId() == keyId) {
return subkeyChange;
}
}
return null;
}
public void addUserAttribute(WrappedUserAttribute ua) {
addUserAttribute.add(ua);
}
abstract SaveKeyringParcel autoBuild();
public SaveKeyringParcel build() {
setAddUserAttribute(Collections.unmodifiableList(addUserAttribute));
setRevokeSubKeys(Collections.unmodifiableList(revokeSubKeys));
setRevokeUserIds(Collections.unmodifiableList(revokeUserIds));
setAddSubKeys(Collections.unmodifiableList(addSubKeys));
setAddUserIds(Collections.unmodifiableList(addUserIds));
setChangeSubKeys(Collections.unmodifiableList(changeSubKeys));
return autoBuild();
}
}
// performance gain for using Parcelable here would probably be negligible,
@@ -208,114 +286,6 @@ public class SaveKeyringParcel implements Parcelable {
}
}
public SubkeyChange getSubkeyChange(long keyId) {
for (SubkeyChange subkeyChange : mChangeSubKeys) {
if (subkeyChange.getSubKeyId() == keyId) {
return subkeyChange;
}
}
return null;
}
public void addOrReplaceSubkeyChange(SubkeyChange change) {
SubkeyChange foundSubkeyChange = getSubkeyChange(change.getSubKeyId());
if (foundSubkeyChange != null) {
mChangeSubKeys.remove(foundSubkeyChange);
}
mChangeSubKeys.add(change);
}
public void removeSubkeyChange(SubkeyChange change) {
mChangeSubKeys.remove(change);
}
@SuppressWarnings("unchecked") // we verify the reads against writes in writeToParcel
public SaveKeyringParcel(Parcel source) {
mMasterKeyId = source.readInt() != 0 ? source.readLong() : null;
mFingerprint = source.createByteArray();
mNewUnlock = source.readParcelable(getClass().getClassLoader());
mAddUserIds = source.createStringArrayList();
mAddUserAttribute = (ArrayList<WrappedUserAttribute>) source.readSerializable();
mAddSubKeys = (ArrayList<SubkeyAdd>) source.readSerializable();
mChangeSubKeys = (ArrayList<SubkeyChange>) source.readSerializable();
mChangePrimaryUserId = source.readString();
mRevokeUserIds = source.createStringArrayList();
mRevokeSubKeys = (ArrayList<Long>) source.readSerializable();
mSecurityTokenPin = source.readParcelable(Passphrase.class.getClassLoader());
mSecurityTokenAdminPin = source.readParcelable(Passphrase.class.getClassLoader());
mUpload = source.readByte() != 0;
mUploadAtomic = source.readByte() != 0;
mKeyserver = source.readParcelable(ParcelableHkpKeyserver.class.getClassLoader());
}
@Override
public void writeToParcel(Parcel destination, int flags) {
destination.writeInt(mMasterKeyId == null ? 0 : 1);
if (mMasterKeyId != null) {
destination.writeLong(mMasterKeyId);
}
destination.writeByteArray(mFingerprint);
// yes, null values are ok for parcelables
destination.writeParcelable(mNewUnlock, flags);
destination.writeStringList(mAddUserIds);
destination.writeSerializable(mAddUserAttribute);
destination.writeSerializable(mAddSubKeys);
destination.writeSerializable(mChangeSubKeys);
destination.writeString(mChangePrimaryUserId);
destination.writeStringList(mRevokeUserIds);
destination.writeSerializable(mRevokeSubKeys);
destination.writeParcelable(mSecurityTokenPin, flags);
destination.writeParcelable(mSecurityTokenAdminPin, flags);
destination.writeByte((byte) (mUpload ? 1 : 0));
destination.writeByte((byte) (mUploadAtomic ? 1 : 0));
destination.writeParcelable(mKeyserver, flags);
}
public static final Creator<SaveKeyringParcel> CREATOR = new Creator<SaveKeyringParcel>() {
public SaveKeyringParcel createFromParcel(final Parcel source) {
return new SaveKeyringParcel(source);
}
public SaveKeyringParcel[] newArray(final int size) {
return new SaveKeyringParcel[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public String toString() {
String out = "mMasterKeyId: " + mMasterKeyId + "\n";
out += "mNewUnlock: " + mNewUnlock + "\n";
out += "mAddUserIds: " + mAddUserIds + "\n";
out += "mAddUserAttribute: " + mAddUserAttribute + "\n";
out += "mAddSubKeys: " + mAddSubKeys + "\n";
out += "mChangeSubKeys: " + mChangeSubKeys + "\n";
out += "mChangePrimaryUserId: " + mChangePrimaryUserId + "\n";
out += "mRevokeUserIds: " + mRevokeUserIds + "\n";
out += "mRevokeSubKeys: " + mRevokeSubKeys + "\n";
out += "mSecurityTokenPin: " + mSecurityTokenPin + "\n";
out += "mSecurityTokenAdminPin: " + mSecurityTokenAdminPin;
return out;
}
// All supported algorithms
public enum Algorithm {
RSA, DSA, ELGAMAL, ECDSA, ECDH
@@ -330,7 +300,4 @@ public class SaveKeyringParcel implements Parcelable {
// (adding support would be trivial though -> JcaPGPKeyConverter.java:190)
// BRAINPOOL_P256, BRAINPOOL_P384, BRAINPOOL_P512
}
}

View File

@@ -295,7 +295,7 @@ public class CreateKeyFinalFragment extends Fragment {
}
private static SaveKeyringParcel createDefaultSaveKeyringParcel(CreateKeyActivity createKeyActivity) {
SaveKeyringParcel saveKeyringParcel = new SaveKeyringParcel();
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
if (createKeyActivity.mCreateSecurityToken) {
if (createKeyActivity.mSecurityTokenSign == null) {
@@ -303,38 +303,40 @@ public class CreateKeyFinalFragment extends Fragment {
createKeyActivity.mSecurityTokenDec = Constants.SECURITY_TOKEN_V2_DEC;
createKeyActivity.mSecurityTokenAuth = Constants.SECURITY_TOKEN_V2_AUTH;
}
createKeyActivity.mSecurityTokenSign.addToSaveKeyringParcel(saveKeyringParcel, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER);
createKeyActivity.mSecurityTokenDec.addToSaveKeyringParcel(saveKeyringParcel, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE);
createKeyActivity.mSecurityTokenAuth.addToSaveKeyringParcel(saveKeyringParcel, KeyFlags.AUTHENTICATION);
createKeyActivity.mSecurityTokenSign.addToSaveKeyringParcel(
builder, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER);
createKeyActivity.mSecurityTokenDec.addToSaveKeyringParcel(
builder, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE);
createKeyActivity.mSecurityTokenAuth.addToSaveKeyringParcel(builder, KeyFlags.AUTHENTICATION);
// use empty passphrase
saveKeyringParcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
} else {
Constants.addDefaultSubkeys(saveKeyringParcel);
Constants.addDefaultSubkeys(builder);
if (createKeyActivity.mPassphrase != null) {
saveKeyringParcel.setNewUnlock(
builder.setNewUnlock(
ChangeUnlockParcel.createUnLockParcelForNewKey(createKeyActivity.mPassphrase));
} else {
saveKeyringParcel.setNewUnlock(null);
builder.setNewUnlock(null);
}
}
String userId = KeyRing.createUserId(
new OpenPgpUtils.UserId(createKeyActivity.mName, createKeyActivity.mEmail, null)
);
saveKeyringParcel.mAddUserIds.add(userId);
saveKeyringParcel.mChangePrimaryUserId = userId;
builder.addUserId(userId);
builder.setChangePrimaryUserId(userId);
if (createKeyActivity.mAdditionalEmails != null
&& createKeyActivity.mAdditionalEmails.size() > 0) {
for (String email : createKeyActivity.mAdditionalEmails) {
String thisUserId = KeyRing.createUserId(
new OpenPgpUtils.UserId(createKeyActivity.mName, email, null)
);
saveKeyringParcel.mAddUserIds.add(thisUserId);
builder.addUserId(thisUserId);
}
}
return saveKeyringParcel;
return builder.build();
}
private void checkEmailValidity() {
@@ -427,11 +429,11 @@ public class CreateKeyFinalFragment extends Fragment {
private void moveToCard(final EditKeyResult saveKeyResult) {
CreateKeyActivity activity = (CreateKeyActivity) getActivity();
final SaveKeyringParcel changeKeyringParcel;
SaveKeyringParcel.Builder builder;
CachedPublicKeyRing key = (KeyRepository.createDatabaseInteractor(getContext()))
.getCachedPublicKeyRing(saveKeyResult.mMasterKeyId);
try {
changeKeyringParcel = new SaveKeyringParcel(key.getMasterKeyId(), key.getFingerprint());
builder = SaveKeyringParcel.buildChangeKeyringParcel(key.getMasterKeyId(), key.getFingerprint());
} catch (PgpKeyNotFoundException e) {
Log.e(Constants.TAG, "Key that should be moved to Security Token not found in database!");
return;
@@ -439,13 +441,13 @@ public class CreateKeyFinalFragment extends Fragment {
// define subkeys that should be moved to the card
Cursor cursor = activity.getContentResolver().query(
KeychainContract.Keys.buildKeysUri(changeKeyringParcel.mMasterKeyId),
KeychainContract.Keys.buildKeysUri(builder.getMasterKeyId()),
new String[]{KeychainContract.Keys.KEY_ID,}, null, null, null
);
try {
while (cursor != null && cursor.moveToNext()) {
long subkeyId = cursor.getLong(0);
changeKeyringParcel.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(subkeyId));
builder.addOrReplaceSubkeyChange(SubkeyChange.createMoveToSecurityTokenChange(subkeyId));
}
} finally {
if (cursor != null) {
@@ -454,15 +456,17 @@ public class CreateKeyFinalFragment extends Fragment {
}
// define new PIN and Admin PIN for the card
changeKeyringParcel.mSecurityTokenPin = activity.mSecurityTokenPin;
changeKeyringParcel.mSecurityTokenAdminPin = activity.mSecurityTokenAdminPin;
builder.setSecurityTokenPin(activity.mSecurityTokenPin);
builder.setSecurityTokenAdminPin(activity.mSecurityTokenAdminPin);
final SaveKeyringParcel saveKeyringParcel = builder.build();
CryptoOperationHelper.Callback<SaveKeyringParcel, EditKeyResult> callback
= new CryptoOperationHelper.Callback<SaveKeyringParcel, EditKeyResult>() {
@Override
public SaveKeyringParcel createOperationInput() {
return changeKeyringParcel;
return saveKeyringParcel;
}
@Override

View File

@@ -82,7 +82,7 @@ public class EditIdentitiesFragment extends Fragment
private Uri mDataUri;
private SaveKeyringParcel mSaveKeyringParcel;
private SaveKeyringParcel.Builder mSkpBuilder;
private CryptoOperationHelper<SaveKeyringParcel, EditKeyResult> mEditOpHelper;
private CryptoOperationHelper<UploadKeyringParcel, UploadResult> mUploadOpHelper;
@@ -180,7 +180,7 @@ public class EditIdentitiesFragment extends Fragment
return;
}
mSaveKeyringParcel = new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint());
mSkpBuilder = SaveKeyringParcel.buildChangeKeyringParcel(masterKeyId, keyRing.getFingerprint());
mPrimaryUserId = keyRing.getPrimaryUserIdWithFallback();
} catch (PgpKeyNotFoundException | NotFoundException e) {
@@ -193,11 +193,11 @@ public class EditIdentitiesFragment extends Fragment
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, EditIdentitiesFragment.this);
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0);
mUserIdsAdapter.setEditMode(mSaveKeyringParcel);
mUserIdsAdapter.setEditMode(mSkpBuilder);
mUserIdsList.setAdapter(mUserIdsAdapter);
// TODO: SaveParcel from savedInstance?!
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds, false);
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSkpBuilder.getMutableAddUserIds(), false);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
}
@@ -266,23 +266,23 @@ public class EditIdentitiesFragment extends Fragment
switch (message.what) {
case EditUserIdDialogFragment.MESSAGE_CHANGE_PRIMARY_USER_ID:
// toggle
if (mSaveKeyringParcel.mChangePrimaryUserId != null
&& mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) {
mSaveKeyringParcel.mChangePrimaryUserId = null;
if (mSkpBuilder.getChangePrimaryUserId() != null
&& mSkpBuilder.getChangePrimaryUserId().equals(userId)) {
mSkpBuilder.setChangePrimaryUserId(null);
} else {
mSaveKeyringParcel.mChangePrimaryUserId = userId;
mSkpBuilder.setChangePrimaryUserId(userId);
}
break;
case EditUserIdDialogFragment.MESSAGE_REVOKE:
// toggle
if (mSaveKeyringParcel.mRevokeUserIds.contains(userId)) {
mSaveKeyringParcel.mRevokeUserIds.remove(userId);
if (mSkpBuilder.getMutableRevokeUserIds().contains(userId)) {
mSkpBuilder.removeRevokeUserId(userId);
} else {
mSaveKeyringParcel.mRevokeUserIds.add(userId);
mSkpBuilder.addRevokeUserId(userId);
// not possible to revoke and change to primary user id
if (mSaveKeyringParcel.mChangePrimaryUserId != null
&& mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) {
mSaveKeyringParcel.mChangePrimaryUserId = null;
if (mSkpBuilder.getChangePrimaryUserId() != null
&& mSkpBuilder.getChangePrimaryUserId().equals(userId)) {
mSkpBuilder.setChangePrimaryUserId(null);
}
}
break;
@@ -339,7 +339,7 @@ public class EditIdentitiesFragment extends Fragment
= new CryptoOperationHelper.Callback<SaveKeyringParcel, EditKeyResult>() {
@Override
public SaveKeyringParcel createOperationInput() {
return mSaveKeyringParcel;
return mSkpBuilder.build();
}
@Override

View File

@@ -100,7 +100,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
private Uri mDataUri;
private SaveKeyringParcel mSaveKeyringParcel;
private SaveKeyringParcel.Builder mSkpBuilder;
private String mPrimaryUserId;
@@ -184,13 +184,13 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
}
private void loadSaveKeyringParcel(SaveKeyringParcel saveKeyringParcel) {
mSaveKeyringParcel = saveKeyringParcel;
mPrimaryUserId = saveKeyringParcel.mChangePrimaryUserId;
mSkpBuilder = SaveKeyringParcel.buildUpon(saveKeyringParcel);
mPrimaryUserId = saveKeyringParcel.getChangePrimaryUserId();
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds, true);
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSkpBuilder.getMutableAddUserIds(), true);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys, true);
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSkpBuilder.getMutableAddSubKeys(), true);
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
}
@@ -213,7 +213,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
return;
}
mSaveKeyringParcel = new SaveKeyringParcel(masterKeyId, keyRing.getFingerprint());
mSkpBuilder = SaveKeyringParcel.buildChangeKeyringParcel(masterKeyId, keyRing.getFingerprint());
mPrimaryUserId = keyRing.getPrimaryUserIdWithFallback();
} catch (PgpKeyNotFoundException | NotFoundException e) {
@@ -227,18 +227,18 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, EditKeyFragment.this);
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0);
mUserIdsAdapter.setEditMode(mSaveKeyringParcel);
mUserIdsAdapter.setEditMode(mSkpBuilder);
mUserIdsList.setAdapter(mUserIdsAdapter);
// TODO: SaveParcel from savedInstance?!
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds, false);
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSkpBuilder.getMutableAddUserIds(), false);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0);
mSubkeysAdapter.setEditMode(mSaveKeyringParcel);
mSubkeysAdapter.setEditMode(mSkpBuilder);
mSubkeysList.setAdapter(mSubkeysAdapter);
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys, false);
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSkpBuilder.getMutableAddSubKeys(), false);
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
}
@@ -341,8 +341,8 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
Bundle data = message.getData();
// cache new returned passphrase!
mSaveKeyringParcel.setNewUnlock(ChangeUnlockParcel.createChangeUnlockParcel(
mSaveKeyringParcel.mMasterKeyId, mSaveKeyringParcel.mFingerprint,
mSkpBuilder.setNewUnlock(ChangeUnlockParcel.createChangeUnlockParcel(
mSkpBuilder.getMasterKeyId(), mSkpBuilder.getFingerprint(),
(Passphrase) data.getParcelable(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE)));
}
}
@@ -368,23 +368,23 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
switch (message.what) {
case EditUserIdDialogFragment.MESSAGE_CHANGE_PRIMARY_USER_ID:
// toggle
if (mSaveKeyringParcel.mChangePrimaryUserId != null
&& mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) {
mSaveKeyringParcel.mChangePrimaryUserId = null;
String changePrimaryUserId = mSkpBuilder.getChangePrimaryUserId();
if (changePrimaryUserId != null && changePrimaryUserId.equals(userId)) {
mSkpBuilder.setChangePrimaryUserId(null);
} else {
mSaveKeyringParcel.mChangePrimaryUserId = userId;
mSkpBuilder.setChangePrimaryUserId(userId);
}
break;
case EditUserIdDialogFragment.MESSAGE_REVOKE:
// toggle
if (mSaveKeyringParcel.mRevokeUserIds.contains(userId)) {
mSaveKeyringParcel.mRevokeUserIds.remove(userId);
if (mSkpBuilder.getMutableRevokeUserIds().contains(userId)) {
mSkpBuilder.removeRevokeUserId(userId);
} else {
mSaveKeyringParcel.mRevokeUserIds.add(userId);
mSkpBuilder.addRevokeUserId(userId);
// not possible to revoke and change to primary user id
if (mSaveKeyringParcel.mChangePrimaryUserId != null
&& mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) {
mSaveKeyringParcel.mChangePrimaryUserId = null;
if (mSkpBuilder.getChangePrimaryUserId() != null
&& mSkpBuilder.getChangePrimaryUserId().equals(userId)) {
mSkpBuilder.setChangePrimaryUserId(null);
}
}
break;
@@ -417,10 +417,10 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
break;
case EditSubkeyDialogFragment.MESSAGE_REVOKE:
// toggle
if (mSaveKeyringParcel.mRevokeSubKeys.contains(keyId)) {
mSaveKeyringParcel.mRevokeSubKeys.remove(keyId);
if (mSkpBuilder.getMutableRevokeSubKeys().contains(keyId)) {
mSkpBuilder.removeRevokeSubkey(keyId);
} else {
mSaveKeyringParcel.mRevokeSubKeys.add(keyId);
mSkpBuilder.addRevokeSubkey(keyId);
}
break;
case EditSubkeyDialogFragment.MESSAGE_STRIP: {
@@ -430,11 +430,11 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
break;
}
SubkeyChange change = mSaveKeyringParcel.getSubkeyChange(keyId);
SubkeyChange change = mSkpBuilder.getSubkeyChange(keyId);
if (change == null || !change.getDummyStrip()) {
mSaveKeyringParcel.addOrReplaceSubkeyChange(SubkeyChange.createStripChange(keyId));
mSkpBuilder.addOrReplaceSubkeyChange(SubkeyChange.createStripChange(keyId));
} else {
mSaveKeyringParcel.removeSubkeyChange(change);
mSkpBuilder.removeSubkeyChange(change);
}
break;
}
@@ -474,13 +474,13 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
break;
}
SubkeyChange change = mSaveKeyringParcel.getSubkeyChange(keyId);
SubkeyChange change = mSkpBuilder.getSubkeyChange(keyId);
if (change == null || !change.getMoveKeyToSecurityToken()) {
mSaveKeyringParcel.addOrReplaceSubkeyChange(
mSkpBuilder.addOrReplaceSubkeyChange(
SubkeyChange.createMoveToSecurityTokenChange(keyId));
break;
} else {
mSaveKeyringParcel.removeSubkeyChange(change);
mSkpBuilder.removeSubkeyChange(change);
}
break;
}
@@ -514,7 +514,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY:
Long expiry = (Long) message.getData().getSerializable(
EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY);
mSaveKeyringParcel.addOrReplaceSubkeyChange(
mSkpBuilder.addOrReplaceSubkeyChange(
SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry));
break;
}
@@ -576,20 +576,20 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
}
protected void returnKeyringParcel() {
if (mSaveKeyringParcel.mAddUserIds.size() == 0) {
if (mSkpBuilder.getMutableAddUserIds().size() == 0) {
Notify.create(getActivity(), R.string.edit_key_error_add_identity, Notify.Style.ERROR).show();
return;
}
if (mSaveKeyringParcel.mAddSubKeys.size() == 0) {
if (mSkpBuilder.getMutableAddSubKeys().size() == 0) {
Notify.create(getActivity(), R.string.edit_key_error_add_subkey, Notify.Style.ERROR).show();
return;
}
// use first user id as primary
mSaveKeyringParcel.mChangePrimaryUserId = mSaveKeyringParcel.mAddUserIds.get(0);
String firstUserId = mSkpBuilder.getMutableAddUserIds().get(0);
mSkpBuilder.setChangePrimaryUserId(firstUserId);
Intent returnIntent = new Intent();
returnIntent.putExtra(EditKeyActivity.EXTRA_SAVE_KEYRING_PARCEL, mSaveKeyringParcel);
returnIntent.putExtra(EditKeyActivity.EXTRA_SAVE_KEYRING_PARCEL, mSkpBuilder.build());
getActivity().setResult(Activity.RESULT_OK, returnIntent);
getActivity().finish();
}
@@ -610,7 +610,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
@Override
public SaveKeyringParcel createOperationInput() {
return mSaveKeyringParcel;
return mSkpBuilder.build();
}
@Override

View File

@@ -82,7 +82,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
private long mMasterKeyId;
private byte[] mFingerprint;
private boolean mHasSecret;
private SaveKeyringParcel mEditModeSaveKeyringParcel;
private SaveKeyringParcel.Builder mEditModeSkpBuilder;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
@@ -250,15 +250,15 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mEditModeSaveKeyringParcel = new SaveKeyringParcel(mMasterKeyId, mFingerprint);
mEditModeSkpBuilder = SaveKeyringParcel.buildChangeKeyringParcel(mMasterKeyId, mFingerprint);
mSubkeysAddedAdapter =
new SubkeysAddedAdapter(getActivity(), mEditModeSaveKeyringParcel.mAddSubKeys, false);
mSubkeysAddedAdapter = new SubkeysAddedAdapter(
getActivity(), mEditModeSkpBuilder.getMutableAddSubKeys(), false);
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
mSubkeysAddedLayout.setVisibility(View.VISIBLE);
mSubkeyAddFabLayout.setDisplayedChild(1);
mSubkeysAdapter.setEditMode(mEditModeSaveKeyringParcel);
mSubkeysAdapter.setEditMode(mEditModeSkpBuilder);
getLoaderManager().restartLoader(LOADER_ID_SUBKEYS, null, ViewKeyAdvSubkeysFragment.this);
mode.setTitle(R.string.title_edit_subkeys);
@@ -280,7 +280,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
@Override
public void onDestroyActionMode(ActionMode mode) {
mEditModeSaveKeyringParcel = null;
mEditModeSkpBuilder = null;
mSubkeysAdapter.setEditMode(null);
mSubkeysAddedLayout.setVisibility(View.GONE);
mSubkeyAddFabLayout.setDisplayedChild(0);
@@ -323,10 +323,10 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
break;
case EditSubkeyDialogFragment.MESSAGE_REVOKE:
// toggle
if (mEditModeSaveKeyringParcel.mRevokeSubKeys.contains(keyId)) {
mEditModeSaveKeyringParcel.mRevokeSubKeys.remove(keyId);
if (mEditModeSkpBuilder.getMutableRevokeSubKeys().contains(keyId)) {
mEditModeSkpBuilder.removeRevokeSubkey(keyId);
} else {
mEditModeSaveKeyringParcel.mRevokeSubKeys.add(keyId);
mEditModeSkpBuilder.addRevokeSubkey(keyId);
}
break;
case EditSubkeyDialogFragment.MESSAGE_STRIP: {
@@ -336,11 +336,11 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
break;
}
SubkeyChange change = mEditModeSaveKeyringParcel.getSubkeyChange(keyId);
SubkeyChange change = mEditModeSkpBuilder.getSubkeyChange(keyId);
if (change == null || !change.getDummyStrip()) {
mEditModeSaveKeyringParcel.addOrReplaceSubkeyChange(SubkeyChange.createStripChange(keyId));
mEditModeSkpBuilder.addOrReplaceSubkeyChange(SubkeyChange.createStripChange(keyId));
} else {
mEditModeSaveKeyringParcel.removeSubkeyChange(change);
mEditModeSkpBuilder.removeSubkeyChange(change);
}
break;
}
@@ -380,12 +380,12 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
break;
}
SubkeyChange change = mEditModeSaveKeyringParcel.getSubkeyChange(keyId);
SubkeyChange change = mEditModeSkpBuilder.getSubkeyChange(keyId);
if (change == null || !change.getMoveKeyToSecurityToken()) {
mEditModeSaveKeyringParcel.addOrReplaceSubkeyChange(
mEditModeSkpBuilder.addOrReplaceSubkeyChange(
SubkeyChange.createMoveToSecurityTokenChange(keyId));
} else {
mEditModeSaveKeyringParcel.removeSubkeyChange(change);
mEditModeSkpBuilder.removeSubkeyChange(change);
}
break;
}
@@ -419,7 +419,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY:
Long expiry = (Long) message.getData().getSerializable(
EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY);
mEditModeSaveKeyringParcel.addOrReplaceSubkeyChange(
mEditModeSkpBuilder.addOrReplaceSubkeyChange(
SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry));
break;
}
@@ -447,7 +447,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
@Override
public SaveKeyringParcel createOperationInput() {
return mEditModeSaveKeyringParcel;
return mEditModeSkpBuilder.build();
}
@Override

View File

@@ -79,7 +79,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
private long mMasterKeyId;
private byte[] mFingerprint;
private boolean mHasSecret;
private SaveKeyringParcel mEditModeSaveKeyringParcel;
private SaveKeyringParcel.Builder mSkpBuilder;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
@@ -122,7 +122,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
}
private void showOrEditUserIdInfo(final int position) {
if (mEditModeSaveKeyringParcel != null) {
if (mSkpBuilder != null) {
editUserId(position);
} else {
showUserIdInfo(position);
@@ -140,23 +140,23 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
switch (message.what) {
case EditUserIdDialogFragment.MESSAGE_CHANGE_PRIMARY_USER_ID:
// toggle
if (mEditModeSaveKeyringParcel.mChangePrimaryUserId != null
&& mEditModeSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) {
mEditModeSaveKeyringParcel.mChangePrimaryUserId = null;
if (mSkpBuilder.getChangePrimaryUserId() != null
&& mSkpBuilder.getChangePrimaryUserId().equals(userId)) {
mSkpBuilder.setChangePrimaryUserId(null);
} else {
mEditModeSaveKeyringParcel.mChangePrimaryUserId = userId;
mSkpBuilder.setChangePrimaryUserId(userId);
}
break;
case EditUserIdDialogFragment.MESSAGE_REVOKE:
// toggle
if (mEditModeSaveKeyringParcel.mRevokeUserIds.contains(userId)) {
mEditModeSaveKeyringParcel.mRevokeUserIds.remove(userId);
if (mSkpBuilder.getMutableRevokeUserIds().contains(userId)) {
mSkpBuilder.removeRevokeUserId(userId);
} else {
mEditModeSaveKeyringParcel.mRevokeUserIds.add(userId);
mSkpBuilder.addRevokeUserId(userId);
// not possible to revoke and change to primary user id
if (mEditModeSaveKeyringParcel.mChangePrimaryUserId != null
&& mEditModeSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) {
mEditModeSaveKeyringParcel.mChangePrimaryUserId = null;
if (mSkpBuilder.getChangePrimaryUserId() != null
&& mSkpBuilder.getChangePrimaryUserId().equals(userId)) {
mSkpBuilder.setChangePrimaryUserId(null);
}
}
break;
@@ -342,15 +342,15 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mEditModeSaveKeyringParcel = new SaveKeyringParcel(mMasterKeyId, mFingerprint);
mSkpBuilder = SaveKeyringParcel.buildChangeKeyringParcel(mMasterKeyId, mFingerprint);
mUserIdsAddedAdapter =
new UserIdsAddedAdapter(getActivity(), mEditModeSaveKeyringParcel.mAddUserIds, false);
new UserIdsAddedAdapter(getActivity(), mSkpBuilder.getMutableAddUserIds(), false);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
mUserIdsAddedLayout.setVisibility(View.VISIBLE);
mUserIdAddFabLayout.setDisplayedChild(1);
mUserIdsAdapter.setEditMode(mEditModeSaveKeyringParcel);
mUserIdsAdapter.setEditMode(mSkpBuilder);
getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this);
mode.setTitle(R.string.title_edit_identities);
@@ -372,7 +372,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
@Override
public void onDestroyActionMode(ActionMode mode) {
mEditModeSaveKeyringParcel = null;
mSkpBuilder = null;
mUserIdsAdapter.setEditMode(null);
mUserIdsAddedLayout.setVisibility(View.GONE);
mUserIdAddFabLayout.setDisplayedChild(0);
@@ -387,7 +387,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
@Override
public SaveKeyringParcel createOperationInput() {
return mEditModeSaveKeyringParcel;
return mSkpBuilder.build();
}
@Override

View File

@@ -17,6 +17,11 @@
package org.sufficientlysecure.keychain.ui.adapter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import android.content.Context;
import android.content.res.ColorStateList;
import android.database.Cursor;
@@ -42,13 +47,9 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class SubkeysAdapter extends CursorAdapter {
private LayoutInflater mInflater;
private SaveKeyringParcel mSaveKeyringParcel;
private SaveKeyringParcel.Builder mSkpBuilder;
private boolean mHasAnySecret;
private ColorStateList mDefaultTextColor;
@@ -177,10 +178,7 @@ public class SubkeysAdapter extends CursorAdapter {
cursor.getString(INDEX_KEY_CURVE_OID)
));
SubkeyChange change = mSaveKeyringParcel != null
? mSaveKeyringParcel.getSubkeyChange(keyId)
: null;
SubkeyChange change = mSkpBuilder != null ? mSkpBuilder.getSubkeyChange(keyId) : null;
if (change != null && (change.getDummyStrip() || change.getMoveKeyToSecurityToken())) {
if (change.getDummyStrip()) {
algorithmStr.append(", ");
@@ -242,8 +240,8 @@ public class SubkeysAdapter extends CursorAdapter {
}
// for edit key
if (mSaveKeyringParcel != null) {
boolean revokeThisSubkey = (mSaveKeyringParcel.mRevokeSubKeys.contains(keyId));
if (mSkpBuilder != null) {
boolean revokeThisSubkey = (mSkpBuilder.getMutableRevokeSubKeys().contains(keyId));
if (revokeThisSubkey) {
if (!isRevoked) {
@@ -251,7 +249,7 @@ public class SubkeysAdapter extends CursorAdapter {
}
}
SaveKeyringParcel.SubkeyChange subkeyChange = mSaveKeyringParcel.getSubkeyChange(keyId);
SaveKeyringParcel.SubkeyChange subkeyChange = mSkpBuilder.getSubkeyChange(keyId);
if (subkeyChange != null) {
if (subkeyChange.getExpiry() == null || subkeyChange.getExpiry() == 0L) {
expiryDate = null;
@@ -345,7 +343,7 @@ public class SubkeysAdapter extends CursorAdapter {
// Disable selection of items, http://stackoverflow.com/a/4075045
@Override
public boolean areAllItemsEnabled() {
if (mSaveKeyringParcel == null) {
if (mSkpBuilder == null) {
return false;
} else {
return super.areAllItemsEnabled();
@@ -355,7 +353,7 @@ public class SubkeysAdapter extends CursorAdapter {
// Disable selection of items, http://stackoverflow.com/a/4075045
@Override
public boolean isEnabled(int position) {
if (mSaveKeyringParcel == null) {
if (mSkpBuilder == null) {
return false;
} else {
return super.isEnabled(position);
@@ -370,10 +368,10 @@ public class SubkeysAdapter extends CursorAdapter {
*
* @see SaveKeyringParcel
*
* @param saveKeyringParcel The parcel to get info from, or null to leave edit mode.
* @param builder The parcel to get info from, or null to leave edit mode.
*/
public void setEditMode(@Nullable SaveKeyringParcel saveKeyringParcel) {
mSaveKeyringParcel = saveKeyringParcel;
public void setEditMode(@Nullable SaveKeyringParcel.Builder builder) {
mSkpBuilder = builder;
}
}

View File

@@ -32,9 +32,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ViewAnimator;
import org.openintents.openpgp.util.OpenPgpUtils;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
@@ -43,20 +41,18 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
public class UserIdsAdapter extends UserAttributesAdapter {
protected LayoutInflater mInflater;
private SaveKeyringParcel mSaveKeyringParcel;
private SaveKeyringParcel.Builder mSkpBuilder;
private boolean mShowStatusImages;
public UserIdsAdapter(Context context, Cursor c, int flags,
boolean showStatusImages, SaveKeyringParcel saveKeyringParcel) {
public UserIdsAdapter(Context context, Cursor c, int flags, boolean showStatusImages) {
super(context, c, flags);
mInflater = LayoutInflater.from(context);
mSaveKeyringParcel = saveKeyringParcel;
mShowStatusImages = showStatusImages;
}
public UserIdsAdapter(Context context, Cursor c, int flags) {
this(context, c, flags, true, null);
this(context, c, flags, true);
}
@Override
@@ -96,11 +92,11 @@ public class UserIdsAdapter extends UserAttributesAdapter {
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
// for edit key
if (mSaveKeyringParcel != null) {
boolean changeAnyPrimaryUserId = (mSaveKeyringParcel.mChangePrimaryUserId != null);
boolean changeThisPrimaryUserId = (mSaveKeyringParcel.mChangePrimaryUserId != null
&& mSaveKeyringParcel.mChangePrimaryUserId.equals(userId));
boolean revokeThisUserId = (mSaveKeyringParcel.mRevokeUserIds.contains(userId));
if (mSkpBuilder != null) {
String changePrimaryUserId = mSkpBuilder.getChangePrimaryUserId();
boolean changeAnyPrimaryUserId = (changePrimaryUserId != null);
boolean changeThisPrimaryUserId = (changeAnyPrimaryUserId && changePrimaryUserId.equals(userId));
boolean revokeThisUserId = (mSkpBuilder.getMutableRevokeUserIds().contains(userId));
// only if primary user id will be changed
// (this is not triggered if the user id is currently the primary one)
@@ -161,8 +157,8 @@ public class UserIdsAdapter extends UserAttributesAdapter {
String userId = mCursor.getString(INDEX_USER_ID);
boolean isRevokedPending = false;
if (mSaveKeyringParcel != null) {
if (mSaveKeyringParcel.mRevokeUserIds.contains(userId)) {
if (mSkpBuilder != null) {
if (mSkpBuilder.getMutableRevokeUserIds().contains(userId)) {
isRevokedPending = true;
}
@@ -181,8 +177,8 @@ public class UserIdsAdapter extends UserAttributesAdapter {
*
* @param saveKeyringParcel The parcel to get info from, or null to leave edit mode.
*/
public void setEditMode(@Nullable SaveKeyringParcel saveKeyringParcel) {
mSaveKeyringParcel = saveKeyringParcel;
public void setEditMode(@Nullable SaveKeyringParcel.Builder saveKeyringParcel) {
mSkpBuilder = saveKeyringParcel;
}
@Override

View File

@@ -143,7 +143,7 @@ public class ViewKeyFragment extends LoaderFragment implements LoaderManager.Loa
mIsSecret = getArguments().getBoolean(ARG_IS_SECRET);
// load user ids after we know if it's a secret key
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, !mIsSecret, null);
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, !mIsSecret);
mUserIds.setAdapter(mUserIdsAdapter);
// initialize loaders, which will take care of auto-refresh on change

View File

@@ -210,15 +210,11 @@ public abstract class LinkedIdCreateFinalFragment extends CryptoOperationFragmen
@Nullable
@Override
public Parcelable createOperationInput() {
SaveKeyringParcel skp =
new SaveKeyringParcel(mLinkedIdWizard.mMasterKeyId, mLinkedIdWizard.mFingerprint);
WrappedUserAttribute ua =
LinkedAttribute.fromResource(mVerifiedResource).toUserAttribute();
skp.mAddUserAttribute.add(ua);
return skp;
SaveKeyringParcel.Builder builder=
SaveKeyringParcel.buildChangeKeyringParcel(mLinkedIdWizard.mMasterKeyId, mLinkedIdWizard.mFingerprint);
WrappedUserAttribute ua = LinkedAttribute.fromResource(mVerifiedResource).toUserAttribute();
builder.addUserAttribute(ua);
return builder.build();
}
@Override

View File

@@ -96,7 +96,7 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe
byte[] mFingerprint;
long mMasterKeyId;
private SaveKeyringParcel mSaveKeyringParcel;
private SaveKeyringParcel.Builder mSkpBuilder;
private TextView mLinkedIdTitle, mLinkedIdComment;
private boolean mFinishOnStop;
@@ -405,13 +405,10 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
WrappedUserAttribute ua = LinkedAttribute.fromResource(resource).toUserAttribute();
mSaveKeyringParcel = new SaveKeyringParcel(mMasterKeyId, mFingerprint);
mSaveKeyringParcel.mAddUserAttribute.add(ua);
mSkpBuilder = SaveKeyringParcel.buildChangeKeyringParcel(mMasterKeyId, mFingerprint);
mSkpBuilder.addUserAttribute(ua);
cryptoOperation();
}
}, 250);
@@ -421,7 +418,7 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment<SaveKe
@Override
public SaveKeyringParcel createOperationInput() {
// if this is null, the cryptoOperation silently aborts - which is what we want in that case
return mSaveKeyringParcel;
return mSkpBuilder.build();
}
@Override