001: /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
002: /*
003: Copyright (c) 2002-2008 ymnk, JCraft,Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: 1. Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010:
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in
013: the documentation and/or other materials provided with the distribution.
014:
015: 3. The names of the authors may not be used to endorse or promote products
016: derived from this software without specific prior written permission.
017:
018: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
019: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
020: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
021: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
022: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
024: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
027: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jcraft.jsch;
031:
032: public abstract class KeyExchange {
033:
034: static final int PROPOSAL_KEX_ALGS = 0;
035: static final int PROPOSAL_SERVER_HOST_KEY_ALGS = 1;
036: static final int PROPOSAL_ENC_ALGS_CTOS = 2;
037: static final int PROPOSAL_ENC_ALGS_STOC = 3;
038: static final int PROPOSAL_MAC_ALGS_CTOS = 4;
039: static final int PROPOSAL_MAC_ALGS_STOC = 5;
040: static final int PROPOSAL_COMP_ALGS_CTOS = 6;
041: static final int PROPOSAL_COMP_ALGS_STOC = 7;
042: static final int PROPOSAL_LANG_CTOS = 8;
043: static final int PROPOSAL_LANG_STOC = 9;
044: static final int PROPOSAL_MAX = 10;
045:
046: //static String kex_algs="diffie-hellman-group-exchange-sha1"+
047: // ",diffie-hellman-group1-sha1";
048:
049: //static String kex="diffie-hellman-group-exchange-sha1";
050: static String kex = "diffie-hellman-group1-sha1";
051: static String server_host_key = "ssh-rsa,ssh-dss";
052: static String enc_c2s = "blowfish-cbc";
053: static String enc_s2c = "blowfish-cbc";
054: static String mac_c2s = "hmac-md5"; // hmac-md5,hmac-sha1,hmac-ripemd160,
055: // hmac-sha1-96,hmac-md5-96
056: static String mac_s2c = "hmac-md5";
057: //static String comp_c2s="none"; // zlib
058: //static String comp_s2c="none";
059: static String lang_c2s = "";
060: static String lang_s2c = "";
061:
062: public static final int STATE_END = 0;
063:
064: protected Session session = null;
065: protected HASH sha = null;
066: protected byte[] K = null;
067: protected byte[] H = null;
068: protected byte[] K_S = null;
069:
070: public abstract void init(Session session, byte[] V_S, byte[] V_C,
071: byte[] I_S, byte[] I_C) throws Exception;
072:
073: public abstract boolean next(Buffer buf) throws Exception;
074:
075: public abstract String getKeyType();
076:
077: public abstract int getState();
078:
079: /*
080: void dump(byte[] foo){
081: for(int i=0; i<foo.length; i++){
082: if((foo[i]&0xf0)==0)System.err.print("0");
083: System.err.print(Integer.toHexString(foo[i]&0xff));
084: if(i%16==15){System.err.println(""); continue;}
085: if(i%2==1)System.err.print(" ");
086: }
087: }
088: */
089:
090: protected static String[] guess(byte[] I_S, byte[] I_C) {
091: //System.err.println("guess: ");
092: String[] guess = new String[PROPOSAL_MAX];
093: Buffer sb = new Buffer(I_S);
094: sb.setOffSet(17);
095: Buffer cb = new Buffer(I_C);
096: cb.setOffSet(17);
097:
098: for (int i = 0; i < PROPOSAL_MAX; i++) {
099: byte[] sp = sb.getString(); // server proposal
100: byte[] cp = cb.getString(); // client proposal
101:
102: //System.err.println("server-proposal: |"+new String(sp)+"|");
103: //System.err.println("client-proposal: |"+new String(cp)+"|");
104:
105: int j = 0;
106: int k = 0;
107: //System.err.println(new String(cp));
108: loop: while (j < cp.length) {
109: while (j < cp.length && cp[j] != ',')
110: j++;
111: if (k == j)
112: return null;
113: String algorithm = new String(cp, k, j - k);
114: //System.err.println("algorithm: "+algorithm);
115: int l = 0;
116: int m = 0;
117: while (l < sp.length) {
118: while (l < sp.length && sp[l] != ',')
119: l++;
120: if (m == l)
121: return null;
122: //System.err.println(" "+new String(sp, m, l-m));
123: if (algorithm.equals(new String(sp, m, l - m))) {
124: guess[i] = algorithm;
125: //System.err.println(" "+algorithm);
126: break loop;
127: }
128: l++;
129: m = l;
130: }
131: j++;
132: k = j;
133: }
134: if (j == 0) {
135: guess[i] = "";
136: } else if (guess[i] == null) {
137: //System.err.println(" fail");
138: return null;
139: }
140: }
141:
142: if (JSch.getLogger().isEnabled(Logger.INFO)) {
143: JSch.getLogger().log(
144: Logger.INFO,
145: "kex: server->client" + " "
146: + guess[PROPOSAL_ENC_ALGS_STOC] + " "
147: + guess[PROPOSAL_MAC_ALGS_STOC] + " "
148: + guess[PROPOSAL_COMP_ALGS_STOC]);
149: JSch.getLogger().log(
150: Logger.INFO,
151: "kex: client->server" + " "
152: + guess[PROPOSAL_ENC_ALGS_CTOS] + " "
153: + guess[PROPOSAL_MAC_ALGS_CTOS] + " "
154: + guess[PROPOSAL_COMP_ALGS_CTOS]);
155: }
156:
157: // for(int i=0; i<PROPOSAL_MAX; i++){
158: // System.err.println("guess: ["+guess[i]+"]");
159: // }
160:
161: return guess;
162: }
163:
164: public String getFingerPrint() {
165: HASH hash = null;
166: try {
167: Class c = Class.forName(session.getConfig("md5"));
168: hash = (HASH) (c.newInstance());
169: } catch (Exception e) {
170: System.err.println("getFingerPrint: " + e);
171: }
172: return Util.getFingerPrint(hash, getHostKey());
173: }
174:
175: byte[] getK() {
176: return K;
177: }
178:
179: byte[] getH() {
180: return H;
181: }
182:
183: HASH getHash() {
184: return sha;
185: }
186:
187: byte[] getHostKey() {
188: return K_S;
189: }
190: }
|