Added allowed keys and checks for signing
This commit is contained in:
@@ -25,6 +25,8 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
|
|||||||
|
|
||||||
public class PgpSignEncryptResult extends InputPendingResult {
|
public class PgpSignEncryptResult extends InputPendingResult {
|
||||||
|
|
||||||
|
public static final int RESULT_KEY_DISALLOWED = RESULT_ERROR + 32;
|
||||||
|
|
||||||
byte[] mOutputBytes;
|
byte[] mOutputBytes;
|
||||||
|
|
||||||
byte[] mDetachedSignature;
|
byte[] mDetachedSignature;
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import android.net.Uri;
|
|||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
|
||||||
public class PgpSignEncryptInputParcel implements Parcelable {
|
public class PgpSignEncryptInputParcel implements Parcelable {
|
||||||
|
|
||||||
@@ -31,6 +33,8 @@ public class PgpSignEncryptInputParcel implements Parcelable {
|
|||||||
private Uri mOutputUri;
|
private Uri mOutputUri;
|
||||||
private byte[] mInputBytes;
|
private byte[] mInputBytes;
|
||||||
|
|
||||||
|
private HashSet<Long> mAllowedKeyIds;
|
||||||
|
|
||||||
public PgpSignEncryptInputParcel(PgpSignEncryptData data) {
|
public PgpSignEncryptInputParcel(PgpSignEncryptData data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
@@ -41,6 +45,8 @@ public class PgpSignEncryptInputParcel implements Parcelable {
|
|||||||
mInputBytes = source.createByteArray();
|
mInputBytes = source.createByteArray();
|
||||||
|
|
||||||
data = source.readParcelable(getClass().getClassLoader());
|
data = source.readParcelable(getClass().getClassLoader());
|
||||||
|
|
||||||
|
mAllowedKeyIds = (HashSet<Long>) source.readSerializable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,6 +61,8 @@ public class PgpSignEncryptInputParcel implements Parcelable {
|
|||||||
dest.writeByteArray(mInputBytes);
|
dest.writeByteArray(mInputBytes);
|
||||||
|
|
||||||
data.writeToParcel(dest, 0);
|
data.writeToParcel(dest, 0);
|
||||||
|
|
||||||
|
dest.writeSerializable(mAllowedKeyIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInputBytes(byte[] inputBytes) {
|
public void setInputBytes(byte[] inputBytes) {
|
||||||
@@ -91,6 +99,14 @@ public class PgpSignEncryptInputParcel implements Parcelable {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashSet<Long> getAllowedKeyIds() {
|
||||||
|
return mAllowedKeyIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedKeyIds(HashSet<Long> allowedKeyIds) {
|
||||||
|
mAllowedKeyIds = allowedKeyIds;
|
||||||
|
}
|
||||||
|
|
||||||
public static final Creator<PgpSignEncryptInputParcel> CREATOR = new Creator<PgpSignEncryptInputParcel>() {
|
public static final Creator<PgpSignEncryptInputParcel> CREATOR = new Creator<PgpSignEncryptInputParcel>() {
|
||||||
public PgpSignEncryptInputParcel createFromParcel(final Parcel source) {
|
public PgpSignEncryptInputParcel createFromParcel(final Parcel source) {
|
||||||
return new PgpSignEncryptInputParcel(source);
|
return new PgpSignEncryptInputParcel(source);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ package org.sufficientlysecure.keychain.pgp;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
||||||
@@ -40,8 +39,6 @@ import org.bouncycastle.openpgp.operator.jcajce.PGPUtil;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.operations.BaseOperation;
|
import org.sufficientlysecure.keychain.operations.BaseOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
|
||||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
|
||||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||||
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
|
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
|
||||||
@@ -229,6 +226,15 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa
|
|||||||
mProviderHelper.getCanonicalizedSecretKeyRing(signingMasterKeyId);
|
mProviderHelper.getCanonicalizedSecretKeyRing(signingMasterKeyId);
|
||||||
signingKey = signingKeyRing.getSecretKey(data.getSignatureSubKeyId());
|
signingKey = signingKeyRing.getSecretKey(data.getSignatureSubKeyId());
|
||||||
|
|
||||||
|
if (input.getAllowedKeyIds() != null) {
|
||||||
|
if (!input.getAllowedKeyIds().contains(signingMasterKeyId)) {
|
||||||
|
// this key is in our db, but NOT allowed!
|
||||||
|
log.add(LogType.MSG_DC_ASKIP_NOT_ALLOWED, indent + 1);
|
||||||
|
log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
|
||||||
|
return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_KEY_DISALLOWED, log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Make sure key is not expired or revoked
|
// Make sure key is not expired or revoked
|
||||||
if (signingKeyRing.isExpired() || signingKeyRing.isRevoked()
|
if (signingKeyRing.isExpired() || signingKeyRing.isRevoked()
|
||||||
|
|||||||
@@ -19,15 +19,6 @@
|
|||||||
package org.sufficientlysecure.keychain.remote;
|
package org.sufficientlysecure.keychain.remote;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -75,6 +66,15 @@ import org.sufficientlysecure.keychain.util.InputData;
|
|||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class OpenPgpService extends Service {
|
public class OpenPgpService extends Service {
|
||||||
public static final int API_VERSION_WITH_RESULT_METADATA = 4;
|
public static final int API_VERSION_WITH_RESULT_METADATA = 4;
|
||||||
public static final int API_VERSION_WITH_KEY_REVOKED_EXPIRED = 5;
|
public static final int API_VERSION_WITH_KEY_REVOKED_EXPIRED = 5;
|
||||||
@@ -109,6 +109,8 @@ public class OpenPgpService extends Service {
|
|||||||
try {
|
try {
|
||||||
boolean asciiArmor = cleartextSign || data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
|
boolean asciiArmor = cleartextSign || data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
|
||||||
|
|
||||||
|
int targetApiVersion = data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1);
|
||||||
|
|
||||||
// sign-only
|
// sign-only
|
||||||
PgpSignEncryptData pgpData = new PgpSignEncryptData();
|
PgpSignEncryptData pgpData = new PgpSignEncryptData();
|
||||||
pgpData.setEnableAsciiArmorOutput(asciiArmor)
|
pgpData.setEnableAsciiArmorOutput(asciiArmor)
|
||||||
@@ -143,6 +145,7 @@ public class OpenPgpService extends Service {
|
|||||||
|
|
||||||
|
|
||||||
PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData);
|
PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData);
|
||||||
|
pseInput.setAllowedKeyIds(getAllowedKeyIds(targetApiVersion));
|
||||||
|
|
||||||
// Get Input- and OutputStream from ParcelFileDescriptor
|
// Get Input- and OutputStream from ParcelFileDescriptor
|
||||||
if (!cleartextSign) {
|
if (!cleartextSign) {
|
||||||
@@ -204,6 +207,7 @@ public class OpenPgpService extends Service {
|
|||||||
OutputStream outputStream, boolean sign) {
|
OutputStream outputStream, boolean sign) {
|
||||||
try {
|
try {
|
||||||
boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
|
boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
|
||||||
|
int targetApiVersion = data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1);
|
||||||
String originalFilename = data.getStringExtra(OpenPgpApi.EXTRA_ORIGINAL_FILENAME);
|
String originalFilename = data.getStringExtra(OpenPgpApi.EXTRA_ORIGINAL_FILENAME);
|
||||||
if (originalFilename == null) {
|
if (originalFilename == null) {
|
||||||
originalFilename = "";
|
originalFilename = "";
|
||||||
@@ -278,6 +282,7 @@ public class OpenPgpService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData);
|
PgpSignEncryptInputParcel pseInput = new PgpSignEncryptInputParcel(pgpData);
|
||||||
|
pseInput.setAllowedKeyIds(getAllowedKeyIds(targetApiVersion));
|
||||||
|
|
||||||
CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
|
CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
|
||||||
if (inputParcel == null) {
|
if (inputParcel == null) {
|
||||||
@@ -330,15 +335,7 @@ public class OpenPgpService extends Service {
|
|||||||
outputStream = null;
|
outputStream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String currentPkg = mApiPermissionHelper.getCurrentCallingPackage();
|
|
||||||
HashSet<Long> allowedKeyIds = mApiDao.getAllowedKeyIdsForApp(
|
|
||||||
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
|
|
||||||
|
|
||||||
int targetApiVersion = data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1);
|
int targetApiVersion = data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1);
|
||||||
if (targetApiVersion <= API_VERSION_HIGHEST_WITH_ACCOUNTS) {
|
|
||||||
allowedKeyIds.addAll(mApiDao.getAllKeyIdsForApp(
|
|
||||||
ApiAccounts.buildBaseUri(currentPkg)));
|
|
||||||
}
|
|
||||||
|
|
||||||
CryptoInputParcel cryptoInput = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
|
CryptoInputParcel cryptoInput = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
|
||||||
if (cryptoInput == null) {
|
if (cryptoInput == null) {
|
||||||
@@ -368,7 +365,7 @@ public class OpenPgpService extends Service {
|
|||||||
// no support for symmetric encryption
|
// no support for symmetric encryption
|
||||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel()
|
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel()
|
||||||
.setAllowSymmetricDecryption(false)
|
.setAllowSymmetricDecryption(false)
|
||||||
.setAllowedKeyIds(allowedKeyIds)
|
.setAllowedKeyIds(getAllowedKeyIds(targetApiVersion))
|
||||||
.setDecryptMetadataOnly(decryptMetadataOnly)
|
.setDecryptMetadataOnly(decryptMetadataOnly)
|
||||||
.setDetachedSignature(detachedSignature)
|
.setDetachedSignature(detachedSignature)
|
||||||
.setSenderAddress(senderAddress);
|
.setSenderAddress(senderAddress);
|
||||||
@@ -694,6 +691,19 @@ public class OpenPgpService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HashSet<Long> getAllowedKeyIds(int targetApiVersion) {
|
||||||
|
String currentPkg = mApiPermissionHelper.getCurrentCallingPackage();
|
||||||
|
HashSet<Long> allowedKeyIds = mApiDao.getAllowedKeyIdsForApp(
|
||||||
|
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
|
||||||
|
|
||||||
|
if (targetApiVersion <= API_VERSION_HIGHEST_WITH_ACCOUNTS) {
|
||||||
|
allowedKeyIds.addAll(mApiDao.getAllKeyIdsForApp(
|
||||||
|
ApiAccounts.buildBaseUri(currentPkg)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return allowedKeyIds;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check requirements:
|
* Check requirements:
|
||||||
* - params != null
|
* - params != null
|
||||||
|
|||||||
Reference in New Issue
Block a user