diff options
author | hsm <hsm@lamia.panaceas.james.local> | 2016-05-29 03:12:09 +0100 |
---|---|---|
committer | hsm <hsm@lamia.panaceas.james.local> | 2016-05-29 04:47:15 +0100 |
commit | 5aa36b089f09346787e44f9850924faae1fda363 (patch) | |
tree | 0f14297dedecb42af771743241a0ed7ee78f308c /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp | |
parent | 24b92172be818c7ee67a235ad8403f01a4495987 (diff) | |
download | open-keychain-5aa36b089f09346787e44f9850924faae1fda363.tar.gz open-keychain-5aa36b089f09346787e44f9850924faae1fda363.tar.bz2 open-keychain-5aa36b089f09346787e44f9850924faae1fda363.zip |
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp')
2 files changed, 84 insertions, 7 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java index c4e569d24..5d904331e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java @@ -30,6 +30,7 @@ public class PgpSignEncryptData implements Parcelable { protected String mVersionHeader = null; protected boolean mEnableAsciiArmorOutput = false; + protected boolean mSshAuth = false; protected int mCompressionAlgorithm = CompressionAlgorithmTags.UNCOMPRESSED; protected long[] mEncryptionMasterKeyIds = null; protected Passphrase mSymmetricPassphrase = null; @@ -53,6 +54,7 @@ public class PgpSignEncryptData implements Parcelable { mVersionHeader = source.readString(); mEnableAsciiArmorOutput = source.readInt() == 1; + mSshAuth = source.readInt() == 1; mCompressionAlgorithm = source.readInt(); mEncryptionMasterKeyIds = source.createLongArray(); mSymmetricPassphrase = source.readParcelable(loader); @@ -78,6 +80,7 @@ public class PgpSignEncryptData implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(mVersionHeader); dest.writeInt(mEnableAsciiArmorOutput ? 1 : 0); + dest.writeInt(mSshAuth ? 1 : 0); dest.writeInt(mCompressionAlgorithm); dest.writeLongArray(mEncryptionMasterKeyIds); dest.writeParcelable(mSymmetricPassphrase, 0); @@ -183,6 +186,10 @@ public class PgpSignEncryptData implements Parcelable { return mEnableAsciiArmorOutput; } + public boolean isSshAuth() { + return mSshAuth; + } + public String getVersionHeader() { return mVersionHeader; } @@ -197,6 +204,11 @@ public class PgpSignEncryptData implements Parcelable { return this; } + public PgpSignEncryptData setSshAuth(boolean sshAuth) { + mSshAuth = sshAuth; + return this; + } + public PgpSignEncryptData setCleartextSignature(boolean cleartextSignature) { this.mCleartextSignature = cleartextSignature; return this; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index 7a1d99927..a855dcac8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -24,6 +24,7 @@ import android.net.Uri; import android.os.Parcelable; import android.support.annotation.NonNull; +import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.CompressionAlgorithmTags; @@ -58,6 +59,10 @@ import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.ProgressScaler; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import java.nio.ByteBuffer; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; @@ -165,6 +170,7 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa return executeInternal(input, cryptoInput, inputData, outputStream); } + /** * Signs and/or encrypts data based on parameters of class */ @@ -238,7 +244,10 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa } // Make sure we are allowed to sign here! - if (!signingKey.canSign()) { + if ((!signingKey.canSign() && !data.isSshAuth()) || + (!signingKey.canAuthenticate() && data.isSshAuth())) { + Log.w(Constants.TAG, "canSign " + signingKey.canSign() + " canAuthenticate " + + signingKey.canAuthenticate() + " isSshAuth "+ data.isSshAuth()); log.add(LogType.MSG_PSE_ERROR_KEY_SIGN, indent); return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); } @@ -298,7 +307,11 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa // Use requested hash algo int requestedAlgorithm = data.getSignatureHashAlgorithm(); if (requestedAlgorithm == PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT) { - data.setSignatureHashAlgorithm(PgpSecurityConstants.DEFAULT_HASH_ALGORITHM); + if (data.isSshAuth()) { + data.setSignatureHashAlgorithm(HashAlgorithmTags.SHA1); + } else { + data.setSignatureHashAlgorithm(PgpSecurityConstants.DEFAULT_HASH_ALGORITHM); + } } } updateProgress(R.string.progress_preparing_streams, 2, 100); @@ -386,6 +399,7 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa ByteArrayOutputStream detachedByteOut = null; ArmoredOutputStream detachedArmorOut = null; BCPGOutputStream detachedBcpgOut = null; + MessageDigest raw_digest = null; long opTime, startTime = System.currentTimeMillis(); @@ -491,6 +505,28 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa } else if (enableSignature && data.isDetachedSignature()) { /* detached signature */ + // JMM - GROSS HACK + // + // The PGP stack doesn't do signatures of arbitary data: it wants + // to use its own structure for the message, so we have + // to be creative. We let the pgp stack do its stuff, but when + // it calls out to the NFC stack, we catch it and swap the + // message digest for own own. + // + // this means we have to check cyrptoInput for the correct + // hash ourselves on the 2nd trip through when the + // client resents the request. + // + + if (data.isSshAuth()) { + try { + raw_digest = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + log.add(LogType.MSG_PSE_ERROR_IO, indent); + return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); + } + } + updateProgress(R.string.progress_signing, 8, 100); log.add(LogType.MSG_PSE_SIGNING_DETACHED, indent); @@ -515,6 +551,9 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa while ((length = in.read(buffer)) > 0) { // no output stream is written, no changed to original data! + if (raw_digest != null) + raw_digest.update(buffer, 0, length); + signatureGenerator.update(buffer, 0, length); alreadyWritten += length; @@ -582,11 +621,37 @@ public class PgpSignEncryptOperation extends BaseOperation<PgpSignEncryptInputPa signatureGenerator.generate().encode(pOut); } } catch (NfcSyncPGPContentSignerBuilder.NfcInteractionNeeded e) { - // this secret key diverts to a OpenPGP card, throw exception with hash that will be signed - log.add(LogType.MSG_PSE_PENDING_NFC, indent); - return new PgpSignEncryptResult(log, RequiredInputParcel.createSecurityTokenSignOperation( - signingKey.getRing().getMasterKeyId(), signingKey.getKeyId(), - e.hashToSign, e.hashAlgo, cryptoInput.getSignatureTime()), cryptoInput); + + // JMM - 2nd part of gross hack + // first swap the message digest for the raw one + // before this hits the NFC stack + + if (raw_digest != null) + e.hashToSign = raw_digest.digest(); + + // Test to see if we already have the answer for the hash + // as the test in encode() above was checking the wrong + // hash. + + byte [] answer = cryptoInput.getCryptoData().get(ByteBuffer.wrap(e.hashToSign)); + + if (raw_digest == null || answer == null) { + // We haven't done the hash yet, so kick it off to the NFC stack + + // this secret key diverts to a OpenPGP card, throw exception with hash that will be signed + + log.add(LogType.MSG_PSE_PENDING_NFC, indent); + return new PgpSignEncryptResult(log, RequiredInputParcel.createSecurityTokenSignOperation( + signingKey.getRing().getMasterKeyId(), signingKey.getKeyId(), + e.hashToSign, e.hashAlgo, cryptoInput.getSignatureTime()), cryptoInput); + } else if (raw_digest != null) { + // We've aready done the work, replace the output stream + // from the PGP signature with just the signature as we want just + // a raw signature + + detachedByteOut = new ByteArrayOutputStream(); + detachedByteOut.write(answer, 0, answer.length); + } } } |