mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-06 17:25:05 -05:00
certs: provider cleanup and bugfixing
This commit is contained in:
parent
6bacb5ff51
commit
5c28da44d6
@ -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<String, String> pmap = new HashMap<String, String>();
|
||||
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<String, String> pmap2 = new HashMap<String, String>();
|
||||
pmap2.put(Certs._ID, Tables.CERTS + "." + Certs._ID);
|
||||
|
@ -207,7 +207,7 @@ public class ProviderHelper {
|
||||
}
|
||||
|
||||
// get a list of owned secret keys, for verification filtering
|
||||
Map<Long, PGPKeyRing> allKeyRings = getPGPKeyRings(context, KeyRings.buildPublicKeyRingsUri());
|
||||
Map<Long, PGPKeyRing> allKeyRings = getPGPKeyRings(context, KeyRings.buildSecretKeyRingsUri());
|
||||
|
||||
int userIdRank = 0;
|
||||
for (String userId : new IterableIterator<String>(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;
|
||||
|
@ -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<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
|
@ -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<Cursor> 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);
|
||||
|
@ -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;
|
||||
|
@ -60,24 +60,6 @@
|
||||
android:paddingRight="5dip" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:paddingRight="10dip"
|
||||
android:text="@string/label_subkey_rank" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subkey_rank"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="5dip" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
Loading…
Reference in New Issue
Block a user