aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-04-13 21:06:39 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-04-13 21:06:39 +0200
commit55bad4cac747cedfdda978a94d41f8069358373f (patch)
tree548be7f2f019ed6501634ebdbbf6a40bca844ebe /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
parente10b24e2ea9591af4abe5f00817b23c940baeca8 (diff)
downloadopen-keychain-55bad4cac747cedfdda978a94d41f8069358373f.tar.gz
open-keychain-55bad4cac747cedfdda978a94d41f8069358373f.tar.bz2
open-keychain-55bad4cac747cedfdda978a94d41f8069358373f.zip
Rework verifyCleartextSignature
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java172
1 files changed, 98 insertions, 74 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
index be917dc30..22cd62379 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java
@@ -67,7 +67,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SignatureException;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
@@ -450,7 +449,7 @@ public class PgpDecryptVerify {
isSignatureKeyCertified = (Long) data > 0;
} else {
- // no key in our database -> return "unknwon pub key" status including the first key id
+ // no key in our database -> return "unknown pub key" status including the first key id
if (!sigList.isEmpty()) {
signatureResult.setKeyId(sigList.get(0).getKeyID());
}
@@ -522,23 +521,13 @@ public class PgpDecryptVerify {
// TODO: what about binary signatures?
signatureResult.setSignatureOnly(false);
- //Now check binding signatures
- boolean validKeyBinding = verifyKeyBinding(messageSignature, signatureKey);
+ // Verify signature and check binding signatures
boolean validSignature = signature.verify(messageSignature);
+ boolean validKeyBinding = verifyKeyBinding(messageSignature, signatureKey);
- if (validKeyBinding && validSignature) {
- if (isSignatureKeyCertified) {
- Log.d(Constants.TAG, "SIGNATURE_SUCCESS_CERTIFIED");
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED);
- } else {
- Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED");
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
- }
- } else {
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
- Log.e(Constants.TAG, "Error!\nvalidKeyBinding: " + validKeyBinding
- + "\nvalidSignature: " + validSignature);
- }
+ signatureResult.setStatus(
+ getSignatureResultStatus(validSignature, validKeyBinding, isSignatureKeyCertified)
+ );
}
}
@@ -610,85 +599,96 @@ public class PgpDecryptVerify {
if (sigList == null) {
throw new InvalidDataException();
}
- PGPSignature signature = null;
- long signatureKeyId = 0;
- PGPPublicKey signatureKey = null;
- for (int i = 0; i < sigList.size(); ++i) {
- signature = sigList.get(i);
- signatureKeyId = signature.getKeyID();
-
- // find data about this subkey
- HashMap<String, Object> data = mProviderHelper.getGenericData(
- KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(Long.toString(signature.getKeyID())),
- new String[]{KeyRings.MASTER_KEY_ID, KeyRings.USER_ID},
- new int[]{ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_STRING});
- // any luck? otherwise, try next.
- if (data.get(KeyRings.MASTER_KEY_ID) == null) {
- signature = null;
- // do NOT reset signatureMasterKeyId, that one is shown when no known one is found!
- continue;
- }
- // this one can't fail now (yay database constraints)
+ // go through all signatures
+ // and find out for which signature we have a key in our database
+ Long masterKeyId = null;
+ int signatureIndex = 0;
+ for (int i = 0; i < sigList.size(); ++i) {
try {
- signatureKey = mProviderHelper.getPGPPublicKeyRing((Long) data.get(KeyRings.MASTER_KEY_ID)).getPublicKey();
+ Uri uri = KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(
+ Long.toString(sigList.get(i).getKeyID()));
+ masterKeyId = mProviderHelper.getMasterKeyId(uri);
+ signatureIndex = i;
} catch (ProviderHelper.NotFoundException e) {
- Log.e(Constants.TAG, "key not found!", e);
+ Log.d(Constants.TAG, "key not found!");
+ // try next one...
}
- signatureResult.setUserId((String) data.get(KeyRings.USER_ID));
-
- break;
}
- signatureResult.setKeyId(signatureKeyId);
+ PGPSignature signature = null;
+ PGPPublicKey signatureKey = null;
+ boolean isSignatureKeyCertified = false;
+ if (masterKeyId != null) {
+ // key found in our database!
+
+ try {
+ signatureKey = mProviderHelper
+ .getPGPPublicKeyRing(masterKeyId).getPublicKey();
+ } catch (ProviderHelper.NotFoundException e) {
+ // can't happen
+ }
+
+ signature = sigList.get(signatureIndex);
+ signatureResult.setUserId(PgpKeyHelper.getMainUserId(signatureKey));
+ signatureResult.setKeyId(signature.getKeyID());
+ JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
+ new JcaPGPContentVerifierBuilderProvider()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ signature.init(contentVerifierBuilderProvider, signatureKey);
+
+ // get certification status of this key
+ Object data = mProviderHelper.getGenericData(
+ KeychainContract.UserIds.buildUserIdsUri(Long.toString(masterKeyId)),
+ KeyRings.VERIFIED,
+ ProviderHelper.FIELD_TYPE_INTEGER);
+
+ isSignatureKeyCertified = (Long) data > 0;
+ } else {
+ // no key in our database -> return "unknown pub key" status including the first key id
+ if (!sigList.isEmpty()) {
+ signatureResult.setKeyId(sigList.get(0).getKeyID());
+ }
- if (signature == null) {
Log.d(Constants.TAG, "SIGNATURE_UNKNOWN_PUB_KEY");
signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY);
- result.setSignatureResult(signatureResult);
-
- updateProgress(R.string.progress_done, 100, 100);
- return result;
}
- JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
- new JcaPGPContentVerifierBuilderProvider()
- .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
+ if (signature != null) {
+ updateProgress(R.string.progress_verifying_signature, 90, 100);
- signature.init(contentVerifierBuilderProvider, signatureKey);
+ JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
+ new JcaPGPContentVerifierBuilderProvider()
+ .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
- InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText));
+ signature.init(contentVerifierBuilderProvider, signatureKey);
- lookAhead = readInputLine(lineOut, sigIn);
+ InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText));
- processLine(signature, lineOut.toByteArray());
+ lookAhead = readInputLine(lineOut, sigIn);
- if (lookAhead != -1) {
- do {
- lookAhead = readInputLine(lineOut, lookAhead, sigIn);
+ processLine(signature, lineOut.toByteArray());
- signature.update((byte) '\r');
- signature.update((byte) '\n');
+ if (lookAhead != -1) {
+ do {
+ lookAhead = readInputLine(lineOut, lookAhead, sigIn);
- processLine(signature, lineOut.toByteArray());
- } while (lookAhead != -1);
- }
+ signature.update((byte) '\r');
+ signature.update((byte) '\n');
- //Now check binding signatures
- boolean validKeyBinding = verifyKeyBinding(signature, signatureKey);
- boolean validSignature = signature.verify();
+ processLine(signature, lineOut.toByteArray());
+ } while (lookAhead != -1);
+ }
- if (validKeyBinding && validSignature) {
- Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED");
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
- } else {
- signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
- Log.e(Constants.TAG, "Error!\nvalidKeyBinding: " + validKeyBinding
- + "\nvalidSignature: " + validSignature);
- }
+ // Verify signature and check binding signatures
+ boolean validSignature = signature.verify();
+ boolean validKeyBinding = verifyKeyBinding(signature, signatureKey);
- // TODO: what about SIGNATURE_SUCCESS_CERTIFIED and SIGNATURE_ERROR????
+ signatureResult.setStatus(
+ getSignatureResultStatus(validSignature, validKeyBinding, isSignatureKeyCertified)
+ );
+ }
result.setSignatureResult(signatureResult);
@@ -696,6 +696,30 @@ public class PgpDecryptVerify {
return result;
}
+ /**
+ * Returns SIGNATURE_SUCCESS_CERTIFIED, SIGNATURE_SUCCESS_UNCERTIFIED, or SIGNATURE_ERROR
+ *
+ * @param validSignature
+ * @param validKeyBinding
+ * @param isSignatureKeyCertified
+ * @return
+ */
+ private int getSignatureResultStatus(boolean validSignature, boolean validKeyBinding, boolean isSignatureKeyCertified) {
+ if (validKeyBinding && validSignature) {
+ if (isSignatureKeyCertified) {
+ Log.d(Constants.TAG, "SIGNATURE_SUCCESS_CERTIFIED");
+ return OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED;
+ } else {
+ Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED");
+ return OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED;
+ }
+ } else {
+ Log.e(Constants.TAG, "Error!\nvalidKeyBinding: " + validKeyBinding
+ + "\nvalidSignature: " + validSignature);
+ return OpenPgpSignatureResult.SIGNATURE_ERROR;
+ }
+ }
+
private boolean verifyKeyBinding(PGPSignature signature, PGPPublicKey signatureKey) {
long signatureKeyId = signature.getKeyID();
boolean validKeyBinding = false;