From c107fc668fb6ef1be2e2775fd2143fb2235942b2 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 23 May 2014 16:48:41 +0200 Subject: introduce WrappedSignature for the ViewCert* ui code --- .../keychain/pgp/WrappedSignature.java | 124 +++++++++++++++++++++ .../keychain/ui/ViewCertActivity.java | 44 ++++---- .../keychain/ui/ViewKeyCertsFragment.java | 12 +- 3 files changed, 149 insertions(+), 31 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java (limited to 'OpenKeychain/src/main') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java new file mode 100644 index 000000000..cdadbca7f --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSignature.java @@ -0,0 +1,124 @@ +package org.sufficientlysecure.keychain.pgp; + +import org.spongycastle.bcpg.SignatureSubpacket; +import org.spongycastle.bcpg.SignatureSubpacketTags; +import org.spongycastle.bcpg.sig.RevocationReason; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPObjectFactory; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureList; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.IOException; +import java.security.SignatureException; + +public class WrappedSignature { + + public static final int DEFAULT_CERTIFICATION = PGPSignature.DEFAULT_CERTIFICATION; + public static final int NO_CERTIFICATION = PGPSignature.NO_CERTIFICATION; + public static final int CASUAL_CERTIFICATION = PGPSignature.CASUAL_CERTIFICATION; + public static final int POSITIVE_CERTIFICATION = PGPSignature.POSITIVE_CERTIFICATION; + public static final int CERTIFICATION_REVOCATION = PGPSignature.CERTIFICATION_REVOCATION; + + final PGPSignature mSig; + + protected WrappedSignature(PGPSignature sig) { + mSig = sig; + } + + public long getKeyId() { + return mSig.getKeyID(); + } + + public int getKeyAlgorithm() { + return mSig.getKeyAlgorithm(); + } + + public void init(WrappedPublicKey key) throws PgpGeneralException { + try { + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = + new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + mSig.init(contentVerifierBuilderProvider, key.getPublicKey()); + } catch(PGPException e) { + throw new PgpGeneralException(e); + } + } + + public void update(byte[] data, int offset, int length) throws PgpGeneralException { + try { + mSig.update(data, offset, length); + } catch(SignatureException e) { + throw new PgpGeneralException(e); + } + } + + public void update(byte data) throws PgpGeneralException { + try { + mSig.update(data); + } catch(SignatureException e) { + throw new PgpGeneralException(e); + } + } + + public boolean verify() throws PgpGeneralException { + try { + return mSig.verify(); + } catch(SignatureException e) { + throw new PgpGeneralException(e); + } catch(PGPException e) { + throw new PgpGeneralException(e); + } + } + + public boolean isRevocation() { + return mSig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.REVOCATION_REASON); + } + + public String getRevocationReason() throws PgpGeneralException { + if(!isRevocation()) { + throw new PgpGeneralException("Not a revocation signature."); + } + SignatureSubpacket p = mSig.getHashedSubPackets().getSubpacket( + SignatureSubpacketTags.REVOCATION_REASON); + // For some reason, this is missing in SignatureSubpacketInputStream:146 + if (!(p instanceof RevocationReason)) { + p = new RevocationReason(false, p.getData()); + } + return ((RevocationReason) p).getRevocationDescription(); + } + + /** Verify a signature for this pubkey, after it has been initialized by the signer using + * initSignature(). This method should probably move into a wrapped PGPSignature class + * at some point. + */ + public boolean verifySignature(WrappedPublicKey key, String uid) throws PgpGeneralException { + try { + return mSig.verifyCertification(uid, key.getPublicKey()); + } catch (SignatureException e) { + throw new PgpGeneralException("Error!", e); + } catch (PGPException e) { + throw new PgpGeneralException("Error!", e); + } + } + + public static WrappedSignature fromBytes(byte[] data) { + PGPObjectFactory factory = new PGPObjectFactory(data); + PGPSignatureList signatures = null; + try { + if ((signatures = (PGPSignatureList) factory.nextObject()) == null || signatures.isEmpty()) { + Log.e(Constants.TAG, "No signatures given!"); + return null; + } + } catch (IOException e) { + Log.e(Constants.TAG, "Error while converting to PGPSignature!", e); + return null; + } + + return new WrappedSignature(signatures.get(0)); + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java index 465815f14..ae0206ab1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java @@ -32,16 +32,11 @@ import android.view.MenuItem; import android.view.View; import android.widget.TextView; -import org.spongycastle.bcpg.SignatureSubpacket; -import org.spongycastle.bcpg.SignatureSubpacketTags; -import org.spongycastle.bcpg.sig.RevocationReason; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPSignature; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.WrappedPublicKeyRing; -import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.WrappedSignature; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; @@ -144,23 +139,25 @@ public class ViewCertActivity extends ActionBarActivity mCertifierUid.setText(R.string.unknown_uid); } - PGPSignature sig = PgpConversionHelper.BytesToPGPSignature(data.getBlob(INDEX_DATA)); + WrappedSignature sig = WrappedSignature.fromBytes(data.getBlob(INDEX_DATA)); try { ProviderHelper providerHelper = new ProviderHelper(this); - WrappedPublicKeyRing signeeRing = providerHelper.getWrappedPublicKeyRing(data.getLong(INDEX_MASTER_KEY_ID)); - WrappedPublicKeyRing signerRing = providerHelper.getWrappedPublicKeyRing(sig.getKeyID()); + WrappedPublicKeyRing signeeRing = + providerHelper.getWrappedPublicKeyRing(data.getLong(INDEX_MASTER_KEY_ID)); + WrappedPublicKeyRing signerRing = + providerHelper.getWrappedPublicKeyRing(sig.getKeyId()); try { - signerRing.getSubkey().initSignature(sig); - if (signeeRing.getSubkey().verifySignature(sig, signeeUid)) { + sig.init(signerRing.getSubkey()); + if (sig.verifySignature(signeeRing.getSubkey(), signeeUid)) { mStatus.setText(R.string.cert_verify_ok); mStatus.setTextColor(getResources().getColor(R.color.bbutton_success)); } else { mStatus.setText(R.string.cert_verify_failed); mStatus.setTextColor(getResources().getColor(R.color.alert)); } - } catch (PGPException e) { + } catch (PgpGeneralException e) { mStatus.setText(R.string.cert_verify_error); mStatus.setTextColor(getResources().getColor(R.color.alert)); } @@ -174,29 +171,26 @@ public class ViewCertActivity extends ActionBarActivity mRowReason.setVisibility(View.GONE); switch (data.getInt(INDEX_TYPE)) { - case PGPSignature.DEFAULT_CERTIFICATION: + case WrappedSignature.DEFAULT_CERTIFICATION: mType.setText(R.string.cert_default); break; - case PGPSignature.NO_CERTIFICATION: + case WrappedSignature.NO_CERTIFICATION: mType.setText(R.string.cert_none); break; - case PGPSignature.CASUAL_CERTIFICATION: + case WrappedSignature.CASUAL_CERTIFICATION: mType.setText(R.string.cert_casual); break; - case PGPSignature.POSITIVE_CERTIFICATION: + case WrappedSignature.POSITIVE_CERTIFICATION: mType.setText(R.string.cert_positive); break; - case PGPSignature.CERTIFICATION_REVOCATION: { + case WrappedSignature.CERTIFICATION_REVOCATION: { mType.setText(R.string.cert_revoke); - if (sig.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.REVOCATION_REASON)) { - SignatureSubpacket p = sig.getHashedSubPackets().getSubpacket( - SignatureSubpacketTags.REVOCATION_REASON); - // For some reason, this is missing in SignatureSubpacketInputStream:146 - if (!(p instanceof RevocationReason)) { - p = new RevocationReason(false, p.getData()); + if (sig.isRevocation()) { + try { + mReason.setText(sig.getRevocationReason()); + } catch(PgpGeneralException e) { + mReason.setText(R.string.none); } - String reason = ((RevocationReason) p).getRevocationDescription(); - mReason.setText(reason); mRowReason.setVisibility(View.VISIBLE); } break; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java index d5658586d..3cd43638a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java @@ -33,10 +33,10 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.TextView; -import org.spongycastle.openpgp.PGPSignature; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.WrappedSignature; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.util.Log; @@ -227,19 +227,19 @@ public class ViewKeyCertsFragment extends LoaderFragment wSignerKeyId.setText(signerKeyId); switch (cursor.getInt(mIndexType)) { - case PGPSignature.DEFAULT_CERTIFICATION: // 0x10 + case WrappedSignature.DEFAULT_CERTIFICATION: // 0x10 wSignStatus.setText(R.string.cert_default); break; - case PGPSignature.NO_CERTIFICATION: // 0x11 + case WrappedSignature.NO_CERTIFICATION: // 0x11 wSignStatus.setText(R.string.cert_none); break; - case PGPSignature.CASUAL_CERTIFICATION: // 0x12 + case WrappedSignature.CASUAL_CERTIFICATION: // 0x12 wSignStatus.setText(R.string.cert_casual); break; - case PGPSignature.POSITIVE_CERTIFICATION: // 0x13 + case WrappedSignature.POSITIVE_CERTIFICATION: // 0x13 wSignStatus.setText(R.string.cert_positive); break; - case PGPSignature.CERTIFICATION_REVOCATION: // 0x30 + case WrappedSignature.CERTIFICATION_REVOCATION: // 0x30 wSignStatus.setText(R.string.cert_revoke); break; } -- cgit v1.2.3