use autovalue for SaveKeyringParcel
This commit is contained in:
parent
147e4dbee7
commit
d58f1bd225
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -95,17 +95,17 @@ public class BackupOperationTest {
|
|||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
parcel.mAddUserIds.add("snips");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1));
|
||||
builder.addUserId("snips");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1));
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
assertTrue("initial test key creation must succeed", result.success());
|
||||
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
|
||||
|
||||
|
@ -113,17 +113,17 @@ public class BackupOperationTest {
|
|||
}
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
parcel.mAddUserIds.add("snails");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase("1234")));
|
||||
builder.addUserId("snails");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase("1234")));
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
assertTrue("initial test key creation must succeed", result.success());
|
||||
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
|
||||
|
||||
|
|
|
@ -73,17 +73,17 @@ public class CertifyOperationTest {
|
|||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
parcel.mAddUserIds.add("derp");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1));
|
||||
builder.addUserId("derp");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1));
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
Assert.assertTrue("initial test key creation must succeed", result.success());
|
||||
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
|
||||
|
||||
|
@ -91,23 +91,22 @@ public class CertifyOperationTest {
|
|||
}
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
|
||||
parcel.mAddUserIds.add("ditz");
|
||||
builder.addUserId("ditz");
|
||||
byte[] uatdata = new byte[random.nextInt(150)+10];
|
||||
random.nextBytes(uatdata);
|
||||
parcel.mAddUserAttribute.add(
|
||||
WrappedUserAttribute.fromSubpacket(random.nextInt(100)+1, uatdata));
|
||||
builder.addUserAttribute(WrappedUserAttribute.fromSubpacket(random.nextInt(100)+1, uatdata));
|
||||
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase2));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase2));
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
Assert.assertTrue("initial test key creation must succeed", result.success());
|
||||
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
|
||||
|
||||
|
|
|
@ -69,17 +69,17 @@ public class PromoteKeyOperationTest {
|
|||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
parcel.mAddUserIds.add("derp");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1));
|
||||
builder.addUserId("derp");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(mKeyPhrase1));
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
Assert.assertTrue("initial test key creation must succeed", result.success());
|
||||
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
|
||||
|
||||
|
|
|
@ -621,10 +621,10 @@ public class PgpEncryptDecryptTest {
|
|||
|
||||
{ // strip first encrypted subkey, decryption should skip it
|
||||
|
||||
SaveKeyringParcel parcel =
|
||||
new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint());
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(encKeyId1));
|
||||
UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1,
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildChangeKeyringParcel(
|
||||
mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint());
|
||||
builder.addOrReplaceSubkeyChange(SubkeyChange.createStripChange(encKeyId1));
|
||||
UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(builder.build(), mStaticRing1,
|
||||
new ArrayList<RawPacket>(), new ArrayList<RawPacket>(),
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1));
|
||||
|
||||
|
@ -644,10 +644,10 @@ public class PgpEncryptDecryptTest {
|
|||
|
||||
{ // change flags of second encrypted subkey, decryption should skip it
|
||||
|
||||
SaveKeyringParcel parcel =
|
||||
new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint());
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(encKeyId1, KeyFlags.CERTIFY_OTHER, null));
|
||||
UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1,
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildChangeKeyringParcel(
|
||||
mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint());
|
||||
builder.addOrReplaceSubkeyChange(SubkeyChange.createFlagsOrExpiryChange(encKeyId1, KeyFlags.CERTIFY_OTHER, null));
|
||||
UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(builder.build(), mStaticRing1,
|
||||
new ArrayList<RawPacket>(), new ArrayList<RawPacket>(),
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1));
|
||||
|
||||
|
@ -673,9 +673,10 @@ public class PgpEncryptDecryptTest {
|
|||
String plaintext = "dies ist ein plaintext ☭" + TestingUtils.genPassphrase(true);
|
||||
|
||||
{ // revoke first encryption subkey of keyring in database
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint());
|
||||
parcel.mRevokeSubKeys.add(KeyringTestingHelper.getSubkeyId(mStaticRing1, 2));
|
||||
UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1,
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildChangeKeyringParcel(
|
||||
mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint());
|
||||
builder.addRevokeSubkey(KeyringTestingHelper.getSubkeyId(mStaticRing1, 2));
|
||||
UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(builder.build(), mStaticRing1,
|
||||
new ArrayList<RawPacket>(), new ArrayList<RawPacket>(),
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), mKeyPhrase1));
|
||||
|
||||
|
|
|
@ -18,8 +18,20 @@
|
|||
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.Security;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
import org.bouncycastle.bcpg.BCPGInputStream;
|
||||
import org.bouncycastle.bcpg.Packet;
|
||||
import org.bouncycastle.bcpg.PacketTags;
|
||||
|
@ -58,16 +70,18 @@ import org.sufficientlysecure.keychain.util.Passphrase;
|
|||
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||
import org.sufficientlysecure.keychain.util.TestingUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.Security;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import static org.bouncycastle.bcpg.sig.KeyFlags.CERTIFY_OTHER;
|
||||
import static org.bouncycastle.bcpg.sig.KeyFlags.SIGN_DATA;
|
||||
import static org.sufficientlysecure.keychain.operations.results.OperationResult.LogType.MSG_MF_ERROR_FINGERPRINT;
|
||||
import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm.ECDSA;
|
||||
import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm.RSA;
|
||||
import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve.NIST_P256;
|
||||
import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd.createSubkeyAdd;
|
||||
import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange.createFlagsOrExpiryChange;
|
||||
import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange.createRecertifyChange;
|
||||
import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange.createStripChange;
|
||||
import static org.sufficientlysecure.keychain.service.SaveKeyringParcel.buildChangeKeyringParcel;
|
||||
|
||||
|
||||
@RunWith(KeychainTestRunner.class)
|
||||
public class PgpKeyOperationTest {
|
||||
|
@ -77,7 +91,7 @@ public class PgpKeyOperationTest {
|
|||
|
||||
UncachedKeyRing ring;
|
||||
PgpKeyOperation op;
|
||||
SaveKeyringParcel parcel;
|
||||
SaveKeyringParcel.Builder builder;
|
||||
ArrayList<RawPacket> onlyA = new ArrayList<>();
|
||||
ArrayList<RawPacket> onlyB = new ArrayList<>();
|
||||
|
||||
|
@ -88,28 +102,28 @@ public class PgpKeyOperationTest {
|
|||
Security.insertProviderAt(new BouncyCastleProvider(), 1);
|
||||
ShadowLog.stream = System.out;
|
||||
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
|
||||
parcel.mAddUserIds.add("twi");
|
||||
parcel.mAddUserIds.add("pink");
|
||||
builder.addUserId("twi");
|
||||
builder.addUserId("pink");
|
||||
|
||||
{
|
||||
int type = 42;
|
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4 };
|
||||
WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data);
|
||||
parcel.mAddUserAttribute.add(uat);
|
||||
builder.addUserAttribute(uat);
|
||||
}
|
||||
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
Assert.assertTrue("initial test key creation must succeed", result.success());
|
||||
Assert.assertNotNull("initial test key creation must succeed", result.getRing());
|
||||
|
||||
|
@ -123,7 +137,8 @@ public class PgpKeyOperationTest {
|
|||
|
||||
}
|
||||
|
||||
@Before public void setUp() throws Exception {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// show Log.x messages in system.out
|
||||
ShadowLog.stream = System.out;
|
||||
ring = staticRing;
|
||||
|
@ -131,76 +146,76 @@ public class PgpKeyOperationTest {
|
|||
// setting up some parameters just to reduce code duplication
|
||||
op = new PgpKeyOperation(new ProgressScaler(null, 0, 100, 100));
|
||||
|
||||
// set this up, gonna need it more than once
|
||||
parcel = new SaveKeyringParcel();
|
||||
parcel.mMasterKeyId = ring.getMasterKeyId();
|
||||
parcel.mFingerprint = ring.getFingerprint();
|
||||
resetBuilder();
|
||||
}
|
||||
|
||||
private void resetBuilder() {
|
||||
builder = SaveKeyringParcel.buildChangeKeyringParcel(ring.getMasterKeyId(), ring.getFingerprint());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSecretKeyRingTests() {
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.RSA, new Random().nextInt(256)+255, null, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddUserIds.add("shy");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
builder.addUserId("shy");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
|
||||
assertFailure("creating ring with < 2048 bit keysize should fail", parcel,
|
||||
assertFailure("creating ring with < 2048 bit keysize should fail", builder.build(),
|
||||
LogType.MSG_CR_ERROR_KEYSIZE_2048);
|
||||
}
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ELGAMAL, 2048, null, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddUserIds.add("shy");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
builder.addUserId("shy");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
|
||||
assertFailure("creating ring with ElGamal master key should fail", parcel,
|
||||
assertFailure("creating ring with ElGamal master key should fail", builder.build(),
|
||||
LogType.MSG_CR_ERROR_FLAGS_ELGAMAL);
|
||||
}
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, null));
|
||||
parcel.mAddUserIds.add("lotus");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
builder.addUserId("lotus");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
|
||||
assertFailure("creating master key with null expiry should fail", parcel,
|
||||
assertFailure("creating master key with null expiry should fail", builder.build(),
|
||||
LogType.MSG_CR_ERROR_NULL_EXPIRY);
|
||||
}
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddUserIds.add("shy");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
builder.addUserId("shy");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
|
||||
assertFailure("creating ring with non-certifying master key should fail", parcel,
|
||||
assertFailure("creating ring with non-certifying master key should fail", builder.build(),
|
||||
LogType.MSG_CR_ERROR_NO_CERTIFY);
|
||||
}
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
|
||||
assertFailure("creating ring without user ids should fail", parcel,
|
||||
assertFailure("creating ring without user ids should fail", builder.build(),
|
||||
LogType.MSG_CR_ERROR_NO_USER_ID);
|
||||
}
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
parcel.mAddUserIds.add("shy");
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
resetBuilder();
|
||||
builder.addUserId("shy");
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
|
||||
assertFailure("creating ring with no master key should fail", parcel,
|
||||
assertFailure("creating ring with no master key should fail", builder.build(),
|
||||
LogType.MSG_CR_ERROR_NO_MASTER);
|
||||
}
|
||||
|
||||
|
@ -210,11 +225,11 @@ public class PgpKeyOperationTest {
|
|||
// this is a special case since the flags are in user id certificates rather than
|
||||
// subkey binding certificates
|
||||
public void testMasterFlags() throws Exception {
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddUserIds.add("luna");
|
||||
ring = assertCreateSuccess("creating ring with master key flags must succeed", parcel);
|
||||
builder.addUserId("luna");
|
||||
ring = assertCreateSuccess("creating ring with master key flags must succeed", builder.build());
|
||||
|
||||
Assert.assertEquals("the keyring should contain only the master key",
|
||||
1, KeyringTestingHelper.itToList(ring.getPublicKeys()).size());
|
||||
|
@ -280,43 +295,27 @@ public class PgpKeyOperationTest {
|
|||
public void testBadKeyModification() throws Exception {
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
// off by one
|
||||
parcel.mMasterKeyId = ring.getMasterKeyId() -1;
|
||||
parcel.mFingerprint = ring.getFingerprint();
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildChangeKeyringParcel(
|
||||
ring.getMasterKeyId() -1, ring.getFingerprint());
|
||||
|
||||
assertModifyFailure("keyring modification with bad master key id should fail",
|
||||
ring, parcel, LogType.MSG_MF_ERROR_KEYID);
|
||||
ring, builder.build(), LogType.MSG_MF_ERROR_KEYID);
|
||||
}
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
// off by one
|
||||
parcel.mMasterKeyId = null;
|
||||
parcel.mFingerprint = ring.getFingerprint();
|
||||
byte[] fingerprint = Arrays.copyOf(ring.getFingerprint(), ring.getFingerprint().length);
|
||||
fingerprint[5] += 1;
|
||||
|
||||
assertModifyFailure("keyring modification with null master key id should fail",
|
||||
ring, parcel, LogType.MSG_MF_ERROR_KEYID);
|
||||
}
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mMasterKeyId = ring.getMasterKeyId();
|
||||
parcel.mFingerprint = ring.getFingerprint();
|
||||
// some byte, off by one
|
||||
parcel.mFingerprint[5] += 1;
|
||||
SaveKeyringParcel.Builder builder = buildChangeKeyringParcel(ring.getMasterKeyId(), fingerprint);
|
||||
|
||||
assertModifyFailure("keyring modification with bad fingerprint should fail",
|
||||
ring, parcel, LogType.MSG_MF_ERROR_FINGERPRINT);
|
||||
ring, builder.build(), MSG_MF_ERROR_FINGERPRINT);
|
||||
}
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mMasterKeyId = ring.getMasterKeyId();
|
||||
parcel.mFingerprint = null;
|
||||
|
||||
SaveKeyringParcel.Builder builder = buildChangeKeyringParcel(ring.getMasterKeyId(), null);
|
||||
assertModifyFailure("keyring modification with null fingerprint should fail",
|
||||
ring, parcel, LogType.MSG_MF_ERROR_FINGERPRINT);
|
||||
ring, builder.build(), MSG_MF_ERROR_FINGERPRINT);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -324,16 +323,16 @@ public class PgpKeyOperationTest {
|
|||
if (badphrase.equals(passphrase)) {
|
||||
badphrase = new Passphrase("a");
|
||||
}
|
||||
parcel.mAddUserIds.add("allure");
|
||||
builder.addUserId("allure");
|
||||
|
||||
assertModifyFailure("keyring modification with bad passphrase should fail",
|
||||
ring, parcel, CryptoInputParcel.createCryptoInputParcel(badphrase), LogType.MSG_MF_UNLOCK_ERROR);
|
||||
ring, builder.build(), CryptoInputParcel.createCryptoInputParcel(badphrase), LogType.MSG_MF_UNLOCK_ERROR);
|
||||
}
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
resetBuilder();
|
||||
assertModifyFailure("no-op should fail",
|
||||
ring, parcel, cryptoInput, LogType.MSG_MF_ERROR_NOOP);
|
||||
ring, builder.build(), cryptoInput, LogType.MSG_MF_ERROR_NOOP);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -343,10 +342,10 @@ public class PgpKeyOperationTest {
|
|||
|
||||
long expiry = new Date().getTime() / 1000 + 159;
|
||||
int flags = KeyFlags.SIGN_DATA;
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, flags, expiry));
|
||||
|
||||
UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
|
||||
UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("no extra packets in original", 0, onlyA.size());
|
||||
Assert.assertEquals("exactly two extra packets in modified", 2, onlyB.size());
|
||||
|
@ -381,26 +380,27 @@ public class PgpKeyOperationTest {
|
|||
flags, (long) newKey.getKeyUsage());
|
||||
|
||||
{ // bad keysize should fail
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.RSA, new Random().nextInt(512), null, KeyFlags.SIGN_DATA, 0L));
|
||||
assertModifyFailure("creating a subkey with keysize < 2048 should fail", ring, parcel,
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(createSubkeyAdd(
|
||||
RSA, new Random().nextInt(512), null, SIGN_DATA, 0L));
|
||||
assertModifyFailure("creating a subkey with keysize < 2048 should fail", ring, builder.build(),
|
||||
LogType.MSG_CR_ERROR_KEYSIZE_2048);
|
||||
}
|
||||
|
||||
{ // null expiry should fail
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, null));
|
||||
assertModifyFailure("creating master key with null expiry should fail", ring, parcel,
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(createSubkeyAdd(
|
||||
ECDSA, 0, NIST_P256, SIGN_DATA, null));
|
||||
assertModifyFailure("creating master key with null expiry should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_ERROR_NULL_EXPIRY);
|
||||
}
|
||||
|
||||
{ // a past expiry should fail
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, new Date().getTime()/1000-10));
|
||||
assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel,
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(createSubkeyAdd(
|
||||
ECDSA, 0, NIST_P256, SIGN_DATA,
|
||||
new Date().getTime() / 1000 - 10));
|
||||
assertModifyFailure("creating subkey with past expiry date should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_ERROR_PAST_EXPIRY);
|
||||
}
|
||||
|
||||
|
@ -414,8 +414,8 @@ public class PgpKeyOperationTest {
|
|||
|
||||
UncachedKeyRing modified = ring;
|
||||
{
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, expiry));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("one extra packet in original", 1, onlyA.size());
|
||||
Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
|
||||
|
@ -441,8 +441,8 @@ public class PgpKeyOperationTest {
|
|||
{ // change expiry
|
||||
expiry += 60*60*24;
|
||||
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, expiry));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertNotNull("modified key must have an expiry date",
|
||||
modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
|
||||
|
@ -454,9 +454,9 @@ public class PgpKeyOperationTest {
|
|||
|
||||
{
|
||||
int flags = KeyFlags.SIGN_DATA | KeyFlags.ENCRYPT_COMMS;
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, flags, null));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, flags, null));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("old packet must be signature",
|
||||
PacketTags.SIGNATURE, onlyA.get(0).tag);
|
||||
|
@ -477,9 +477,9 @@ public class PgpKeyOperationTest {
|
|||
}
|
||||
|
||||
{ // expiry of 0 should be "no expiry"
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, 0L));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, 0L));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("old packet must be signature",
|
||||
PacketTags.SIGNATURE, onlyA.get(0).tag);
|
||||
|
@ -495,18 +495,18 @@ public class PgpKeyOperationTest {
|
|||
}
|
||||
|
||||
{ // a past expiry should fail
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, new Date().getTime()/1000-10));
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, new Date().getTime() / 1000 - 10));
|
||||
|
||||
assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel,
|
||||
assertModifyFailure("setting subkey expiry to a past date should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_ERROR_PAST_EXPIRY);
|
||||
}
|
||||
|
||||
{ // modifying nonexistent subkey should fail
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(123, null, null));
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(123, null, null));
|
||||
|
||||
assertModifyFailure("modifying non-existent subkey should fail", ring, parcel,
|
||||
assertModifyFailure("modifying non-existent subkey should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_ERROR_SUBKEY_MISSING);
|
||||
}
|
||||
|
||||
|
@ -521,15 +521,15 @@ public class PgpKeyOperationTest {
|
|||
UncachedKeyRing modified = ring;
|
||||
|
||||
// to make this check less trivial, we add a user id, change the primary one and revoke one
|
||||
parcel.mAddUserIds.add("aloe");
|
||||
parcel.mChangePrimaryUserId = "aloe";
|
||||
parcel.mRevokeUserIds.add("pink");
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
builder.addUserId("aloe");
|
||||
builder.setChangePrimaryUserId("aloe");
|
||||
builder.addRevokeUserId("pink");
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
{
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, expiry));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
// this implies that only the two non-revoked signatures were changed!
|
||||
Assert.assertEquals("two extra packets in original", 2, onlyA.size());
|
||||
|
@ -555,8 +555,8 @@ public class PgpKeyOperationTest {
|
|||
{ // change expiry
|
||||
expiry += 60*60*24;
|
||||
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, expiry));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, expiry));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertNotNull("modified key must have an expiry date",
|
||||
modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting());
|
||||
|
@ -574,9 +574,9 @@ public class PgpKeyOperationTest {
|
|||
|
||||
{
|
||||
int flags = KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA;
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, flags, null));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, flags, null));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("modified key must have expected flags",
|
||||
flags, (long) modified.getPublicKey(keyId).getKeyUsage());
|
||||
|
@ -590,13 +590,13 @@ public class PgpKeyOperationTest {
|
|||
|
||||
// even if there is a non-expiring user id while all others are revoked, it doesn't count!
|
||||
// for this purpose we revoke one while they still have expiry times
|
||||
parcel.reset();
|
||||
parcel.mRevokeUserIds.add("aloe");
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
resetBuilder();
|
||||
builder.addRevokeUserId("aloe");
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, 0L));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, 0L));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
// for this check, it is relevant that we DON'T use the unsafe one!
|
||||
Assert.assertNull("key must not expire anymore",
|
||||
|
@ -607,28 +607,28 @@ public class PgpKeyOperationTest {
|
|||
}
|
||||
|
||||
{ // if we revoke everything, nothing is left to properly sign...
|
||||
parcel.reset();
|
||||
parcel.mRevokeUserIds.add("twi");
|
||||
parcel.mRevokeUserIds.add("pink");
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, KeyFlags.CERTIFY_OTHER, null));
|
||||
resetBuilder();
|
||||
builder.addRevokeUserId("twi");
|
||||
builder.addRevokeUserId("pink");
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, CERTIFY_OTHER, null));
|
||||
|
||||
assertModifyFailure("master key modification with all user ids revoked should fail", ring, parcel,
|
||||
assertModifyFailure("master key modification with all user ids revoked should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_ERROR_MASTER_NONE);
|
||||
}
|
||||
|
||||
{ // any flag not including CERTIFY_OTHER should fail
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, KeyFlags.SIGN_DATA, null));
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, SIGN_DATA, null));
|
||||
|
||||
assertModifyFailure("setting master key flags without certify should fail", ring, parcel,
|
||||
assertModifyFailure("setting master key flags without certify should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_ERROR_NO_CERTIFY);
|
||||
}
|
||||
|
||||
{ // a past expiry should fail
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createFlagsOrExpiryChange(keyId, null, new Date().getTime()/1000-10));
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createFlagsOrExpiryChange(keyId, null, new Date().getTime() / 1000 - 10));
|
||||
|
||||
assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel,
|
||||
assertModifyFailure("setting subkey expiry to a past date should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_ERROR_PAST_EXPIRY);
|
||||
}
|
||||
|
||||
|
@ -637,10 +637,10 @@ public class PgpKeyOperationTest {
|
|||
@Test
|
||||
public void testMasterRevoke() throws Exception {
|
||||
|
||||
parcel.reset();
|
||||
parcel.mRevokeSubKeys.add(ring.getMasterKeyId());
|
||||
resetBuilder();
|
||||
builder.addRevokeSubkey(ring.getMasterKeyId());
|
||||
|
||||
UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
|
||||
UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("no extra packets in original", 0, onlyA.size());
|
||||
Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size());
|
||||
|
@ -669,11 +669,11 @@ public class PgpKeyOperationTest {
|
|||
|
||||
{
|
||||
|
||||
parcel.reset();
|
||||
parcel.mRevokeSubKeys.add(123L);
|
||||
resetBuilder();
|
||||
builder.addRevokeSubkey(123L);
|
||||
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0);
|
||||
UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, cryptoInput, parcel).getRing();
|
||||
UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, cryptoInput, builder.build()).getRing();
|
||||
|
||||
Assert.assertNull("revoking a nonexistent subkey should fail", otherModified);
|
||||
|
||||
|
@ -681,10 +681,10 @@ public class PgpKeyOperationTest {
|
|||
|
||||
{ // revoked second subkey
|
||||
|
||||
parcel.reset();
|
||||
parcel.mRevokeSubKeys.add(keyId);
|
||||
resetBuilder();
|
||||
builder.addRevokeSubkey(keyId);
|
||||
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB,
|
||||
modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), passphrase));
|
||||
|
||||
Assert.assertEquals("no extra packets in original", 0, onlyA.size());
|
||||
|
@ -705,11 +705,11 @@ public class PgpKeyOperationTest {
|
|||
|
||||
{ // re-add second subkey
|
||||
|
||||
parcel.reset();
|
||||
resetBuilder();
|
||||
// re-certify the revoked subkey
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true));
|
||||
builder.addOrReplaceSubkeyChange(createRecertifyChange(keyId, true));
|
||||
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("exactly two outdated packets in original", 2, onlyA.size());
|
||||
Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size());
|
||||
|
@ -749,8 +749,8 @@ public class PgpKeyOperationTest {
|
|||
public void testSubkeyStrip() throws Exception {
|
||||
|
||||
long keyId = KeyringTestingHelper.getSubkeyId(ring, 1);
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId));
|
||||
applyModificationWithChecks(parcel, ring, onlyA, onlyB);
|
||||
builder.addOrReplaceSubkeyChange(createStripChange(keyId));
|
||||
applyModificationWithChecks(builder.build(), ring, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("one extra packet in original", 1, onlyA.size());
|
||||
Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
|
||||
|
@ -775,8 +775,8 @@ public class PgpKeyOperationTest {
|
|||
public void testMasterStrip() throws Exception {
|
||||
|
||||
long keyId = ring.getMasterKeyId();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId));
|
||||
applyModificationWithChecks(parcel, ring, onlyA, onlyB);
|
||||
builder.addOrReplaceSubkeyChange(createStripChange(keyId));
|
||||
applyModificationWithChecks(builder.build(), ring, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("one extra packet in original", 1, onlyA.size());
|
||||
Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
|
||||
|
@ -803,9 +803,9 @@ public class PgpKeyOperationTest {
|
|||
UncachedKeyRing modified;
|
||||
|
||||
{ // we should be able to change the stripped status of subkeys without passphrase
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createStripChange(keyId));
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB,
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createStripChange(keyId));
|
||||
modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB,
|
||||
CryptoInputParcel.createCryptoInputParcel());
|
||||
Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
|
||||
Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
|
||||
|
@ -816,11 +816,11 @@ public class PgpKeyOperationTest {
|
|||
}
|
||||
|
||||
{ // trying to edit a subkey with signing capability should fail
|
||||
parcel.reset();
|
||||
parcel.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true));
|
||||
resetBuilder();
|
||||
builder.addOrReplaceSubkeyChange(createRecertifyChange(keyId, true));
|
||||
|
||||
assertModifyFailure("subkey modification for signing-enabled but stripped subkey should fail",
|
||||
modified, parcel, LogType.MSG_MF_ERROR_SUB_STRIPPED);
|
||||
modified, builder.build(), LogType.MSG_MF_ERROR_SUB_STRIPPED);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -829,51 +829,49 @@ public class PgpKeyOperationTest {
|
|||
public void testKeyToSecurityToken() throws Exception {
|
||||
|
||||
// Special keyring for security token tests with 2048 bit RSA as a subkey
|
||||
SaveKeyringParcel parcelKey = new SaveKeyringParcel();
|
||||
parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder keyBuilder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
keyBuilder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.DSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
keyBuilder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L));
|
||||
parcelKey.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
keyBuilder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.RSA, 3072, null, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
|
||||
parcelKey.mAddUserIds.add("yubikey");
|
||||
keyBuilder.addUserId("yubikey");
|
||||
|
||||
parcelKey.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
keyBuilder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(passphrase));
|
||||
PgpKeyOperation opSecurityToken = new PgpKeyOperation(null);
|
||||
|
||||
PgpEditKeyResult resultSecurityToken = opSecurityToken.createSecretKeyRing(parcelKey);
|
||||
PgpEditKeyResult resultSecurityToken = opSecurityToken.createSecretKeyRing(keyBuilder.build());
|
||||
Assert.assertTrue("initial test key creation must succeed", resultSecurityToken.success());
|
||||
Assert.assertNotNull("initial test key creation must succeed", resultSecurityToken.getRing());
|
||||
|
||||
UncachedKeyRing ringSecurityToken = resultSecurityToken.getRing();
|
||||
|
||||
SaveKeyringParcel parcelSecurityToken = new SaveKeyringParcel();
|
||||
parcelSecurityToken.mMasterKeyId = ringSecurityToken.getMasterKeyId();
|
||||
parcelSecurityToken.mFingerprint = ringSecurityToken.getFingerprint();
|
||||
|
||||
UncachedKeyRing modified;
|
||||
|
||||
{ // moveKeyToSecurityToken should fail with BAD_NFC_ALGO when presented with the DSA-1024 key
|
||||
long keyId = KeyringTestingHelper.getSubkeyId(ringSecurityToken, 0);
|
||||
parcelSecurityToken.reset();
|
||||
parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(keyId));
|
||||
SaveKeyringParcel.Builder securityTokenBuilder = SaveKeyringParcel.buildChangeKeyringParcel(
|
||||
ringSecurityToken.getMasterKeyId(), ringSecurityToken.getFingerprint());
|
||||
securityTokenBuilder.addOrReplaceSubkeyChange(SubkeyChange.createMoveToSecurityTokenChange(keyId));
|
||||
|
||||
assertModifyFailure("moveKeyToSecurityToken operation should fail on invalid key algorithm", ringSecurityToken,
|
||||
parcelSecurityToken, cryptoInput, LogType.MSG_MF_ERROR_BAD_SECURITY_TOKEN_ALGO);
|
||||
securityTokenBuilder.build(), cryptoInput, LogType.MSG_MF_ERROR_BAD_SECURITY_TOKEN_ALGO);
|
||||
}
|
||||
|
||||
long keyId = KeyringTestingHelper.getSubkeyId(ringSecurityToken, 1);
|
||||
|
||||
{ // moveKeyToSecurityToken should return a pending SECURITY_TOKEN_MOVE_KEY_TO_CARD result when presented with the RSA-2048
|
||||
// key, and then make key divert-to-card when it gets a serial in the cryptoInputParcel.
|
||||
parcelSecurityToken.reset();
|
||||
parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createMoveToSecurityTokenChange(keyId));
|
||||
SaveKeyringParcel.Builder securityTokenBuilder = SaveKeyringParcel.buildChangeKeyringParcel(
|
||||
ringSecurityToken.getMasterKeyId(), ringSecurityToken.getFingerprint());
|
||||
securityTokenBuilder.addOrReplaceSubkeyChange(SubkeyChange.createMoveToSecurityTokenChange(keyId));
|
||||
|
||||
CanonicalizedSecretKeyRing secretRing =
|
||||
new CanonicalizedSecretKeyRing(ringSecurityToken.getEncoded(), 0);
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcelSecurityToken);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, securityTokenBuilder.build());
|
||||
Assert.assertTrue("moveKeyToSecurityToken operation should be pending", result.isPending());
|
||||
Assert.assertEquals("required input should be RequiredInputType.SECURITY_TOKEN_MOVE_KEY_TO_CARD",
|
||||
result.getRequiredInputParcel().mType, RequiredInputType.SECURITY_TOKEN_MOVE_KEY_TO_CARD);
|
||||
|
@ -889,7 +887,7 @@ public class PgpKeyOperationTest {
|
|||
CryptoInputParcel inputParcel = CryptoInputParcel.createCryptoInputParcel();
|
||||
inputParcel = inputParcel.withCryptoData(keyIdBytes, serial);
|
||||
|
||||
modified = applyModificationWithChecks(parcelSecurityToken, ringSecurityToken, onlyA, onlyB, inputParcel);
|
||||
modified = applyModificationWithChecks(securityTokenBuilder.build(), ringSecurityToken, onlyA, onlyB, inputParcel);
|
||||
Assert.assertEquals("one extra packet in modified", 1, onlyB.size());
|
||||
Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket();
|
||||
Assert.assertEquals("new packet should have GNU_DUMMY S2K type",
|
||||
|
@ -901,13 +899,14 @@ public class PgpKeyOperationTest {
|
|||
}
|
||||
|
||||
{ // editing a signing subkey requires a primary key binding sig -> pendinginput
|
||||
parcelSecurityToken.reset();
|
||||
parcelSecurityToken.mChangeSubKeys.add(SubkeyChange.createRecertifyChange(keyId, true));
|
||||
SaveKeyringParcel.Builder securityTokenBuilder = SaveKeyringParcel.buildChangeKeyringParcel(
|
||||
ringSecurityToken.getMasterKeyId(), ringSecurityToken.getFingerprint());
|
||||
securityTokenBuilder.addOrReplaceSubkeyChange(SubkeyChange.createRecertifyChange(keyId, true));
|
||||
|
||||
CanonicalizedSecretKeyRing secretRing =
|
||||
new CanonicalizedSecretKeyRing(modified.getEncoded(), 0);
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcelSecurityToken);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, securityTokenBuilder.build());
|
||||
Assert.assertTrue("moveKeyToSecurityToken operation should be pending", result.isPending());
|
||||
Assert.assertEquals("required input should be RequiredInputType.SECURITY_TOKEN_SIGN",
|
||||
RequiredInputType.SECURITY_TOKEN_SIGN, result.getRequiredInputParcel().mType);
|
||||
|
@ -922,10 +921,8 @@ public class PgpKeyOperationTest {
|
|||
String uid = ring.getPublicKey().getUnorderedUserIds().get(1);
|
||||
|
||||
{ // revoke second user id
|
||||
|
||||
parcel.mRevokeUserIds.add(uid);
|
||||
|
||||
modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
|
||||
builder.addRevokeUserId(uid);
|
||||
modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("no extra packets in original", 0, onlyA.size());
|
||||
Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size());
|
||||
|
@ -943,20 +940,20 @@ public class PgpKeyOperationTest {
|
|||
|
||||
{ // re-add second user id
|
||||
|
||||
parcel.reset();
|
||||
parcel.mChangePrimaryUserId = uid;
|
||||
resetBuilder();
|
||||
builder.setChangePrimaryUserId(uid);
|
||||
|
||||
assertModifyFailure("setting primary user id to a revoked user id should fail", modified, parcel,
|
||||
assertModifyFailure("setting primary user id to a revoked user id should fail", modified, builder.build(),
|
||||
LogType.MSG_MF_ERROR_REVOKED_PRIMARY);
|
||||
|
||||
}
|
||||
|
||||
{ // re-add second user id
|
||||
|
||||
parcel.reset();
|
||||
parcel.mAddUserIds.add(uid);
|
||||
resetBuilder();
|
||||
builder.addUserId(uid);
|
||||
|
||||
applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("exactly two outdated packets in original", 2, onlyA.size());
|
||||
Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size());
|
||||
|
@ -986,10 +983,10 @@ public class PgpKeyOperationTest {
|
|||
}
|
||||
|
||||
{ // revocation of non-existent user id should fail
|
||||
parcel.reset();
|
||||
parcel.mRevokeUserIds.add("nonexistent");
|
||||
resetBuilder();
|
||||
builder.addRevokeUserId("nonexistent");
|
||||
|
||||
assertModifyFailure("revocation of nonexistent user id should fail", modified, parcel,
|
||||
assertModifyFailure("revocation of nonexistent user id should fail", modified, builder.build(),
|
||||
LogType.MSG_MF_ERROR_NOEXIST_REVOKE);
|
||||
}
|
||||
|
||||
|
@ -999,15 +996,15 @@ public class PgpKeyOperationTest {
|
|||
public void testUserIdAdd() throws Exception {
|
||||
|
||||
{
|
||||
parcel.mAddUserIds.add("");
|
||||
assertModifyFailure("adding an empty user id should fail", ring, parcel,
|
||||
builder.addUserId("");
|
||||
assertModifyFailure("adding an empty user id should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_UID_ERROR_EMPTY);
|
||||
}
|
||||
|
||||
parcel.reset();
|
||||
parcel.mAddUserIds.add("rainbow");
|
||||
resetBuilder();
|
||||
builder.addUserId("rainbow");
|
||||
|
||||
UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
|
||||
UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB);
|
||||
|
||||
Assert.assertTrue("keyring must contain added user id",
|
||||
modified.getPublicKey().getUnorderedUserIds().contains("rainbow"));
|
||||
|
@ -1036,12 +1033,12 @@ public class PgpKeyOperationTest {
|
|||
public void testUserAttributeAdd() throws Exception {
|
||||
|
||||
{
|
||||
parcel.mAddUserAttribute.add(WrappedUserAttribute.fromData(new byte[0]));
|
||||
assertModifyFailure("adding an empty user attribute should fail", ring, parcel,
|
||||
builder.addUserAttribute(WrappedUserAttribute.fromData(new byte[0]));
|
||||
assertModifyFailure("adding an empty user attribute should fail", ring, builder.build(),
|
||||
LogType.MSG_MF_UAT_ERROR_EMPTY);
|
||||
}
|
||||
|
||||
parcel.reset();
|
||||
resetBuilder();
|
||||
|
||||
Random r = new Random();
|
||||
int type = r.nextInt(110)+2; // any type except image attribute, to avoid interpretation of these
|
||||
|
@ -1049,9 +1046,9 @@ public class PgpKeyOperationTest {
|
|||
new Random().nextBytes(data);
|
||||
|
||||
WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data);
|
||||
parcel.mAddUserAttribute.add(uat);
|
||||
builder.addUserAttribute(uat);
|
||||
|
||||
UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB);
|
||||
UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("no extra packets in original", 0, onlyA.size());
|
||||
Assert.assertEquals("exactly two extra packets in modified", 2, onlyB.size());
|
||||
|
@ -1082,7 +1079,7 @@ public class PgpKeyOperationTest {
|
|||
|
||||
// applying the same modification AGAIN should not add more certifications but drop those
|
||||
// as duplicates
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB,
|
||||
applyModificationWithChecks(builder.build(), modified, onlyA, onlyB,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), passphrase), true, false);
|
||||
|
||||
Assert.assertEquals("duplicate modification: one extra packet in original", 1, onlyA.size());
|
||||
|
@ -1103,20 +1100,20 @@ public class PgpKeyOperationTest {
|
|||
String uid = ring.getPublicKey().getUnorderedUserIds().get(1);
|
||||
|
||||
{ // first part, add new user id which is also primary
|
||||
parcel.mAddUserIds.add("jack");
|
||||
parcel.mChangePrimaryUserId = "jack";
|
||||
builder.addUserId("jack");
|
||||
builder.setChangePrimaryUserId("jack");
|
||||
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("primary user id must be the one added",
|
||||
"jack", modified.getPublicKey().getPrimaryUserId());
|
||||
}
|
||||
|
||||
{ // second part, change primary to a different one
|
||||
parcel.reset();
|
||||
parcel.mChangePrimaryUserId = uid;
|
||||
resetBuilder();
|
||||
builder.setChangePrimaryUserId(uid);
|
||||
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB);
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB);
|
||||
|
||||
Assert.assertEquals("old keyring must have two outdated certificates", 2, onlyA.size());
|
||||
Assert.assertEquals("new keyring must have two new packets", 2, onlyB.size());
|
||||
|
@ -1126,15 +1123,11 @@ public class PgpKeyOperationTest {
|
|||
}
|
||||
|
||||
{ // third part, change primary to a non-existent one
|
||||
parcel.reset();
|
||||
resetBuilder();
|
||||
//noinspection SpellCheckingInspection
|
||||
parcel.mChangePrimaryUserId = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
if (parcel.mChangePrimaryUserId.equals(passphrase)) {
|
||||
parcel.mChangePrimaryUserId += "A";
|
||||
}
|
||||
|
||||
builder.setChangePrimaryUserId("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||
assertModifyFailure("changing primary user id to a non-existent one should fail",
|
||||
ring, parcel, LogType.MSG_MF_ERROR_NOEXIST_PRIMARY);
|
||||
ring, builder.build(), LogType.MSG_MF_ERROR_NOEXIST_PRIMARY);
|
||||
}
|
||||
|
||||
// check for revoked primary user id already done in revoke test
|
||||
|
@ -1145,9 +1138,9 @@ public class PgpKeyOperationTest {
|
|||
public void testPassphraseChange() throws Exception {
|
||||
|
||||
// change passphrase to empty
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
// note that canonicalization here necessarily strips the empty notation packet
|
||||
UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, cryptoInput);
|
||||
UncachedKeyRing modified = applyModificationWithChecks(builder.build(), ring, onlyA, onlyB, cryptoInput);
|
||||
|
||||
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
|
||||
3, onlyB.size());
|
||||
|
@ -1160,15 +1153,15 @@ public class PgpKeyOperationTest {
|
|||
// modify keyring, change to non-empty passphrase
|
||||
Passphrase otherPassphrase = TestingUtils.genPassphrase(true);
|
||||
CryptoInputParcel otherCryptoInput = CryptoInputParcel.createCryptoInputParcel(otherPassphrase);
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(otherPassphrase));
|
||||
modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB,
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(otherPassphrase));
|
||||
modified = applyModificationWithChecks(builder.build(), modified, onlyA, onlyB,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()));
|
||||
|
||||
Assert.assertEquals("exactly three packets should have been modified (the secret keys)",
|
||||
3, onlyB.size());
|
||||
|
||||
{ // quick check to make sure no two secret keys have the same IV
|
||||
HashSet<ByteBuffer> ivs = new HashSet<ByteBuffer>();
|
||||
HashSet<ByteBuffer> ivs = new HashSet<>();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
SecretKeyPacket p = (SecretKeyPacket) new BCPGInputStream(
|
||||
new ByteArrayInputStream(onlyB.get(i).buf)).readPacket();
|
||||
|
@ -1186,7 +1179,7 @@ public class PgpKeyOperationTest {
|
|||
PacketTags.SECRET_SUBKEY, sKeyNoPassphrase.tag);
|
||||
|
||||
Passphrase otherPassphrase2 = TestingUtils.genPassphrase(true);
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(otherPassphrase2));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(otherPassphrase2));
|
||||
{
|
||||
// if we replace a secret key with one without passphrase
|
||||
modified = KeyringTestingHelper.removePacket(modified, sKeyNoPassphrase.position);
|
||||
|
@ -1195,7 +1188,7 @@ public class PgpKeyOperationTest {
|
|||
// we should still be able to modify it (and change its passphrase) without errors
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), 0);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, otherCryptoInput, parcel);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, otherCryptoInput, builder.build());
|
||||
Assert.assertTrue("key modification must succeed", result.success());
|
||||
Assert.assertFalse("log must not contain a warning",
|
||||
result.getLog().containsWarnings());
|
||||
|
@ -1212,7 +1205,7 @@ public class PgpKeyOperationTest {
|
|||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), 0);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing,
|
||||
CryptoInputParcel.createCryptoInputParcel(otherPassphrase2), parcel);
|
||||
CryptoInputParcel.createCryptoInputParcel(otherPassphrase2), builder.build());
|
||||
Assert.assertTrue("key modification must succeed", result.success());
|
||||
Assert.assertTrue("log must contain a failed passphrase change warning",
|
||||
result.getLog().containsType(LogType.MSG_MF_PASSPHRASE_FAIL));
|
||||
|
@ -1225,10 +1218,10 @@ public class PgpKeyOperationTest {
|
|||
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), 0);
|
||||
|
||||
parcel.mAddUserIds.add("discord");
|
||||
builder.addUserId("discord");
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date()), parcel);
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date()), builder.build());
|
||||
Assert.assertFalse("non-restricted operations should fail without passphrase", result.success());
|
||||
}
|
||||
|
||||
|
@ -1299,8 +1292,8 @@ public class PgpKeyOperationTest {
|
|||
CanonicalizedKeyRing canonicalized = inputKeyRing.canonicalize(new OperationLog(), 0);
|
||||
Assert.assertNotNull("canonicalization must succeed", canonicalized);
|
||||
|
||||
ArrayList onlyA = new ArrayList<RawPacket>();
|
||||
ArrayList onlyB = new ArrayList<RawPacket>();
|
||||
ArrayList onlyA = new ArrayList<>();
|
||||
ArrayList onlyB = new ArrayList<>();
|
||||
//noinspection unchecked
|
||||
Assert.assertTrue("keyrings differ", !KeyringTestingHelper.diffKeyrings(
|
||||
expectedKeyRing.getEncoded(), expectedKeyRing.getEncoded(), onlyA, onlyB));
|
||||
|
|
|
@ -96,27 +96,27 @@ public class UncachedKeyringCanonicalizeTest {
|
|||
Security.insertProviderAt(new BouncyCastleProvider(), 1);
|
||||
ShadowLog.stream = System.out;
|
||||
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
|
||||
parcel.mAddUserIds.add("twi");
|
||||
parcel.mAddUserIds.add("pink");
|
||||
builder.addUserId("twi");
|
||||
builder.addUserId("pink");
|
||||
{
|
||||
WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(100,
|
||||
"sunshine, sunshine, ladybugs awake~".getBytes());
|
||||
parcel.mAddUserAttribute.add(uat);
|
||||
builder.addUserAttribute(uat);
|
||||
}
|
||||
|
||||
// passphrase is tested in PgpKeyOperationTest, just use empty here
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
Assert.assertTrue("initial test key creation must succeed", result.success());
|
||||
staticRing = result.getRing();
|
||||
Assert.assertNotNull("initial test key creation must succeed", staticRing);
|
||||
|
@ -352,14 +352,14 @@ public class UncachedKeyringCanonicalizeTest {
|
|||
|
||||
@Test public void testForeignSignature() throws Exception {
|
||||
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddUserIds.add("trix");
|
||||
builder.addUserId("trix");
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
OperationResult.OperationLog log = new OperationResult.OperationLog();
|
||||
UncachedKeyRing foreign = op.createSecretKeyRing(parcel).getRing();
|
||||
UncachedKeyRing foreign = op.createSecretKeyRing(builder.build()).getRing();
|
||||
|
||||
Assert.assertNotNull("initial test key creation must succeed", foreign);
|
||||
PGPSecretKey foreignSecretKey =
|
||||
|
|
|
@ -89,7 +89,7 @@ public class UncachedKeyringMergeTest {
|
|||
ArrayList<RawPacket> onlyB = new ArrayList<>();
|
||||
OperationResult.OperationLog log = new OperationResult.OperationLog();
|
||||
PgpKeyOperation op;
|
||||
SaveKeyringParcel parcel;
|
||||
SaveKeyringParcel.Builder builder;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpOnce() throws Exception {
|
||||
|
@ -97,43 +97,42 @@ public class UncachedKeyringMergeTest {
|
|||
ShadowLog.stream = System.out;
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
|
||||
parcel.mAddUserIds.add("twi");
|
||||
parcel.mAddUserIds.add("pink");
|
||||
builder.addUserId("twi");
|
||||
builder.addUserId("pink");
|
||||
{
|
||||
WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(100,
|
||||
"sunshine, sunshine, ladybugs awake~".getBytes());
|
||||
parcel.mAddUserAttribute.add(uat);
|
||||
builder.addUserAttribute(uat);
|
||||
}
|
||||
|
||||
// passphrase is tested in PgpKeyOperationTest, just use empty here
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
OperationResult.OperationLog log = new OperationResult.OperationLog();
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
staticRingA = result.getRing();
|
||||
staticRingA = staticRingA.canonicalize(new OperationLog(), 0).getUncachedKeyRing();
|
||||
}
|
||||
|
||||
{
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
|
||||
parcel.mAddUserIds.add("shy");
|
||||
builder.addUserId("shy");
|
||||
// passphrase is tested in PgpKeyOperationTest, just use empty here
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
OperationResult.OperationLog log = new OperationResult.OperationLog();
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
staticRingB = result.getRing();
|
||||
staticRingB = staticRingB.canonicalize(new OperationLog(), 0).getUncachedKeyRing();
|
||||
}
|
||||
|
@ -155,10 +154,11 @@ public class UncachedKeyringMergeTest {
|
|||
// setting up some parameters just to reduce code duplication
|
||||
op = new PgpKeyOperation(new ProgressScaler(null, 0, 100, 100));
|
||||
|
||||
// set this up, gonna need it more than once
|
||||
parcel = new SaveKeyringParcel();
|
||||
parcel.mMasterKeyId = ringA.getMasterKeyId();
|
||||
parcel.mFingerprint = ringA.getFingerprint();
|
||||
resetBuilder();
|
||||
}
|
||||
|
||||
private void resetBuilder() {
|
||||
builder = SaveKeyringParcel.buildChangeKeyringParcel(ringA.getMasterKeyId(), ringA.getFingerprint());
|
||||
}
|
||||
|
||||
public void testSelfNoOp() throws Exception {
|
||||
|
@ -190,15 +190,15 @@ public class UncachedKeyringMergeTest {
|
|||
CanonicalizedSecretKeyRing secretRing =
|
||||
new CanonicalizedSecretKeyRing(ringA.getEncoded(), 0);
|
||||
|
||||
parcel.reset();
|
||||
parcel.mAddUserIds.add("flim");
|
||||
resetBuilder();
|
||||
builder.addUserId("flim");
|
||||
modifiedA = op.modifySecretKeyRing(secretRing,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing();
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing();
|
||||
|
||||
parcel.reset();
|
||||
parcel.mAddUserIds.add("flam");
|
||||
resetBuilder();
|
||||
builder.addUserId("flam");
|
||||
modifiedB = op.modifySecretKeyRing(secretRing,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing();
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing();
|
||||
}
|
||||
|
||||
{ // merge A into base
|
||||
|
@ -232,13 +232,13 @@ public class UncachedKeyringMergeTest {
|
|||
{
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringA.getEncoded(), 0);
|
||||
|
||||
parcel.reset();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
resetBuilder();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
modifiedA = op.modifySecretKeyRing(secretRing,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing();
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing();
|
||||
modifiedB = op.modifySecretKeyRing(secretRing,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing();
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing();
|
||||
|
||||
subKeyIdA = KeyringTestingHelper.getSubkeyId(modifiedA, 2);
|
||||
subKeyIdB = KeyringTestingHelper.getSubkeyId(modifiedB, 2);
|
||||
|
@ -275,12 +275,12 @@ public class UncachedKeyringMergeTest {
|
|||
public void testAddedKeySignature() throws Exception {
|
||||
|
||||
final UncachedKeyRing modified; {
|
||||
parcel.reset();
|
||||
parcel.mRevokeSubKeys.add(KeyringTestingHelper.getSubkeyId(ringA, 1));
|
||||
resetBuilder();
|
||||
builder.addRevokeSubkey(KeyringTestingHelper.getSubkeyId(ringA, 1));
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(
|
||||
ringA.getEncoded(), 0);
|
||||
modified = op.modifySecretKeyRing(secretRing,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing();
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing();
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -368,7 +368,7 @@ public class UncachedKeyringMergeTest {
|
|||
public void testAddedUserAttributeSignature() throws Exception {
|
||||
|
||||
final UncachedKeyRing modified; {
|
||||
parcel.reset();
|
||||
resetBuilder();
|
||||
|
||||
Random r = new Random();
|
||||
int type = r.nextInt(110)+1;
|
||||
|
@ -376,12 +376,12 @@ public class UncachedKeyringMergeTest {
|
|||
new Random().nextBytes(data);
|
||||
|
||||
WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data);
|
||||
parcel.mAddUserAttribute.add(uat);
|
||||
builder.addUserAttribute(uat);
|
||||
|
||||
CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(
|
||||
ringA.getEncoded(), 0);
|
||||
modified = op.modifySecretKeyRing(secretRing,
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), parcel).getRing();
|
||||
CryptoInputParcel.createCryptoInputParcel(new Date(), new Passphrase()), builder.build()).getRing();
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -54,16 +54,16 @@ public class UncachedKeyringTest {
|
|||
Security.insertProviderAt(new BouncyCastleProvider(), 1);
|
||||
ShadowLog.stream = System.out;
|
||||
|
||||
SaveKeyringParcel parcel = new SaveKeyringParcel();
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
SaveKeyringParcel.Builder builder = SaveKeyringParcel.buildNewKeyringParcel();
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
|
||||
parcel.mAddSubKeys.add(SubkeyAdd.createSubkeyAdd(
|
||||
builder.addSubkeyAdd(SubkeyAdd.createSubkeyAdd(
|
||||
Algorithm.ECDH, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
|
||||
|
||||
parcel.mAddUserIds.add("twi");
|
||||
parcel.mAddUserIds.add("pink");
|
||||
builder.addUserId("twi");
|
||||
builder.addUserId("pink");
|
||||
{
|
||||
Random r = new Random();
|
||||
int type = r.nextInt(110)+1;
|
||||
|
@ -71,13 +71,13 @@ public class UncachedKeyringTest {
|
|||
new Random().nextBytes(data);
|
||||
|
||||
WrappedUserAttribute uat = WrappedUserAttribute.fromSubpacket(type, data);
|
||||
parcel.mAddUserAttribute.add(uat);
|
||||
builder.addUserAttribute(uat);
|
||||
}
|
||||
// passphrase is tested in PgpKeyOperationTest, just use empty here
|
||||
parcel.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
builder.setNewUnlock(ChangeUnlockParcel.createUnLockParcelForNewKey(new Passphrase()));
|
||||
PgpKeyOperation op = new PgpKeyOperation(null);
|
||||
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(parcel);
|
||||
PgpEditKeyResult result = op.createSecretKeyRing(builder.build());
|
||||
staticRing = result.getRing();
|
||||
staticPubRing = staticRing.extractPublicKeyRing();
|
||||
|
||||
|
|
Loading…
Reference in a new issue