From f8fffe5e29f55856b93b5e21f1a672bb1a0fec40 Mon Sep 17 00:00:00 2001 From: hsm Date: Sun, 29 May 2016 04:17:53 +0100 Subject: Add support for auth with open-keychain --- .../trilead/ssh2/signature/TokenRSASHA1Verify.java | 175 +++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 sshlib/src/main/java/com/trilead/ssh2/signature/TokenRSASHA1Verify.java (limited to 'sshlib/src/main/java/com/trilead/ssh2/signature/TokenRSASHA1Verify.java') diff --git a/sshlib/src/main/java/com/trilead/ssh2/signature/TokenRSASHA1Verify.java b/sshlib/src/main/java/com/trilead/ssh2/signature/TokenRSASHA1Verify.java new file mode 100644 index 0000000..d8b95fa --- /dev/null +++ b/sshlib/src/main/java/com/trilead/ssh2/signature/TokenRSASHA1Verify.java @@ -0,0 +1,175 @@ + +package com.trilead.ssh2.signature; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.Signature; +import java.security.SignatureException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; + + +import com.trilead.ssh2.log.Logger; +import com.trilead.ssh2.packets.TypesReader; +import com.trilead.ssh2.packets.TypesWriter; + +import android.app.Activity; +import android.content.IntentSender; +import android.content.Intent; +import android.app.PendingIntent; + + + +import org.openintents.openpgp.IOpenPgpService2; +import org.openintents.openpgp.OpenPgpDecryptionResult; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.openintents.openpgp.util.OpenPgpApi; +import org.openintents.openpgp.util.OpenPgpServiceConnection; +import org.openintents.openpgp.util.OpenPgpUtils; + + +/** + * TokenRSASHA1Verify. + * + * @author James McKenzie + */ +public class TokenRSASHA1Verify +{ + private static final Object lock = new Object(); + + private static final Logger log = Logger.getLogger (TokenRSASHA1Verify.class); + private static final int pending_intent_code = 28674; + + static private Activity activity; + static private OpenPgpServiceConnection mServiceConnection; + + static private boolean async_semaphore = false; + static private boolean async_abort = false; + static private Intent async_intent; + + public static void open (Activity _activity) + { + activity = _activity; + + if (activity == null) + return; + + mServiceConnection = new OpenPgpServiceConnection (activity, "org.sufficientlysecure.keychain"); + mServiceConnection.bindToService(); + } + + + public static void callback (int requestCode, int resultCode, Intent intent) + { + if (requestCode != pending_intent_code) return; + + synchronized (lock) { + if (resultCode == Activity.RESULT_OK) { + async_intent = intent; + async_abort = false; + } else + async_abort = true; + + async_semaphore = true; + + lock.notify(); + } + } + + public static byte[] generateSignature (byte[] message, TokenRSAPrivateKey pk) throws IOException + { + byte [] fail = new byte[0]; + long key_id = pk.getKeyId(); + + if ((activity == null) || (mServiceConnection == null)) return fail; + + Intent data = new Intent(); + data.setAction (OpenPgpApi.ACTION_SSH_AUTH); + data.putExtra (OpenPgpApi.EXTRA_SIGN_KEY_ID, key_id); + + InputStream is = new ByteArrayInputStream (message); + + OpenPgpApi api = new OpenPgpApi (activity, mServiceConnection.getService()); + Intent result = api.executeApi (data, is, null); + + + int result_code; + + do { + result_code = result.getIntExtra (OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + + if (result_code == OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED) { + + synchronized (lock) { + async_semaphore = false; + async_abort = true; + + PendingIntent pi = result.getParcelableExtra (OpenPgpApi.RESULT_INTENT); + + try { + activity.startIntentSenderForResult (pi.getIntentSender(), pending_intent_code, null, 0, 0, 0); + } catch (IntentSender.SendIntentException e) { + return fail; + } + + try { + while (async_semaphore == false) + lock.wait(); + } catch (InterruptedException e) { } + + if (async_abort) + return fail; + + data = async_intent; + } + + is = new ByteArrayInputStream (message); + result = api.executeApi (data, is, null); + + } else + break; + + } while (true); + + switch (result_code) { + case OpenPgpApi.RESULT_CODE_SUCCESS: { + + byte [] output = result.getByteArrayExtra (OpenPgpApi.RESULT_DETACHED_SIGNATURE); + + if (output == null) + return fail; + + return output; + } + + case OpenPgpApi.RESULT_CODE_ERROR: { + //OpenPgpError error = result.getParcelableExtra (OpenPgpApi.RESULT_ERROR); + return fail; + } + } + + return fail; + + } + + public static void close() + { + if (mServiceConnection != null) + mServiceConnection.unbindFromService(); + + activity = null; + } + +} -- cgit v1.2.3