1 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
3 Copyright (c) 2002-2010 ymnk, JCraft,Inc. All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 1. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the distribution.
15 3. The names of the authors may not be used to endorse or promote products
16 derived from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 package com.jcraft.jsch;
32 public class DHG1 extends KeyExchange{
34 static final byte[] g={ 2 };
35 static final byte[] p={
37 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
38 (byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
39 (byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
40 (byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
41 (byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
42 (byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
43 (byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
44 (byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
45 (byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
46 (byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
47 (byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
48 (byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
49 (byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
50 (byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
51 (byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81,
52 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
55 private static final int SSH_MSG_KEXDH_INIT= 30;
56 private static final int SSH_MSG_KEXDH_REPLY= 31;
58 static final int RSA=0;
59 static final int DSS=1;
80 private Packet packet;
82 public void init(Session session,
83 byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
93 Class c=Class.forName(session.getConfig("sha-1"));
94 sha=(HASH)(c.newInstance());
98 System.err.println(e);
102 packet=new Packet(buf);
105 Class c=Class.forName(session.getConfig("dh"));
106 dh=(DH)(c.newInstance());
110 //System.err.println(e);
117 // The client responds with:
118 // byte SSH_MSG_KEXDH_INIT(30)
119 // mpint e <- g^x mod p
120 // x is a random number (1 < x < (p-1)/2)
125 buf.putByte((byte)SSH_MSG_KEXDH_INIT);
127 session.write(packet);
129 if(JSch.getLogger().isEnabled(Logger.INFO)){
130 JSch.getLogger().log(Logger.INFO,
131 "SSH_MSG_KEXDH_INIT sent");
132 JSch.getLogger().log(Logger.INFO,
133 "expecting SSH_MSG_KEXDH_REPLY");
136 state=SSH_MSG_KEXDH_REPLY;
139 public boolean next(Buffer _buf) throws Exception{
143 case SSH_MSG_KEXDH_REPLY:
144 // The server responds with:
145 // byte SSH_MSG_KEXDH_REPLY(31)
146 // string server public host key and certificates (K_S)
148 // string signature of H
153 System.err.println("type: must be 31 "+j);
157 K_S=_buf.getString();
158 // K_S is server_key_blob, which includes ....
163 // impint pub_key of dsa
164 //System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
165 byte[] f=_buf.getMPInt();
166 byte[] sig_of_H=_buf.getString();
168 for(int ii=0; ii<sig_of_H.length;ii++){
169 System.err.print(Integer.toHexString(sig_of_H[ii]&0xff));
170 System.err.print(": ");
172 System.err.println("");
178 //The hash H is computed as the HASH hash of the concatenation of the
180 // string V_C, the client's version string (CR and NL excluded)
181 // string V_S, the server's version string (CR and NL excluded)
182 // string I_C, the payload of the client's SSH_MSG_KEXINIT
183 // string I_S, the payload of the server's SSH_MSG_KEXINIT
184 // string K_S, the host key
185 // mpint e, exchange value sent by the client
186 // mpint f, exchange value sent by the server
187 // mpint K, the shared secret
188 // This value is called the exchange hash, and it is used to authenti-
189 // cate the key exchange.
191 buf.putString(V_C); buf.putString(V_S);
192 buf.putString(I_C); buf.putString(I_S);
194 buf.putMPInt(e); buf.putMPInt(f);
196 byte[] foo=new byte[buf.getLength()];
198 sha.update(foo, 0, foo.length);
200 //System.err.print("H -> "); //dump(H, 0, H.length);
204 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
205 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
206 String alg=Util.byte2str(K_S, i, j);
209 boolean result=false;
211 if(alg.equals("ssh-rsa")){
218 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
219 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
220 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
222 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
223 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
224 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
227 // SignatureRSA sig=new SignatureRSA();
230 SignatureRSA sig=null;
232 Class c=Class.forName(session.getConfig("signature.rsa"));
233 sig=(SignatureRSA)(c.newInstance());
237 System.err.println(e);
240 sig.setPubKey(ee, n);
242 result=sig.verify(sig_of_H);
244 if(JSch.getLogger().isEnabled(Logger.INFO)){
245 JSch.getLogger().log(Logger.INFO,
246 "ssh_rsa_verify: signature "+result);
250 else if(alg.equals("ssh-dss")){
258 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
259 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
260 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
262 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
263 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
264 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
266 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
267 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
268 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
270 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
271 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
272 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
274 // SignatureDSA sig=new SignatureDSA();
276 SignatureDSA sig=null;
278 Class c=Class.forName(session.getConfig("signature.dss"));
279 sig=(SignatureDSA)(c.newInstance());
283 System.err.println(e);
285 sig.setPubKey(f, p, q, g);
287 result=sig.verify(sig_of_H);
289 if(JSch.getLogger().isEnabled(Logger.INFO)){
290 JSch.getLogger().log(Logger.INFO,
291 "ssh_dss_verify: signature "+result);
296 System.err.println("unknown alg");
304 public String getKeyType(){
305 if(type==DSS) return "DSA";
309 public int getState(){return state; }