diff options
Diffstat (limited to 'OpenKeychain')
2 files changed, 150 insertions, 51 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java new file mode 100644 index 000000000..550b5088c --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/OpenPgpSignatureResultBuilder.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.pgp; + +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.util.Log; + +/** + * This class can be used to build OpenPgpSignatureResult objects based on several checks. + * It serves as a constraint which information are returned inside an OpenPgpSignatureResult object. + */ +public class OpenPgpSignatureResultBuilder { + // OpenPgpSignatureResult + private int mStatus = OpenPgpSignatureResult.SIGNATURE_ERROR; + private boolean mSignatureOnly = false; + private String mUserId; + private long mKeyId; + + // builder + private boolean mSignatureAvailable = false; + private boolean mKnownKey = false; + private boolean mValidSignature = false; + private boolean mValidKeyBinding = false; + private boolean mIsSignatureKeyCertified = false; + + public void status(int status) { + this.mStatus = status; + } + + public void signatureOnly(boolean signatureOnly) { + this.mSignatureOnly = signatureOnly; + } + + public void userId(String userId) { + this.mUserId = userId; + } + + public void keyId(long keyId) { + this.mKeyId = keyId; + } + + public void knownKey(boolean knownKey) { + this.mKnownKey = knownKey; + } + + public void validSignature(boolean validSignature) { + this.mValidSignature = validSignature; + } + + public void validKeyBinding(boolean validKeyBinding) { + this.mValidKeyBinding = validKeyBinding; + } + + public void signatureKeyCertified(boolean isSignatureKeyCertified) { + this.mIsSignatureKeyCertified = isSignatureKeyCertified; + } + + public void signatureAvailable(boolean signatureAvailable) { + this.mSignatureAvailable = signatureAvailable; + } + + public OpenPgpSignatureResult build() { + if (mSignatureAvailable) { + OpenPgpSignatureResult result = new OpenPgpSignatureResult(); + result.setSignatureOnly(mSignatureOnly); + + if (mValidKeyBinding && mValidSignature) { + // valid sig! + if (mKnownKey) { + result.setKeyId(mKeyId); + result.setUserId(mUserId); + + if (mIsSignatureKeyCertified) { + Log.d(Constants.TAG, "SIGNATURE_SUCCESS_CERTIFIED"); + result.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED); + } else { + Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED"); + result.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED); + } + } else { + result.setKeyId(mKeyId); + + Log.d(Constants.TAG, "SIGNATURE_UNKNOWN_PUB_KEY"); + result.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY); + } + } else { + Log.d(Constants.TAG, "Error!\nvalidKeyBinding: " + mValidKeyBinding + + "\nvalidSignature: " + mValidSignature); + result.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR); + } + + return result; + } else { + Log.d(Constants.TAG, "no signature found!"); + + return null; + } + } + + +} 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 f0d605f4e..40d487a48 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -20,7 +20,6 @@ package org.sufficientlysecure.keychain.pgp; import android.net.Uri; -import org.openintents.openpgp.OpenPgpSignatureResult; import org.spongycastle.bcpg.ArmoredInputStream; import org.spongycastle.bcpg.SignatureSubpacketTags; import org.spongycastle.openpgp.PGPCompressedData; @@ -388,7 +387,7 @@ public class PgpDecryptVerify { PGPObjectFactory plainFact = new PGPObjectFactory(clear); Object dataChunk = plainFact.nextObject(); PGPOnePassSignature signature = null; - OpenPgpSignatureResult signatureResult = null; + OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder(); PGPPublicKey signatureKey = null; int signatureIndex = -1; boolean isSignatureKeyCertified = false; @@ -406,7 +405,8 @@ public class PgpDecryptVerify { if (dataChunk instanceof PGPOnePassSignatureList) { updateProgress(R.string.progress_processing_signature, currentProgress, 100); - signatureResult = new OpenPgpSignatureResult(); + signatureResultBuilder.signatureAvailable(true); + PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; // go through all signatures @@ -434,8 +434,11 @@ public class PgpDecryptVerify { } signature = sigList.get(signatureIndex); - signatureResult.setUserId(PgpKeyHelper.getMainUserId(signatureKey)); - signatureResult.setKeyId(signature.getKeyID()); + + signatureResultBuilder.knownKey(true); + signatureResultBuilder.userId(PgpKeyHelper.getMainUserId(signatureKey)); + signatureResultBuilder.keyId(signature.getKeyID()); + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); @@ -450,12 +453,11 @@ public class PgpDecryptVerify { isSignatureKeyCertified = ((Long) data > 0); } else { // no key in our database -> return "unknown pub key" status including the first key id + signatureResultBuilder.knownKey(false); + if (!sigList.isEmpty()) { - signatureResult.setKeyId(sigList.get(0).getKeyID()); + signatureResultBuilder.keyId(sigList.get(0).getKeyID()); } - - Log.d(Constants.TAG, "SIGNATURE_UNKNOWN_PUB_KEY"); - signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY); } dataChunk = plainFact.nextObject(); @@ -494,7 +496,7 @@ public class PgpDecryptVerify { signature.update(buffer, 0, n); } catch (SignatureException e) { Log.d(Constants.TAG, "SIGNATURE_ERROR"); - signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR); + signatureResultBuilder.validSignature(false); signature = null; } } @@ -519,15 +521,15 @@ public class PgpDecryptVerify { // these are not cleartext signatures! // TODO: what about binary signatures? - signatureResult.setSignatureOnly(false); + signatureResultBuilder.signatureOnly(false); // Verify signature and check binding signatures boolean validSignature = signature.verify(messageSignature); boolean validKeyBinding = verifyKeyBinding(messageSignature, signatureKey); - signatureResult.setStatus( - getSignatureResultStatus(validSignature, validKeyBinding, isSignatureKeyCertified) - ); + signatureResultBuilder.validSignature(validSignature); + signatureResultBuilder.validKeyBinding(validKeyBinding); + signatureResultBuilder.signatureKeyCertified(isSignatureKeyCertified); } } @@ -550,7 +552,7 @@ public class PgpDecryptVerify { updateProgress(R.string.progress_done, 100, 100); - result.setSignatureResult(signatureResult); + result.setSignatureResult(signatureResultBuilder.build()); return result; } @@ -564,9 +566,9 @@ public class PgpDecryptVerify { private PgpDecryptVerifyResult verifyCleartextSignature(ArmoredInputStream aIn) throws IOException, PGPException, SignatureException, InvalidDataException { PgpDecryptVerifyResult result = new PgpDecryptVerifyResult(); - OpenPgpSignatureResult signatureResult = new OpenPgpSignatureResult(); + OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder(); // cleartext signatures are never encrypted ;) - signatureResult.setSignatureOnly(true); + signatureResultBuilder.signatureOnly(true); ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -600,6 +602,8 @@ public class PgpDecryptVerify { throw new InvalidDataException(); } + signatureResultBuilder.signatureAvailable(true); + // go through all signatures // and find out for which signature we have a key in our database Long masterKeyId = null; @@ -630,8 +634,11 @@ public class PgpDecryptVerify { } signature = sigList.get(signatureIndex); - signatureResult.setUserId(PgpKeyHelper.getMainUserId(signatureKey)); - signatureResult.setKeyId(signature.getKeyID()); + + signatureResultBuilder.knownKey(true); + signatureResultBuilder.userId(PgpKeyHelper.getMainUserId(signatureKey)); + signatureResultBuilder.keyId(signature.getKeyID()); + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); @@ -646,12 +653,11 @@ public class PgpDecryptVerify { isSignatureKeyCertified = ((Long) data > 0); } else { // no key in our database -> return "unknown pub key" status including the first key id + signatureResultBuilder.knownKey(false); + if (!sigList.isEmpty()) { - signatureResult.setKeyId(sigList.get(0).getKeyID()); + signatureResultBuilder.keyId(sigList.get(0).getKeyID()); } - - Log.d(Constants.TAG, "SIGNATURE_UNKNOWN_PUB_KEY"); - signatureResult.setStatus(OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY); } if (signature != null) { @@ -684,41 +690,17 @@ public class PgpDecryptVerify { boolean validSignature = signature.verify(); boolean validKeyBinding = verifyKeyBinding(signature, signatureKey); - signatureResult.setStatus( - getSignatureResultStatus(validSignature, validKeyBinding, isSignatureKeyCertified) - ); + signatureResultBuilder.validSignature(validSignature); + signatureResultBuilder.validKeyBinding(validKeyBinding); + signatureResultBuilder.signatureKeyCertified(isSignatureKeyCertified); } - result.setSignatureResult(signatureResult); + result.setSignatureResult(signatureResultBuilder.build()); updateProgress(R.string.progress_done, 100, 100); 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; |