mirror of
https://github.com/moparisthebest/open-keychain
synced 2025-02-17 07:30:14 -05:00
add SignEncryptResult parcel (probably break stuff)
This commit is contained in:
parent
6156600e42
commit
f0e159a372
@ -35,6 +35,10 @@ 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.results.OperationResultParcel.LogLevel;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.OperationResultParcel.LogType;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.OperationResultParcel.OperationLog;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.SignEncryptResult;
|
||||||
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;
|
||||||
@ -45,8 +49,6 @@ import java.io.InputStream;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.NoSuchProviderException;
|
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -247,44 +249,16 @@ public class PgpSignEncrypt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class KeyExtractionException extends Exception {
|
|
||||||
public KeyExtractionException() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NoPassphraseException extends Exception {
|
|
||||||
public NoPassphraseException() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class WrongPassphraseException extends Exception {
|
|
||||||
public WrongPassphraseException() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NoSigningKeyException extends Exception {
|
|
||||||
public NoSigningKeyException() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NeedNfcDataException extends Exception {
|
|
||||||
public byte[] mHashToSign;
|
|
||||||
public int mHashAlgo;
|
|
||||||
public Date mCreationTimestamp;
|
|
||||||
|
|
||||||
public NeedNfcDataException(byte[] hashToSign, int hashAlgo, Date creationTimestamp) {
|
|
||||||
mHashToSign = hashToSign;
|
|
||||||
mHashAlgo = hashAlgo;
|
|
||||||
mCreationTimestamp = creationTimestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signs and/or encrypts data based on parameters of class
|
* Signs and/or encrypts data based on parameters of class
|
||||||
*/
|
*/
|
||||||
public void execute()
|
public SignEncryptResult execute() {
|
||||||
throws IOException, PGPException, NoSuchProviderException,
|
|
||||||
NoSuchAlgorithmException, SignatureException, KeyExtractionException, NoSigningKeyException, NoPassphraseException, NeedNfcDataException, WrongPassphraseException {
|
int indent = 0;
|
||||||
|
OperationLog log = new OperationLog();
|
||||||
|
|
||||||
|
log.add(LogLevel.START, LogType.MSG_SE, indent);
|
||||||
|
indent += 1;
|
||||||
|
|
||||||
boolean enableSignature = mSignatureMasterKeyId != Constants.key.none;
|
boolean enableSignature = mSignatureMasterKeyId != Constants.key.none;
|
||||||
boolean enableEncryption = ((mEncryptionMasterKeyIds != null && mEncryptionMasterKeyIds.length > 0)
|
boolean enableEncryption = ((mEncryptionMasterKeyIds != null && mEncryptionMasterKeyIds.length > 0)
|
||||||
@ -320,7 +294,8 @@ public class PgpSignEncrypt {
|
|||||||
|
|
||||||
// If we weren't handed a passphrase, throw early
|
// If we weren't handed a passphrase, throw early
|
||||||
if (mSignaturePassphrase == null) {
|
if (mSignaturePassphrase == null) {
|
||||||
throw new NoPassphraseException();
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_NO_PASSPHRASE, indent);
|
||||||
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -332,22 +307,26 @@ public class PgpSignEncrypt {
|
|||||||
signingKey = signingKeyRing.getSecretKey(signKeyId);
|
signingKey = signingKeyRing.getSecretKey(signKeyId);
|
||||||
// make sure it's a signing key alright!
|
// make sure it's a signing key alright!
|
||||||
} catch (ProviderHelper.NotFoundException e) {
|
} catch (ProviderHelper.NotFoundException e) {
|
||||||
throw new NoSigningKeyException();
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_SIGN_KEY, indent);
|
||||||
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we are allowed to sign here!
|
// Make sure we are allowed to sign here!
|
||||||
if ( ! signingKey.canSign()) {
|
if (!signingKey.canSign()) {
|
||||||
throw new NoSigningKeyException();
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_KEY_SIGN, indent);
|
||||||
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProgress(R.string.progress_extracting_signature_key, 0, 100);
|
updateProgress(R.string.progress_extracting_signature_key, 0, 100);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( ! signingKey.unlock(mSignaturePassphrase)) {
|
if (!signingKey.unlock(mSignaturePassphrase)) {
|
||||||
throw new WrongPassphraseException();
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_BAD_PASSPHRASE, indent);
|
||||||
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
}
|
}
|
||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
throw new KeyExtractionException();
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_UNLOCK, indent);
|
||||||
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if hash algo is supported
|
// check if hash algo is supported
|
||||||
@ -372,12 +351,14 @@ public class PgpSignEncrypt {
|
|||||||
|
|
||||||
if (mSymmetricPassphrase != null) {
|
if (mSymmetricPassphrase != null) {
|
||||||
// Symmetric encryption
|
// Symmetric encryption
|
||||||
Log.d(Constants.TAG, "encryptionMasterKeyIds length is 0 -> symmetric encryption");
|
log.add(LogLevel.DEBUG, LogType.MSG_SE_SYMMETRIC, indent);
|
||||||
|
|
||||||
JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator =
|
JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator =
|
||||||
new JcePBEKeyEncryptionMethodGenerator(mSymmetricPassphrase.toCharArray());
|
new JcePBEKeyEncryptionMethodGenerator(mSymmetricPassphrase.toCharArray());
|
||||||
cPk.addMethod(symmetricEncryptionGenerator);
|
cPk.addMethod(symmetricEncryptionGenerator);
|
||||||
} else {
|
} else {
|
||||||
|
log.add(LogLevel.INFO, LogType.MSG_SE_ASYMMETRIC, indent);
|
||||||
|
|
||||||
// Asymmetric encryption
|
// Asymmetric encryption
|
||||||
for (long id : mEncryptionMasterKeyIds) {
|
for (long id : mEncryptionMasterKeyIds) {
|
||||||
try {
|
try {
|
||||||
@ -385,10 +366,14 @@ public class PgpSignEncrypt {
|
|||||||
KeyRings.buildUnifiedKeyRingUri(id));
|
KeyRings.buildUnifiedKeyRingUri(id));
|
||||||
CanonicalizedPublicKey key = keyRing.getEncryptionSubKey();
|
CanonicalizedPublicKey key = keyRing.getEncryptionSubKey();
|
||||||
cPk.addMethod(key.getPubKeyEncryptionGenerator());
|
cPk.addMethod(key.getPubKeyEncryptionGenerator());
|
||||||
|
log.add(LogLevel.DEBUG, LogType.MSG_SE_KEY_OK, indent +1,
|
||||||
|
PgpKeyHelper.convertKeyIdToHex(id));
|
||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
Log.e(Constants.TAG, "key not found!", e);
|
log.add(LogLevel.WARN, LogType.MSG_SE_KEY_WARN, indent +1,
|
||||||
|
PgpKeyHelper.convertKeyIdToHex(id));
|
||||||
} catch (ProviderHelper.NotFoundException e) {
|
} catch (ProviderHelper.NotFoundException e) {
|
||||||
Log.e(Constants.TAG, "key not found!", e);
|
log.add(LogLevel.WARN, LogType.MSG_SE_KEY_UNKNOWN, indent +1,
|
||||||
|
PgpKeyHelper.convertKeyIdToHex(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,168 +389,199 @@ public class PgpSignEncrypt {
|
|||||||
signatureGenerator = signingKey.getSignatureGenerator(
|
signatureGenerator = signingKey.getSignatureGenerator(
|
||||||
mSignatureHashAlgorithm, cleartext, mNfcSignedHash, mNfcCreationTimestamp);
|
mSignatureHashAlgorithm, cleartext, mNfcSignedHash, mNfcCreationTimestamp);
|
||||||
} catch (PgpGeneralException e) {
|
} catch (PgpGeneralException e) {
|
||||||
// TODO throw correct type of exception (which shouldn't be PGPException)
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_NFC, indent);
|
||||||
throw new KeyExtractionException();
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressScaler progressScaler =
|
ProgressScaler progressScaler =
|
||||||
new ProgressScaler(mProgressable, 8, 95, 100);
|
new ProgressScaler(mProgressable, 8, 95, 100);
|
||||||
PGPCompressedDataGenerator compressGen = null;
|
PGPCompressedDataGenerator compressGen = null;
|
||||||
OutputStream pOut = null;
|
OutputStream pOut;
|
||||||
OutputStream encryptionOut = null;
|
OutputStream encryptionOut = null;
|
||||||
BCPGOutputStream bcpgOut;
|
BCPGOutputStream bcpgOut;
|
||||||
|
|
||||||
if (enableEncryption) {
|
try {
|
||||||
/* actual encryption */
|
|
||||||
updateProgress(R.string.progress_encrypting, 8, 100);
|
|
||||||
|
|
||||||
encryptionOut = cPk.open(out, new byte[1 << 16]);
|
if (enableEncryption) {
|
||||||
|
/* actual encryption */
|
||||||
|
updateProgress(R.string.progress_encrypting, 8, 100);
|
||||||
|
log.add(LogLevel.DEBUG, enableSignature
|
||||||
|
? LogType.MSG_SE_SIGCRYPTING
|
||||||
|
: LogType.MSG_SE_ENCRYPTING,
|
||||||
|
indent);
|
||||||
|
indent += 1;
|
||||||
|
|
||||||
if (enableCompression) {
|
encryptionOut = cPk.open(out, new byte[1 << 16]);
|
||||||
compressGen = new PGPCompressedDataGenerator(mCompressionId);
|
|
||||||
bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
|
if (enableCompression) {
|
||||||
|
log.add(LogLevel.DEBUG, LogType.MSG_SE_COMPRESSING, indent);
|
||||||
|
compressGen = new PGPCompressedDataGenerator(mCompressionId);
|
||||||
|
bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
|
||||||
|
} else {
|
||||||
|
bcpgOut = new BCPGOutputStream(encryptionOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableSignature) {
|
||||||
|
signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
|
||||||
|
char literalDataFormatTag;
|
||||||
|
if (mCleartextInput) {
|
||||||
|
literalDataFormatTag = PGPLiteralData.UTF8;
|
||||||
|
} else {
|
||||||
|
literalDataFormatTag = PGPLiteralData.BINARY;
|
||||||
|
}
|
||||||
|
pOut = literalGen.open(bcpgOut, literalDataFormatTag, mOriginalFilename, new Date(),
|
||||||
|
new byte[1 << 16]);
|
||||||
|
|
||||||
|
long alreadyWritten = 0;
|
||||||
|
int length;
|
||||||
|
byte[] buffer = new byte[1 << 16];
|
||||||
|
InputStream in = mData.getInputStream();
|
||||||
|
while ((length = in.read(buffer)) > 0) {
|
||||||
|
pOut.write(buffer, 0, length);
|
||||||
|
|
||||||
|
// update signature buffer if signature is requested
|
||||||
|
if (enableSignature) {
|
||||||
|
signatureGenerator.update(buffer, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
alreadyWritten += length;
|
||||||
|
if (mData.getSize() > 0) {
|
||||||
|
long progress = 100 * alreadyWritten / mData.getSize();
|
||||||
|
progressScaler.setProgress((int) progress, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
literalGen.close();
|
||||||
|
indent -= 1;
|
||||||
|
|
||||||
|
} else if (enableSignature && mCleartextInput && mEnableAsciiArmorOutput) {
|
||||||
|
/* cleartext signature: sign-only of ascii text */
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_signing, 8, 100);
|
||||||
|
log.add(LogLevel.DEBUG, LogType.MSG_SE_SIGNING, indent);
|
||||||
|
|
||||||
|
// write -----BEGIN PGP SIGNED MESSAGE-----
|
||||||
|
armorOut.beginClearText(mSignatureHashAlgorithm);
|
||||||
|
|
||||||
|
InputStream in = mData.getInputStream();
|
||||||
|
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||||
|
|
||||||
|
// update signature buffer with first line
|
||||||
|
processLine(reader.readLine(), armorOut, signatureGenerator);
|
||||||
|
|
||||||
|
// TODO: progress: fake annealing?
|
||||||
|
while (true) {
|
||||||
|
String line = reader.readLine();
|
||||||
|
|
||||||
|
// end cleartext signature with newline, see http://tools.ietf.org/html/rfc4880#section-7
|
||||||
|
if (line == null) {
|
||||||
|
armorOut.write(NEW_LINE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
armorOut.write(NEW_LINE);
|
||||||
|
|
||||||
|
// update signature buffer with input line
|
||||||
|
signatureGenerator.update(NEW_LINE);
|
||||||
|
processLine(line, armorOut, signatureGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
armorOut.endClearText();
|
||||||
|
|
||||||
|
pOut = new BCPGOutputStream(armorOut);
|
||||||
|
} else if (enableSignature && !mCleartextInput) {
|
||||||
|
/* sign-only binary (files/data stream) */
|
||||||
|
|
||||||
|
updateProgress(R.string.progress_signing, 8, 100);
|
||||||
|
log.add(LogLevel.DEBUG, LogType.MSG_SE_ENCRYPTING, indent);
|
||||||
|
|
||||||
|
InputStream in = mData.getInputStream();
|
||||||
|
|
||||||
|
if (enableCompression) {
|
||||||
|
compressGen = new PGPCompressedDataGenerator(mCompressionId);
|
||||||
|
bcpgOut = new BCPGOutputStream(compressGen.open(out));
|
||||||
|
} else {
|
||||||
|
bcpgOut = new BCPGOutputStream(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
|
||||||
|
|
||||||
|
PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
|
||||||
|
pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, mOriginalFilename, new Date(),
|
||||||
|
new byte[1 << 16]);
|
||||||
|
|
||||||
|
long alreadyWritten = 0;
|
||||||
|
int length;
|
||||||
|
byte[] buffer = new byte[1 << 16];
|
||||||
|
while ((length = in.read(buffer)) > 0) {
|
||||||
|
pOut.write(buffer, 0, length);
|
||||||
|
|
||||||
|
signatureGenerator.update(buffer, 0, length);
|
||||||
|
|
||||||
|
alreadyWritten += length;
|
||||||
|
if (mData.getSize() > 0) {
|
||||||
|
long progress = 100 * alreadyWritten / mData.getSize();
|
||||||
|
progressScaler.setProgress((int) progress, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
literalGen.close();
|
||||||
} else {
|
} else {
|
||||||
bcpgOut = new BCPGOutputStream(encryptionOut);
|
pOut = null;
|
||||||
|
log.add(LogLevel.WARN, LogType.MSG_SE_CLEARSIGN_ONLY, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableSignature) {
|
if (enableSignature) {
|
||||||
signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
|
updateProgress(R.string.progress_generating_signature, 95, 100);
|
||||||
}
|
try {
|
||||||
|
signatureGenerator.generate().encode(pOut);
|
||||||
PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
|
} catch (NfcSyncPGPContentSignerBuilder.NfcInteractionNeeded e) {
|
||||||
char literalDataFormatTag;
|
// this secret key diverts to a OpenPGP card, throw exception with hash that will be signed
|
||||||
if (mCleartextInput) {
|
log.add(LogLevel.OK, LogType.MSG_SE_PENDING_NFC, indent);
|
||||||
literalDataFormatTag = PGPLiteralData.UTF8;
|
SignEncryptResult result =
|
||||||
} else {
|
new SignEncryptResult(SignEncryptResult.RESULT_PENDING_NFC, log);
|
||||||
literalDataFormatTag = PGPLiteralData.BINARY;
|
result.setNfcData(e.hashToSign, e.hashAlgo, e.creationTimestamp);
|
||||||
}
|
return new SignEncryptResult(SignEncryptResult.RESULT_PENDING_NFC, log);
|
||||||
pOut = literalGen.open(bcpgOut, literalDataFormatTag, mOriginalFilename, new Date(),
|
|
||||||
new byte[1 << 16]);
|
|
||||||
|
|
||||||
long alreadyWritten = 0;
|
|
||||||
int length;
|
|
||||||
byte[] buffer = new byte[1 << 16];
|
|
||||||
InputStream in = mData.getInputStream();
|
|
||||||
while ((length = in.read(buffer)) > 0) {
|
|
||||||
pOut.write(buffer, 0, length);
|
|
||||||
|
|
||||||
// update signature buffer if signature is requested
|
|
||||||
if (enableSignature) {
|
|
||||||
signatureGenerator.update(buffer, 0, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
alreadyWritten += length;
|
|
||||||
if (mData.getSize() > 0) {
|
|
||||||
long progress = 100 * alreadyWritten / mData.getSize();
|
|
||||||
progressScaler.setProgress((int) progress, 100);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
literalGen.close();
|
// closing outputs
|
||||||
} else if (enableSignature && mCleartextInput && mEnableAsciiArmorOutput) {
|
// NOTE: closing needs to be done in the correct order!
|
||||||
/* cleartext signature: sign-only of ascii text */
|
// TODO: closing bcpgOut and pOut???
|
||||||
|
if (enableEncryption) {
|
||||||
updateProgress(R.string.progress_signing, 8, 100);
|
if (enableCompression) {
|
||||||
|
compressGen.close();
|
||||||
// write -----BEGIN PGP SIGNED MESSAGE-----
|
|
||||||
armorOut.beginClearText(mSignatureHashAlgorithm);
|
|
||||||
|
|
||||||
InputStream in = mData.getInputStream();
|
|
||||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
|
||||||
|
|
||||||
// update signature buffer with first line
|
|
||||||
processLine(reader.readLine(), armorOut, signatureGenerator);
|
|
||||||
|
|
||||||
// TODO: progress: fake annealing?
|
|
||||||
while (true) {
|
|
||||||
String line = reader.readLine();
|
|
||||||
|
|
||||||
// end cleartext signature with newline, see http://tools.ietf.org/html/rfc4880#section-7
|
|
||||||
if (line == null) {
|
|
||||||
armorOut.write(NEW_LINE);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
armorOut.write(NEW_LINE);
|
encryptionOut.close();
|
||||||
|
}
|
||||||
// update signature buffer with input line
|
if (mEnableAsciiArmorOutput) {
|
||||||
signatureGenerator.update(NEW_LINE);
|
armorOut.close();
|
||||||
processLine(line, armorOut, signatureGenerator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
armorOut.endClearText();
|
out.close();
|
||||||
|
mOutStream.close();
|
||||||
|
|
||||||
pOut = new BCPGOutputStream(armorOut);
|
} catch (SignatureException e) {
|
||||||
} else if (enableSignature && !mCleartextInput) {
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_SIG, indent);
|
||||||
/* sign-only binary (files/data stream) */
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
|
} catch (PGPException e) {
|
||||||
updateProgress(R.string.progress_signing, 8, 100);
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_PGP, indent);
|
||||||
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
InputStream in = mData.getInputStream();
|
} catch (IOException e) {
|
||||||
|
log.add(LogLevel.ERROR, LogType.MSG_SE_ERROR_IO, indent);
|
||||||
if (enableCompression) {
|
return new SignEncryptResult(SignEncryptResult.RESULT_ERROR, log);
|
||||||
compressGen = new PGPCompressedDataGenerator(mCompressionId);
|
|
||||||
bcpgOut = new BCPGOutputStream(compressGen.open(out));
|
|
||||||
} else {
|
|
||||||
bcpgOut = new BCPGOutputStream(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
|
|
||||||
|
|
||||||
PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
|
|
||||||
pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, mOriginalFilename, new Date(),
|
|
||||||
new byte[1 << 16]);
|
|
||||||
|
|
||||||
long alreadyWritten = 0;
|
|
||||||
int length;
|
|
||||||
byte[] buffer = new byte[1 << 16];
|
|
||||||
while ((length = in.read(buffer)) > 0) {
|
|
||||||
pOut.write(buffer, 0, length);
|
|
||||||
|
|
||||||
signatureGenerator.update(buffer, 0, length);
|
|
||||||
|
|
||||||
alreadyWritten += length;
|
|
||||||
if (mData.getSize() > 0) {
|
|
||||||
long progress = 100 * alreadyWritten / mData.getSize();
|
|
||||||
progressScaler.setProgress((int) progress, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
literalGen.close();
|
|
||||||
} else {
|
|
||||||
pOut = null;
|
|
||||||
Log.e(Constants.TAG, "not supported!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableSignature) {
|
|
||||||
updateProgress(R.string.progress_generating_signature, 95, 100);
|
|
||||||
try {
|
|
||||||
signatureGenerator.generate().encode(pOut);
|
|
||||||
} catch (NfcSyncPGPContentSignerBuilder.NfcInteractionNeeded e) {
|
|
||||||
// this secret key diverts to a OpenPGP card, throw exception with hash that will be signed
|
|
||||||
throw new NeedNfcDataException(e.hashToSign, e.hashAlgo, e.creationTimestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// closing outputs
|
|
||||||
// NOTE: closing needs to be done in the correct order!
|
|
||||||
// TODO: closing bcpgOut and pOut???
|
|
||||||
if (enableEncryption) {
|
|
||||||
if (enableCompression) {
|
|
||||||
compressGen.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
encryptionOut.close();
|
|
||||||
}
|
|
||||||
if (mEnableAsciiArmorOutput) {
|
|
||||||
armorOut.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
out.close();
|
|
||||||
mOutStream.close();
|
|
||||||
|
|
||||||
updateProgress(R.string.progress_done, 100, 100);
|
updateProgress(R.string.progress_done, 100, 100);
|
||||||
|
|
||||||
|
log.add(LogLevel.OK, LogType.MSG_SE_OK, indent);
|
||||||
|
return new SignEncryptResult(SignEncryptResult.RESULT_OK, log);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
|
private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput,
|
||||||
|
@ -45,6 +45,8 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
|||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
|
import org.sufficientlysecure.keychain.remote.ui.RemoteServiceActivity;
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.OperationResultParcel.LogEntryParcel;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.SignEncryptResult;
|
||||||
import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
|
import org.sufficientlysecure.keychain.ui.ImportKeysActivity;
|
||||||
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
|
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
@ -269,25 +271,28 @@ public class OpenPgpService extends RemoteService {
|
|||||||
// TODO: currently always assume cleartext input, no sign-only of binary currently!
|
// TODO: currently always assume cleartext input, no sign-only of binary currently!
|
||||||
builder.setCleartextInput(true);
|
builder.setCleartextInput(true);
|
||||||
|
|
||||||
try {
|
// execute PGP operation!
|
||||||
builder.build().execute();
|
SignEncryptResult result = builder.build().execute();
|
||||||
|
|
||||||
// throw exceptions upwards to client with meaningful messages
|
if (result.isPending()) {
|
||||||
} catch (PgpSignEncrypt.KeyExtractionException e) {
|
switch (result.getResult()) {
|
||||||
throw new Exception(getString(R.string.error_could_not_extract_private_key));
|
case SignEncryptResult.RESULT_PENDING_NFC:
|
||||||
} catch (PgpSignEncrypt.NoPassphraseException e) {
|
// return PendingIntent to execute NFC activity
|
||||||
throw new Exception(getString(R.string.error_no_signature_passphrase));
|
// pass through the signature creation timestamp to be used again on second execution
|
||||||
} catch (PgpSignEncrypt.WrongPassphraseException e) {
|
// of PgpSignEncrypt when we have the signed hash!
|
||||||
throw new Exception(getString(R.string.error_wrong_passphrase));
|
data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, result.getNfcTimestamp().getTime());
|
||||||
} catch (PgpSignEncrypt.NoSigningKeyException e) {
|
return getNfcSignIntent(data, passphrase, result.getNfcHash(), result.getNfcAlgo());
|
||||||
throw new Exception(getString(R.string.error_no_signature_key));
|
|
||||||
} catch (PgpSignEncrypt.NeedNfcDataException e) {
|
default:
|
||||||
// return PendingIntent to execute NFC activity
|
throw new Exception("Encountered unhandled pending state - please file a bug report!");
|
||||||
// pass through the signature creation timestamp to be used again on second execution
|
}
|
||||||
// of PgpSignEncrypt when we have the signed hash!
|
|
||||||
data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, e.mCreationTimestamp.getTime());
|
|
||||||
return getNfcSignIntent(data, passphrase, e.mHashToSign, e.mHashAlgo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!result.success()) {
|
||||||
|
LogEntryParcel errorMsg = result.getLog().getLast();
|
||||||
|
throw new Exception(getString(errorMsg.mType.getMsgId()));
|
||||||
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
is.close();
|
is.close();
|
||||||
os.close();
|
os.close();
|
||||||
@ -379,26 +384,28 @@ public class OpenPgpService extends RemoteService {
|
|||||||
.setNfcState(nfcSignedHash, nfcCreationDate);
|
.setNfcState(nfcSignedHash, nfcCreationDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
// execute PGP operation!
|
||||||
// execute PGP operation!
|
SignEncryptResult result = builder.build().execute();
|
||||||
builder.build().execute();
|
|
||||||
|
|
||||||
// throw exceptions upwards to client with meaningful messages
|
if (result.isPending()) {
|
||||||
} catch (PgpSignEncrypt.KeyExtractionException e) {
|
switch (result.getResult()) {
|
||||||
throw new Exception(getString(R.string.error_could_not_extract_private_key));
|
case SignEncryptResult.RESULT_PENDING_NFC:
|
||||||
} catch (PgpSignEncrypt.NoPassphraseException e) {
|
// return PendingIntent to execute NFC activity
|
||||||
throw new Exception(getString(R.string.error_no_signature_passphrase));
|
// pass through the signature creation timestamp to be used again on second execution
|
||||||
} catch (PgpSignEncrypt.WrongPassphraseException e) {
|
// of PgpSignEncrypt when we have the signed hash!
|
||||||
throw new Exception(getString(R.string.error_wrong_passphrase));
|
data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, result.getNfcTimestamp().getTime());
|
||||||
} catch (PgpSignEncrypt.NoSigningKeyException e) {
|
return getNfcSignIntent(data, passphrase, result.getNfcHash(), result.getNfcAlgo());
|
||||||
throw new Exception(getString(R.string.error_no_signature_key));
|
|
||||||
} catch (PgpSignEncrypt.NeedNfcDataException e) {
|
default:
|
||||||
// return PendingIntent to execute NFC activity
|
throw new Exception("Encountered unhandled pending state - please file a bug report!");
|
||||||
// pass through the signature creation timestamp to be used again on second execution
|
}
|
||||||
// of PgpSignEncrypt when we have the signed hash!
|
|
||||||
data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, e.mCreationTimestamp.getTime());
|
|
||||||
return getNfcSignIntent(data, passphrase, e.mHashToSign, e.mHashAlgo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!result.success()) {
|
||||||
|
LogEntryParcel errorMsg = result.getLog().getLast();
|
||||||
|
throw new Exception(getString(errorMsg.mType.getMsgId()));
|
||||||
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
is.close();
|
is.close();
|
||||||
os.close();
|
os.close();
|
||||||
|
@ -63,6 +63,7 @@ import org.sufficientlysecure.keychain.service.results.ConsolidateResult;
|
|||||||
import org.sufficientlysecure.keychain.service.results.EditKeyResult;
|
import org.sufficientlysecure.keychain.service.results.EditKeyResult;
|
||||||
import org.sufficientlysecure.keychain.service.results.ImportKeyResult;
|
import org.sufficientlysecure.keychain.service.results.ImportKeyResult;
|
||||||
import org.sufficientlysecure.keychain.service.results.SaveKeyringResult;
|
import org.sufficientlysecure.keychain.service.results.SaveKeyringResult;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.SignEncryptResult;
|
||||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||||
import org.sufficientlysecure.keychain.util.InputData;
|
import org.sufficientlysecure.keychain.util.InputData;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
@ -91,7 +92,7 @@ public class KeychainIntentService extends IntentService implements Progressable
|
|||||||
public static final String EXTRA_DATA = "data";
|
public static final String EXTRA_DATA = "data";
|
||||||
|
|
||||||
/* possible actions */
|
/* possible actions */
|
||||||
public static final String ACTION_ENCRYPT_SIGN = Constants.INTENT_PREFIX + "ENCRYPT_SIGN";
|
public static final String ACTION_SIGN_ENCRYPT = Constants.INTENT_PREFIX + "SIGN_ENCRYPT";
|
||||||
|
|
||||||
public static final String ACTION_DECRYPT_VERIFY = Constants.INTENT_PREFIX + "DECRYPT_VERIFY";
|
public static final String ACTION_DECRYPT_VERIFY = Constants.INTENT_PREFIX + "DECRYPT_VERIFY";
|
||||||
|
|
||||||
@ -247,7 +248,7 @@ public class KeychainIntentService extends IntentService implements Progressable
|
|||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
|
|
||||||
// executeServiceMethod action from extra bundle
|
// executeServiceMethod action from extra bundle
|
||||||
if (ACTION_ENCRYPT_SIGN.equals(action)) {
|
if (ACTION_SIGN_ENCRYPT.equals(action)) {
|
||||||
try {
|
try {
|
||||||
/* Input */
|
/* Input */
|
||||||
int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET);
|
int source = data.get(SOURCE) != null ? data.getInt(SOURCE) : data.getInt(TARGET);
|
||||||
@ -309,7 +310,8 @@ public class KeychainIntentService extends IntentService implements Progressable
|
|||||||
builder.setCleartextInput(true);
|
builder.setCleartextInput(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.build().execute();
|
SignEncryptResult result = builder.build().execute();
|
||||||
|
resultData.putParcelable(SignEncryptResult.EXTRA_RESULT, result);
|
||||||
|
|
||||||
outStream.close();
|
outStream.close();
|
||||||
|
|
||||||
@ -779,12 +781,6 @@ public class KeychainIntentService extends IntentService implements Progressable
|
|||||||
if (e instanceof PgpGeneralMsgIdException) {
|
if (e instanceof PgpGeneralMsgIdException) {
|
||||||
e = ((PgpGeneralMsgIdException) e).getContextualized(this);
|
e = ((PgpGeneralMsgIdException) e).getContextualized(this);
|
||||||
message = e.getMessage();
|
message = e.getMessage();
|
||||||
} else if (e instanceof PgpSignEncrypt.KeyExtractionException) {
|
|
||||||
message = getString(R.string.error_could_not_extract_private_key);
|
|
||||||
} else if (e instanceof PgpSignEncrypt.NoPassphraseException) {
|
|
||||||
message = getString(R.string.error_no_signature_passphrase);
|
|
||||||
} else if (e instanceof PgpSignEncrypt.NoSigningKeyException) {
|
|
||||||
message = getString(R.string.error_no_signature_key);
|
|
||||||
} else {
|
} else {
|
||||||
message = e.getMessage();
|
message = e.getMessage();
|
||||||
}
|
}
|
||||||
|
@ -474,6 +474,30 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
MSG_DC_TRAIL_UNKNOWN (R.string.msg_dc_trail_unknown),
|
MSG_DC_TRAIL_UNKNOWN (R.string.msg_dc_trail_unknown),
|
||||||
MSG_DC_UNLOCKING (R.string.msg_dc_unlocking),
|
MSG_DC_UNLOCKING (R.string.msg_dc_unlocking),
|
||||||
|
|
||||||
|
// signencrypt
|
||||||
|
MSG_SE_ASYMMETRIC (R.string.msg_se_asymmetric),
|
||||||
|
MSG_SE_CLEARSIGN_ONLY (R.string.msg_se_clearsign_only),
|
||||||
|
MSG_SE_COMPRESSING (R.string.msg_se_compressing),
|
||||||
|
MSG_SE_ENCRYPTING (R.string.msg_se_encrypting),
|
||||||
|
MSG_SE_ERROR_BAD_PASSPHRASE (R.string.msg_se_error_bad_passphrase),
|
||||||
|
MSG_SE_ERROR_IO (R.string.msg_se_error_io),
|
||||||
|
MSG_SE_ERROR_SIGN_KEY(R.string.msg_se_error_sign_key),
|
||||||
|
MSG_SE_ERROR_KEY_SIGN (R.string.msg_se_error_key_sign),
|
||||||
|
MSG_SE_ERROR_NFC (R.string.msg_se_error_nfc),
|
||||||
|
MSG_SE_ERROR_NO_PASSPHRASE (R.string.msg_se_error_no_passphrase),
|
||||||
|
MSG_SE_ERROR_PGP (R.string.msg_se_error_pgp),
|
||||||
|
MSG_SE_ERROR_SIG (R.string.msg_se_error_sig),
|
||||||
|
MSG_SE_ERROR_UNLOCK (R.string.msg_se_error_unlock),
|
||||||
|
MSG_SE_KEY_OK (R.string.msg_se_key_ok),
|
||||||
|
MSG_SE_KEY_UNKNOWN (R.string.msg_se_key_unknown),
|
||||||
|
MSG_SE_KEY_WARN (R.string.msg_se_key_warn),
|
||||||
|
MSG_SE_OK (R.string.msg_se_ok),
|
||||||
|
MSG_SE_PENDING_NFC (R.string.msg_se_pending_nfc),
|
||||||
|
MSG_SE (R.string.msg_se),
|
||||||
|
MSG_SE_SIGNING (R.string.msg_se_signing),
|
||||||
|
MSG_SE_SIGCRYPTING (R.string.msg_se_sigcrypting),
|
||||||
|
MSG_SE_SYMMETRIC (R.string.msg_se_symmetric),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
private final int mMsgId;
|
private final int mMsgId;
|
||||||
@ -562,6 +586,13 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
return mParcels.isEmpty();
|
return mParcels.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LogEntryParcel getLast() {
|
||||||
|
if (mParcels.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return mParcels.get(mParcels.size() -1);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<LogEntryParcel> iterator() {
|
public Iterator<LogEntryParcel> iterator() {
|
||||||
return mParcels.iterator();
|
return mParcels.iterator();
|
||||||
|
@ -183,7 +183,7 @@ public class EncryptFileActivity extends DrawerActivity implements EncryptActivi
|
|||||||
|
|
||||||
// Send all information needed to service to edit key in other thread
|
// Send all information needed to service to edit key in other thread
|
||||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||||
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
|
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
||||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, createEncryptBundle());
|
intent.putExtra(KeychainIntentService.EXTRA_DATA, createEncryptBundle());
|
||||||
|
|
||||||
// Message is received after encrypting is done in KeychainIntentService
|
// Message is received after encrypting is done in KeychainIntentService
|
||||||
|
@ -42,6 +42,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
|||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.SignEncryptResult;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Notify;
|
import org.sufficientlysecure.keychain.util.Notify;
|
||||||
@ -184,7 +185,7 @@ public class EncryptTextActivity extends DrawerActivity implements EncryptActivi
|
|||||||
|
|
||||||
// Send all information needed to service to edit key in other thread
|
// Send all information needed to service to edit key in other thread
|
||||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||||
intent.setAction(KeychainIntentService.ACTION_ENCRYPT_SIGN);
|
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
||||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, createEncryptBundle());
|
intent.putExtra(KeychainIntentService.EXTRA_DATA, createEncryptBundle());
|
||||||
|
|
||||||
// Message is received after encrypting is done in KeychainIntentService
|
// Message is received after encrypting is done in KeychainIntentService
|
||||||
@ -195,14 +196,26 @@ public class EncryptTextActivity extends DrawerActivity implements EncryptActivi
|
|||||||
super.handleMessage(message);
|
super.handleMessage(message);
|
||||||
|
|
||||||
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
||||||
|
|
||||||
|
SignEncryptResult result =
|
||||||
|
message.getData().getParcelable(SignEncryptResult.EXTRA_RESULT);
|
||||||
|
|
||||||
|
// TODO if (result.isPending())
|
||||||
|
|
||||||
|
if (!result.success()) {
|
||||||
|
result.createNotify(EncryptTextActivity.this).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mShareAfterEncrypt) {
|
if (mShareAfterEncrypt) {
|
||||||
// Share encrypted message/file
|
// Share encrypted message/file
|
||||||
startActivity(sendWithChooserExcludingEncrypt(message));
|
startActivity(sendWithChooserExcludingEncrypt(message));
|
||||||
} else {
|
} else {
|
||||||
// Copy to clipboard
|
// Copy to clipboard
|
||||||
copyToClipboard(message);
|
copyToClipboard(message);
|
||||||
Notify.showNotify(EncryptTextActivity.this,
|
result.createNotify(EncryptTextActivity.this).show();
|
||||||
R.string.encrypt_sign_clipboard_successful, Notify.Style.INFO);
|
// Notify.showNotify(EncryptTextActivity.this,
|
||||||
|
// R.string.encrypt_sign_clipboard_successful, Notify.Style.INFO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -701,7 +701,7 @@
|
|||||||
<string name="msg_mf_error_revoked_primary">"Revoked user ids cannot be primary!"</string>
|
<string name="msg_mf_error_revoked_primary">"Revoked user ids cannot be primary!"</string>
|
||||||
<string name="msg_mf_error_null_expiry">"Expiry time cannot be "same as before" on subkey creation. This is a programming error, please file a bug report!"</string>
|
<string name="msg_mf_error_null_expiry">"Expiry time cannot be "same as before" on subkey creation. This is a programming error, please file a bug report!"</string>
|
||||||
<string name="msg_mf_error_passphrase_master">"Fatal error decrypting master key! This is likely a programming error, please file a bug report!"</string>
|
<string name="msg_mf_error_passphrase_master">"Fatal error decrypting master key! This is likely a programming error, please file a bug report!"</string>
|
||||||
<string name="msg_mf_error_pgp">"PGP internal exception!"</string>
|
<string name="msg_mf_error_pgp">"Internal PGP error!"</string>
|
||||||
<string name="msg_mf_error_sig">"Signature exception!"</string>
|
<string name="msg_mf_error_sig">"Signature exception!"</string>
|
||||||
<string name="msg_mf_master">"Modifying master certifications"</string>
|
<string name="msg_mf_master">"Modifying master certifications"</string>
|
||||||
<string name="msg_mf_passphrase">"Changing passphrase for keyring…"</string>
|
<string name="msg_mf_passphrase">"Changing passphrase for keyring…"</string>
|
||||||
@ -803,6 +803,30 @@
|
|||||||
<string name="msg_dc_trail_unknown">"Encountered trailing data of unknown type"</string>
|
<string name="msg_dc_trail_unknown">"Encountered trailing data of unknown type"</string>
|
||||||
<string name="msg_dc_unlocking">"Unlocking secret key"</string>
|
<string name="msg_dc_unlocking">"Unlocking secret key"</string>
|
||||||
|
|
||||||
|
<!-- Messages for SignEncrypt operation -->
|
||||||
|
<string name="msg_se_asymmetric">"Preparing public keys for encryption"</string>
|
||||||
|
<string name="msg_se_clearsign_only">"Signing of cleartext input not supported!"</string>
|
||||||
|
<string name="msg_se_compressing">"Preparing compression"</string>
|
||||||
|
<string name="msg_se_encrypting">"Encrypting data"</string>
|
||||||
|
<string name="msg_se_error_bad_passphrase">"Bad passphrase!"</string>
|
||||||
|
<string name="msg_se_error_io">"Encountered IO Exception during operation!"</string>
|
||||||
|
<string name="msg_se_error_key_sign">"Selected signing key cannot sign data!"</string>
|
||||||
|
<string name="msg_se_error_sign_key">"Error fetching signing key!"</string>
|
||||||
|
<string name="msg_se_error_nfc">"NFC data error!"</string>
|
||||||
|
<string name="msg_se_error_no_passphrase">"No passphrase provided!"</string>
|
||||||
|
<string name="msg_se_error_pgp">"Internal PGP error!"</string>
|
||||||
|
<string name="msg_se_error_sig">"Encountered PGP signature exception!"</string>
|
||||||
|
<string name="msg_se_error_unlock">"Unknown error unlocking key!"</string>
|
||||||
|
<string name="msg_se_key_ok">"Encrypting for key: %s"</string>
|
||||||
|
<string name="msg_se_key_unknown">"Missing key for encryption: %s"</string>
|
||||||
|
<string name="msg_se_key_warn">"Bad key for encryption: %s"</string>
|
||||||
|
<string name="msg_se_ok">"Sign/Encrypt operation successful!"</string>
|
||||||
|
<string name="msg_se_pending_nfc">"NFC token required, requesting user input…"</string>
|
||||||
|
<string name="msg_se_signing">"Signing data (without encryption)"</string>
|
||||||
|
<string name="msg_se_sigcrypting">"Encrypting data with signature"</string>
|
||||||
|
<string name="msg_se">"Starting sign and/or encrypt operation"</string>
|
||||||
|
<string name="msg_se_symmetric">"Preparing symmetric encryption"</string>
|
||||||
|
|
||||||
<!-- PassphraseCache -->
|
<!-- PassphraseCache -->
|
||||||
<string name="passp_cache_notif_click_to_clear">"Click to clear cached passphrases"</string>
|
<string name="passp_cache_notif_click_to_clear">"Click to clear cached passphrases"</string>
|
||||||
<string name="passp_cache_notif_n_keys">"OpenKeychain has cached %d passphrases"</string>
|
<string name="passp_cache_notif_n_keys">"OpenKeychain has cached %d passphrases"</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user