DHG1.java

Go to the documentation of this file.
00001 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
00002 /*
00003 Copyright (c) 2002-2011 ymnk, JCraft,Inc. All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008   1. Redistributions of source code must retain the above copyright notice,
00009      this list of conditions and the following disclaimer.
00010 
00011   2. Redistributions in binary form must reproduce the above copyright 
00012      notice, this list of conditions and the following disclaimer in 
00013      the documentation and/or other materials provided with the distribution.
00014 
00015   3. The names of the authors may not be used to endorse or promote products
00016      derived from this software without specific prior written permission.
00017 
00018 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
00019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00020 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
00021 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
00022 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00025 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00026 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00027 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 //  HASH sha;
00078 
00079 //  byte[] K;
00080 //  byte[] H;
00081 
00082   byte[] V_S;
00083   byte[] V_C;
00084   byte[] I_S;
00085   byte[] I_C;
00086 
00087 //  byte[] K_S;
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 //    sha=new SHA1();
00103 //    sha.init();
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       //System.err.println(e);
00123       throw e;
00124     }
00125 
00126     dh.setP(p);
00127     dh.setG(g);
00128 
00129     // The client responds with:
00130     // byte  SSH_MSG_KEXDH_INIT(30)
00131     // mpint e <- g^x mod p
00132     //         x is a random number (1 < x < (p-1)/2)
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       // The server responds with:
00157       // byte      SSH_MSG_KEXDH_REPLY(31)
00158       // string    server public host key and certificates (K_S)
00159       // mpint     f
00160       // string    signature of H
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       // K_S is server_key_blob, which includes ....
00171       // string ssh-dss
00172       // impint p of dsa
00173       // impint q of dsa
00174       // impint g of dsa
00175       // impint pub_key of dsa
00176       //System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
00177       byte[] f=_buf.getMPInt();
00178       byte[] sig_of_H=_buf.getString();
00179       /*
00180 for(int ii=0; ii<sig_of_H.length;ii++){
00181   System.err.print(Integer.toHexString(sig_of_H[ii]&0xff));
00182   System.err.print(": ");
00183 }
00184 System.err.println("");
00185       */
00186 
00187       dh.setF(f);
00188       K=dh.getK();
00189 
00190       //The hash H is computed as the HASH hash of the concatenation of the
00191       //following:
00192       // string    V_C, the client's version string (CR and NL excluded)
00193       // string    V_S, the server's version string (CR and NL excluded)
00194       // string    I_C, the payload of the client's SSH_MSG_KEXINIT
00195       // string    I_S, the payload of the server's SSH_MSG_KEXINIT
00196       // string    K_S, the host key
00197       // mpint     e, exchange value sent by the client
00198       // mpint     f, exchange value sent by the server
00199       // mpint     K, the shared secret
00200       // This value is called the exchange hash, and it is used to authenti-
00201       // cate the key exchange.
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       //System.err.print("H -> "); //dump(H, 0, H.length);
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 //  SignatureRSA sig=new SignatureRSA();
00240 //  sig.init();
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 //  SignatureDSA sig=new SignatureDSA();
00287 //  sig.init();
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 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1