mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-12-25 00:18:51 -05:00
Experimental support for revoked, expired keys with signatures
This commit is contained in:
parent
40e6b24b14
commit
a64443e71f
@ -21,6 +21,8 @@ import org.openintents.openpgp.OpenPgpSignatureResult;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class can be used to build OpenPgpSignatureResult objects based on several checks.
|
* 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.
|
* It serves as a constraint which information are returned inside an OpenPgpSignatureResult object.
|
||||||
@ -28,7 +30,8 @@ import org.sufficientlysecure.keychain.util.Log;
|
|||||||
public class OpenPgpSignatureResultBuilder {
|
public class OpenPgpSignatureResultBuilder {
|
||||||
// OpenPgpSignatureResult
|
// OpenPgpSignatureResult
|
||||||
private boolean mSignatureOnly = false;
|
private boolean mSignatureOnly = false;
|
||||||
private String mUserId;
|
private String mPrimaryUserId;
|
||||||
|
private ArrayList<String> mUserIds = new ArrayList<String>();
|
||||||
private long mKeyId;
|
private long mKeyId;
|
||||||
|
|
||||||
// builder
|
// builder
|
||||||
@ -36,35 +39,49 @@ public class OpenPgpSignatureResultBuilder {
|
|||||||
private boolean mKnownKey = false;
|
private boolean mKnownKey = false;
|
||||||
private boolean mValidSignature = false;
|
private boolean mValidSignature = false;
|
||||||
private boolean mIsSignatureKeyCertified = false;
|
private boolean mIsSignatureKeyCertified = false;
|
||||||
|
private boolean mIsKeyRevoked = false;
|
||||||
|
private boolean mIsKeyExpired = false;
|
||||||
|
|
||||||
public void signatureOnly(boolean signatureOnly) {
|
public void setSignatureOnly(boolean signatureOnly) {
|
||||||
this.mSignatureOnly = signatureOnly;
|
this.mSignatureOnly = signatureOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void userId(String userId) {
|
public void setPrimaryUserId(String userId) {
|
||||||
this.mUserId = userId;
|
this.mPrimaryUserId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void keyId(long keyId) {
|
public void setKeyId(long keyId) {
|
||||||
this.mKeyId = keyId;
|
this.mKeyId = keyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void knownKey(boolean knownKey) {
|
public void setKnownKey(boolean knownKey) {
|
||||||
this.mKnownKey = knownKey;
|
this.mKnownKey = knownKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validSignature(boolean validSignature) {
|
public void setValidSignature(boolean validSignature) {
|
||||||
this.mValidSignature = validSignature;
|
this.mValidSignature = validSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void signatureKeyCertified(boolean isSignatureKeyCertified) {
|
public void setSignatureKeyCertified(boolean isSignatureKeyCertified) {
|
||||||
this.mIsSignatureKeyCertified = isSignatureKeyCertified;
|
this.mIsSignatureKeyCertified = isSignatureKeyCertified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void signatureAvailable(boolean signatureAvailable) {
|
public void setSignatureAvailable(boolean signatureAvailable) {
|
||||||
this.mSignatureAvailable = signatureAvailable;
|
this.mSignatureAvailable = signatureAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setKeyRevoked(boolean keyRevoked) {
|
||||||
|
this.mIsKeyRevoked = keyRevoked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyExpired(boolean keyExpired) {
|
||||||
|
this.mIsKeyExpired = keyExpired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserIds(ArrayList<String> userIds) {
|
||||||
|
this.mUserIds = userIds;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isValidSignature() {
|
public boolean isValidSignature() {
|
||||||
return mValidSignature;
|
return mValidSignature;
|
||||||
}
|
}
|
||||||
@ -78,9 +95,16 @@ public class OpenPgpSignatureResultBuilder {
|
|||||||
if (mKnownKey) {
|
if (mKnownKey) {
|
||||||
if (mValidSignature) {
|
if (mValidSignature) {
|
||||||
result.setKeyId(mKeyId);
|
result.setKeyId(mKeyId);
|
||||||
result.setPrimaryUserId(mUserId);
|
result.setPrimaryUserId(mPrimaryUserId);
|
||||||
|
result.setUserIds(mUserIds);
|
||||||
|
|
||||||
if (mIsSignatureKeyCertified) {
|
if (mIsKeyRevoked) {
|
||||||
|
Log.d(Constants.TAG, "SIGNATURE_KEY_REVOKED");
|
||||||
|
result.setStatus(OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED);
|
||||||
|
} else if (mIsKeyExpired) {
|
||||||
|
Log.d(Constants.TAG, "SIGNATURE_KEY_EXPIRED");
|
||||||
|
result.setStatus(OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED);
|
||||||
|
} else if (mIsSignatureKeyCertified) {
|
||||||
Log.d(Constants.TAG, "SIGNATURE_SUCCESS_CERTIFIED");
|
Log.d(Constants.TAG, "SIGNATURE_SUCCESS_CERTIFIED");
|
||||||
result.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED);
|
result.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED);
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,6 +38,7 @@ import org.spongycastle.openpgp.PGPUtil;
|
|||||||
import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory;
|
import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory;
|
||||||
import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider;
|
import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider;
|
||||||
import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||||
|
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||||
import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;
|
import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;
|
||||||
@ -46,7 +47,6 @@ import org.sufficientlysecure.keychain.R;
|
|||||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||||
@ -226,7 +226,7 @@ public class PgpDecryptVerify {
|
|||||||
InvalidDataException, IntegrityCheckFailedException {
|
InvalidDataException, IntegrityCheckFailedException {
|
||||||
PgpDecryptVerifyResult result = new PgpDecryptVerifyResult();
|
PgpDecryptVerifyResult result = new PgpDecryptVerifyResult();
|
||||||
|
|
||||||
PGPObjectFactory pgpF = new PGPObjectFactory(in);
|
PGPObjectFactory pgpF = new PGPObjectFactory(in, new JcaKeyFingerprintCalculator());
|
||||||
PGPEncryptedDataList enc;
|
PGPEncryptedDataList enc;
|
||||||
Object o = pgpF.nextObject();
|
Object o = pgpF.nextObject();
|
||||||
|
|
||||||
@ -377,7 +377,7 @@ public class PgpDecryptVerify {
|
|||||||
throw new NoSecretKeyException();
|
throw new NoSecretKeyException();
|
||||||
}
|
}
|
||||||
|
|
||||||
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
|
PGPObjectFactory plainFact = new PGPObjectFactory(clear, new JcaKeyFingerprintCalculator());
|
||||||
Object dataChunk = plainFact.nextObject();
|
Object dataChunk = plainFact.nextObject();
|
||||||
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
|
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
|
||||||
int signatureIndex = -1;
|
int signatureIndex = -1;
|
||||||
@ -390,7 +390,7 @@ public class PgpDecryptVerify {
|
|||||||
|
|
||||||
PGPCompressedData compressedData = (PGPCompressedData) dataChunk;
|
PGPCompressedData compressedData = (PGPCompressedData) dataChunk;
|
||||||
|
|
||||||
PGPObjectFactory fact = new PGPObjectFactory(compressedData.getDataStream());
|
PGPObjectFactory fact = new PGPObjectFactory(compressedData.getDataStream(), new JcaKeyFingerprintCalculator());
|
||||||
dataChunk = fact.nextObject();
|
dataChunk = fact.nextObject();
|
||||||
plainFact = fact;
|
plainFact = fact;
|
||||||
}
|
}
|
||||||
@ -421,15 +421,18 @@ public class PgpDecryptVerify {
|
|||||||
// key found in our database!
|
// key found in our database!
|
||||||
signature = sigList.get(signatureIndex);
|
signature = sigList.get(signatureIndex);
|
||||||
|
|
||||||
signatureResultBuilder.signatureAvailable(true);
|
signatureResultBuilder.setSignatureAvailable(true);
|
||||||
signatureResultBuilder.knownKey(true);
|
signatureResultBuilder.setKnownKey(true);
|
||||||
signatureResultBuilder.keyId(signingRing.getMasterKeyId());
|
signatureResultBuilder.setKeyId(signingRing.getMasterKeyId());
|
||||||
try {
|
try {
|
||||||
signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback());
|
signatureResultBuilder.setPrimaryUserId(signingRing.getPrimaryUserIdWithFallback());
|
||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No primary user id in keyring with master key id " + signingRing.getMasterKeyId());
|
Log.d(Constants.TAG, "No primary user id in keyring with master key id " + signingRing.getMasterKeyId());
|
||||||
}
|
}
|
||||||
signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0);
|
signatureResultBuilder.setSignatureKeyCertified(signingRing.getVerified() > 0);
|
||||||
|
signatureResultBuilder.setKeyExpired(signingKey.isExpired());
|
||||||
|
signatureResultBuilder.setKeyRevoked(signingKey.isRevoked());
|
||||||
|
signatureResultBuilder.setUserIds(signingKey.getUnorderedUserIds());
|
||||||
|
|
||||||
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
|
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
|
||||||
new JcaPGPContentVerifierBuilderProvider()
|
new JcaPGPContentVerifierBuilderProvider()
|
||||||
@ -438,9 +441,9 @@ public class PgpDecryptVerify {
|
|||||||
} else {
|
} else {
|
||||||
// no key in our database -> return "unknown 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()) {
|
if (!sigList.isEmpty()) {
|
||||||
signatureResultBuilder.signatureAvailable(true);
|
signatureResultBuilder.setSignatureAvailable(true);
|
||||||
signatureResultBuilder.knownKey(false);
|
signatureResultBuilder.setKnownKey(false);
|
||||||
signatureResultBuilder.keyId(sigList.get(0).getKeyID());
|
signatureResultBuilder.setKeyId(sigList.get(0).getKeyID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,11 +550,11 @@ public class PgpDecryptVerify {
|
|||||||
|
|
||||||
// these are not cleartext signatures!
|
// these are not cleartext signatures!
|
||||||
// TODO: what about binary signatures?
|
// TODO: what about binary signatures?
|
||||||
signatureResultBuilder.signatureOnly(false);
|
signatureResultBuilder.setSignatureOnly(false);
|
||||||
|
|
||||||
// Verify signature and check binding signatures
|
// Verify signature and check binding signatures
|
||||||
boolean validSignature = signature.verify(messageSignature);
|
boolean validSignature = signature.verify(messageSignature);
|
||||||
signatureResultBuilder.validSignature(validSignature);
|
signatureResultBuilder.setValidSignature(validSignature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +599,7 @@ public class PgpDecryptVerify {
|
|||||||
PgpDecryptVerifyResult result = new PgpDecryptVerifyResult();
|
PgpDecryptVerifyResult result = new PgpDecryptVerifyResult();
|
||||||
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
|
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
|
||||||
// cleartext signatures are never encrypted ;)
|
// cleartext signatures are never encrypted ;)
|
||||||
signatureResultBuilder.signatureOnly(true);
|
signatureResultBuilder.setSignatureOnly(true);
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
|
||||||
@ -623,7 +626,7 @@ public class PgpDecryptVerify {
|
|||||||
mOutStream.write(clearText);
|
mOutStream.write(clearText);
|
||||||
|
|
||||||
updateProgress(R.string.progress_processing_signature, 60, 100);
|
updateProgress(R.string.progress_processing_signature, 60, 100);
|
||||||
PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
|
PGPObjectFactory pgpFact = new PGPObjectFactory(aIn, new JcaKeyFingerprintCalculator());
|
||||||
|
|
||||||
PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
|
PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
|
||||||
if (sigList == null) {
|
if (sigList == null) {
|
||||||
@ -655,15 +658,18 @@ public class PgpDecryptVerify {
|
|||||||
// key found in our database!
|
// key found in our database!
|
||||||
signature = sigList.get(signatureIndex);
|
signature = sigList.get(signatureIndex);
|
||||||
|
|
||||||
signatureResultBuilder.signatureAvailable(true);
|
signatureResultBuilder.setSignatureAvailable(true);
|
||||||
signatureResultBuilder.knownKey(true);
|
signatureResultBuilder.setKnownKey(true);
|
||||||
signatureResultBuilder.keyId(signingRing.getMasterKeyId());
|
signatureResultBuilder.setKeyId(signingRing.getMasterKeyId());
|
||||||
try {
|
try {
|
||||||
signatureResultBuilder.userId(signingRing.getPrimaryUserIdWithFallback());
|
signatureResultBuilder.setPrimaryUserId(signingRing.getPrimaryUserIdWithFallback());
|
||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.d(Constants.TAG, "No primary user id in key with master key id " + signingRing.getMasterKeyId());
|
Log.d(Constants.TAG, "No primary user id in key with master key id " + signingRing.getMasterKeyId());
|
||||||
}
|
}
|
||||||
signatureResultBuilder.signatureKeyCertified(signingRing.getVerified() > 0);
|
signatureResultBuilder.setSignatureKeyCertified(signingRing.getVerified() > 0);
|
||||||
|
signatureResultBuilder.setKeyExpired(signingKey.isExpired());
|
||||||
|
signatureResultBuilder.setKeyRevoked(signingKey.isRevoked());
|
||||||
|
signatureResultBuilder.setUserIds(signingKey.getUnorderedUserIds());
|
||||||
|
|
||||||
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
|
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
|
||||||
new JcaPGPContentVerifierBuilderProvider()
|
new JcaPGPContentVerifierBuilderProvider()
|
||||||
@ -672,9 +678,9 @@ public class PgpDecryptVerify {
|
|||||||
} else {
|
} else {
|
||||||
// no key in our database -> return "unknown 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()) {
|
if (!sigList.isEmpty()) {
|
||||||
signatureResultBuilder.signatureAvailable(true);
|
signatureResultBuilder.setSignatureAvailable(true);
|
||||||
signatureResultBuilder.knownKey(false);
|
signatureResultBuilder.setKnownKey(false);
|
||||||
signatureResultBuilder.keyId(sigList.get(0).getKeyID());
|
signatureResultBuilder.setKeyId(sigList.get(0).getKeyID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,7 +707,7 @@ public class PgpDecryptVerify {
|
|||||||
// Verify signature and check binding signatures
|
// Verify signature and check binding signatures
|
||||||
boolean validSignature = signature.verify();
|
boolean validSignature = signature.verify();
|
||||||
|
|
||||||
signatureResultBuilder.validSignature(validSignature);
|
signatureResultBuilder.setValidSignature(validSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.setSignatureResult(signatureResultBuilder.build());
|
result.setSignatureResult(signatureResultBuilder.build());
|
||||||
|
Loading…
Reference in New Issue
Block a user