diff options
| author | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-07-22 18:09:12 +0200 | 
|---|---|---|
| committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-07-22 18:09:12 +0200 | 
| commit | 99af2c33d35f9557c2f23e1abddd82d770e763d8 (patch) | |
| tree | 9173537ce1b1d1c2fe2fa58b9b52d302f16c7eaf /OpenKeychain/src/main/java/org | |
| parent | afd6851e5b8b8dd0f1c50144fe36dbcf9ae8f5cd (diff) | |
| download | open-keychain-99af2c33d35f9557c2f23e1abddd82d770e763d8.tar.gz open-keychain-99af2c33d35f9557c2f23e1abddd82d770e763d8.tar.bz2 open-keychain-99af2c33d35f9557c2f23e1abddd82d770e763d8.zip  | |
Reuse signature creation timestamp for synchronous signing
Diffstat (limited to 'OpenKeychain/src/main/java/org')
3 files changed, 44 insertions, 33 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 cc34e8737..41b81bf1c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -18,10 +18,8 @@  package org.sufficientlysecure.keychain.pgp; -import org.openkeychain.nfc.NfcHandler;  import org.spongycastle.bcpg.ArmoredOutputStream;  import org.spongycastle.bcpg.BCPGOutputStream; -import org.spongycastle.bcpg.S2K;  import org.spongycastle.openpgp.PGPCompressedDataGenerator;  import org.spongycastle.openpgp.PGPEncryptedDataGenerator;  import org.spongycastle.openpgp.PGPException; @@ -41,17 +39,14 @@ import org.sufficientlysecure.keychain.util.InputData;  import org.sufficientlysecure.keychain.util.Log;  import java.io.BufferedReader; -import java.io.ByteArrayOutputStream;  import java.io.IOException;  import java.io.InputStream;  import java.io.InputStreamReader;  import java.io.OutputStream;  import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset;  import java.security.NoSuchAlgorithmException;  import java.security.NoSuchProviderException;  import java.security.SignatureException; -import java.util.ArrayList;  import java.util.Arrays;  import java.util.Date;  import java.util.LinkedList; @@ -77,7 +72,9 @@ public class PgpSignEncrypt {      private String mSignaturePassphrase;      private boolean mEncryptToSigner;      private boolean mCleartextInput; -    private byte[] mNfcData; + +    private byte[] mNfcSignedHash = null; +    private Date mNfcCreationTimestamp = null;      private static byte[] NEW_LINE; @@ -108,7 +105,8 @@ public class PgpSignEncrypt {          this.mSignaturePassphrase = builder.mSignaturePassphrase;          this.mEncryptToSigner = builder.mEncryptToSigner;          this.mCleartextInput = builder.mCleartextInput; -        this.mNfcData = builder.mNfcData; +        this.mNfcSignedHash = builder.mNfcSignedHash; +        this.mNfcCreationTimestamp = builder.mNfcCreationTimestamp;      }      public static class Builder { @@ -131,7 +129,9 @@ public class PgpSignEncrypt {          private String mSignaturePassphrase = null;          private boolean mEncryptToSigner = false;          private boolean mCleartextInput = false; -        private byte[] mNfcData = null; + +        private byte[] mNfcSignedHash = null; +        private Date mNfcCreationTimestamp = null;          public Builder(ProviderHelper providerHelper, String versionHeader, InputData data, OutputStream outStream) {              this.mProviderHelper = providerHelper; @@ -216,8 +216,9 @@ public class PgpSignEncrypt {              return this;          } -        public Builder setNfcData(byte[] nfcData) { -            mNfcData = nfcData; +        public Builder setNfcState(byte[] signedHash, Date creationTimestamp) { +            mNfcSignedHash = signedHash; +            mNfcCreationTimestamp = creationTimestamp;              return this;          } @@ -259,19 +260,15 @@ public class PgpSignEncrypt {      }      public static class NeedNfcDataException extends Exception { -        public byte[] mData; +        public byte[] mHashToSign; +        public Date mCreationTimestamp; -        public NeedNfcDataException(byte[] data) { -            mData = data; +        public NeedNfcDataException(byte[] hashToSign, Date creationTimestamp) { +            mHashToSign = hashToSign; +            mCreationTimestamp = creationTimestamp;          }      } -    // TODO: remove later -    static String convertStreamToString(java.io.InputStream is) { -        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); -        return s.hasNext() ? s.next() : ""; -    } -      /**       * Signs and/or encrypts data based on parameters of class       */ @@ -381,7 +378,7 @@ public class PgpSignEncrypt {                              mSignatureHashAlgorithm, cleartext);                  } else {                      signatureGenerator = signingKey.getSignatureGenerator( -                            mSignatureHashAlgorithm, cleartext, mNfcData); +                            mSignatureHashAlgorithm, cleartext, mNfcSignedHash, mNfcCreationTimestamp);                  }              } catch (PgpGeneralException e) {                  // TODO throw correct type of exception (which shouldn't be PGPException) @@ -546,8 +543,8 @@ public class PgpSignEncrypt {                  try {                      signatureGenerator.generate().encode(pOut);                  } catch (NfcSyncPGPContentSignerBuilder.NfcInteractionNeeded e) { -                    // this secret key diverts to a OpenPGP card, throw exception with to-be-signed hash -                    throw new NeedNfcDataException(e.hashToSign); +                    // this secret key diverts to a OpenPGP card, throw exception with hash that will be signed +                    throw new NeedNfcDataException(e.hashToSign, e.creationTimestamp);                  }              }          } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSecretKey.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSecretKey.java index 141f2d5eb..ea919b683 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSecretKey.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSecretKey.java @@ -1,7 +1,6 @@  package org.sufficientlysecure.keychain.pgp;  import org.spongycastle.bcpg.HashAlgorithmTags; -import org.spongycastle.bcpg.PublicKeyAlgorithmTags;  import org.spongycastle.bcpg.S2K;  import org.spongycastle.openpgp.PGPException;  import org.spongycastle.openpgp.PGPPrivateKey; @@ -30,11 +29,9 @@ import org.sufficientlysecure.keychain.util.Log;  import java.security.NoSuchAlgorithmException;  import java.security.NoSuchProviderException;  import java.security.SignatureException; -import java.util.ArrayList; -import java.util.HashSet; +import java.util.Date;  import java.util.LinkedList;  import java.util.List; -import java.util.Set;  /** Wrapper for a PGPSecretKey.   * @@ -121,7 +118,7 @@ public class WrappedSecretKey extends WrappedPublicKey {      }      public PGPSignatureGenerator getSignatureGenerator(int hashAlgo, boolean cleartext, -                                                       byte[] nfcSignedHash) +                                                       byte[] nfcSignedHash, Date nfcCreationTimestamp)              throws PgpGeneralException {          if (mPrivateKeyState == PRIVATE_KEY_STATE_LOCKED) {              throw new PrivateKeyNotUnlockedException(); @@ -129,11 +126,21 @@ public class WrappedSecretKey extends WrappedPublicKey {          PGPContentSignerBuilder contentSignerBuilder;          if (mPrivateKeyState == PRIVATE_KEY_STATE_DIVERT_TO_CARD) { +            // to sign using nfc PgpSignEncrypt is executed two times. +            // the first time it stops to return the PendingIntent for nfc connection and signing the hash +            // the second time the signed hash is used. +            // to get the same hash we cache the timestamp for the second round! +            if (nfcCreationTimestamp == null) { +                nfcCreationTimestamp = new Date(); +            } +              // use synchronous "NFC based" SignerBuilder              contentSignerBuilder = new NfcSyncPGPContentSignerBuilder(                      mSecretKey.getPublicKey().getAlgorithm(), hashAlgo, -                    mSecretKey.getKeyID(), nfcSignedHash) +                    mSecretKey.getKeyID(), nfcSignedHash, nfcCreationTimestamp)                      .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + +            Log.d(Constants.TAG, "mSecretKey.getKeyID() "+ PgpKeyHelper.convertKeyIdToHex(mSecretKey.getKeyID()));          } else {              // content signer based on signing key algorithm and chosen hash algorithm              contentSignerBuilder = new JcaPGPContentSignerBuilder( @@ -155,6 +162,10 @@ public class WrappedSecretKey extends WrappedPublicKey {              PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();              spGen.setSignerUserID(false, mRing.getPrimaryUserIdWithFallback()); +            if (nfcCreationTimestamp != null) { +                spGen.setSignatureCreationTime(false, nfcCreationTimestamp); +                Log.d(Constants.TAG, "For NFC: set sig creation time to " + nfcCreationTimestamp); +            }              signatureGenerator.setHashedSubpackets(spGen.generate());              return signatureGenerator;          } catch(PGPException e) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index a00759180..e18af2eda 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -50,6 +50,7 @@ import org.sufficientlysecure.keychain.util.Log;  import java.io.InputStream;  import java.io.OutputStream;  import java.util.ArrayList; +import java.util.Date;  import java.util.Set;  public class OpenPgpService extends RemoteService { @@ -136,11 +137,11 @@ public class OpenPgpService extends RemoteService {          return result;      } -    private Intent getNfcIntent(Intent data, byte[] in) { +    private Intent getNfcIntent(Intent data, byte[] hashToSign) {          // build PendingIntent for Yubikey NFC operations          Intent intent = new Intent(getBaseContext(), NfcActivity.class);          intent.setAction(NfcActivity.ACTION_SIGN_HASH); -        intent.putExtra(NfcActivity.EXTRA_NFC_DATA, in); +        intent.putExtra(NfcActivity.EXTRA_NFC_HASH_TO_SIGN, hashToSign);          intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);          // pass params through to activity that it can be returned again later to repeat pgp operation          intent.putExtra(NfcActivity.EXTRA_DATA, data); @@ -191,7 +192,8 @@ public class OpenPgpService extends RemoteService {                  return passphraseBundle;              } -            byte[] nfcData = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_DATA); +            byte[] nfcSignedHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH); +            Date nfcCreationTimestamp = new Date(data.getLongExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, 0));              // Get Input- and OutputStream from ParcelFileDescriptor              InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); @@ -210,7 +212,7 @@ public class OpenPgpService extends RemoteService {                          .setSignatureForceV3(false)                          .setSignatureMasterKeyId(accSettings.getKeyId())                          .setSignaturePassphrase(passphrase) -                        .setNfcData(nfcData); +                        .setNfcState(nfcSignedHash, nfcCreationTimestamp);                  // TODO: currently always assume cleartext input, no sign-only of binary currently!                  builder.setCleartextInput(true); @@ -229,7 +231,8 @@ public class OpenPgpService extends RemoteService {                      throw new Exception(getString(R.string.error_no_signature_key));                  } catch (PgpSignEncrypt.NeedNfcDataException e) {                      // return PendingIntent to execute NFC activity -                    Intent nfcIntent = getNfcIntent(data, e.mData); +                    data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, e.mCreationTimestamp.getTime()); +                    Intent nfcIntent = getNfcIntent(data, e.mHashToSign);                      return nfcIntent;                  }              } finally {  | 
