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-master.tar.gz open-keychain-master.tar.bz2 open-keychain-master.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); +                    }                  }              } | 
