diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2014-04-05 22:35:27 +0200 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2014-04-05 22:35:27 +0200 |
commit | 1b1304e6e043e95d9e9f5d7082c0a47c5d9ad865 (patch) | |
tree | 7d1c785b95ef96819193a48207b6ae5330ffd9d4 /OpenPGP-Keychain | |
parent | 2802718efb3be3dd39743445de886707dead680f (diff) | |
download | open-keychain-1b1304e6e043e95d9e9f5d7082c0a47c5d9ad865.tar.gz open-keychain-1b1304e6e043e95d9e9f5d7082c0a47c5d9ad865.tar.bz2 open-keychain-1b1304e6e043e95d9e9f5d7082c0a47c5d9ad865.zip |
certs: various improvements
* recognize self-certifications
* save signature type
* save expiry time
* drop encoded data blob from db
Diffstat (limited to 'OpenPGP-Keychain')
6 files changed, 55 insertions, 30 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 2b40300d7..4a2dd2da2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -55,13 +55,13 @@ public class KeychainContract { } interface CertsColumns { - String MASTER_KEY_ID = "master_key_id"; // verified id, foreign key to key_rings._ID - String RANK = "rank"; // rank of verified key - String KEY_ID_CERTIFIER = "key_id_certifier"; // verifying id, not a database id + String MASTER_KEY_ID = "master_key_id"; + String RANK = "rank"; + String KEY_ID_CERTIFIER = "key_id_certifier"; + String TYPE = "type"; + String VERIFIED = "verified"; String CREATION = "creation"; String EXPIRY = "expiry"; - String VERIFIED = "verified"; - String KEY_DATA = "key_data"; // certification blob } interface ApiAppsColumns { @@ -262,6 +262,9 @@ public class KeychainContract { public static final String USER_ID = UserIdsColumns.USER_ID; public static final String SIGNER_UID = "signer_user_id"; + public static final int VERIFIED_SECRET = 1; + public static final int VERIFIED_SELF = 2; + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() .appendPath(BASE_KEY_RINGS).build(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index fda1783cb..c704da0e7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -110,11 +110,11 @@ public class KeychainDatabase extends SQLiteOpenHelper { + CertsColumns.RANK + " INTEGER, " // rank of certified uid + CertsColumns.KEY_ID_CERTIFIER + " INTEGER, " // certifying key + + CertsColumns.TYPE + " INTEGER, " + + CertsColumns.VERIFIED + " INTEGER, " + CertsColumns.CREATION + " INTEGER, " + CertsColumns.EXPIRY + " INTEGER, " - + CertsColumns.VERIFIED + " INTEGER, " - + CertsColumns.KEY_DATA + " BLOB," + "PRIMARY KEY(" + CertsColumns.MASTER_KEY_ID + ", " + CertsColumns.RANK + ", " + CertsColumns.KEY_ID_CERTIFIER + "), " + "FOREIGN KEY(" + CertsColumns.MASTER_KEY_ID + ") REFERENCES " 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 01120eedf..0b15187dd 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 @@ -439,10 +439,10 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(Certs._ID, Tables.CERTS + ".oid AS " + Certs._ID); projectionMap.put(Certs.MASTER_KEY_ID, Tables.CERTS + "." + Certs.MASTER_KEY_ID); projectionMap.put(Certs.RANK, Tables.CERTS + "." + Certs.RANK); + projectionMap.put(Certs.VERIFIED, Tables.CERTS + "." + Certs.VERIFIED); + projectionMap.put(Certs.TYPE, Tables.CERTS + "." + Certs.TYPE); projectionMap.put(Certs.CREATION, Tables.CERTS + "." + Certs.CREATION); projectionMap.put(Certs.KEY_ID_CERTIFIER, Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER); - projectionMap.put(Certs.VERIFIED, Tables.CERTS + "." + Certs.VERIFIED); - projectionMap.put(Certs.KEY_DATA, Tables.CERTS + "." + Certs.KEY_DATA); projectionMap.put(Certs.USER_ID, Tables.USER_IDS + "." + UserIds.USER_ID); projectionMap.put(Certs.SIGNER_UID, "signer." + UserIds.USER_ID + " AS " + Certs.SIGNER_UID); qb.setProjectionMap(projectionMap); 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 02d8d29f2..1b653ae06 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 @@ -29,6 +29,8 @@ import android.database.DatabaseUtils; import android.net.Uri; import android.os.RemoteException; +import org.spongycastle.bcpg.SignatureSubpacketTags; +import org.spongycastle.bcpg.sig.SignatureExpirationTime; import org.spongycastle.openpgp.PGPException; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; @@ -231,22 +233,37 @@ public class ProviderHelper { for (String userId : new IterableIterator<String>(masterKey.getUserIDs())) { operations.add(buildUserIdOperations(context, masterKeyId, userId, userIdRank)); + // HashMap<Long, PGPSignature> certs = new HashMap<Long,PGPSignature>(); + // look through signatures for this specific key for (PGPSignature cert : new IterableIterator<PGPSignature>( masterKey.getSignaturesForID(userId))) { long certId = cert.getKeyID(); - boolean verified = false; - // do verify signatures from our own private keys - if(allKeyRings.containsKey(certId)) try { - // mark them as verified - cert.init( - new JcaPGPContentVerifierBuilderProvider().setProvider( + int verified = 0; + // verify from the key itself + try { + // verify signatures from known private keys + if(allKeyRings.containsKey(certId)) { + // mark them as verified + cert.init( + new JcaPGPContentVerifierBuilderProvider().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME), + allKeyRings.get(certId).getPublicKey()); + verified = cert.verifyCertification(userId, masterKey) ? Certs.VERIFIED_SECRET : 0; + Log.d(Constants.TAG, "Verified sig for " + userId + " " + verified + " from " + + PgpKeyHelper.convertKeyIdToHex(certId) + ); + // if that didn't work out, is it at least an own signature? + } else if(certId == masterKeyId) { + cert.init( + new JcaPGPContentVerifierBuilderProvider().setProvider( Constants.BOUNCY_CASTLE_PROVIDER_NAME), - allKeyRings.get(certId).getPublicKey()); - verified = cert.verifyCertification(userId, masterKey); - Log.d(Constants.TAG, "Verified sig for " + userId + " " + verified + " from " - + PgpKeyHelper.convertKeyIdToHex(cert.getKeyID()) - ); + masterKey); + verified = cert.verifyCertification(userId, masterKey) ? Certs.VERIFIED_SELF : 0; + Log.d(Constants.TAG, "Verified sig for " + userId + " " + verified + " from " + + PgpKeyHelper.convertKeyIdToHex(certId) + ); + } } catch(SignatureException e) { Log.e(Constants.TAG, "Signature verification failed! " + PgpKeyHelper.convertKeyIdToHex(masterKey.getKeyID()) @@ -263,7 +280,7 @@ public class ProviderHelper { ); // regardless of verification, save the certification operations.add(buildCertOperations( - context, masterKeyId, userIdRank, masterKey.getKeyID(), cert, verified)); + context, masterKeyId, userIdRank, cert, verified)); } ++userIdRank; @@ -354,18 +371,21 @@ public class ProviderHelper { private static ContentProviderOperation buildCertOperations(Context context, long masterKeyId, int rank, - long keyId, PGPSignature cert, - boolean verified) + int verified) throws IOException { ContentValues values = new ContentValues(); values.put(Certs.MASTER_KEY_ID, masterKeyId); values.put(Certs.RANK, rank); values.put(Certs.KEY_ID_CERTIFIER, cert.getKeyID()); + values.put(Certs.TYPE, cert.getSignatureType()); values.put(Certs.CREATION, cert.getCreationTime().getTime() / 1000); - values.put(Certs.EXPIRY, (String) null); // TODO + if(cert.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.EXPIRE_TIME)) { + long ext = ((SignatureExpirationTime) cert.getHashedSubPackets().getSubpacket( + SignatureSubpacketTags.EXPIRE_TIME)).getTime(); + values.put(Certs.EXPIRY, cert.getCreationTime().getTime() / 1000 + ext); + } values.put(Certs.VERIFIED, verified); - values.put(Certs.KEY_DATA, cert.getEncoded()); Uri uri = Certs.buildCertsUri(Long.toString(masterKeyId)); 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 b273955dd..ca548ac34 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 @@ -57,7 +57,7 @@ public class ViewCertActivity extends ActionBarActivity Certs.CREATION, Certs.KEY_ID_CERTIFIER, Certs.SIGNER_UID, - Certs.KEY_DATA + Certs.TYPE }; private static final int INDEX_MASTER_KEY_ID = 1; private static final int INDEX_USER_ID = 2; @@ -65,6 +65,7 @@ public class ViewCertActivity extends ActionBarActivity 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 static final int INDEX_KEY_TYPE = 6; private Uri mDataUri; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java index 772486384..ba304436b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java @@ -30,6 +30,7 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; +import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import java.util.ArrayList; @@ -108,12 +109,12 @@ public class ViewKeyUserIdsAdapter extends CursorAdapter { int verified = cursor.getInt(mVerifiedId); // TODO introduce own resources for this :) - if(verified == 1) + if(verified == Certs.VERIFIED_SECRET) vVerified.setImageResource(android.R.drawable.presence_online); - else if(verified > 1) - vVerified.setImageResource(android.R.drawable.presence_away); - else + else if(verified == Certs.VERIFIED_SELF) vVerified.setImageResource(android.R.drawable.presence_invisible); + else + vVerified.setImageResource(android.R.drawable.presence_busy); // don't care further if checkboxes aren't shown if (mCheckStates == null) { |