diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java index 1784ae063..2e4eafe41 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -29,6 +29,7 @@ import org.spongycastle.openpgp.PGPLiteralDataGenerator; import org.spongycastle.openpgp.PGPSignatureGenerator; import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; @@ -49,6 +50,7 @@ import java.security.NoSuchProviderException; import java.security.SignatureException; import java.util.Arrays; import java.util.Date; +import java.util.LinkedList; /** * This class uses a Builder pattern! @@ -72,6 +74,9 @@ public class PgpSignEncrypt { private boolean mCleartextInput; private String mOriginalFilename; + private byte[] mNfcSignedHash = null; + private Date mNfcCreationTimestamp = null; + private static byte[] NEW_LINE; static { @@ -100,6 +105,8 @@ public class PgpSignEncrypt { this.mSignaturePassphrase = builder.mSignaturePassphrase; this.mAdditionalEncryptId = builder.mAdditionalEncryptId; this.mCleartextInput = builder.mCleartextInput; + this.mNfcSignedHash = builder.mNfcSignedHash; + this.mNfcCreationTimestamp = builder.mNfcCreationTimestamp; this.mOriginalFilename = builder.mOriginalFilename; } @@ -123,6 +130,8 @@ public class PgpSignEncrypt { private long mAdditionalEncryptId = Constants.key.none; private boolean mCleartextInput = false; private String mOriginalFilename = ""; + private byte[] mNfcSignedHash = null; + private Date mNfcCreationTimestamp = null; public Builder(ProviderHelper providerHelper, InputData data, OutputStream outStream) { mProviderHelper = providerHelper; @@ -207,6 +216,12 @@ public class PgpSignEncrypt { return this; } + public Builder setNfcState(byte[] signedHash, Date creationTimestamp) { + mNfcSignedHash = signedHash; + mNfcCreationTimestamp = creationTimestamp; + return this; + } + public PgpSignEncrypt build() { return new PgpSignEncrypt(this); } @@ -234,17 +249,34 @@ public class PgpSignEncrypt { } } + 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 */ public void execute() throws IOException, PGPException, NoSuchProviderException, - NoSuchAlgorithmException, SignatureException, KeyExtractionException, NoSigningKeyException, NoPassphraseException { + NoSuchAlgorithmException, SignatureException, KeyExtractionException, NoSigningKeyException, NoPassphraseException, NeedNfcDataException, WrongPassphraseException { boolean enableSignature = mSignatureMasterKeyId != Constants.key.none; boolean enableEncryption = ((mEncryptionMasterKeyIds != null && mEncryptionMasterKeyIds.length > 0) @@ -296,10 +328,19 @@ public class PgpSignEncrypt { updateProgress(R.string.progress_extracting_signature_key, 0, 100); try { - signingKey.unlock(mSignaturePassphrase); + if (!signingKey.unlock(mSignaturePassphrase)) { + throw new WrongPassphraseException(); + } } catch (PgpGeneralException e) { throw new KeyExtractionException(); } + + // check if hash algo is supported + LinkedList<Integer> supported = signingKey.getSupportedHashAlgorithms(); + if (!supported.contains(mSignatureHashAlgorithm)) { + // get most preferred + mSignatureHashAlgorithm = supported.getLast(); + } } updateProgress(R.string.progress_preparing_streams, 2, 100); @@ -346,7 +387,7 @@ public class PgpSignEncrypt { try { boolean cleartext = mCleartextInput && mEnableAsciiArmorOutput && !enableEncryption; signatureGenerator = signingKey.getSignatureGenerator( - mSignatureHashAlgorithm, cleartext); + mSignatureHashAlgorithm, cleartext, mNfcSignedHash, mNfcCreationTimestamp); } catch (PgpGeneralException e) { // TODO throw correct type of exception (which shouldn't be PGPException) throw new KeyExtractionException(); @@ -356,9 +397,10 @@ public class PgpSignEncrypt { ProgressScaler progressScaler = new ProgressScaler(mProgressable, 8, 95, 100); PGPCompressedDataGenerator compressGen = null; - OutputStream pOut; + OutputStream pOut = null; OutputStream encryptionOut = null; BCPGOutputStream bcpgOut; + if (enableEncryption) { /* actual encryption */ updateProgress(R.string.progress_encrypting, 8, 100); @@ -477,7 +519,12 @@ public class PgpSignEncrypt { if (enableSignature) { updateProgress(R.string.progress_generating_signature, 95, 100); - signatureGenerator.generate().encode(pOut); + 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 |