aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-07-22 18:09:12 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-07-22 18:09:12 +0200
commit99af2c33d35f9557c2f23e1abddd82d770e763d8 (patch)
tree9173537ce1b1d1c2fe2fa58b9b52d302f16c7eaf
parentafd6851e5b8b8dd0f1c50144fe36dbcf9ae8f5cd (diff)
downloadopen-keychain-99af2c33d35f9557c2f23e1abddd82d770e763d8.tar.gz
open-keychain-99af2c33d35f9557c2f23e1abddd82d770e763d8.tar.bz2
open-keychain-99af2c33d35f9557c2f23e1abddd82d770e763d8.zip
Reuse signature creation timestamp for synchronous signing
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java41
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/WrappedSecretKey.java23
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java13
m---------extern/openpgp-card-nfc-lib0
4 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 {
diff --git a/extern/openpgp-card-nfc-lib b/extern/openpgp-card-nfc-lib
-Subproject bedea7f2734451e7990d4971cb7f9f4e3cbe2fe
+Subproject 6402aa9232d6de01c696dc6ba23ca86355474d4