service: support sender address status and list of confirmed user ids to OpenPgpSignatureResult
This commit is contained in:
parent
24b92172be
commit
88b0903bf5
|
@ -17,22 +17,30 @@
|
|||
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
// injected
|
||||
private final ProviderHelper mProviderHelper;
|
||||
|
||||
// OpenPgpSignatureResult
|
||||
private String mPrimaryUserId;
|
||||
private ArrayList<String> mUserIds = new ArrayList<>();
|
||||
private ArrayList<String> mConfirmedUserIds;
|
||||
private long mKeyId;
|
||||
private int mSenderStatus;
|
||||
|
||||
// builder
|
||||
private boolean mSignatureAvailable = false;
|
||||
|
@ -42,6 +50,11 @@ public class OpenPgpSignatureResultBuilder {
|
|||
private boolean mIsKeyRevoked = false;
|
||||
private boolean mIsKeyExpired = false;
|
||||
private boolean mInsecure = false;
|
||||
private String mSenderAddress;
|
||||
|
||||
public OpenPgpSignatureResultBuilder(ProviderHelper providerHelper) {
|
||||
this.mProviderHelper = providerHelper;
|
||||
}
|
||||
|
||||
public void setPrimaryUserId(String userId) {
|
||||
this.mPrimaryUserId = userId;
|
||||
|
@ -79,8 +92,9 @@ public class OpenPgpSignatureResultBuilder {
|
|||
this.mIsKeyExpired = keyExpired;
|
||||
}
|
||||
|
||||
public void setUserIds(ArrayList<String> userIds) {
|
||||
public void setUserIds(ArrayList<String> userIds, ArrayList<String> confirmedUserIds) {
|
||||
this.mUserIds = userIds;
|
||||
this.mConfirmedUserIds = confirmedUserIds;
|
||||
}
|
||||
|
||||
public boolean isValidSignature() {
|
||||
|
@ -105,8 +119,27 @@ public class OpenPgpSignatureResultBuilder {
|
|||
Log.d(Constants.TAG, "No primary user id in keyring with master key id " + signingRing.getMasterKeyId());
|
||||
}
|
||||
setSignatureKeyCertified(signingRing.getVerified() > 0);
|
||||
Log.d(Constants.TAG, "signingRing.getUnorderedUserIds(): " + signingRing.getUnorderedUserIds());
|
||||
setUserIds(signingRing.getUnorderedUserIds());
|
||||
|
||||
try {
|
||||
ArrayList<String> allUserIds = signingRing.getUnorderedUserIds();
|
||||
ArrayList<String> confirmedUserIds = mProviderHelper.getConfirmedUserIds(signingRing.getMasterKeyId());
|
||||
setUserIds(allUserIds, confirmedUserIds);
|
||||
|
||||
if (mSenderAddress != null) {
|
||||
if (confirmedUserIds.contains(mSenderAddress)) {
|
||||
setSenderStatus(OpenPgpSignatureResult.SENDER_RESULT_CONFIRMED);
|
||||
} else if (allUserIds.contains(mSenderAddress)) {
|
||||
setSenderStatus(OpenPgpSignatureResult.SENDER_RESULT_UNCONFIRMED);
|
||||
} else {
|
||||
setSenderStatus(OpenPgpSignatureResult.SENDER_RESULT_MISSING);
|
||||
}
|
||||
} else {
|
||||
setSenderStatus(OpenPgpSignatureResult.SENDER_RESULT_NO_SENDER);
|
||||
}
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
throw new IllegalStateException("Key didn't exist anymore for user id query!", e);
|
||||
}
|
||||
|
||||
// either master key is expired/revoked or this specific subkey is expired/revoked
|
||||
setKeyExpired(signingRing.isExpired() || signingKey.isExpired());
|
||||
|
@ -139,6 +172,8 @@ public class OpenPgpSignatureResultBuilder {
|
|||
result.setKeyId(mKeyId);
|
||||
result.setPrimaryUserId(mPrimaryUserId);
|
||||
result.setUserIds(mUserIds);
|
||||
result.setConfirmedUserIds(mConfirmedUserIds);
|
||||
result.setSenderResult(mSenderStatus);
|
||||
|
||||
if (mIsKeyRevoked) {
|
||||
Log.d(Constants.TAG, "RESULT_INVALID_KEY_REVOKED");
|
||||
|
@ -160,5 +195,11 @@ public class OpenPgpSignatureResultBuilder {
|
|||
return result;
|
||||
}
|
||||
|
||||
public void setSenderAddress(String senderAddress) {
|
||||
mSenderAddress = senderAddress;
|
||||
}
|
||||
|
||||
public void setSenderStatus(int senderStatus) {
|
||||
mSenderStatus = senderStatus;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ public class PgpDecryptVerifyInputParcel implements Parcelable {
|
|||
private boolean mDecryptMetadataOnly;
|
||||
private byte[] mDetachedSignature;
|
||||
private String mRequiredSignerFingerprint;
|
||||
private String mSenderAddress;
|
||||
|
||||
public PgpDecryptVerifyInputParcel() {
|
||||
}
|
||||
|
@ -138,6 +139,15 @@ public class PgpDecryptVerifyInputParcel implements Parcelable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PgpDecryptVerifyInputParcel setSenderAddress(String senderAddress) {
|
||||
mSenderAddress = senderAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSenderAddress() {
|
||||
return mSenderAddress;
|
||||
}
|
||||
|
||||
String getRequiredSignerFingerprint() {
|
||||
return mRequiredSignerFingerprint;
|
||||
}
|
||||
|
@ -156,6 +166,5 @@ public class PgpDecryptVerifyInputParcel implements Parcelable {
|
|||
return new PgpDecryptVerifyInputParcel[size];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
|
||||
if (aIn.isClearText()) {
|
||||
// a cleartext signature, verify it with the other method
|
||||
return verifyCleartextSignature(aIn, outputStream, 0);
|
||||
return verifyCleartextSignature(input, aIn, outputStream, 0);
|
||||
} else {
|
||||
// else: ascii armored encryption! go on...
|
||||
return decryptVerify(input, cryptoInput, inputData, inputStream, outputStream, 0);
|
||||
|
@ -354,7 +354,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
plainFact = fact;
|
||||
}
|
||||
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mProviderHelper);
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mProviderHelper, input.getSenderAddress());
|
||||
if (signatureChecker.initializeOnePassSignature(dataChunk, log, indent +1)) {
|
||||
dataChunk = plainFact.nextObject();
|
||||
}
|
||||
|
@ -835,7 +835,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
*/
|
||||
@NonNull
|
||||
private DecryptVerifyResult verifyCleartextSignature(
|
||||
ArmoredInputStream aIn, OutputStream outputStream, int indent) throws IOException, PGPException {
|
||||
PgpDecryptVerifyInputParcel input, ArmoredInputStream aIn, OutputStream outputStream, int indent) throws IOException, PGPException {
|
||||
|
||||
OperationLog log = new OperationLog();
|
||||
|
||||
|
@ -872,7 +872,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
updateProgress(R.string.progress_processing_signature, 60, 100);
|
||||
JcaSkipMarkerPGPObjectFactory pgpFact = new JcaSkipMarkerPGPObjectFactory(aIn);
|
||||
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mProviderHelper);
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mProviderHelper, input.getSenderAddress());
|
||||
|
||||
Object o = pgpFact.nextObject();
|
||||
if (!signatureChecker.initializeSignature(o, log, indent+1)) {
|
||||
|
@ -927,7 +927,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||
o = pgpFact.nextObject();
|
||||
}
|
||||
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mProviderHelper);
|
||||
PgpSignatureChecker signatureChecker = new PgpSignatureChecker(mProviderHelper, input.getSenderAddress());
|
||||
|
||||
if ( ! signatureChecker.initializeSignature(o, log, indent+1)) {
|
||||
log.add(LogType.MSG_DC_ERROR_INVALID_DATA, 0);
|
||||
|
|
|
@ -47,7 +47,7 @@ import org.sufficientlysecure.keychain.util.Log;
|
|||
*/
|
||||
class PgpSignatureChecker {
|
||||
|
||||
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
|
||||
private final OpenPgpSignatureResultBuilder signatureResultBuilder;
|
||||
|
||||
private CanonicalizedPublicKey signingKey;
|
||||
|
||||
|
@ -57,8 +57,11 @@ class PgpSignatureChecker {
|
|||
|
||||
ProviderHelper mProviderHelper;
|
||||
|
||||
PgpSignatureChecker(ProviderHelper providerHelper) {
|
||||
PgpSignatureChecker(ProviderHelper providerHelper, String senderAddress) {
|
||||
mProviderHelper = providerHelper;
|
||||
|
||||
signatureResultBuilder = new OpenPgpSignatureResultBuilder(providerHelper);
|
||||
signatureResultBuilder.setSenderAddress(senderAddress);
|
||||
}
|
||||
|
||||
boolean initializeSignature(Object dataChunk, OperationLog log, int indent) throws PGPException {
|
||||
|
|
|
@ -274,6 +274,27 @@ public class ProviderHelper {
|
|||
return (CanonicalizedSecretKeyRing) getCanonicalizedKeyRing(queryUri, true);
|
||||
}
|
||||
|
||||
public ArrayList<String> getConfirmedUserIds(long masterKeyId) throws NotFoundException {
|
||||
Cursor cursor = mContentResolver.query(UserPackets.buildUserIdsUri(masterKeyId),
|
||||
new String[]{ UserPackets.USER_ID }, UserPackets.VERIFIED + " = " + Certs.VERIFIED_SECRET, null, null
|
||||
);
|
||||
if (cursor == null) {
|
||||
throw new NotFoundException("Key id for requested user ids not found");
|
||||
}
|
||||
|
||||
try {
|
||||
ArrayList<String> userIds = new ArrayList<>(cursor.getCount());
|
||||
while (cursor.moveToNext()) {
|
||||
String userId = cursor.getString(0);
|
||||
userIds.add(userId);
|
||||
}
|
||||
|
||||
return userIds;
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
private KeyRing getCanonicalizedKeyRing(Uri queryUri, boolean secret) throws NotFoundException {
|
||||
Cursor cursor = mContentResolver.query(queryUri,
|
||||
new String[]{
|
||||
|
|
|
@ -478,6 +478,7 @@ public class OpenPgpService extends Service {
|
|||
}
|
||||
|
||||
byte[] detachedSignature = data.getByteArrayExtra(OpenPgpApi.EXTRA_DETACHED_SIGNATURE);
|
||||
String senderAddress = data.getStringExtra(OpenPgpApi.EXTRA_SENDER_ADDRESS);
|
||||
|
||||
PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(this, mProviderHelper, progressable);
|
||||
|
||||
|
@ -490,7 +491,8 @@ public class OpenPgpService extends Service {
|
|||
.setAllowSymmetricDecryption(false)
|
||||
.setAllowedKeyIds(allowedKeyIds)
|
||||
.setDecryptMetadataOnly(decryptMetadataOnly)
|
||||
.setDetachedSignature(detachedSignature);
|
||||
.setDetachedSignature(detachedSignature)
|
||||
.setSenderAddress(senderAddress);
|
||||
|
||||
DecryptVerifyResult pgpResult = op.execute(input, cryptoInput, inputData, outputStream);
|
||||
|
||||
|
|
2
extern/openpgp-api-lib
vendored
2
extern/openpgp-api-lib
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 32794ee94fcd3c8065163da1f6da41e7ceb87c05
|
||||
Subproject commit 84fdd0c37dc2ef6e303a3488cc412c8d2cc4fd28
|
Loading…
Reference in a new issue