DHGEX.java
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 package com.jcraft.jsch;
00031
00048 public class DHGEX extends KeyExchange{
00049
00050 private static final int SSH_MSG_KEX_DH_GEX_GROUP= 31;
00051 private static final int SSH_MSG_KEX_DH_GEX_INIT= 32;
00052 private static final int SSH_MSG_KEX_DH_GEX_REPLY= 33;
00053 private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34;
00054
00055 static int min=1024;
00056
00057
00058 static int preferred=1024;
00059 static int max=1024;
00060
00061
00062
00063
00064 static final int RSA=0;
00065 static final int DSS=1;
00066 private int type=0;
00067
00068 private int state;
00069
00070
00071 DH dh;
00072
00073 byte[] V_S;
00074 byte[] V_C;
00075 byte[] I_S;
00076 byte[] I_C;
00077
00078 private Buffer buf;
00079 private Packet packet;
00080
00081 private byte[] p;
00082 private byte[] g;
00083 private byte[] e;
00084
00085
00086
00087
00088 public void init(Session session,
00089 byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
00090 this.session=session;
00091 this.V_S=V_S;
00092 this.V_C=V_C;
00093 this.I_S=I_S;
00094 this.I_C=I_C;
00095
00096 try{
00097 Class c=Class.forName(session.getConfig("sha-1"));
00098 sha=(HASH)(c.newInstance());
00099 sha.init();
00100 }
00101 catch(Exception e){
00102 System.err.println(e);
00103 }
00104
00105 buf=new Buffer();
00106 packet=new Packet(buf);
00107
00108 try{
00109 Class c=Class.forName(session.getConfig("dh"));
00110 dh=(com.jcraft.jsch.DH)(c.newInstance());
00111 dh.init();
00112 }
00113 catch(Exception e){
00114
00115 throw e;
00116 }
00117
00118 packet.reset();
00119 buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST);
00120 buf.putInt(min);
00121 buf.putInt(preferred);
00122 buf.putInt(max);
00123 session.write(packet);
00124
00125 if(JSch.getLogger().isEnabled(Logger.INFO)){
00126 JSch.getLogger().log(Logger.INFO,
00127 "SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent");
00128 JSch.getLogger().log(Logger.INFO,
00129 "expecting SSH_MSG_KEX_DH_GEX_GROUP");
00130 }
00131
00132 state=SSH_MSG_KEX_DH_GEX_GROUP;
00133 }
00134
00135 public boolean next(Buffer _buf) throws Exception{
00136 int i,j;
00137 switch(state){
00138 case SSH_MSG_KEX_DH_GEX_GROUP:
00139
00140
00141
00142 _buf.getInt();
00143 _buf.getByte();
00144 j=_buf.getByte();
00145 if(j!=SSH_MSG_KEX_DH_GEX_GROUP){
00146 System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j);
00147 return false;
00148 }
00149
00150 p=_buf.getMPInt();
00151 g=_buf.getMPInt();
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 dh.setP(p);
00162 dh.setG(g);
00163
00164
00165
00166
00167
00168
00169 e=dh.getE();
00170
00171 packet.reset();
00172 buf.putByte((byte)SSH_MSG_KEX_DH_GEX_INIT);
00173 buf.putMPInt(e);
00174 session.write(packet);
00175
00176 if(JSch.getLogger().isEnabled(Logger.INFO)){
00177 JSch.getLogger().log(Logger.INFO,
00178 "SSH_MSG_KEX_DH_GEX_INIT sent");
00179 JSch.getLogger().log(Logger.INFO,
00180 "expecting SSH_MSG_KEX_DH_GEX_REPLY");
00181 }
00182
00183 state=SSH_MSG_KEX_DH_GEX_REPLY;
00184 return true;
00185
00186
00187 case SSH_MSG_KEX_DH_GEX_REPLY:
00188
00189
00190
00191
00192
00193 j=_buf.getInt();
00194 j=_buf.getByte();
00195 j=_buf.getByte();
00196 if(j!=SSH_MSG_KEX_DH_GEX_REPLY){
00197 System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j);
00198 return false;
00199 }
00200
00201 K_S=_buf.getString();
00202
00203
00204
00205
00206
00207
00208
00209
00210 byte[] f=_buf.getMPInt();
00211 byte[] sig_of_H=_buf.getString();
00212
00213 dh.setF(f);
00214 K=dh.getK();
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 buf.reset();
00235 buf.putString(V_C); buf.putString(V_S);
00236 buf.putString(I_C); buf.putString(I_S);
00237 buf.putString(K_S);
00238 buf.putInt(min); buf.putInt(preferred); buf.putInt(max);
00239 buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f);
00240 buf.putMPInt(K);
00241
00242 byte[] foo=new byte[buf.getLength()];
00243 buf.getByte(foo);
00244 sha.update(foo, 0, foo.length);
00245
00246 H=sha.digest();
00247
00248
00249
00250 i=0;
00251 j=0;
00252 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00253 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00254 String alg=Util.byte2str(K_S, i, j);
00255 i+=j;
00256
00257 boolean result=false;
00258 if(alg.equals("ssh-rsa")){
00259 byte[] tmp;
00260 byte[] ee;
00261 byte[] n;
00262
00263 type=RSA;
00264
00265 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00266 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00267 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00268 ee=tmp;
00269 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00270 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00271 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00272 n=tmp;
00273
00274
00275
00276
00277 SignatureRSA sig=null;
00278 try{
00279 Class c=Class.forName(session.getConfig("signature.rsa"));
00280 sig=(SignatureRSA)(c.newInstance());
00281 sig.init();
00282 }
00283 catch(Exception e){
00284 System.err.println(e);
00285 }
00286
00287 sig.setPubKey(ee, n);
00288 sig.update(H);
00289 result=sig.verify(sig_of_H);
00290
00291 if(JSch.getLogger().isEnabled(Logger.INFO)){
00292 JSch.getLogger().log(Logger.INFO,
00293 "ssh_rsa_verify: signature "+result);
00294 }
00295
00296 }
00297 else if(alg.equals("ssh-dss")){
00298 byte[] q=null;
00299 byte[] tmp;
00300
00301 type=DSS;
00302
00303 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00304 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00305 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00306 p=tmp;
00307 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00308 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00309 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00310 q=tmp;
00311 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00312 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00313 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00314 g=tmp;
00315 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00316 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00317 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00318 f=tmp;
00319
00320
00321
00322
00323 SignatureDSA sig=null;
00324 try{
00325 Class c=Class.forName(session.getConfig("signature.dss"));
00326 sig=(SignatureDSA)(c.newInstance());
00327 sig.init();
00328 }
00329 catch(Exception e){
00330 System.err.println(e);
00331 }
00332
00333 sig.setPubKey(f, p, q, g);
00334 sig.update(H);
00335 result=sig.verify(sig_of_H);
00336
00337 if(JSch.getLogger().isEnabled(Logger.INFO)){
00338 JSch.getLogger().log(Logger.INFO,
00339 "ssh_dss_verify: signature "+result);
00340 }
00341
00342 }
00343 else{
00344 System.err.println("unknown alg");
00345 }
00346 state=STATE_END;
00347 return result;
00348 }
00349 return false;
00350 }
00351
00352 public String getKeyType(){
00353 if(type==DSS) return "DSA";
00354 return "RSA";
00355 }
00356
00357 public int getState(){return state; }
00358 }