comparison app/src/main/java/com/five_ten_sg/connectbot/service/AuthAgentService.java @ 438:d29cce60f393

migrate from Eclipse to Android Studio
author Carl Byington <carl@five-ten-sg.com>
date Thu, 03 Dec 2015 11:23:55 -0800
parents src/com/five_ten_sg/connectbot/service/AuthAgentService.java@b40bc65fa09a
children
comparison
equal deleted inserted replaced
437:208b31032318 438:d29cce60f393
1 package com.five_ten_sg.connectbot.service;
2
3 import java.io.IOException;
4 import java.security.KeyPair;
5 import java.security.PrivateKey;
6 import java.security.PublicKey;
7 import java.security.interfaces.DSAPrivateKey;
8 import java.security.interfaces.DSAPublicKey;
9 import java.security.interfaces.ECPrivateKey;
10 import java.security.interfaces.ECPublicKey;
11 import java.security.interfaces.RSAPrivateKey;
12 import java.security.interfaces.RSAPublicKey;
13 import java.util.HashMap;
14 import java.util.Map;
15 import java.util.Map.Entry;
16 import java.util.concurrent.locks.Condition;
17 import java.util.concurrent.locks.Lock;
18 import java.util.concurrent.locks.ReentrantLock;
19
20 import com.five_ten_sg.connectbot.service.TerminalManager;
21 import com.five_ten_sg.connectbot.service.TerminalManager.KeyHolder;
22 import android.app.Service;
23 import android.content.ComponentName;
24 import android.content.Intent;
25 import android.content.ServiceConnection;
26 import android.os.IBinder;
27 import android.os.RemoteException;
28 import android.util.Log;
29
30 import com.madgag.ssh.android.authagent.AndroidAuthAgent;
31 import ch.ethz.ssh2.crypto.SecureRandomFix;
32 import ch.ethz.ssh2.signature.DSASHA1Verify;
33 import ch.ethz.ssh2.signature.ECDSASHA2Verify;
34 import ch.ethz.ssh2.signature.RSASHA1Verify;
35
36
37 public class AuthAgentService extends Service {
38 private static final String TAG = "ConnectBot.AuthAgentService";
39 protected TerminalManager manager;
40 final Lock lock = new ReentrantLock();
41 final Condition managerReady = lock.newCondition();
42
43 private ServiceConnection connection = new ServiceConnection() {
44 public void onServiceConnected(ComponentName className, IBinder service) {
45 Log.d(TAG, "Terminal manager available! Hurrah");
46 manager = ((TerminalManager.TerminalBinder) service).getService();
47 lock.lock();
48
49 try {
50 managerReady.signal();
51 }
52 finally {
53 lock.unlock();
54 }
55 }
56 public void onServiceDisconnected(ComponentName className) {
57 manager = null;
58 Log.d(TAG, "Terminal manager gone...");
59 }
60 };
61
62 @Override
63 public IBinder onBind(Intent intent) {
64 Log.d(TAG, "onBind() called");
65 bindService(new Intent(this, TerminalManager.class), connection, BIND_AUTO_CREATE);
66 return mBinder;
67 }
68
69 private final AndroidAuthAgent.Stub mBinder = new AndroidAuthAgent.Stub() {
70 public Map getIdentities() throws RemoteException {
71 Log.d(TAG, "getIdentities() called");
72 waitForTerminalManager();
73 Log.d(TAG, "getIdentities() manager.loadedKeypairs : " + manager.loadedKeypairs);
74 return sshEncodedPubKeysFrom(manager.loadedKeypairs);
75 }
76 public byte[] sign(byte[] publicKey, byte[] data) throws RemoteException {
77 Log.d(TAG, "sign() called");
78 waitForTerminalManager();
79 KeyPair pair = keyPairFor(publicKey);
80 Log.d(TAG, "sign() - signing keypair found : " + pair);
81
82 if (pair == null) {
83 return null;
84 }
85
86 PrivateKey privKey = pair.getPrivate();
87
88 if (privKey instanceof RSAPrivateKey) {
89 return sshEncodedSignatureFor(data, (RSAPrivateKey) privKey);
90 }
91 else if (privKey instanceof DSAPrivateKey) {
92 return sshEncodedSignatureFor(data, (DSAPrivateKey) privKey);
93 }
94 else if (privKey instanceof ECPrivateKey) {
95 return sshEncodedSignatureFor(data, (ECPrivateKey) privKey);
96 }
97
98 return null;
99 }
100 private void waitForTerminalManager() throws RemoteException {
101 lock.lock();
102
103 try {
104 while (manager == null) {
105 Log.d(TAG, "Waiting for TerminalManager...");
106 managerReady.await();
107 }
108 }
109 catch (InterruptedException e) {
110 throw new RemoteException();
111 }
112 finally {
113 lock.unlock();
114 }
115
116 Log.d(TAG, "Got TerminalManager : " + manager);
117 }
118 private Map<String, byte[]> sshEncodedPubKeysFrom(Map<String, KeyHolder> keypairs) {
119 Map<String, byte[]> pubkeys = new HashMap<String, byte[]> (keypairs.size());
120
121 for (Entry<String, KeyHolder> entry : keypairs.entrySet()) {
122 byte[] encodedKey = sshEncodedPubKeyFrom(entry.getValue().pair);
123
124 if (encodedKey != null) {
125 pubkeys.put(entry.getKey(), encodedKey);
126 }
127 }
128
129 return pubkeys;
130 }
131 private byte[] sshEncodedPubKeyFrom(KeyPair pair) {
132 try {
133 PrivateKey privKey = pair.getPrivate();
134
135 if (privKey instanceof RSAPrivateKey) {
136 RSAPublicKey pubkey = (RSAPublicKey)pair.getPublic();
137 return RSASHA1Verify.encodeSSHRSAPublicKey(pubkey);
138 }
139 else if (privKey instanceof DSAPrivateKey) {
140 DSAPublicKey pubkey = (DSAPublicKey)pair.getPublic();
141 return DSASHA1Verify.encodeSSHDSAPublicKey(pubkey);
142 }
143 else if (privKey instanceof ECPrivateKey) {
144 ECPublicKey pubkey = (ECPublicKey) pair.getPublic();
145 return ECDSASHA2Verify.encodeSSHECDSAPublicKey(pubkey);
146 }
147 }
148 catch (IOException e) {
149 Log.e(TAG, "Couldn't encode " + pair, e);
150 }
151
152 return null;
153 }
154 private byte[] sshEncodedSignatureFor(byte[] data, RSAPrivateKey privKey) {
155 try {
156 byte[] signature = RSASHA1Verify.generateSignature(data, privKey);
157 return RSASHA1Verify.encodeSSHRSASignature(signature);
158 }
159 catch (IOException e) {
160 throw new RuntimeException(e);
161 }
162 }
163 private byte[] sshEncodedSignatureFor(byte[] data, DSAPrivateKey privKey) {
164 try {
165 byte[] signature = DSASHA1Verify.generateSignature(data, privKey, new SecureRandomFix());
166 return DSASHA1Verify.encodeSSHDSASignature(signature);
167 }
168 catch (IOException e) {
169 throw new RuntimeException(e);
170 }
171 }
172 private byte[] sshEncodedSignatureFor(byte[] data, ECPrivateKey privKey) {
173 try {
174 byte[] signature = ECDSASHA2Verify.generateSignature(data, privKey);
175 return ECDSASHA2Verify.encodeSSHECDSASignature(signature, privKey.getParams());
176 }
177 catch (IOException e) {
178 throw new RuntimeException(e);
179 }
180 }
181 private KeyPair keyPairFor(byte[] publicKey) {
182 String nickname = manager.getKeyNickname(publicKey);
183
184 if (nickname == null) {
185 Log.w(TAG, "No key-pair found for public-key.");
186 return null;
187 }
188
189 // check manager.loadedKeypairs.get(nickname).bean.isConfirmUse() and promptForPubkeyUse(nickname) ?
190 return manager.getKey(nickname);
191 }
192 };
193 }