change security problem structure
This commit is contained in:
parent
10dfcb08fc
commit
c1ba764ce8
|
@ -19,16 +19,12 @@
|
|||
package org.sufficientlysecure.keychain.operations.results;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpDecryptionResult;
|
||||
import org.openintents.openpgp.OpenPgpMetadata;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.DecryptVerifySecurityProblem;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
||||
|
||||
|
@ -40,7 +36,7 @@ public class DecryptVerifyResult extends InputPendingResult {
|
|||
OpenPgpSignatureResult mSignatureResult;
|
||||
OpenPgpDecryptionResult mDecryptionResult;
|
||||
OpenPgpMetadata mDecryptionMetadata;
|
||||
ArrayList<SecurityProblem> mSecurityProblems;
|
||||
DecryptVerifySecurityProblem mSecurityProblem;
|
||||
|
||||
CryptoInputParcel mCachedCryptoInputParcel;
|
||||
|
||||
|
@ -73,7 +69,7 @@ public class DecryptVerifyResult extends InputPendingResult {
|
|||
mCachedCryptoInputParcel = source.readParcelable(CryptoInputParcel.class.getClassLoader());
|
||||
mSkippedDisallowedKeys = source.createLongArray();
|
||||
|
||||
mSecurityProblems = (ArrayList<SecurityProblem>) source.readSerializable();
|
||||
mSecurityProblem = (DecryptVerifySecurityProblem) source.readSerializable();
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,7 +133,7 @@ public class DecryptVerifyResult extends InputPendingResult {
|
|||
dest.writeParcelable(mCachedCryptoInputParcel, flags);
|
||||
dest.writeLongArray(mSkippedDisallowedKeys);
|
||||
|
||||
dest.writeSerializable(mSecurityProblems);
|
||||
dest.writeSerializable(mSecurityProblem);
|
||||
}
|
||||
|
||||
public static final Creator<DecryptVerifyResult> CREATOR = new Creator<DecryptVerifyResult>() {
|
||||
|
@ -150,28 +146,11 @@ public class DecryptVerifyResult extends InputPendingResult {
|
|||
}
|
||||
};
|
||||
|
||||
public void addSecurityProblem(SecurityProblem securityProblem) {
|
||||
if (securityProblem == null) {
|
||||
return;
|
||||
}
|
||||
if (mSecurityProblems == null) {
|
||||
mSecurityProblems = new ArrayList<>();
|
||||
}
|
||||
mSecurityProblems.add(securityProblem);
|
||||
public DecryptVerifySecurityProblem getSecurityProblem() {
|
||||
return mSecurityProblem;
|
||||
}
|
||||
|
||||
public void addSecurityProblems(List<SecurityProblem> securityProblems) {
|
||||
if (securityProblems == null) {
|
||||
return;
|
||||
}
|
||||
if (mSecurityProblems == null) {
|
||||
mSecurityProblems = new ArrayList<>();
|
||||
}
|
||||
mSecurityProblems.addAll(securityProblems);
|
||||
}
|
||||
|
||||
public List<SecurityProblem> getSecurityProblems() {
|
||||
return mSecurityProblems != null ?
|
||||
Collections.unmodifiableList(mSecurityProblems) : Collections.<SecurityProblem>emptyList();
|
||||
public void setSecurityProblemResult(DecryptVerifySecurityProblem securityProblem) {
|
||||
mSecurityProblem = securityProblem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureSigningAlgorithm;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.KeySecurityProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.EncryptionAlgorithmProblem;
|
||||
|
||||
|
||||
public class DecryptVerifySecurityProblem implements Serializable {
|
||||
public final KeySecurityProblem encryptionKeySecurityProblem;
|
||||
public final KeySecurityProblem signingKeySecurityProblem;
|
||||
public final EncryptionAlgorithmProblem symmetricSecurityProblem;
|
||||
public final InsecureSigningAlgorithm signatureSecurityProblem;
|
||||
|
||||
private DecryptVerifySecurityProblem(DecryptVerifySecurityProblemBuilder builder) {
|
||||
encryptionKeySecurityProblem = builder.encryptionKeySecurityProblem;
|
||||
signingKeySecurityProblem = builder.signingKeySecurityProblem;
|
||||
symmetricSecurityProblem = builder.symmetricSecurityProblem;
|
||||
signatureSecurityProblem = builder.signatureSecurityProblem;
|
||||
}
|
||||
|
||||
static class DecryptVerifySecurityProblemBuilder {
|
||||
private KeySecurityProblem encryptionKeySecurityProblem;
|
||||
private KeySecurityProblem signingKeySecurityProblem;
|
||||
private EncryptionAlgorithmProblem symmetricSecurityProblem;
|
||||
private InsecureSigningAlgorithm signatureSecurityProblem;
|
||||
|
||||
void addEncryptionKeySecurityProblem(KeySecurityProblem encryptionKeySecurityProblem) {
|
||||
this.encryptionKeySecurityProblem = encryptionKeySecurityProblem;
|
||||
}
|
||||
|
||||
void addSigningKeyProblem(KeySecurityProblem keySecurityProblem) {
|
||||
this.signingKeySecurityProblem = keySecurityProblem;
|
||||
}
|
||||
|
||||
void addSymmetricSecurityProblem(EncryptionAlgorithmProblem symmetricSecurityProblem) {
|
||||
this.symmetricSecurityProblem = symmetricSecurityProblem;
|
||||
}
|
||||
|
||||
void addSignatureSecurityProblem(InsecureSigningAlgorithm signatureSecurityProblem) {
|
||||
this.signatureSecurityProblem = signatureSecurityProblem;
|
||||
}
|
||||
|
||||
public DecryptVerifySecurityProblem build() {
|
||||
if (encryptionKeySecurityProblem == null && signingKeySecurityProblem == null &&
|
||||
symmetricSecurityProblem == null && signatureSecurityProblem == null) {
|
||||
return null;
|
||||
}
|
||||
return new DecryptVerifySecurityProblem(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,33 +17,20 @@
|
|||
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpDecryptionResult;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.SymmetricAlgorithmProblem;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
public class OpenPgpDecryptionResultBuilder {
|
||||
class OpenPgpDecryptionResultBuilder {
|
||||
|
||||
// builder
|
||||
private boolean isInsecure = false;
|
||||
private boolean isEncrypted = false;
|
||||
private byte[] sessionKey;
|
||||
private byte[] decryptedSessionKey;
|
||||
private ArrayList<SecurityProblem> securityProblems;
|
||||
|
||||
public void addSecurityProblem(SecurityProblem securityProblem) {
|
||||
if (securityProblems == null) {
|
||||
securityProblems = new ArrayList<>();
|
||||
}
|
||||
securityProblems.add(securityProblem);
|
||||
}
|
||||
|
||||
public List<SecurityProblem> getKeySecurityProblems() {
|
||||
return securityProblems != null ? Collections.unmodifiableList(securityProblems) : null;
|
||||
public void setInsecure(boolean insecure) {
|
||||
this.isInsecure = insecure;
|
||||
}
|
||||
|
||||
public void setEncrypted(boolean encrypted) {
|
||||
|
@ -51,15 +38,14 @@ public class OpenPgpDecryptionResultBuilder {
|
|||
}
|
||||
|
||||
public OpenPgpDecryptionResult build() {
|
||||
if (securityProblems != null && !securityProblems.isEmpty()) {
|
||||
if (isInsecure) {
|
||||
Log.d(Constants.TAG, "RESULT_INSECURE");
|
||||
return new OpenPgpDecryptionResult(OpenPgpDecryptionResult.RESULT_INSECURE, sessionKey, decryptedSessionKey);
|
||||
}
|
||||
|
||||
if (isEncrypted) {
|
||||
Log.d(Constants.TAG, "RESULT_ENCRYPTED");
|
||||
return new OpenPgpDecryptionResult(
|
||||
OpenPgpDecryptionResult.RESULT_ENCRYPTED, sessionKey, decryptedSessionKey);
|
||||
return new OpenPgpDecryptionResult(OpenPgpDecryptionResult.RESULT_ENCRYPTED, sessionKey, decryptedSessionKey);
|
||||
}
|
||||
|
||||
Log.d(Constants.TAG, "RESULT_NOT_ENCRYPTED");
|
||||
|
@ -67,12 +53,11 @@ public class OpenPgpDecryptionResultBuilder {
|
|||
}
|
||||
|
||||
|
||||
public void setSessionKey(byte[] sessionKey, byte[] decryptedSessionKey) {
|
||||
void setSessionKey(byte[] sessionKey, byte[] decryptedSessionKey) {
|
||||
if ((sessionKey == null) != (decryptedSessionKey == null)) {
|
||||
throw new AssertionError("sessionKey must be null iff decryptedSessionKey is null!");
|
||||
}
|
||||
this.sessionKey = sessionKey;
|
||||
this.decryptedSessionKey = decryptedSessionKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,9 +19,7 @@ package org.sufficientlysecure.keychain.pgp;
|
|||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.SenderStatusResult;
|
||||
|
@ -55,9 +53,9 @@ public class OpenPgpSignatureResultBuilder {
|
|||
private boolean mIsSignatureKeyCertified = false;
|
||||
private boolean mIsKeyRevoked = false;
|
||||
private boolean mIsKeyExpired = false;
|
||||
private boolean mInsecure = false;
|
||||
private String mSenderAddress;
|
||||
private Date mSignatureTimestamp;
|
||||
private ArrayList<SecurityProblem> mSecurityProblems;
|
||||
|
||||
public OpenPgpSignatureResultBuilder(KeyRepository keyRepository) {
|
||||
this.mKeyRepository = keyRepository;
|
||||
|
@ -83,15 +81,8 @@ public class OpenPgpSignatureResultBuilder {
|
|||
this.mValidSignature = validSignature;
|
||||
}
|
||||
|
||||
public void addSecurityProblem(SecurityProblem securityProblem) {
|
||||
if (mSecurityProblems == null) {
|
||||
mSecurityProblems = new ArrayList<>();
|
||||
}
|
||||
mSecurityProblems.add(securityProblem);
|
||||
}
|
||||
|
||||
public List<SecurityProblem> getSecurityProblems() {
|
||||
return mSecurityProblems != null ? Collections.unmodifiableList(mSecurityProblems) : null;
|
||||
public void setInsecure(boolean insecure) {
|
||||
this.mInsecure = insecure;
|
||||
}
|
||||
|
||||
public void setSignatureKeyCertified(boolean isSignatureKeyCertified) {
|
||||
|
@ -115,6 +106,10 @@ public class OpenPgpSignatureResultBuilder {
|
|||
this.mConfirmedUserIds = confirmedUserIds;
|
||||
}
|
||||
|
||||
public boolean isInsecure() {
|
||||
return mInsecure;
|
||||
}
|
||||
|
||||
public void initValid(CanonicalizedPublicKey signingKey) {
|
||||
setSignatureAvailable(true);
|
||||
setKnownKey(true);
|
||||
|
@ -189,7 +184,7 @@ public class OpenPgpSignatureResultBuilder {
|
|||
} else if (mIsKeyExpired) {
|
||||
Log.d(Constants.TAG, "RESULT_INVALID_KEY_EXPIRED");
|
||||
signatureStatus = OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED;
|
||||
} else if (mSecurityProblems != null && !mSecurityProblems.isEmpty()) {
|
||||
} else if (mInsecure) {
|
||||
Log.d(Constants.TAG, "RESULT_INVALID_INSECURE");
|
||||
signatureStatus = OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE;
|
||||
} else if (mIsSignatureKeyCertified) {
|
||||
|
|
|
@ -68,9 +68,11 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
|||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
|
||||
import org.sufficientlysecure.keychain.pgp.DecryptVerifySecurityProblem.DecryptVerifySecurityProblemBuilder;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureBitStrength;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.KeySecurityProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.MissingMdc;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.SymmetricAlgorithmProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.EncryptionAlgorithmProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
||||
|
@ -301,6 +303,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
JcaSkipMarkerPGPObjectFactory plainFact;
|
||||
Object dataChunk;
|
||||
EncryptStreamResult esResult = null;
|
||||
DecryptVerifySecurityProblemBuilder securityProblemBuilder = new DecryptVerifySecurityProblemBuilder();
|
||||
{ // resolve encrypted (symmetric and asymmetric) packets
|
||||
JcaSkipMarkerPGPObjectFactory pgpF = new JcaSkipMarkerPGPObjectFactory(in);
|
||||
Object obj = pgpF.nextObject();
|
||||
|
@ -322,15 +325,17 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
|
||||
if (esResult.encryptionKeySecurityProblem != null) {
|
||||
log.add(LogType.MSG_DC_INSECURE_SYMMETRIC_ENCRYPTION_ALGO, indent + 1);
|
||||
decryptionResultBuilder.addSecurityProblem(esResult.encryptionKeySecurityProblem);
|
||||
securityProblemBuilder.addEncryptionKeySecurityProblem(esResult.encryptionKeySecurityProblem);
|
||||
decryptionResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
// Check for insecure encryption algorithms!
|
||||
SymmetricAlgorithmProblem symmetricSecurityProblem =
|
||||
EncryptionAlgorithmProblem symmetricSecurityProblem =
|
||||
PgpSecurityConstants.checkSecureSymmetricAlgorithm(esResult.symmetricEncryptionAlgo);
|
||||
if (symmetricSecurityProblem != null) {
|
||||
log.add(LogType.MSG_DC_INSECURE_SYMMETRIC_ENCRYPTION_ALGO, indent + 1);
|
||||
decryptionResultBuilder.addSecurityProblem(symmetricSecurityProblem);
|
||||
securityProblemBuilder.addSymmetricSecurityProblem(symmetricSecurityProblem);
|
||||
decryptionResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
plainFact = new JcaSkipMarkerPGPObjectFactory(esResult.cleartextStream);
|
||||
|
@ -361,7 +366,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
plainFact = fact;
|
||||
}
|
||||
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mKeyRepository, input.getSenderAddress());
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(
|
||||
mKeyRepository, input.getSenderAddress(), securityProblemBuilder);
|
||||
if (signatureChecker.initializeOnePassSignature(dataChunk, log, indent +1)) {
|
||||
dataChunk = plainFact.nextObject();
|
||||
}
|
||||
|
@ -536,7 +542,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
// Handle missing integrity protection like failed integrity protection!
|
||||
// The MDC packet can be stripped by an attacker!
|
||||
log.add(LogType.MSG_DC_INSECURE_MDC_MISSING, indent);
|
||||
decryptionResultBuilder.addSecurityProblem(new MissingMdc());
|
||||
securityProblemBuilder.addSymmetricSecurityProblem(new MissingMdc());
|
||||
decryptionResultBuilder.setInsecure(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,8 +556,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
result.setCachedCryptoInputParcel(cryptoInput);
|
||||
result.setSignatureResult(signatureChecker.getSignatureResult());
|
||||
result.setDecryptionResult(decryptionResultBuilder.build());
|
||||
result.addSecurityProblems(signatureChecker.getSecurityProblems());
|
||||
result.addSecurityProblems(decryptionResultBuilder.getKeySecurityProblems());
|
||||
result.setSecurityProblemResult(securityProblemBuilder.build());
|
||||
result.setDecryptionMetadata(metadata);
|
||||
result.mOperationTime = opTime;
|
||||
|
||||
|
@ -888,7 +894,9 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
updateProgress(R.string.progress_processing_signature, 60, 100);
|
||||
JcaSkipMarkerPGPObjectFactory pgpFact = new JcaSkipMarkerPGPObjectFactory(aIn);
|
||||
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mKeyRepository, input.getSenderAddress());
|
||||
DecryptVerifySecurityProblemBuilder securityProblemBuilder = new DecryptVerifySecurityProblemBuilder();
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mKeyRepository, input.getSenderAddress(),
|
||||
securityProblemBuilder);
|
||||
|
||||
Object o = pgpFact.nextObject();
|
||||
if (!signatureChecker.initializeSignature(o, log, indent+1)) {
|
||||
|
@ -919,6 +927,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
result.setSignatureResult(signatureChecker.getSignatureResult());
|
||||
result.setDecryptionResult(
|
||||
new OpenPgpDecryptionResult(OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED));
|
||||
result.setSecurityProblemResult(securityProblemBuilder.build());
|
||||
result.setDecryptionMetadata(metadata);
|
||||
return result;
|
||||
}
|
||||
|
@ -943,7 +952,9 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
o = pgpFact.nextObject();
|
||||
}
|
||||
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mKeyRepository, input.getSenderAddress());
|
||||
DecryptVerifySecurityProblemBuilder securityProblemBuilder = new DecryptVerifySecurityProblemBuilder();
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mKeyRepository, input.getSenderAddress(),
|
||||
securityProblemBuilder);
|
||||
|
||||
if ( ! signatureChecker.initializeSignature(o, log, indent+1)) {
|
||||
log.add(LogType.MSG_DC_ERROR_INVALID_DATA, 0);
|
||||
|
@ -994,6 +1005,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
|
||||
DecryptVerifyResult result = new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
|
||||
result.setSignatureResult(signatureChecker.getSignatureResult());
|
||||
result.setSecurityProblemResult(securityProblemBuilder.build());
|
||||
result.setDecryptionResult(
|
||||
new OpenPgpDecryptionResult(OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED));
|
||||
return result;
|
||||
|
|
|
@ -31,11 +31,11 @@ import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
|
|||
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.bouncycastle.crypto.ec.CustomNamedCurves;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureBitStrength;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureHashAlgorithm;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureSymmetricAlgorithm;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureSigningAlgorithm;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureEncryptionAlgorithm;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.KeySecurityProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.NotWhitelistedCurve;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.SymmetricAlgorithmProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.EncryptionAlgorithmProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.UnidentifiedKeyProblem;
|
||||
|
||||
|
||||
|
@ -74,9 +74,9 @@ public class PgpSecurityConstants {
|
|||
// CAMELLIA_256: not used widely
|
||||
));
|
||||
|
||||
public static SymmetricAlgorithmProblem checkSecureSymmetricAlgorithm(int id) {
|
||||
public static EncryptionAlgorithmProblem checkSecureSymmetricAlgorithm(int id) {
|
||||
if (!sSymmetricAlgorithmsWhitelist.contains(id)) {
|
||||
return new InsecureSymmetricAlgorithm(id);
|
||||
return new InsecureEncryptionAlgorithm(id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -107,9 +107,9 @@ public class PgpSecurityConstants {
|
|||
// SHA224: Not used widely, Yahoo argues against it
|
||||
));
|
||||
|
||||
public static InsecureHashAlgorithm checkSignatureAlgorithmForSecurityProblems(int hashAlgorithm) {
|
||||
static InsecureSigningAlgorithm checkSignatureAlgorithmForSecurityProblems(int hashAlgorithm) {
|
||||
if (!sHashAlgorithmsWhitelist.contains(hashAlgorithm)) {
|
||||
return new InsecureHashAlgorithm(hashAlgorithm);
|
||||
return new InsecureSigningAlgorithm(hashAlgorithm);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.SignatureException;
|
||||
import java.util.List;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPOnePassSignature;
|
||||
|
@ -37,11 +36,12 @@ import org.openintents.openpgp.OpenPgpSignatureResult;
|
|||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureHashAlgorithm;
|
||||
import org.sufficientlysecure.keychain.pgp.DecryptVerifySecurityProblem.DecryptVerifySecurityProblemBuilder;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.InsecureSigningAlgorithm;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem.KeySecurityProblem;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
||||
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
|
||||
|
@ -52,20 +52,24 @@ import org.sufficientlysecure.keychain.util.Log;
|
|||
class PgpSignatureChecker {
|
||||
|
||||
private final OpenPgpSignatureResultBuilder signatureResultBuilder;
|
||||
private final DecryptVerifySecurityProblemBuilder securityProblemBuilder;
|
||||
|
||||
private CanonicalizedPublicKey signingKey;
|
||||
|
||||
private int signatureIndex;
|
||||
PGPOnePassSignature onePassSignature;
|
||||
PGPSignature signature;
|
||||
private PGPOnePassSignature onePassSignature;
|
||||
private PGPSignature signature;
|
||||
|
||||
KeyRepository mKeyRepository;
|
||||
private KeyRepository mKeyRepository;
|
||||
|
||||
PgpSignatureChecker(KeyRepository keyRepository, String senderAddress) {
|
||||
PgpSignatureChecker(KeyRepository keyRepository, String senderAddress,
|
||||
DecryptVerifySecurityProblemBuilder securityProblemBuilder) {
|
||||
mKeyRepository = keyRepository;
|
||||
|
||||
signatureResultBuilder = new OpenPgpSignatureResultBuilder(keyRepository);
|
||||
signatureResultBuilder.setSenderAddress(senderAddress);
|
||||
|
||||
this.securityProblemBuilder = securityProblemBuilder;
|
||||
}
|
||||
|
||||
boolean initializeSignature(Object dataChunk, OperationLog log, int indent) throws PGPException {
|
||||
|
@ -142,11 +146,12 @@ class PgpSignatureChecker {
|
|||
PgpSecurityConstants.checkForSecurityProblems(signingKey);
|
||||
if (keySecurityProblem != null) {
|
||||
log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1);
|
||||
signatureResultBuilder.addSecurityProblem(keySecurityProblem);
|
||||
securityProblemBuilder.addSigningKeyProblem(keySecurityProblem);
|
||||
signatureResultBuilder.setInsecure(true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
boolean isInitialized() {
|
||||
return signingKey != null;
|
||||
}
|
||||
|
||||
|
@ -173,7 +178,7 @@ class PgpSignatureChecker {
|
|||
}
|
||||
}
|
||||
|
||||
public void findAvailableSignature(PGPSignatureList sigList) {
|
||||
private void findAvailableSignature(PGPSignatureList sigList) {
|
||||
// go through all signatures (should be just one), make sure we have
|
||||
// the key and it matches the one we’re looking for
|
||||
for (int i = 0; i < sigList.size(); ++i) {
|
||||
|
@ -238,11 +243,12 @@ class PgpSignatureChecker {
|
|||
}
|
||||
|
||||
// check for insecure hash algorithms
|
||||
InsecureHashAlgorithm signatureSecurityProblem =
|
||||
InsecureSigningAlgorithm signatureSecurityProblem =
|
||||
PgpSecurityConstants.checkSignatureAlgorithmForSecurityProblems(signature.getHashAlgorithm());
|
||||
if (signatureSecurityProblem != null) {
|
||||
log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1);
|
||||
signatureResultBuilder.addSecurityProblem(signatureSecurityProblem);
|
||||
securityProblemBuilder.addSignatureSecurityProblem(signatureSecurityProblem);
|
||||
signatureResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
signatureResultBuilder.setSignatureTimestamp(signature.getCreationTime());
|
||||
|
@ -275,11 +281,12 @@ class PgpSignatureChecker {
|
|||
}
|
||||
|
||||
// check for insecure hash algorithms
|
||||
InsecureHashAlgorithm signatureSecurityProblem =
|
||||
InsecureSigningAlgorithm signatureSecurityProblem =
|
||||
PgpSecurityConstants.checkSignatureAlgorithmForSecurityProblems(onePassSignature.getHashAlgorithm());
|
||||
if (signatureSecurityProblem != null) {
|
||||
log.add(LogType.MSG_DC_INSECURE_HASH_ALGO, indent + 1);
|
||||
signatureResultBuilder.addSecurityProblem(signatureSecurityProblem);
|
||||
securityProblemBuilder.addSignatureSecurityProblem(signatureSecurityProblem);
|
||||
signatureResultBuilder.setInsecure(true);
|
||||
}
|
||||
|
||||
signatureResultBuilder.setSignatureTimestamp(messageSignature.getCreationTime());
|
||||
|
@ -297,10 +304,6 @@ class PgpSignatureChecker {
|
|||
return signatureResultBuilder.build();
|
||||
}
|
||||
|
||||
public List<SecurityProblem> getSecurityProblems() {
|
||||
return signatureResultBuilder.getSecurityProblems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostly taken from ClearSignedFileProcessor in Bouncy Castle
|
||||
*/
|
||||
|
|
|
@ -34,7 +34,7 @@ public abstract class SecurityProblem implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public static abstract class SymmetricAlgorithmProblem extends SecurityProblem {
|
||||
public static abstract class EncryptionAlgorithmProblem extends SecurityProblem {
|
||||
|
||||
}
|
||||
|
||||
|
@ -62,23 +62,23 @@ public abstract class SecurityProblem implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public static class InsecureHashAlgorithm extends SecurityProblem {
|
||||
public static class InsecureSigningAlgorithm extends SecurityProblem {
|
||||
public final int hashAlgorithm;
|
||||
|
||||
InsecureHashAlgorithm(int hashAlgorithm) {
|
||||
InsecureSigningAlgorithm(int hashAlgorithm) {
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InsecureSymmetricAlgorithm extends SymmetricAlgorithmProblem {
|
||||
public static class InsecureEncryptionAlgorithm extends EncryptionAlgorithmProblem {
|
||||
public final int symmetricAlgorithm;
|
||||
|
||||
InsecureSymmetricAlgorithm(int symmetricAlgorithm) {
|
||||
InsecureEncryptionAlgorithm(int symmetricAlgorithm) {
|
||||
this.symmetricAlgorithm = symmetricAlgorithm;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MissingMdc extends SymmetricAlgorithmProblem {
|
||||
public static class MissingMdc extends EncryptionAlgorithmProblem {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.DecryptVerifySecurityProblem;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.remote.ui.RemoteBackupActivity;
|
||||
import org.sufficientlysecure.keychain.remote.ui.RemoteErrorActivity;
|
||||
|
@ -143,10 +143,10 @@ public class ApiPendingIntentFactory {
|
|||
return createInternal(data, intent);
|
||||
}
|
||||
|
||||
PendingIntent createSecurityProblemIntent(String packageName, SecurityProblem keySecurityProblem) {
|
||||
PendingIntent createSecurityProblemIntent(String packageName, DecryptVerifySecurityProblem securityProblem) {
|
||||
Intent intent = new Intent(mContext, RemoteSecurityProblemDialogActivity.class);
|
||||
intent.putExtra(RemoteSecurityProblemDialogActivity.EXTRA_PACKAGE_NAME, packageName);
|
||||
intent.putExtra(RemoteSecurityProblemDialogActivity.EXTRA_SECURITY_PROBLEM, keySecurityProblem);
|
||||
intent.putExtra(RemoteSecurityProblemDialogActivity.EXTRA_SECURITY_PROBLEM, securityProblem);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
//noinspection ResourceType, looks like lint is missing FLAG_IMMUTABLE
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.sufficientlysecure.keychain.operations.results.ExportResult;
|
|||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
|
||||
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.DecryptVerifySecurityProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants;
|
||||
|
@ -60,7 +61,6 @@ import org.sufficientlysecure.keychain.pgp.PgpSignEncryptData;
|
|||
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.SecurityProblem;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.ApiDataAccessObject;
|
||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
||||
|
@ -430,17 +430,14 @@ public class OpenPgpService extends Service {
|
|||
}
|
||||
|
||||
private void processSecurityProblemsPendingIntent(Intent result, DecryptVerifyResult decryptVerifyResult) {
|
||||
List<SecurityProblem> securityProblems = decryptVerifyResult.getSecurityProblems();
|
||||
if (securityProblems.isEmpty()) {
|
||||
DecryptVerifySecurityProblem securityProblem = decryptVerifyResult.getSecurityProblem();
|
||||
if (securityProblem == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO what if there is multiple?
|
||||
SecurityProblem keySecurityProblem = securityProblems.get(0);
|
||||
|
||||
String packageName = mApiPermissionHelper.getCurrentCallingPackage();
|
||||
result.putExtra(OpenPgpApi.RESULT_INSECURE_DETAIL_INTENT,
|
||||
mApiPendingIntentFactory.createSecurityProblemIntent(packageName, keySecurityProblem));
|
||||
mApiPendingIntentFactory.createSecurityProblemIntent(packageName, securityProblem));
|
||||
}
|
||||
|
||||
private void processDecryptionResultForResultIntent(int targetApiVersion, Intent result,
|
||||
|
|
|
@ -18,6 +18,15 @@
|
|||
|
||||
package org.sufficientlysecure.keychain.ui.util;
|
||||
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.DigestException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
|
@ -48,14 +57,6 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
|||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.DigestException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
public class KeyFormattingUtils {
|
||||
|
||||
public static String getAlgorithmInfo(int algorithm, Integer keySize, String oid) {
|
||||
|
|
Loading…
Reference in a new issue