From 5c28da44d6e4dfa72e69fecbacce6f988d5f6eb3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 15 Mar 2014 19:57:22 +0100 Subject: [PATCH] certs: provider cleanup and bugfixing --- .../keychain/provider/KeychainProvider.java | 45 ++++++++++--------- .../keychain/provider/ProviderHelper.java | 41 +++++++++-------- .../keychain/ui/CertifyKeyActivity.java | 8 ++-- .../keychain/ui/ViewCertActivity.java | 23 +++++----- .../keychain/ui/ViewKeyMainFragment.java | 24 +++++----- .../main/res/layout/view_cert_activity.xml | 18 -------- 6 files changed, 75 insertions(+), 84 deletions(-) diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index eff011bdf..7ee30a304 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -451,6 +451,9 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID); + // this is the count of known secret keys who certified this uid + projectionMap.put("verified", "COUNT(" + Tables.KEYS + "." + Keys._ID + ") AS verified"); + return projectionMap; } @@ -659,38 +662,37 @@ public class KeychainProvider extends ContentProvider { break; case PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID: - qb.setTables(Tables.USER_IDS + " INNER JOIN " + Tables.KEY_RINGS + " ON " + "(" - + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." - + KeysColumns.KEY_RING_ROW_ID + " )"); - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(3)); - - qb.setProjectionMap(getProjectionMapForUserIds()); - - break; - case PUBLIC_KEY_RING_USER_ID: case SECRET_KEY_RING_USER_ID: qb.setTables(Tables.USER_IDS - + " LEFT JOIN " + Tables.CERTS - + " ON (" + + " INNER JOIN " + Tables.KEY_RINGS + " ON (" + + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + + Tables.USER_IDS + "." + KeysColumns.KEY_RING_ROW_ID + + ") LEFT JOIN " + Tables.CERTS + " ON (" + Tables.USER_IDS + "." + UserIds.KEY_RING_ROW_ID + " = " + Tables.CERTS + "." + Certs.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "." + UserIds.RANK + " = " + Tables.CERTS + "." + Certs.RANK + + ") LEFT JOIN " + Tables.KEYS + " ON (" + + Tables.KEYS + "." + Keys.KEY_ID + " = " + + Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER + // might introduce a "trusted" flag later? for now, we simply assume + // every private key's signature is good. + + " AND " + Tables.KEYS + "." + Keys.TYPE + + " == " + KeyTypes.SECRET + ")"); groupBy = Tables.USER_IDS + "." + UserIds.RANK; - HashMap pmap = new HashMap(); - pmap.put(UserIds._ID, Tables.USER_IDS + "." + UserIds._ID); - pmap.put(UserIds.USER_ID, Tables.USER_IDS + "." + UserIds.USER_ID); - pmap.put(UserIds.RANK, Tables.USER_IDS + "." + UserIds.RANK); - pmap.put("verified", "COUNT(" + Tables.CERTS + "." + Certs._ID + ") AS verified"); - qb.setProjectionMap(pmap); + qb.setProjectionMap(getProjectionMapForUserIds()); - qb.appendWhere(Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + if(match == PUBLIC_KEY_RING_BY_MASTER_KEY_ID_USER_ID) { + qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(3)); + } else { + qb.appendWhere(Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + } break; @@ -728,7 +730,8 @@ public class KeychainProvider extends ContentProvider { + "signer." + Keys.RANK + " = 0" + ")"); - // groupBy = Tables.USER_IDS + "." + UserIds.RANK; + groupBy = Tables.CERTS + "." + Certs.RANK + ", " + + Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER; HashMap pmap2 = new HashMap(); pmap2.put(Certs._ID, Tables.CERTS + "." + Certs._ID); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index dfc65f778..3d81743f1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -207,7 +207,7 @@ public class ProviderHelper { } // get a list of owned secret keys, for verification filtering - Map allKeyRings = getPGPKeyRings(context, KeyRings.buildPublicKeyRingsUri()); + Map allKeyRings = getPGPKeyRings(context, KeyRings.buildSecretKeyRingsUri()); int userIdRank = 0; for (String userId : new IterableIterator(masterKey.getUserIDs())) { @@ -218,35 +218,34 @@ public class ProviderHelper { masterKey.getSignaturesForID(userId))) { long certId = cert.getKeyID(); boolean verified = false; - // only care for signatures from our own private keys + // do verify signatures from our own private keys if(allKeyRings.containsKey(certId)) try { // mark them as verified - cert.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), allKeyRings.get(certId).getPublicKey()); + cert.init( + new JcaPGPContentVerifierBuilderProvider().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME), + allKeyRings.get(certId).getPublicKey()); verified = cert.verifyCertification(userId, masterKey); - // TODO: at this point, we only save signatures from available secret keys. - // should we save all? those are quite a lot of rows for info we don't really - // use. I left it out for now - it is available from key servers, so we can - // always get it later. - Log.d(Constants.TAG, "sig for " + userId + " " + verified + " from " + Log.d(Constants.TAG, "Verified sig for " + userId + " " + verified + " from " + PgpKeyHelper.convertKeyIdToHex(cert.getKeyID()) ); - operations.add(buildPublicCertOperations( - context, keyRingRowId, userIdRank, masterKey.getKeyID(), cert, verified)); } catch(SignatureException e) { - Log.e(Constants.TAG, "Signature verification failed.", e); - } catch(PGPException e) { - Log.e(Constants.TAG, "Signature verification failed.", e); - } else { - Log.d(Constants.TAG, "ignored sig for " + Log.e(Constants.TAG, "Signature verification failed! " + PgpKeyHelper.convertKeyIdToHex(masterKey.getKeyID()) + " from " - + PgpKeyHelper.convertKeyIdToHex(cert.getKeyID()) - ); - operations.add(buildPublicCertOperations( - context, keyRingRowId, userIdRank, masterKey.getKeyID(), cert, false)); + + PgpKeyHelper.convertKeyIdToHex(cert.getKeyID()), e); + } catch(PGPException e) { + Log.e(Constants.TAG, "Signature verification failed! " + + PgpKeyHelper.convertKeyIdToHex(masterKey.getKeyID()) + + " from " + + PgpKeyHelper.convertKeyIdToHex(cert.getKeyID()), e); } - // if we wanted to save all, not just our own verifications - // buildPublicCertOperations(context, keyRingRowId, rank, cert, verified); + Log.d(Constants.TAG, "sig for " + userId + " from " + + PgpKeyHelper.convertKeyIdToHex(cert.getKeyID()) + ); + // regardless of verification, save the certification + operations.add(buildPublicCertOperations( + context, keyRingRowId, userIdRank, masterKey.getKeyID(), cert, verified)); } ++userIdRank; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index d8df5ced3..f2e6c4bd9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -43,6 +43,7 @@ import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; @@ -164,7 +165,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID, KeychainContract.Keys.FINGERPRINT, - KeychainContract.UserIds.USER_ID + KeychainContract.UserIds.USER_ID, }; static final int INDEX_MASTER_KEY_ID = 1; static final int INDEX_FINGERPRINT = 2; @@ -174,10 +175,11 @@ public class CertifyKeyActivity extends ActionBarActivity implements new String[]{ KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID, - KeychainContract.UserIds.RANK + KeychainContract.UserIds.RANK, + "verified" }; static final String USER_IDS_SORT_ORDER = - KeychainContract.UserIds.RANK + " ASC"; + KeychainDatabase.Tables.USER_IDS + "." + KeychainContract.UserIds.RANK + " ASC"; @Override public Loader onCreateLoader(int id, Bundle args) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java index c0ecc5001..611864d8e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java @@ -53,12 +53,17 @@ public class ViewCertActivity extends ActionBarActivity KeychainContract.Certs._ID, KeychainContract.Certs.KEY_ID, KeychainContract.UserIds.USER_ID, - KeychainContract.Certs.RANK, KeychainContract.Certs.CREATION, KeychainContract.Certs.KEY_ID_CERTIFIER, "signer_uid", KeychainContract.Certs.KEY_DATA }; + private static final int INDEX_KEY_ID = 1; + private static final int INDEX_USER_ID = 2; + private static final int INDEX_CREATION = 3; + private static final int INDEX_KEY_ID_CERTIFIER = 4; + private static final int INDEX_UID_CERTIFIER = 5; + private static final int INDEX_KEY_DATA = 6; private Uri mDataUri; @@ -78,7 +83,6 @@ public class ViewCertActivity extends ActionBarActivity mSigneeKey = (TextView) findViewById(R.id.signee_key); mSigneeUid = (TextView) findViewById(R.id.signee_uid); - mRank = (TextView) findViewById(R.id.subkey_rank); mAlgorithm = (TextView) findViewById(R.id.algorithm); mType = (TextView) findViewById(R.id.signature_type); mCreation = (TextView) findViewById(R.id.creation); @@ -108,29 +112,26 @@ public class ViewCertActivity extends ActionBarActivity @Override public void onLoadFinished(Loader loader, Cursor data) { if(data.moveToFirst()) { - String signeeKey = "0x" + PgpKeyHelper.convertKeyIdToHex(data.getLong(1)); + String signeeKey = "0x" + PgpKeyHelper.convertKeyIdToHex(data.getLong(INDEX_KEY_ID)); mSigneeKey.setText(signeeKey); - String signeeUid = data.getString(2); + String signeeUid = data.getString(INDEX_USER_ID); mSigneeUid.setText(signeeUid); - String subkey_rank = Integer.toString(data.getInt(3)); - mRank.setText(subkey_rank); - - Date creationDate = new Date(data.getLong(4) * 1000); + Date creationDate = new Date(data.getLong(INDEX_CREATION) * 1000); mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(creationDate)); - mSignerKeyId = data.getLong(5); + mSignerKeyId = data.getLong(INDEX_KEY_ID_CERTIFIER); String signerKey = "0x" + PgpKeyHelper.convertKeyIdToHex(mSignerKeyId); mSignerKey.setText(signerKey); - String signerUid = data.getString(6); + String signerUid = data.getString(INDEX_UID_CERTIFIER); if(signerUid != null) mSignerUid.setText(signerUid); else mSignerUid.setText(R.string.unknown_uid); - byte[] sigData = data.getBlob(7); + byte[] sigData = data.getBlob(INDEX_KEY_DATA); PGPSignature sig = PgpConversionHelper.BytesToPGPSignature(sigData); if(sig != null) { String algorithmStr = PgpKeyHelper.getAlgorithmInfo(sig.getKeyAlgorithm(), 0); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index 46c3e0b92..8f8c13c29 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -198,22 +198,26 @@ public class ViewKeyMainFragment extends Fragment implements static final int KEYRING_INDEX_MASTER_KEY_ID = 1; static final int KEYRING_INDEX_USER_ID = 2; - static final String[] USER_IDS_PROJECTION = - new String[]{ - KeychainContract.UserIds._ID, - KeychainContract.UserIds.USER_ID, - KeychainContract.UserIds.RANK, - }; + static final String[] USER_IDS_PROJECTION = new String[]{ + KeychainContract.UserIds._ID, + KeychainContract.UserIds.USER_ID, + KeychainContract.UserIds.RANK, + "verified", + }; + // not the main user id + static final String USER_IDS_SELECTION = + KeychainDatabase.Tables.USER_IDS + "." + KeychainContract.UserIds.RANK + " > 0 "; static final String USER_IDS_SORT_ORDER = - KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC"; + KeychainDatabase.Tables.USER_IDS + "." + KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC"; - static final String[] KEYS_PROJECTION = - new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID, + static final String[] KEYS_PROJECTION = new String[]{ + KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID, KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, KeychainContract.Keys.CAN_SIGN, KeychainContract.Keys.CAN_ENCRYPT, KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY, - KeychainContract.Keys.FINGERPRINT}; + KeychainContract.Keys.FINGERPRINT + }; static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC"; static final int KEYS_INDEX_ID = 0; static final int KEYS_INDEX_KEY_ID = 1; diff --git a/OpenPGP-Keychain/src/main/res/layout/view_cert_activity.xml b/OpenPGP-Keychain/src/main/res/layout/view_cert_activity.xml index c21362beb..3c6c09429 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_cert_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_cert_activity.xml @@ -60,24 +60,6 @@ android:paddingRight="5dip" /> - - - - - - -