aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp
diff options
context:
space:
mode:
authorhsm <hsm@lamia.panaceas.james.local>2016-05-29 03:12:09 +0100
committerhsm <hsm@lamia.panaceas.james.local>2016-05-29 04:47:15 +0100
commit5aa36b089f09346787e44f9850924faae1fda363 (patch)
tree0f14297dedecb42af771743241a0ed7ee78f308c /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp
parent24b92172be818c7ee67a235ad8403f01a4495987 (diff)
downloadopen-keychain-master.tar.gz
open-keychain-master.tar.bz2
open-keychain-master.zip
ssh authentication supportHEADmaster
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptData.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java79
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);
+ }
}
}