Introduce constants in OpenPgpSignature and DecryptionResult for unsigned/unencrypted content, update API, introduce simple checks for insecure symmetric algos

This commit is contained in:
Dominik Schürmann
2015-07-25 14:32:47 +02:00
parent dc81e0254c
commit 57378be1c0
19 changed files with 430 additions and 279 deletions

View File

@@ -184,7 +184,7 @@ public class CanonicalizedSecretKey extends CanonicalizedPublicKey {
// TODO: intersection between preferred hash algos of this key and PgpConstants.PREFERRED_HASH_ALGORITHMS
// choose best algo
return PgpConstants.sPreferredHashAlgorithms;
return new ArrayList<>();
}
private PGPContentSignerBuilder getContentSignerBuilder(int hashAlgo,

View File

@@ -30,7 +30,6 @@ import java.util.ArrayList;
*/
public class OpenPgpSignatureResultBuilder {
// OpenPgpSignatureResult
private boolean mSignatureOnly = false;
private String mPrimaryUserId;
private ArrayList<String> mUserIds = new ArrayList<>();
private long mKeyId;
@@ -42,10 +41,7 @@ public class OpenPgpSignatureResultBuilder {
private boolean mIsSignatureKeyCertified = false;
private boolean mIsKeyRevoked = false;
private boolean mIsKeyExpired = false;
public void setSignatureOnly(boolean signatureOnly) {
this.mSignatureOnly = signatureOnly;
}
private boolean mInsecure = false;
public void setPrimaryUserId(String userId) {
this.mPrimaryUserId = userId;
@@ -63,6 +59,10 @@ public class OpenPgpSignatureResultBuilder {
this.mValidSignature = validSignature;
}
public void setInsecure(boolean insecure) {
this.mInsecure = insecure;
}
public void setSignatureKeyCertified(boolean isSignatureKeyCertified) {
this.mIsSignatureKeyCertified = isSignatureKeyCertified;
}
@@ -87,6 +87,10 @@ public class OpenPgpSignatureResultBuilder {
return mValidSignature;
}
public boolean isInsecure() {
return mInsecure;
}
public void initValid(CanonicalizedPublicKeyRing signingRing,
CanonicalizedPublicKey signingKey) {
setSignatureAvailable(true);
@@ -109,47 +113,50 @@ public class OpenPgpSignatureResultBuilder {
}
public OpenPgpSignatureResult build() {
if (mSignatureAvailable) {
OpenPgpSignatureResult result = new OpenPgpSignatureResult();
result.setSignatureOnly(mSignatureOnly);
// valid sig!
if (mKnownKey) {
if (mValidSignature) {
result.setKeyId(mKeyId);
result.setPrimaryUserId(mPrimaryUserId);
result.setUserIds(mUserIds);
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");
result.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED);
} else {
Log.d(Constants.TAG, "SIGNATURE_SUCCESS_UNCERTIFIED");
result.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
}
} else {
Log.d(Constants.TAG, "Error! Invalid signature.");
result.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
}
} else {
result.setKeyId(mKeyId);
Log.d(Constants.TAG, "SIGNATURE_KEY_MISSING");
result.setStatus(OpenPgpSignatureResult.SIGNATURE_KEY_MISSING);
}
OpenPgpSignatureResult result = new OpenPgpSignatureResult();
if (!mSignatureAvailable) {
Log.d(Constants.TAG, "RESULT_NO_SIGNATURE");
result.setResult(OpenPgpSignatureResult.RESULT_NO_SIGNATURE);
return result;
} else {
Log.d(Constants.TAG, "no signature found!");
return null;
}
if (!mKnownKey) {
result.setKeyId(mKeyId);
Log.d(Constants.TAG, "RESULT_KEY_MISSING");
result.setResult(OpenPgpSignatureResult.RESULT_KEY_MISSING);
return result;
}
if (!mValidSignature) {
Log.d(Constants.TAG, "RESULT_INVALID_SIGNATURE");
result.setResult(OpenPgpSignatureResult.RESULT_INVALID_SIGNATURE);
return result;
}
result.setKeyId(mKeyId);
result.setPrimaryUserId(mPrimaryUserId);
result.setUserIds(mUserIds);
if (mIsKeyRevoked) {
Log.d(Constants.TAG, "RESULT_INVALID_KEY_REVOKED");
result.setResult(OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED);
} else if (mIsKeyExpired) {
Log.d(Constants.TAG, "RESULT_INVALID_KEY_EXPIRED");
result.setResult(OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED);
} else if (mInsecure) {
Log.d(Constants.TAG, "RESULT_INVALID_INSECURE");
result.setResult(OpenPgpSignatureResult.RESULT_INVALID_INSECURE);
} else if (mIsSignatureKeyCertified) {
Log.d(Constants.TAG, "RESULT_VALID_CONFIRMED");
result.setResult(OpenPgpSignatureResult.RESULT_VALID_CONFIRMED);
} else {
Log.d(Constants.TAG, "RESULT_VALID_UNCONFIRMED");
result.setResult(OpenPgpSignatureResult.RESULT_VALID_UNCONFIRMED);
}
return result;
}

View File

@@ -21,51 +21,96 @@ import org.spongycastle.bcpg.CompressionAlgorithmTags;
import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
import java.util.ArrayList;
import java.util.HashSet;
/**
* NIST requirements for 2011-2030 (http://www.keylength.com/en/4/):
* - RSA: 2048 bit
* - ECC: 224 bit
* - Symmetric: 3TDEA
* - Digital Signature (hash A): SHA-224 - SHA-512
*/
public class PgpConstants {
public static ArrayList<Integer> sPreferredSymmetricAlgorithms = new ArrayList<>();
public static ArrayList<Integer> sPreferredHashAlgorithms = new ArrayList<>();
public static ArrayList<Integer> sPreferredCompressionAlgorithms = new ArrayList<>();
// public interface MIN_REQUIREMENT {
// int MIN_BITS;
// int BINDING_SIGNATURE_HASH_ALGO; // for User IDs, subkeys,...
// int SYMMETRIC_ALGO;
// }
// https://tools.ietf.org/html/rfc6637#section-13
// TODO: use hashmaps for contains in O(1) and intersections!
// PgpDecryptVerify: Secure Algorithms Whitelist
// all other algorithms will be rejected with OpenPgpDecryptionResult.RESULT_INSECURE
public static HashSet<Integer> sSymmetricAlgorithmsWhitelist = new HashSet<>();
static {
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_256);
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_192);
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.AES_128);
sSymmetricAlgorithmsWhitelist.add(SymmetricKeyAlgorithmTags.TWOFISH);
}
// all other algorithms will be rejected with OpenPgpSignatureResult.RESULT_INVALID_INSECURE
public static HashSet<Integer> sHashAlgorithmsWhitelist = new HashSet<>();
static {
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA256);
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA512);
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA384);
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA224);
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.SHA1);
sHashAlgorithmsWhitelist.add(HashAlgorithmTags.RIPEMD160);
}
/*
* Most preferred is first
* These arrays are written as preferred algorithms into the keys on creation.
* Other implementations may choose to honor this selection.
*
* These lists also define the only algorithms which are used in OpenKeychain.
* We do not support algorithms such as MD5
*/
static {
sPreferredSymmetricAlgorithms.add(SymmetricKeyAlgorithmTags.AES_256);
sPreferredSymmetricAlgorithms.add(SymmetricKeyAlgorithmTags.AES_192);
sPreferredSymmetricAlgorithms.add(SymmetricKeyAlgorithmTags.AES_128);
sPreferredSymmetricAlgorithms.add(SymmetricKeyAlgorithmTags.TWOFISH);
public static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
SymmetricKeyAlgorithmTags.AES_256,
SymmetricKeyAlgorithmTags.AES_192,
SymmetricKeyAlgorithmTags.AES_128,
SymmetricKeyAlgorithmTags.TWOFISH
};
// NOTE: some implementations do not support SHA512, thus we choose SHA256 as default (Mailvelope?)
sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA256);
sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA512);
sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA384);
sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA224);
sPreferredHashAlgorithms.add(HashAlgorithmTags.SHA1);
sPreferredHashAlgorithms.add(HashAlgorithmTags.RIPEMD160);
// NOTE: some implementations do not support SHA512, thus we choose SHA256 as default (Mailvelope?)
public static final int[] PREFERRED_HASH_ALGORITHMS = new int[]{
HashAlgorithmTags.SHA256,
HashAlgorithmTags.SHA512,
HashAlgorithmTags.SHA384,
HashAlgorithmTags.SHA224,
};
/*
* Prefer ZIP
* "ZLIB provides no benefit over ZIP and is more malleable"
* - (OpenPGP WG mailinglist: "[openpgp] Intent to deprecate: Insecure primitives")
* BZIP2: very slow
*/
sPreferredCompressionAlgorithms.add(CompressionAlgorithmTags.ZIP);
sPreferredCompressionAlgorithms.add(CompressionAlgorithmTags.ZLIB);
sPreferredCompressionAlgorithms.add(CompressionAlgorithmTags.BZIP2);
}
/*
* Prefer ZIP
* "ZLIB provides no benefit over ZIP and is more malleable"
* - (OpenPGP WG mailinglist: "[openpgp] Intent to deprecate: Insecure primitives")
* BZIP2: very slow
*/
public static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[]{
CompressionAlgorithmTags.ZIP,
CompressionAlgorithmTags.ZLIB,
CompressionAlgorithmTags.BZIP2
};
public static final int CERTIFY_HASH_ALGO = HashAlgorithmTags.SHA256;
public static final int DEFAULT_SYMMETRIC_ALGORITHM = SymmetricKeyAlgorithmTags.AES_256;
public interface OpenKeychainSymmetricKeyAlgorithmTags extends SymmetricKeyAlgorithmTags {
int USE_DEFAULT = -1;
}
public static final int DEFAULT_HASH_ALGORITHM = HashAlgorithmTags.SHA256;
public interface OpenKeychainHashAlgorithmTags extends HashAlgorithmTags {
int USE_DEFAULT = -1;
}
public static final int DEFAULT_COMPRESSION_ALGORITHM = CompressionAlgorithmTags.ZIP;
public interface OpenKeychainCompressionAlgorithmTags extends CompressionAlgorithmTags {
int USE_DEFAULT = -1;
}
/*
* Note: s2kcount is a number between 0 and 0xff that controls the
* number of times to iterate the password hash before use. More
@@ -87,28 +132,9 @@ public class PgpConstants {
public static final int SECRET_KEY_ENCRYPTOR_S2K_COUNT = 0x90;
public static final int SECRET_KEY_ENCRYPTOR_HASH_ALGO = HashAlgorithmTags.SHA256;
public static final int SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO = SymmetricKeyAlgorithmTags.AES_256;
public static final int SECRET_KEY_SIGNATURE_HASH_ALGO = HashAlgorithmTags.SHA256;
public static final int SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO = HashAlgorithmTags.SHA256;
// NOTE: only SHA1 is supported for key checksum calculations in OpenPGP,
// see http://tools.ietf.org/html/rfc488 0#section-5.5.3
public static final int SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO = HashAlgorithmTags.SHA1;
public static interface OpenKeychainSymmetricKeyAlgorithmTags extends SymmetricKeyAlgorithmTags {
public static final int USE_PREFERRED = -1;
}
public static interface OpenKeychainHashAlgorithmTags extends HashAlgorithmTags {
public static final int USE_PREFERRED = -1;
}
public static interface OpenKeychainCompressionAlgorithmTags extends CompressionAlgorithmTags {
public static final int USE_PREFERRED = -1;
}
public static int[] getAsArray(ArrayList<Integer> list) {
int[] array = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
return array;
}
}

View File

@@ -22,6 +22,7 @@ import android.content.Context;
import android.support.annotation.NonNull;
import android.webkit.MimeTypeMap;
import org.openintents.openpgp.OpenPgpDecryptionResult;
import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.spongycastle.bcpg.ArmoredInputStream;
@@ -283,10 +284,6 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
PGPSignatureList signatureList = (PGPSignatureList) pgpF.nextObject();
PGPSignature messageSignature = signatureList.get(signatureIndex);
// these are not cleartext signatures!
// TODO: what about binary signatures?
signatureResultBuilder.setSignatureOnly(false);
// Verify signature and check binding signatures
boolean validSignature = signature.verify(messageSignature);
if (validSignature) {
@@ -298,8 +295,8 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
OpenPgpSignatureResult signatureResult = signatureResultBuilder.build();
if (signatureResult.getStatus() != OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED
&& signatureResult.getStatus() != OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED) {
if (signatureResult.getResult() != OpenPgpSignatureResult.RESULT_VALID_CONFIRMED
&& signatureResult.getResult() != OpenPgpSignatureResult.RESULT_VALID_UNCONFIRMED) {
log.add(LogType.MSG_VL_ERROR_INTEGRITY_CHECK, indent);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
@@ -309,9 +306,10 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
log.add(LogType.MSG_VL_OK, indent);
// Return a positive result, with metadata and verification info
DecryptVerifyResult result =
new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
DecryptVerifyResult result = new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
result.setSignatureResult(signatureResult);
result.setDecryptionResult(
new OpenPgpDecryptionResult(OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED));
return result;
}
@@ -322,6 +320,8 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput,
InputStream in, OutputStream out, int indent) throws IOException, PGPException {
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
OpenPgpDecryptionResult decryptionResult = new OpenPgpDecryptionResult();
OperationLog log = new OperationLog();
log.add(LogType.MSG_DC, indent);
@@ -614,15 +614,16 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
}
decryptionResult.setResult(OpenPgpDecryptionResult.RESULT_ENCRYPTED);
// Warn about old encryption algorithms!
if (!PgpConstants.sPreferredSymmetricAlgorithms.contains(symmetricEncryptionAlgo)) {
// Check for insecure encryption algorithms!
if (!PgpConstants.sSymmetricAlgorithmsWhitelist.contains(symmetricEncryptionAlgo)) {
log.add(LogType.MSG_DC_OLD_SYMMETRIC_ENCRYPTION_ALGO, indent + 1);
decryptionResult.setResult(OpenPgpDecryptionResult.RESULT_INSECURE);
}
JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
Object dataChunk = plainFact.nextObject();
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
int signatureIndex = -1;
CanonicalizedPublicKeyRing signingRing = null;
CanonicalizedPublicKey signingKey = null;
@@ -752,7 +753,7 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
DecryptVerifyResult result =
new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
result.setCharset(charset);
result.setDecryptMetadata(metadata);
result.setDecryptionMetadata(metadata);
return result;
}
@@ -809,11 +810,9 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject();
PGPSignature messageSignature = signatureList.get(signatureIndex);
// these are not cleartext signatures!
// TODO: what about binary signatures?
signatureResultBuilder.setSignatureOnly(false);
// Verify signature and check binding signatures
// Verify signature
boolean validSignature = signature.verify(messageSignature);
if (validSignature) {
log.add(LogType.MSG_DC_CLEAR_SIGNATURE_OK, indent + 1);
@@ -821,10 +820,10 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1);
}
// Don't allow verification of old hash algorithms!
if (!PgpConstants.sPreferredHashAlgorithms.contains(signature.getHashAlgorithm())) {
validSignature = false;
// check for insecure hash algorithms
if (!PgpConstants.sHashAlgorithmsWhitelist.contains(signature.getHashAlgorithm())) {
log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
signatureResultBuilder.setInsecure(true);
}
signatureResultBuilder.setValidSignature(validSignature);
@@ -852,7 +851,7 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
Log.d(Constants.TAG, "MDC fail");
if (!signatureResultBuilder.isValidSignature()) {
log.add(LogType.MSG_DC_ERROR_INTEGRITY_MISSING, indent);
return new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log);
decryptionResult.setResult(OpenPgpDecryptionResult.RESULT_INSECURE);
}
}
@@ -861,12 +860,12 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
log.add(LogType.MSG_DC_OK, indent);
// Return a positive result, with metadata and verification info
DecryptVerifyResult result =
new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
DecryptVerifyResult result = new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
result.setCachedCryptoInputParcel(cryptoInput);
result.setDecryptMetadata(metadata);
result.setSignatureResult(signatureResultBuilder.build());
result.setCharset(charset);
result.setDecryptionResult(decryptionResult);
result.setDecryptionMetadata(metadata);
return result;
}
@@ -885,8 +884,6 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
OperationLog log = new OperationLog();
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
// cleartext signatures are never encrypted ;)
signatureResultBuilder.setSignatureOnly(true);
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -956,10 +953,10 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1);
}
// Don't allow verification of old hash algorithms!
if (!PgpConstants.sPreferredHashAlgorithms.contains(signature.getHashAlgorithm())) {
validSignature = false;
// check for insecure hash algorithms
if (!PgpConstants.sHashAlgorithmsWhitelist.contains(signature.getHashAlgorithm())) {
log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
signatureResultBuilder.setInsecure(true);
}
signatureResultBuilder.setValidSignature(validSignature);
@@ -981,8 +978,10 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
clearText.length);
DecryptVerifyResult result = new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
result.setDecryptMetadata(metadata);
result.setSignatureResult(signatureResultBuilder.build());
result.setDecryptionResult(
new OpenPgpDecryptionResult(OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED));
result.setDecryptionMetadata(metadata);
return result;
}
@@ -994,8 +993,6 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
OperationLog log = new OperationLog();
OpenPgpSignatureResultBuilder signatureResultBuilder = new OpenPgpSignatureResultBuilder();
// detached signatures are never encrypted
signatureResultBuilder.setSignatureOnly(true);
updateProgress(R.string.progress_processing_signature, 0, 100);
InputStream detachedSigIn = new ByteArrayInputStream(input.getDetachedSignature());
@@ -1050,9 +1047,6 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
updateProgress(R.string.progress_verifying_signature, 90, 100);
log.add(LogType.MSG_DC_CLEAR_SIGNATURE_CHECK, indent);
// these are not cleartext signatures!
signatureResultBuilder.setSignatureOnly(false);
// Verify signature and check binding signatures
boolean validSignature = signature.verify();
if (validSignature) {
@@ -1061,10 +1055,10 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
log.add(LogType.MSG_DC_CLEAR_SIGNATURE_BAD, indent + 1);
}
// Don't allow verification of old hash algorithms!
if (!PgpConstants.sPreferredHashAlgorithms.contains(signature.getHashAlgorithm())) {
validSignature = false;
// check for insecure hash algorithms
if (!PgpConstants.sHashAlgorithmsWhitelist.contains(signature.getHashAlgorithm())) {
log.add(LogType.MSG_DC_ERROR_UNSUPPORTED_HASH_ALGO, indent + 1);
signatureResultBuilder.setInsecure(true);
}
signatureResultBuilder.setValidSignature(validSignature);
@@ -1076,6 +1070,8 @@ public class PgpDecryptVerify extends BaseOperation<PgpDecryptVerifyInputParcel>
DecryptVerifyResult result = new DecryptVerifyResult(DecryptVerifyResult.RESULT_OK, log);
result.setSignatureResult(signatureResultBuilder.build());
result.setDecryptionResult(
new OpenPgpDecryptionResult(OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED));
return result;
}

View File

@@ -1206,7 +1206,7 @@ public class PgpKeyOperation {
// add packet with EMPTY notation data (updates old one, but will be stripped later)
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
PgpConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
{ // set subpackets
@@ -1233,7 +1233,7 @@ public class PgpKeyOperation {
// add packet with "pin" notation data
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
masterPrivateKey.getPublicKeyPacket().getAlgorithm(),
PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
PgpConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder);
{ // set subpackets
@@ -1440,13 +1440,13 @@ public class PgpKeyOperation {
if (divertToCard) {
// use synchronous "NFC based" SignerBuilder
builder = new NfcSyncPGPContentSignerBuilder(
pKey.getAlgorithm(), PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO,
pKey.getAlgorithm(), PgpConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO,
pKey.getKeyID(), cryptoInput.getCryptoData())
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
} else {
// content signer based on signing key algorithm and chosen hash algorithm
builder = new JcaPGPContentSignerBuilder(
pKey.getAlgorithm(), PgpConstants.SECRET_KEY_SIGNATURE_HASH_ALGO)
pKey.getAlgorithm(), PgpConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO)
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
}
@@ -1472,11 +1472,11 @@ public class PgpKeyOperation {
*/
/* non-critical subpackets: */
hashedPacketsGen.setPreferredSymmetricAlgorithms(false,
PgpConstants.getAsArray(PgpConstants.sPreferredSymmetricAlgorithms));
PgpConstants.PREFERRED_SYMMETRIC_ALGORITHMS);
hashedPacketsGen.setPreferredHashAlgorithms(false,
PgpConstants.getAsArray(PgpConstants.sPreferredHashAlgorithms));
PgpConstants.PREFERRED_HASH_ALGORITHMS);
hashedPacketsGen.setPreferredCompressionAlgorithms(false,
PgpConstants.getAsArray(PgpConstants.sPreferredCompressionAlgorithms));
PgpConstants.PREFERRED_COMPRESSION_ALGORITHMS);
hashedPacketsGen.setPrimaryUserID(false, primary);
/* critical subpackets: we consider those important for a modern pgp implementation */

View File

@@ -30,13 +30,13 @@ public class PgpSignEncryptInputParcel implements Parcelable {
protected String mVersionHeader = null;
protected boolean mEnableAsciiArmorOutput = false;
protected int mCompressionId = CompressionAlgorithmTags.UNCOMPRESSED;
protected int mCompressionAlgorithm = CompressionAlgorithmTags.UNCOMPRESSED;
protected long[] mEncryptionMasterKeyIds = null;
protected Passphrase mSymmetricPassphrase = null;
protected int mSymmetricEncryptionAlgorithm = PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED;
protected int mSymmetricEncryptionAlgorithm = PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT;
protected long mSignatureMasterKeyId = Constants.key.none;
protected Long mSignatureSubKeyId = null;
protected int mSignatureHashAlgorithm = PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED;
protected int mSignatureHashAlgorithm = PgpConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT;
protected long mAdditionalEncryptId = Constants.key.none;
protected boolean mFailOnMissingEncryptionKeyIds = false;
protected String mCharset;
@@ -55,7 +55,7 @@ public class PgpSignEncryptInputParcel implements Parcelable {
// we do all of those here, so the PgpSignEncryptInput class doesn't have to be parcelable
mVersionHeader = source.readString();
mEnableAsciiArmorOutput = source.readInt() == 1;
mCompressionId = source.readInt();
mCompressionAlgorithm = source.readInt();
mEncryptionMasterKeyIds = source.createLongArray();
mSymmetricPassphrase = source.readParcelable(loader);
mSymmetricEncryptionAlgorithm = source.readInt();
@@ -79,7 +79,7 @@ public class PgpSignEncryptInputParcel implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mVersionHeader);
dest.writeInt(mEnableAsciiArmorOutput ? 1 : 0);
dest.writeInt(mCompressionId);
dest.writeInt(mCompressionAlgorithm);
dest.writeLongArray(mEncryptionMasterKeyIds);
dest.writeParcelable(mSymmetricPassphrase, 0);
dest.writeInt(mSymmetricEncryptionAlgorithm);
@@ -174,12 +174,12 @@ public class PgpSignEncryptInputParcel implements Parcelable {
return this;
}
public int getCompressionId() {
return mCompressionId;
public int getCompressionAlgorithm() {
return mCompressionAlgorithm;
}
public PgpSignEncryptInputParcel setCompressionId(int compressionId) {
mCompressionId = compressionId;
public PgpSignEncryptInputParcel setCompressionAlgorithm(int compressionAlgorithm) {
mCompressionAlgorithm = compressionAlgorithm;
return this;
}

View File

@@ -124,7 +124,7 @@ public class PgpSignEncryptOperation extends BaseOperation {
boolean enableSignature = input.getSignatureMasterKeyId() != Constants.key.none;
boolean enableEncryption = ((input.getEncryptionMasterKeyIds() != null && input.getEncryptionMasterKeyIds().length > 0)
|| input.getSymmetricPassphrase() != null);
boolean enableCompression = (input.getCompressionId() != CompressionAlgorithmTags.UNCOMPRESSED);
boolean enableCompression = (input.getCompressionAlgorithm() != CompressionAlgorithmTags.UNCOMPRESSED);
Log.d(Constants.TAG, "enableSignature:" + enableSignature
+ "\nenableEncryption:" + enableEncryption
@@ -229,9 +229,11 @@ public class PgpSignEncryptOperation extends BaseOperation {
// Use preferred hash algo
int requestedAlgorithm = input.getSignatureHashAlgorithm();
ArrayList<Integer> supported = signingKey.getSupportedHashAlgorithms();
if (requestedAlgorithm == PgpConstants.OpenKeychainHashAlgorithmTags.USE_PREFERRED) {
if (requestedAlgorithm == PgpConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT) {
input.setSignatureHashAlgorithm(PgpConstants.DEFAULT_HASH_ALGORITHM);
// TODO
// get most preferred
input.setSignatureHashAlgorithm(supported.get(0));
// input.setSignatureHashAlgorithm(supported.get(0));
} else if (!supported.contains(requestedAlgorithm)) {
log.add(LogType.MSG_PSE_ERROR_HASH_ALGO, indent);
return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
@@ -245,10 +247,10 @@ public class PgpSignEncryptOperation extends BaseOperation {
// Use preferred encryption algo
int algo = input.getSymmetricEncryptionAlgorithm();
if (algo == PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED) {
if (algo == PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT) {
// get most preferred
// TODO: get from recipients
algo = PgpConstants.sPreferredSymmetricAlgorithms.get(0);
algo = PgpConstants.DEFAULT_SYMMETRIC_ALGORITHM;
}
// has Integrity packet enabled!
JcePGPDataEncryptorBuilder encryptorBuilder =
@@ -341,7 +343,13 @@ public class PgpSignEncryptOperation extends BaseOperation {
if (enableCompression) {
log.add(LogType.MSG_PSE_COMPRESSING, indent);
compressGen = new PGPCompressedDataGenerator(input.getCompressionId());
// Use preferred compression algo
int algo = input.getCompressionAlgorithm();
if (algo == PgpConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) {
algo = PgpConstants.DEFAULT_COMPRESSION_ALGORITHM;
}
compressGen = new PGPCompressedDataGenerator(algo);
bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
} else {
bcpgOut = new BCPGOutputStream(encryptionOut);
@@ -464,7 +472,7 @@ public class PgpSignEncryptOperation extends BaseOperation {
InputStream in = inputData.getInputStream();
if (enableCompression) {
compressGen = new PGPCompressedDataGenerator(input.getCompressionId());
compressGen = new PGPCompressedDataGenerator(input.getCompressionAlgorithm());
bcpgOut = new BCPGOutputStream(compressGen.open(out));
} else {
bcpgOut = new BCPGOutputStream(out);