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
00044 public class DHG1 extends KeyExchange{
00045
00046 static final byte[] g={ 2 };
00047 static final byte[] p={
00048 (byte)0x00,
00049 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
00050 (byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
00051 (byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
00052 (byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
00053 (byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
00054 (byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
00055 (byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
00056 (byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
00057 (byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
00058 (byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
00059 (byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
00060 (byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
00061 (byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
00062 (byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
00063 (byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81,
00064 (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
00065 };
00066
00067 private static final int SSH_MSG_KEXDH_INIT= 30;
00068 private static final int SSH_MSG_KEXDH_REPLY= 31;
00069
00070 static final int RSA=0;
00071 static final int DSS=1;
00072 private int type=0;
00073
00074 private int state;
00075
00076 DH dh;
00077
00078
00079
00080
00081
00082 byte[] V_S;
00083 byte[] V_C;
00084 byte[] I_S;
00085 byte[] I_C;
00086
00087
00088
00089 byte[] e;
00090
00091 private Buffer buf;
00092 private Packet packet;
00093
00094 public void init(Session session,
00095 byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
00096 this.session=session;
00097 this.V_S=V_S;
00098 this.V_C=V_C;
00099 this.I_S=I_S;
00100 this.I_C=I_C;
00101
00102
00103
00104 try{
00105 Class c=Class.forName(session.getConfig("sha-1"));
00106 sha=(HASH)(c.newInstance());
00107 sha.init();
00108 }
00109 catch(Exception e){
00110 System.err.println(e);
00111 }
00112
00113 buf=new Buffer();
00114 packet=new Packet(buf);
00115
00116 try{
00117 Class c=Class.forName(session.getConfig("dh"));
00118 dh=(DH)(c.newInstance());
00119 dh.init();
00120 }
00121 catch(Exception e){
00122
00123 throw e;
00124 }
00125
00126 dh.setP(p);
00127 dh.setG(g);
00128
00129
00130
00131
00132
00133
00134 e=dh.getE();
00135
00136 packet.reset();
00137 buf.putByte((byte)SSH_MSG_KEXDH_INIT);
00138 buf.putMPInt(e);
00139 session.write(packet);
00140
00141 if(JSch.getLogger().isEnabled(Logger.INFO)){
00142 JSch.getLogger().log(Logger.INFO,
00143 "SSH_MSG_KEXDH_INIT sent");
00144 JSch.getLogger().log(Logger.INFO,
00145 "expecting SSH_MSG_KEXDH_REPLY");
00146 }
00147
00148 state=SSH_MSG_KEXDH_REPLY;
00149 }
00150
00151 public boolean next(Buffer _buf) throws Exception{
00152 int i,j;
00153
00154 switch(state){
00155 case SSH_MSG_KEXDH_REPLY:
00156
00157
00158
00159
00160
00161 j=_buf.getInt();
00162 j=_buf.getByte();
00163 j=_buf.getByte();
00164 if(j!=31){
00165 System.err.println("type: must be 31 "+j);
00166 return false;
00167 }
00168
00169 K_S=_buf.getString();
00170
00171
00172
00173
00174
00175
00176
00177 byte[] f=_buf.getMPInt();
00178 byte[] sig_of_H=_buf.getString();
00179
00180
00181
00182
00183
00184
00185
00186
00187 dh.setF(f);
00188 K=dh.getK();
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 buf.reset();
00203 buf.putString(V_C); buf.putString(V_S);
00204 buf.putString(I_C); buf.putString(I_S);
00205 buf.putString(K_S);
00206 buf.putMPInt(e); buf.putMPInt(f);
00207 buf.putMPInt(K);
00208 byte[] foo=new byte[buf.getLength()];
00209 buf.getByte(foo);
00210 sha.update(foo, 0, foo.length);
00211 H=sha.digest();
00212
00213
00214 i=0;
00215 j=0;
00216 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00217 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00218 String alg=Util.byte2str(K_S, i, j);
00219 i+=j;
00220
00221 boolean result=false;
00222
00223 if(alg.equals("ssh-rsa")){
00224 byte[] tmp;
00225 byte[] ee;
00226 byte[] n;
00227
00228 type=RSA;
00229
00230 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00231 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00232 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00233 ee=tmp;
00234 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00235 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00236 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00237 n=tmp;
00238
00239
00240
00241
00242 SignatureRSA sig=null;
00243 try{
00244 Class c=Class.forName(session.getConfig("signature.rsa"));
00245 sig=(SignatureRSA)(c.newInstance());
00246 sig.init();
00247 }
00248 catch(Exception e){
00249 System.err.println(e);
00250 }
00251
00252 sig.setPubKey(ee, n);
00253 sig.update(H);
00254 result=sig.verify(sig_of_H);
00255
00256 if(JSch.getLogger().isEnabled(Logger.INFO)){
00257 JSch.getLogger().log(Logger.INFO,
00258 "ssh_rsa_verify: signature "+result);
00259 }
00260
00261 }
00262 else if(alg.equals("ssh-dss")){
00263 byte[] q=null;
00264 byte[] tmp;
00265 byte[] p;
00266 byte[] g;
00267
00268 type=DSS;
00269
00270 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00271 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00272 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00273 p=tmp;
00274 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00275 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00276 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00277 q=tmp;
00278 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00279 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00280 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00281 g=tmp;
00282 j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
00283 ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
00284 tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
00285 f=tmp;
00286
00287
00288 SignatureDSA sig=null;
00289 try{
00290 Class c=Class.forName(session.getConfig("signature.dss"));
00291 sig=(SignatureDSA)(c.newInstance());
00292 sig.init();
00293 }
00294 catch(Exception e){
00295 System.err.println(e);
00296 }
00297 sig.setPubKey(f, p, q, g);
00298 sig.update(H);
00299 result=sig.verify(sig_of_H);
00300
00301 if(JSch.getLogger().isEnabled(Logger.INFO)){
00302 JSch.getLogger().log(Logger.INFO,
00303 "ssh_dss_verify: signature "+result);
00304 }
00305
00306 }
00307 else{
00308 System.err.println("unknown alg");
00309 }
00310 state=STATE_END;
00311 return result;
00312 }
00313 return false;
00314 }
00315
00316 public String getKeyType(){
00317 if(type==DSS) return "DSA";
00318 return "RSA";
00319 }
00320
00321 public int getState(){return state; }
00322 }