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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-06 10:50:04 UTC
  • mfrom: (4.2.1 experimental) (6.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140106105004-9al5p968hmaaj78t
Tags: 0.1.50-1ubuntu1
* Resync with Debian unstable.
* Drop dependency on libjzlib-java for continued main inclusion. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 
2
/*
 
3
Copyright (c) 2002-2012 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=normalize(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
}