]> Joshua Wise's Git repositories - dumload.git/blob - src/com/jcraft/jsch/DHG1.java
Initial commit.
[dumload.git] / src / com / jcraft / jsch / DHG1.java
1 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2 /*
3 Copyright (c) 2002-2010 ymnk, JCraft,Inc. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8   1. Redistributions of source code must retain the above copyright notice,
9      this list of conditions and the following disclaimer.
10
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.
14
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.
17
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.
28 */
29
30 package com.jcraft.jsch;
31
32 public class DHG1 extends KeyExchange{
33
34   static final byte[] g={ 2 };
35   static final byte[] p={
36 (byte)0x00,
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
53 };
54
55   private static final int SSH_MSG_KEXDH_INIT=                     30;
56   private static final int SSH_MSG_KEXDH_REPLY=                    31;
57
58   static final int RSA=0;
59   static final int DSS=1;
60   private int type=0;
61
62   private int state;
63
64   DH dh;
65 //  HASH sha;
66
67 //  byte[] K;
68 //  byte[] H;
69
70   byte[] V_S;
71   byte[] V_C;
72   byte[] I_S;
73   byte[] I_C;
74
75 //  byte[] K_S;
76
77   byte[] e;
78
79   private Buffer buf;
80   private Packet packet;
81
82   public void init(Session session,
83                    byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
84     this.session=session;
85     this.V_S=V_S;      
86     this.V_C=V_C;      
87     this.I_S=I_S;      
88     this.I_C=I_C;      
89
90 //    sha=new SHA1();
91 //    sha.init();
92     try{
93       Class c=Class.forName(session.getConfig("sha-1"));
94       sha=(HASH)(c.newInstance());
95       sha.init();
96     }
97     catch(Exception e){
98       System.err.println(e);
99     }
100
101     buf=new Buffer();
102     packet=new Packet(buf);
103
104     try{
105       Class c=Class.forName(session.getConfig("dh"));
106       dh=(DH)(c.newInstance());
107       dh.init();
108     }
109     catch(Exception e){
110       //System.err.println(e);
111       throw e;
112     }
113
114     dh.setP(p);
115     dh.setG(g);
116
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)
121
122     e=dh.getE();
123
124     packet.reset();
125     buf.putByte((byte)SSH_MSG_KEXDH_INIT);
126     buf.putMPInt(e);
127     session.write(packet);
128
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");
134     }
135
136     state=SSH_MSG_KEXDH_REPLY;
137   }
138
139   public boolean next(Buffer _buf) throws Exception{
140     int i,j;
141
142     switch(state){
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)
147       // mpint     f
148       // string    signature of H
149       j=_buf.getInt();
150       j=_buf.getByte();
151       j=_buf.getByte();
152       if(j!=31){
153         System.err.println("type: must be 31 "+j);
154         return false;
155       }
156
157       K_S=_buf.getString();
158       // K_S is server_key_blob, which includes ....
159       // string ssh-dss
160       // impint p of dsa
161       // impint q of dsa
162       // impint g of dsa
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();
167       /*
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(": ");
171 }
172 System.err.println("");
173       */
174
175       dh.setF(f);
176       K=dh.getK();
177
178       //The hash H is computed as the HASH hash of the concatenation of the
179       //following:
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.
190       buf.reset();
191       buf.putString(V_C); buf.putString(V_S);
192       buf.putString(I_C); buf.putString(I_S);
193       buf.putString(K_S);
194       buf.putMPInt(e); buf.putMPInt(f);
195       buf.putMPInt(K);
196       byte[] foo=new byte[buf.getLength()];
197       buf.getByte(foo);
198       sha.update(foo, 0, foo.length);
199       H=sha.digest();
200       //System.err.print("H -> "); //dump(H, 0, H.length);
201
202       i=0;
203       j=0;
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);
207       i+=j;
208
209       boolean result=false;
210
211       if(alg.equals("ssh-rsa")){
212         byte[] tmp;
213         byte[] ee;
214         byte[] n;
215
216         type=RSA;
217
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;
221         ee=tmp;
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;
225         n=tmp;
226         
227 //      SignatureRSA sig=new SignatureRSA();
228 //      sig.init();
229
230         SignatureRSA sig=null;
231         try{
232           Class c=Class.forName(session.getConfig("signature.rsa"));
233           sig=(SignatureRSA)(c.newInstance());
234           sig.init();
235         }
236         catch(Exception e){
237           System.err.println(e);
238         }
239
240         sig.setPubKey(ee, n);   
241         sig.update(H);
242         result=sig.verify(sig_of_H);
243
244         if(JSch.getLogger().isEnabled(Logger.INFO)){
245           JSch.getLogger().log(Logger.INFO, 
246                                "ssh_rsa_verify: signature "+result);
247         }
248
249       }
250       else if(alg.equals("ssh-dss")){
251         byte[] q=null;
252         byte[] tmp;
253         byte[] p;
254         byte[] g;
255       
256         type=DSS;
257
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;
261         p=tmp;
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;
265         q=tmp;
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;
269         g=tmp;
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;
273         f=tmp;
274 //      SignatureDSA sig=new SignatureDSA();
275 //      sig.init();
276         SignatureDSA sig=null;
277         try{
278           Class c=Class.forName(session.getConfig("signature.dss"));
279           sig=(SignatureDSA)(c.newInstance());
280           sig.init();
281         }
282         catch(Exception e){
283           System.err.println(e);
284         }
285         sig.setPubKey(f, p, q, g);   
286         sig.update(H);
287         result=sig.verify(sig_of_H);
288
289         if(JSch.getLogger().isEnabled(Logger.INFO)){
290           JSch.getLogger().log(Logger.INFO, 
291                                "ssh_dss_verify: signature "+result);
292         }
293
294       }
295       else{
296         System.err.println("unknown alg");
297       }     
298       state=STATE_END;
299       return result;
300     }
301     return false;
302   }
303
304   public String getKeyType(){
305     if(type==DSS) return "DSA";
306     return "RSA";
307   }
308
309   public int getState(){return state; }
310 }
This page took 0.038239 seconds and 4 git commands to generate.