use Enum for verification status of certificates

This commit is contained in:
Vincent Breitmoser
2018-06-25 14:47:44 +02:00
parent 64bde4c680
commit c8481d0247
19 changed files with 103 additions and 56 deletions

View File

@@ -8,7 +8,7 @@ import org.sufficientlysecure.keychain.CertsModel;
@AutoValue @AutoValue
public abstract class Certification implements CertsModel { public abstract class Certification implements CertsModel {
public static final CertsModel.Factory<Certification> FACTORY = public static final CertsModel.Factory<Certification> FACTORY =
new CertsModel.Factory<>(AutoValue_Certification::new); new CertsModel.Factory<>(AutoValue_Certification::new, CustomColumnAdapters.VERIFICATON_STATUS_ADAPTER);
public static final SelectVerifyingCertDetailsMapper<CertDetails> CERT_DETAILS_MAPPER = public static final SelectVerifyingCertDetailsMapper<CertDetails> CERT_DETAILS_MAPPER =
new SelectVerifyingCertDetailsMapper<>(AutoValue_Certification_CertDetails::new); new SelectVerifyingCertDetailsMapper<>(AutoValue_Certification_CertDetails::new);

View File

@@ -7,10 +7,10 @@ import android.support.annotation.NonNull;
import com.squareup.sqldelight.ColumnAdapter; import com.squareup.sqldelight.ColumnAdapter;
import org.sufficientlysecure.keychain.model.AutocryptPeer.GossipOrigin; import org.sufficientlysecure.keychain.model.AutocryptPeer.GossipOrigin;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
public final class CustomColumnAdapters { public final class CustomColumnAdapters {
private CustomColumnAdapters() { } private CustomColumnAdapters() { }
@@ -64,4 +64,30 @@ public final class CustomColumnAdapters {
return (long) value.getNum(); return (long) value.getNum();
} }
}; };
public static final ColumnAdapter<VerificationStatus,Long> VERIFICATON_STATUS_ADAPTER = new ColumnAdapter<VerificationStatus, Long>() {
@NonNull
@Override
public VerificationStatus decode(Long databaseValue) {
if (databaseValue == null) {
return VerificationStatus.UNVERIFIED;
}
switch (databaseValue.intValue()) {
case 0: return VerificationStatus.UNVERIFIED;
case 1: return VerificationStatus.VERIFIED_SECRET;
case 2: return VerificationStatus.VERIFIED_SELF;
default: throw new IllegalArgumentException();
}
}
@Override
public Long encode(@NonNull VerificationStatus value) {
switch (value) {
case UNVERIFIED: return 0L;
case VERIFIED_SECRET: return 1L;
case VERIFIED_SELF: return 2L;
default: throw new IllegalArgumentException();
}
}
};
} }

View File

@@ -8,6 +8,7 @@ import java.util.List;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
import com.squareup.sqldelight.RowMapper; import com.squareup.sqldelight.RowMapper;
import org.sufficientlysecure.keychain.KeysModel; import org.sufficientlysecure.keychain.KeysModel;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
@@ -15,8 +16,9 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
public abstract class SubKey implements KeysModel { public abstract class SubKey implements KeysModel {
public static final Factory<SubKey> FACTORY = public static final Factory<SubKey> FACTORY =
new Factory<>(AutoValue_SubKey::new, CustomColumnAdapters.SECRET_KEY_TYPE_ADAPTER); new Factory<>(AutoValue_SubKey::new, CustomColumnAdapters.SECRET_KEY_TYPE_ADAPTER);
public static final UnifiedKeyViewMapper<UnifiedKeyInfo> UNIFIED_KEY_INFO_MAPPER = public static final UnifiedKeyViewMapper<UnifiedKeyInfo, Certification> UNIFIED_KEY_INFO_MAPPER =
FACTORY.selectUnifiedKeyInfoByMasterKeyIdMapper(AutoValue_SubKey_UnifiedKeyInfo::new); FACTORY.selectAllUnifiedKeyInfoMapper(
AutoValue_SubKey_UnifiedKeyInfo::new, Certification.FACTORY);
public static Mapper<SubKey> SUBKEY_MAPPER = new Mapper<>(FACTORY); public static Mapper<SubKey> SUBKEY_MAPPER = new Mapper<>(FACTORY);
public static RowMapper<SecretKeyType> SKT_MAPPER = FACTORY.selectSecretKeyTypeMapper(); public static RowMapper<SecretKeyType> SKT_MAPPER = FACTORY.selectSecretKeyTypeMapper();
@@ -38,8 +40,8 @@ public abstract class SubKey implements KeysModel {
} }
public boolean is_verified() { public boolean is_verified() {
Integer verified = verified(); VerificationStatus verified = verified();
return verified != null && verified == 1; return verified != null && verified == VerificationStatus.VERIFIED_SECRET;
} }
public boolean has_duplicate() { public boolean has_duplicate() {

View File

@@ -3,30 +3,29 @@ package org.sufficientlysecure.keychain.model;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
import org.sufficientlysecure.keychain.UserPacketsModel; import org.sufficientlysecure.keychain.UserPacketsModel;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
@AutoValue @AutoValue
public abstract class UserPacket implements UserPacketsModel { public abstract class UserPacket implements UserPacketsModel {
public static final Factory<UserPacket> FACTORY = new Factory<>(AutoValue_UserPacket::new); public static final Factory<UserPacket> FACTORY = new Factory<>(AutoValue_UserPacket::new);
public static final SelectUserIdsByMasterKeyIdMapper<UserId> USER_ID_MAPPER = public static final SelectUserIdsByMasterKeyIdMapper<UserId, Certification> USER_ID_MAPPER =
FACTORY.selectUserIdsByMasterKeyIdMapper(AutoValue_UserPacket_UserId::new); FACTORY.selectUserIdsByMasterKeyIdMapper(AutoValue_UserPacket_UserId::new, Certification.FACTORY);
public static final SelectUserAttributesByTypeAndMasterKeyIdMapper<UserAttribute> USER_ATTRIBUTE_MAPPER = public static final SelectUserAttributesByTypeAndMasterKeyIdMapper<UserAttribute, Certification> USER_ATTRIBUTE_MAPPER =
FACTORY.selectUserAttributesByTypeAndMasterKeyIdMapper(AutoValue_UserPacket_UserAttribute::new); FACTORY.selectUserAttributesByTypeAndMasterKeyIdMapper(AutoValue_UserPacket_UserAttribute::new, Certification.FACTORY);
@AutoValue @AutoValue
public static abstract class UserId implements SelectUserIdsByMasterKeyIdModel { public static abstract class UserId implements SelectUserIdsByMasterKeyIdModel {
public boolean isVerified() { public boolean isVerified() {
Integer verified = verified(); return verified() == VerificationStatus.VERIFIED_SECRET;
return verified != null && verified == Certs.VERIFIED_SECRET;
} }
} }
@AutoValue @AutoValue
public static abstract class UserAttribute implements SelectUserAttributesByTypeAndMasterKeyIdModel { public static abstract class UserAttribute implements SelectUserAttributesByTypeAndMasterKeyIdModel {
public boolean isVerified() { public boolean isVerified() {
Integer verified = verified(); return verified() == VerificationStatus.VERIFIED_SECRET;
return verified != null && verified == Certs.VERIFIED_SECRET;
} }
} }
} }

View File

@@ -43,9 +43,9 @@ import org.sufficientlysecure.keychain.util.IterableIterator;
*/ */
public abstract class CanonicalizedKeyRing extends KeyRing { public abstract class CanonicalizedKeyRing extends KeyRing {
private final int mVerified; private final VerificationStatus mVerified;
CanonicalizedKeyRing(int verified) { CanonicalizedKeyRing(VerificationStatus verified) {
mVerified = verified; mVerified = verified;
} }
@@ -53,7 +53,7 @@ public abstract class CanonicalizedKeyRing extends KeyRing {
return getRing().getPublicKey().getKeyID(); return getRing().getPublicKey().getKeyID();
} }
public int getVerified() { public VerificationStatus getVerified() {
return mVerified; return mVerified;
} }
@@ -194,4 +194,8 @@ public abstract class CanonicalizedKeyRing extends KeyRing {
return false; return false;
} }
public enum VerificationStatus {
UNVERIFIED, VERIFIED_SELF, VERIFIED_SECRET
}
} }

View File

@@ -41,12 +41,12 @@ public class CanonicalizedPublicKeyRing extends CanonicalizedKeyRing {
private PGPPublicKeyRing mRing; private PGPPublicKeyRing mRing;
CanonicalizedPublicKeyRing(PGPPublicKeyRing ring, int verified) { CanonicalizedPublicKeyRing(PGPPublicKeyRing ring, VerificationStatus verified) {
super(verified); super(verified);
mRing = ring; mRing = ring;
} }
public CanonicalizedPublicKeyRing(byte[] blob, int verified) { public CanonicalizedPublicKeyRing(byte[] blob, VerificationStatus verified) {
super(verified); super(verified);
if(mRing == null) { if(mRing == null) {
// get first object in block // get first object in block

View File

@@ -35,12 +35,12 @@ public class CanonicalizedSecretKeyRing extends CanonicalizedKeyRing {
private PGPSecretKeyRing mRing; private PGPSecretKeyRing mRing;
CanonicalizedSecretKeyRing(PGPSecretKeyRing ring, int verified) { CanonicalizedSecretKeyRing(PGPSecretKeyRing ring, VerificationStatus verified) {
super(verified); super(verified);
mRing = ring; mRing = ring;
} }
public CanonicalizedSecretKeyRing(byte[] blob, int verified) public CanonicalizedSecretKeyRing(byte[] blob, VerificationStatus verified)
{ {
super(verified); super(verified);
JcaPGPObjectFactory factory = new JcaPGPObjectFactory(blob); JcaPGPObjectFactory factory = new JcaPGPObjectFactory(blob);

View File

@@ -21,6 +21,7 @@ import android.text.TextUtils;
import org.openintents.openpgp.util.OpenPgpUtils; import org.openintents.openpgp.util.OpenPgpUtils;
import org.openintents.openpgp.util.OpenPgpUtils.UserId; import org.openintents.openpgp.util.OpenPgpUtils.UserId;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import java.io.Serializable; import java.io.Serializable;
@@ -58,7 +59,7 @@ public abstract class KeyRing {
abstract public boolean hasEncrypt() throws PgpKeyNotFoundException; abstract public boolean hasEncrypt() throws PgpKeyNotFoundException;
abstract public int getVerified() throws PgpKeyNotFoundException; abstract public VerificationStatus getVerified() throws PgpKeyNotFoundException;
/** /**
* Splits userId string into naming part, email part, and comment part * Splits userId string into naming part, email part, and comment part

View File

@@ -26,6 +26,7 @@ import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.OpenPgpSignatureResult.SenderStatusResult; import org.openintents.openpgp.OpenPgpSignatureResult.SenderStatusResult;
import org.openintents.openpgp.util.OpenPgpUtils; import org.openintents.openpgp.util.OpenPgpUtils;
import org.openintents.openpgp.util.OpenPgpUtils.UserId; import org.openintents.openpgp.util.OpenPgpUtils.UserId;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeyRepository;
import timber.log.Timber; import timber.log.Timber;
@@ -123,7 +124,7 @@ public class OpenPgpSignatureResultBuilder {
} catch (PgpKeyNotFoundException e) { } catch (PgpKeyNotFoundException e) {
Timber.d("No primary user id in keyring with master key id " + signingRing.getMasterKeyId()); Timber.d("No primary user id in keyring with master key id " + signingRing.getMasterKeyId());
} }
setSignatureKeyCertified(signingRing.getVerified() > 0); setSignatureKeyCertified(signingRing.getVerified() != VerificationStatus.UNVERIFIED);
List<String> allUserIds = signingRing.getUnorderedUserIds(); List<String> allUserIds = signingRing.getUnorderedUserIds();
List<String> confirmedUserIds = mKeyRepository.getConfirmedUserIds(signingRing.getMasterKeyId()); List<String> confirmedUserIds = mKeyRepository.getConfirmedUserIds(signingRing.getMasterKeyId());

View File

@@ -64,6 +64,7 @@ import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.IterableIterator;
@@ -1115,8 +1116,8 @@ public class UncachedKeyRing {
log.add(LogType.MSG_KC_SUCCESS, indent); log.add(LogType.MSG_KC_SUCCESS, indent);
} }
return isSecret() ? new CanonicalizedSecretKeyRing((PGPSecretKeyRing) ring, 1) return isSecret() ? new CanonicalizedSecretKeyRing((PGPSecretKeyRing) ring, VerificationStatus.VERIFIED_SECRET)
: new CanonicalizedPublicKeyRing((PGPPublicKeyRing) ring, 0); : new CanonicalizedPublicKeyRing((PGPPublicKeyRing) ring, VerificationStatus.UNVERIFIED);
} }
/** This operation merges information from a different keyring, returning a combined /** This operation merges information from a different keyring, returning a combined

View File

@@ -20,6 +20,8 @@ package org.sufficientlysecure.keychain.provider;
import android.net.Uri; import android.net.Uri;
import org.sufficientlysecure.keychain.model.CustomColumnAdapters;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
@@ -238,12 +240,12 @@ public class CachedPublicKeyRing extends KeyRing {
} }
@Override @Override
public int getVerified() throws PgpKeyNotFoundException { public VerificationStatus getVerified() throws PgpKeyNotFoundException {
try { try {
Object data = mKeyRepository.getGenericData(mUri, Object data = mKeyRepository.getGenericData(mUri,
KeychainContract.KeyRings.VERIFIED, KeychainContract.KeyRings.VERIFIED,
KeyRepository.FIELD_TYPE_INTEGER); KeyRepository.FIELD_TYPE_INTEGER);
return ((Long) data).intValue(); return CustomColumnAdapters.VERIFICATON_STATUS_ADAPTER.decode((Long) data);
} catch(KeyWritableRepository.NotFoundException e) { } catch(KeyWritableRepository.NotFoundException e) {
throw new PgpKeyNotFoundException(e); throw new PgpKeyNotFoundException(e);
} }

View File

@@ -31,6 +31,8 @@ import android.net.Uri;
import com.squareup.sqldelight.SqlDelightQuery; import com.squareup.sqldelight.SqlDelightQuery;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.sufficientlysecure.keychain.model.Certification;
import org.sufficientlysecure.keychain.model.CustomColumnAdapters;
import org.sufficientlysecure.keychain.model.KeyRingPublic; import org.sufficientlysecure.keychain.model.KeyRingPublic;
import org.sufficientlysecure.keychain.model.SubKey; import org.sufficientlysecure.keychain.model.SubKey;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
@@ -38,12 +40,12 @@ import org.sufficientlysecure.keychain.model.UserPacket;
import org.sufficientlysecure.keychain.model.UserPacket.UserId; import org.sufficientlysecure.keychain.model.UserPacket.UserId;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import timber.log.Timber; import timber.log.Timber;
@@ -197,10 +199,11 @@ public class KeyRepository extends AbstractDao {
try { try {
if (cursor != null && cursor.moveToFirst()) { if (cursor != null && cursor.moveToFirst()) {
long masterKeyId = cursor.getLong(0); long masterKeyId = cursor.getLong(0);
int verified = cursor.getInt(1); long verified = cursor.getLong(1);
byte[] publicKeyData = loadPublicKeyRingData(masterKeyId); byte[] publicKeyData = loadPublicKeyRingData(masterKeyId);
return new CanonicalizedPublicKeyRing(publicKeyData, verified); VerificationStatus verificationStatus = CustomColumnAdapters.VERIFICATON_STATUS_ADAPTER.decode(verified);
return new CanonicalizedPublicKeyRing(publicKeyData, verificationStatus);
} else { } else {
throw new NotFoundException("Key not found!"); throw new NotFoundException("Key not found!");
} }
@@ -221,14 +224,16 @@ public class KeyRepository extends AbstractDao {
try { try {
if (cursor != null && cursor.moveToFirst()) { if (cursor != null && cursor.moveToFirst()) {
long masterKeyId = cursor.getLong(0); long masterKeyId = cursor.getLong(0);
int verified = cursor.getInt(1); long verified = cursor.getLong(1);
int hasAnySecret = cursor.getInt(2); int hasAnySecret = cursor.getInt(2);
if (hasAnySecret == 0) { if (hasAnySecret == 0) {
throw new NotFoundException("No secret key available or unknown public key!"); throw new NotFoundException("No secret key available or unknown public key!");
} }
VerificationStatus verificationStatus = CustomColumnAdapters.VERIFICATON_STATUS_ADAPTER.decode(verified);
byte[] secretKeyData = loadSecretKeyRingData(masterKeyId); byte[] secretKeyData = loadSecretKeyRingData(masterKeyId);
return new CanonicalizedSecretKeyRing(secretKeyData, verified); return new CanonicalizedSecretKeyRing(secretKeyData, verificationStatus);
} else { } else {
throw new NotFoundException("Key not found!"); throw new NotFoundException("Key not found!");
} }
@@ -286,8 +291,8 @@ public class KeyRepository extends AbstractDao {
public List<String> getConfirmedUserIds(long masterKeyId) { public List<String> getConfirmedUserIds(long masterKeyId) {
ArrayList<String> userIds = new ArrayList<>(); ArrayList<String> userIds = new ArrayList<>();
SqlDelightQuery query = SqlDelightQuery query = UserPacket.FACTORY.selectUserIdsByMasterKeyIdAndVerification(
UserPacket.FACTORY.selectUserIdsByMasterKeyIdAndVerification(masterKeyId, Certs.VERIFIED_SECRET); Certification.FACTORY, masterKeyId, VerificationStatus.VERIFIED_SECRET);
for (UserId userId : mapAllRows(query, UserPacket.USER_ID_MAPPER::map)) { for (UserId userId : mapAllRows(query, UserPacket.USER_ID_MAPPER::map)) {
userIds.add(userId.user_id()); userIds.add(userId.user_id());
} }

View File

@@ -39,11 +39,13 @@ import android.support.v4.util.LongSparseArray;
import org.openintents.openpgp.util.OpenPgpUtils; import org.openintents.openpgp.util.OpenPgpUtils;
import org.sufficientlysecure.keychain.KeyRingsPublicModel.DeleteByMasterKeyId; import org.sufficientlysecure.keychain.KeyRingsPublicModel.DeleteByMasterKeyId;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.model.CustomColumnAdapters;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult; import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
import org.sufficientlysecure.keychain.operations.results.UpdateTrustResult; import org.sufficientlysecure.keychain.operations.results.UpdateTrustResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
@@ -134,10 +136,11 @@ public class KeyWritableRepository extends KeyRepository {
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
try { try {
long masterKeyId = cursor.getLong(0); long masterKeyId = cursor.getLong(0);
int verified = cursor.getInt(2); long verified = cursor.getLong(2);
byte[] blob = loadPublicKeyRingData(masterKeyId); byte[] blob = loadPublicKeyRingData(masterKeyId);
VerificationStatus verificationStatus = CustomColumnAdapters.VERIFICATON_STATUS_ADAPTER.decode(verified);
if (blob != null) { if (blob != null) {
result.put(masterKeyId, new CanonicalizedPublicKeyRing(blob, verified).getPublicKey()); result.put(masterKeyId, new CanonicalizedPublicKeyRing(blob, verificationStatus).getPublicKey());
} }
} catch (NotFoundException e) { } catch (NotFoundException e) {
throw new IllegalStateException("Error reading secret key data, this should not happen!", e); throw new IllegalStateException("Error reading secret key data, this should not happen!", e);
@@ -499,7 +502,7 @@ public class KeyWritableRepository extends KeyRepository {
if (item.selfRevocation != null) { if (item.selfRevocation != null) {
operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfRevocation, operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfRevocation,
Certs.VERIFIED_SELF)); VerificationStatus.VERIFIED_SELF));
// don't bother with trusted certs if the uid is revoked, anyways // don't bother with trusted certs if the uid is revoked, anyways
continue; continue;
} }
@@ -509,7 +512,7 @@ public class KeyWritableRepository extends KeyRepository {
} }
operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert, operations.add(buildCertOperations(masterKeyId, userIdRank, item.selfCert,
selfCertsAreTrusted ? Certs.VERIFIED_SECRET : Certs.VERIFIED_SELF)); selfCertsAreTrusted ? VerificationStatus.VERIFIED_SECRET : VerificationStatus.VERIFIED_SELF));
// iterate over signatures // iterate over signatures
for (int i = 0; i < item.trustedCerts.size(); i++) { for (int i = 0; i < item.trustedCerts.size(); i++) {
@@ -521,7 +524,7 @@ public class KeyWritableRepository extends KeyRepository {
} }
// otherwise, build database operation // otherwise, build database operation
operations.add(buildCertOperations( operations.add(buildCertOperations(
masterKeyId, userIdRank, sig, Certs.VERIFIED_SECRET)); masterKeyId, userIdRank, sig, VerificationStatus.VERIFIED_SECRET));
} }
} }
@@ -1064,7 +1067,7 @@ public class KeyWritableRepository extends KeyRepository {
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing * Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
*/ */
private ContentProviderOperation private ContentProviderOperation
buildCertOperations(long masterKeyId, int rank, WrappedSignature cert, int verified) buildCertOperations(long masterKeyId, int rank, WrappedSignature cert, VerificationStatus verificationStatus)
throws IOException { throws IOException {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(Certs.MASTER_KEY_ID, masterKeyId); values.put(Certs.MASTER_KEY_ID, masterKeyId);
@@ -1072,7 +1075,7 @@ public class KeyWritableRepository extends KeyRepository {
values.put(Certs.KEY_ID_CERTIFIER, cert.getKeyId()); values.put(Certs.KEY_ID_CERTIFIER, cert.getKeyId());
values.put(Certs.TYPE, cert.getSignatureType()); values.put(Certs.TYPE, cert.getSignatureType());
values.put(Certs.CREATION, cert.getCreationTime().getTime() / 1000); values.put(Certs.CREATION, cert.getCreationTime().getTime() / 1000);
values.put(Certs.VERIFIED, verified); values.put(Certs.VERIFIED, CustomColumnAdapters.VERIFICATON_STATUS_ADAPTER.encode(verificationStatus));
values.put(Certs.DATA, cert.getEncoded()); values.put(Certs.DATA, cert.getEncoded());
Uri uri = Certs.buildCertsUri(masterKeyId); Uri uri = Certs.buildCertsUri(masterKeyId);

View File

@@ -179,7 +179,6 @@ public class KeychainContract {
} }
public static class Certs implements CertsColumns, BaseColumns { public static class Certs implements CertsColumns, BaseColumns {
public static final int UNVERIFIED = 0;
public static final int VERIFIED_SECRET = 1; public static final int VERIFIED_SECRET = 1;
public static final int VERIFIED_SELF = 2; public static final int VERIFIED_SELF = 2;

View File

@@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.model.UserPacket.UserId; import org.sufficientlysecure.keychain.model.UserPacket.UserId;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.ViewKeyAdvActivity.ViewKeyAdvViewModel; import org.sufficientlysecure.keychain.ui.ViewKeyAdvActivity.ViewKeyAdvViewModel;
@@ -155,7 +156,7 @@ public class ViewKeyAdvUserIdsFragment extends Fragment {
private void showUserIdInfo(final int position) { private void showUserIdInfo(final int position) {
final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position); final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position);
final boolean isVerified = mUserIdsAdapter.getIsVerified(position) == Certs.VERIFIED_SECRET; final boolean isVerified = mUserIdsAdapter.getVerificationStatus(position) == VerificationStatus.VERIFIED_SECRET;
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(() -> { DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(() -> {
UserIdInfoDialogFragment dialogFragment = UserIdInfoDialogFragment dialogFragment =

View File

@@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysResultList
import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.ImportOperation;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeyRepository; import org.sufficientlysecure.keychain.provider.KeyRepository;
@@ -94,7 +95,8 @@ public class ImportKeysAdapter extends RecyclerView.Adapter<ImportKeysAdapter.Vi
keyRing = mKeyRepository.getCachedPublicKeyRing(keyId); keyRing = mKeyRepository.getCachedPublicKeyRing(keyId);
} }
keyState.mAlreadyPresent = true; keyState.mAlreadyPresent = true;
keyState.mVerified = keyRing.getVerified() > 0; VerificationStatus verified = keyRing.getVerified();
keyState.mVerified = verified != null && verified != VerificationStatus.UNVERIFIED;
} catch (KeyRepository.NotFoundException | PgpKeyNotFoundException ignored) { } catch (KeyRepository.NotFoundException | PgpKeyNotFoundException ignored) {
} }

View File

@@ -34,7 +34,7 @@ import android.widget.ViewAnimator;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.model.UserPacket.UserId; import org.sufficientlysecure.keychain.model.UserPacket.UserId;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
@@ -163,12 +163,12 @@ public class UserIdsAdapter extends BaseAdapter {
vAddress.setTypeface(null, Typeface.NORMAL); vAddress.setTypeface(null, Typeface.NORMAL);
} }
int isVerified = getIsVerified(position); VerificationStatus isVerified = getVerificationStatus(position);
switch (isVerified) { switch (isVerified) {
case Certs.VERIFIED_SECRET: case VERIFIED_SECRET:
KeyFormattingUtils.setStatusImage(context, vVerified, null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR); KeyFormattingUtils.setStatusImage(context, vVerified, null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
case Certs.VERIFIED_SELF: case VERIFIED_SELF:
KeyFormattingUtils.setStatusImage(context, vVerified, null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR); KeyFormattingUtils.setStatusImage(context, vVerified, null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
default: default:
@@ -216,7 +216,7 @@ public class UserIdsAdapter extends BaseAdapter {
return data.get(position).is_revoked(); return data.get(position).is_revoked();
} }
public int getIsVerified(int position) { public VerificationStatus getVerificationStatus(int position) {
return data.get(position).verified(); return data.get(position).verified();
} }
} }

View File

@@ -1,4 +1,5 @@
import java.lang.Integer; import java.lang.Integer;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
-- TODO implement. this is only here for reference in SQLDelight -- TODO implement. this is only here for reference in SQLDelight
CREATE TABLE IF NOT EXISTS certs( CREATE TABLE IF NOT EXISTS certs(
@@ -6,7 +7,7 @@ CREATE TABLE IF NOT EXISTS certs(
rank INTEGER NOT NULL, rank INTEGER NOT NULL,
key_id_certifier INTEGER NOT NULL, key_id_certifier INTEGER NOT NULL,
type INTEGER NOT NULL, type INTEGER NOT NULL,
verified INTEGER AS Integer NOT NULL, verified INTEGER AS VerificationStatus NOT NULL,
creation INTEGER NOT NULL, creation INTEGER NOT NULL,
data BLOB NOT NULL, data BLOB NOT NULL,
PRIMARY KEY(master_key_id, rank, key_id_certifier), PRIMARY KEY(master_key_id, rank, key_id_certifier),

View File

@@ -37,12 +37,12 @@ import org.sufficientlysecure.keychain.KeychainTestRunner;
import org.sufficientlysecure.keychain.operations.results.CertifyResult; import org.sufficientlysecure.keychain.operations.results.CertifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import org.sufficientlysecure.keychain.provider.KeyWritableRepository; import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel; import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
import org.sufficientlysecure.keychain.service.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.ChangeUnlockParcel;
@@ -137,7 +137,7 @@ public class CertifyOperationTest {
.getCanonicalizedPublicKeyRing(mStaticRing1.getMasterKeyId()); .getCanonicalizedPublicKeyRing(mStaticRing1.getMasterKeyId());
Assert.assertEquals("secret key must be marked self-certified in database", Assert.assertEquals("secret key must be marked self-certified in database",
// TODO this should be more correctly be VERIFIED_SELF at some point! // TODO this should be more correctly be VERIFIED_SELF at some point!
Certs.VERIFIED_SECRET, ring.getVerified()); VerificationStatus.VERIFIED_SECRET, ring.getVerified());
} }
@@ -150,7 +150,7 @@ public class CertifyOperationTest {
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application) CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId()); .getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertEquals("public key must not be marked verified prior to certification", Assert.assertEquals("public key must not be marked verified prior to certification",
Certs.UNVERIFIED, ring.getVerified()); VerificationStatus.UNVERIFIED, ring.getVerified());
} }
CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId()); CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId());
@@ -164,7 +164,7 @@ public class CertifyOperationTest {
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application) CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId()); .getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertEquals("new key must be verified now", Assert.assertEquals("new key must be verified now",
Certs.VERIFIED_SECRET, ring.getVerified()); VerificationStatus.UNVERIFIED, ring.getVerified());
} }
} }
@@ -178,7 +178,7 @@ public class CertifyOperationTest {
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application) CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId()); .getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertEquals("public key must not be marked verified prior to certification", Assert.assertEquals("public key must not be marked verified prior to certification",
Certs.UNVERIFIED, ring.getVerified()); VerificationStatus.UNVERIFIED, ring.getVerified());
} }
CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId()); CertifyActionsParcel.Builder actions = CertifyActionsParcel.builder(mStaticRing1.getMasterKeyId());
@@ -192,7 +192,7 @@ public class CertifyOperationTest {
CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application) CanonicalizedPublicKeyRing ring = KeyWritableRepository.create(RuntimeEnvironment.application)
.getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId()); .getCanonicalizedPublicKeyRing(mStaticRing2.getMasterKeyId());
Assert.assertEquals("new key must be verified now", Assert.assertEquals("new key must be verified now",
Certs.VERIFIED_SECRET, ring.getVerified()); VerificationStatus.VERIFIED_SECRET, ring.getVerified());
} }
} }