~ubuntu-branches/ubuntu/trusty/jsch/trusty-proposed

« back to all changes in this revision

Viewing changes to src/com/jcraft/jsch/DHG1.java

  • Committer: Bazaar Package Importer
  • Author(s): Jerry Haltom
  • Date: 2005-01-13 16:07:20 UTC
  • Revision ID: james.westby@ubuntu.com-20050113160720-7ohwkg0rbifgq3lu
Tags: upstream-0.1.19
ImportĀ upstreamĀ versionĀ 0.1.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*-mode:java; c-basic-offset:2; -*- */
 
2
/*
 
3
Copyright (c) 2002,2003,2004 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
  static final int SSH_MSG_KEXDH_INIT=                     30;
 
56
  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
    }
 
112
 
 
113
    dh.setP(p);
 
114
    dh.setG(g);
 
115
 
 
116
    // The client responds with:
 
117
    // byte  SSH_MSG_KEXDH_INIT(30)
 
118
    // mpint e <- g^x mod p
 
119
    //         x is a random number (1 < x < (p-1)/2)
 
120
 
 
121
    e=dh.getE();
 
122
 
 
123
    packet.reset();
 
124
    buf.putByte((byte)SSH_MSG_KEXDH_INIT);
 
125
    buf.putMPInt(e);
 
126
    session.write(packet);
 
127
 
 
128
    state=SSH_MSG_KEXDH_REPLY;
 
129
  }
 
130
 
 
131
  public boolean next(Buffer _buf) throws Exception{
 
132
    int i,j;
 
133
 
 
134
    switch(state){
 
135
    case SSH_MSG_KEXDH_REPLY:
 
136
      // The server responds with:
 
137
      // byte      SSH_MSG_KEXDH_REPLY(31)
 
138
      // string    server public host key and certificates (K_S)
 
139
      // mpint     f
 
140
      // string    signature of H
 
141
      j=_buf.getInt();
 
142
      j=_buf.getByte();
 
143
      j=_buf.getByte();
 
144
      if(j!=31){
 
145
        System.err.println("type: must be 31 "+j);
 
146
        return false;
 
147
      }
 
148
 
 
149
      K_S=_buf.getString();
 
150
      // K_S is server_key_blob, which includes ....
 
151
      // string ssh-dss
 
152
      // impint p of dsa
 
153
      // impint q of dsa
 
154
      // impint g of dsa
 
155
      // impint pub_key of dsa
 
156
      //System.out.print("K_S: "); //dump(K_S, 0, K_S.length);
 
157
      byte[] f=_buf.getMPInt();
 
158
      byte[] sig_of_H=_buf.getString();
 
159
      /*
 
160
for(int ii=0; ii<sig_of_H.length;ii++){
 
161
  System.out.print(Integer.toHexString(sig_of_H[ii]&0xff));
 
162
  System.out.print(": ");
 
163
}
 
164
System.out.println("");
 
165
      */
 
166
 
 
167
      dh.setF(f);
 
168
      K=dh.getK();
 
169
 
 
170
      //The hash H is computed as the HASH hash of the concatenation of the
 
171
      //following:
 
172
      // string    V_C, the client's version string (CR and NL excluded)
 
173
      // string    V_S, the server's version string (CR and NL excluded)
 
174
      // string    I_C, the payload of the client's SSH_MSG_KEXINIT
 
175
      // string    I_S, the payload of the server's SSH_MSG_KEXINIT
 
176
      // string    K_S, the host key
 
177
      // mpint     e, exchange value sent by the client
 
178
      // mpint     f, exchange value sent by the server
 
179
      // mpint     K, the shared secret
 
180
      // This value is called the exchange hash, and it is used to authenti-
 
181
      // cate the key exchange.
 
182
      buf.reset();
 
183
      buf.putString(V_C); buf.putString(V_S);
 
184
      buf.putString(I_C); buf.putString(I_S);
 
185
      buf.putString(K_S);
 
186
      buf.putMPInt(e); buf.putMPInt(f);
 
187
      buf.putMPInt(K);
 
188
      byte[] foo=new byte[buf.getLength()];
 
189
      buf.getByte(foo);
 
190
      sha.update(foo, 0, foo.length);
 
191
      H=sha.digest();
 
192
      //System.out.print("H -> "); //dump(H, 0, H.length);
 
193
 
 
194
      i=0;
 
195
      j=0;
 
196
      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 
197
        ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 
198
      String alg=new String(K_S, i, j);
 
199
      i+=j;
 
200
 
 
201
      boolean result=false;
 
202
 
 
203
      if(alg.equals("ssh-rsa")){
 
204
        byte[] tmp;
 
205
        byte[] ee;
 
206
        byte[] n;
 
207
 
 
208
        type=RSA;
 
209
 
 
210
        j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 
211
          ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 
212
        tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
 
213
        ee=tmp;
 
214
        j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 
215
          ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 
216
        tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
 
217
        n=tmp;
 
218
        
 
219
//      SignatureRSA sig=new SignatureRSA();
 
220
//      sig.init();
 
221
 
 
222
        SignatureRSA sig=null;
 
223
        try{
 
224
          Class c=Class.forName(session.getConfig("signature.rsa"));
 
225
          sig=(SignatureRSA)(c.newInstance());
 
226
          sig.init();
 
227
        }
 
228
        catch(Exception e){
 
229
          System.err.println(e);
 
230
        }
 
231
 
 
232
        sig.setPubKey(ee, n);   
 
233
        sig.update(H);
 
234
        result=sig.verify(sig_of_H);
 
235
      }
 
236
      else if(alg.equals("ssh-dss")){
 
237
        byte[] q=null;
 
238
        byte[] tmp;
 
239
        byte[] p;
 
240
        byte[] g;
 
241
      
 
242
        type=DSS;
 
243
 
 
244
        j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 
245
          ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 
246
        tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
 
247
        p=tmp;
 
248
        j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 
249
          ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 
250
        tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
 
251
        q=tmp;
 
252
        j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 
253
          ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 
254
        tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
 
255
        g=tmp;
 
256
        j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 
257
          ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 
258
        tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
 
259
        f=tmp;
 
260
//      SignatureDSA sig=new SignatureDSA();
 
261
//      sig.init();
 
262
        SignatureDSA sig=null;
 
263
        try{
 
264
          Class c=Class.forName(session.getConfig("signature.dss"));
 
265
          sig=(SignatureDSA)(c.newInstance());
 
266
          sig.init();
 
267
        }
 
268
        catch(Exception e){
 
269
          System.err.println(e);
 
270
        }
 
271
        sig.setPubKey(f, p, q, g);   
 
272
        sig.update(H);
 
273
        result=sig.verify(sig_of_H);
 
274
      }
 
275
      else{
 
276
        System.out.println("unknow alg");
 
277
      }     
 
278
      state=STATE_END;
 
279
      return result;
 
280
    }
 
281
    return false;
 
282
  }
 
283
 
 
284
  public String getKeyType(){
 
285
    if(type==DSS) return "DSA";
 
286
    return "RSA";
 
287
  }
 
288
 
 
289
  public int getState(){return state; }
 
290
}