Exemple #1
0
        //private byte[] f;

        public override void init(Session session,
                                  byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
        {
            this.session = session;
            this.V_S     = V_S;
            this.V_C     = V_C;
            this.I_S     = I_S;
            this.I_C     = I_C;

            try
            {
                Type c = Type.GetType(session.getConfig("sha-1"));
                sha = (HASH)(c.newInstance());
                sha.init();
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }

            buf    = new Buffer();
            packet = new Packet(buf);

            try
            {
                Type c = Type.GetType(session.getConfig("dh"));
                dh = (DH)(c.newInstance());
                dh.init();
            }
            catch (Exception e)
            {
                //      Console.Error.WriteLine(e);
                throw e;
            }

            packet.reset();
            buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST);
            buf.putInt(min);
            buf.putInt(preferred);
            buf.putInt(max);
            session.write(packet);

            if (JSch.getLogger().isEnabled(Logger.INFO))
            {
                JSch.getLogger().log(Logger.INFO,
                                     "SSH_MSG_KEX_DH_GEX_REQUEST(" + min + "<" + preferred + "<" + max + ") sent");
                JSch.getLogger().log(Logger.INFO,
                                     "expecting SSH_MSG_KEX_DH_GEX_GROUP");
            }

            state = SSH_MSG_KEX_DH_GEX_GROUP;
        }
Exemple #2
0
        public override bool start(Session session)
        {
            base.start(session);


            // send
            // byte      SSH_MSG_SERVICE_REQUEST(5)
            // string    service name "ssh-userauth"
            packet.reset();
            buf.putByte((byte)Session.SSH_MSG_SERVICE_REQUEST);
            buf.putString("ssh-userauth".getBytes());
            session.write(packet);

            if (JSch.getLogger().isEnabled(Logger.INFO))
            {
                JSch.getLogger().log(Logger.INFO,
                                     "SSH_MSG_SERVICE_REQUEST sent");
            }

            // receive
            // byte      SSH_MSG_SERVICE_ACCEPT(6)
            // string    service name
            buf = session.Read(buf);
            int command = buf.getCommand();

            bool result = (command == SSH_MSG_SERVICE_ACCEPT);

            if (JSch.getLogger().isEnabled(Logger.INFO))
            {
                JSch.getLogger().log(Logger.INFO,
                                     "SSH_MSG_SERVICE_ACCEPT received");
            }
            if (!result)
            {
                return(false);
            }

            byte[] _username = null;
            _username = Util.str2byte(username);

            // send
            // byte      SSH_MSG_USERAUTH_REQUEST(50)
            // string    user name
            // string    service name ("ssh-connection")
            // string    "none"
            packet.reset();
            buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
            buf.putString(_username);
            buf.putString("ssh-connection".getBytes());
            buf.putString("none".getBytes());
            session.write(packet);

            while (true)
            {
                buf     = session.Read(buf);
                command = buf.getCommand() & 0xff;

                if (command == SSH_MSG_USERAUTH_SUCCESS)
                {
                    return(true);
                }
                if (command == SSH_MSG_USERAUTH_BANNER)
                {
                    buf.getInt(); buf.getByte(); buf.getByte();
                    byte[] _message = buf.getString();
                    byte[] lang     = buf.getString();
                    string message  = null;

                    //try
                    //{
                    message = Encoding.UTF8.GetString(_message);
                    //}
                    //catch (DecoderFallbackException e)
                    //{
                    //    message = Encoding.UTF8.GetString(_message);
                    //}
                    if (userinfo != null)
                    {
                        //try
                        //{
                        userinfo.showMessage(message);
                        //}
                        //catch (RuntimeException ee)
                        //{
                        //}
                    }
                    goto loop;
                }
                if (command == SSH_MSG_USERAUTH_FAILURE)
                {
                    buf.getInt(); buf.getByte(); buf.getByte();
                    byte[] foo             = buf.getString();
                    int    partial_success = buf.getByte();
                    methods = Encoding.UTF8.GetString(foo);
                    //Console.Error.WriteLine("UserAuthNONE: "+methods+
                    //		   " partial_success:"+(partial_success!=0));
                    //	if(partial_success!=0){
                    //	  throw new JSchPartialAuthException(Encoding.UTF8.GetString(foo));
                    //	}

                    break;
                }
                else
                {
                    //      Console.Error.WriteLine("USERAUTH fail ("+command+")");
                    throw new JSchException("USERAUTH fail (" + command + ")");
                }
loop:
                new object();
            }
            //throw new JSchException("USERAUTH fail");
            return(false);
        }
Exemple #3
0
        /*
         * void dump(byte[] foo){
         * for(int i=0; i<foo.Length; i++){
         *  if((foo[i]&0xf0)==0)System.err.print("0");
         *  System.err.print(Integer.toHexString(foo[i]&0xff));
         *  if(i%16==15){Console.Error.WriteLine(""); continue;}
         *  if(i%2==1)System.err.print(" ");
         * }
         * }
         */

        internal static string[] guess(byte[] I_S, byte[] I_C)
        {
            //Console.Error.WriteLine("guess: ");
            string[] guess = new string[PROPOSAL_MAX];
            Buffer   sb    = new Buffer(I_S); sb.setOffSet(17);
            Buffer   cb    = new Buffer(I_C); cb.setOffSet(17);

            for (int i = 0; i < PROPOSAL_MAX; i++)
            {
                byte[] sp = sb.getString();  // server proposal
                byte[] cp = cb.getString();  // client proposal

                //Console.Error.WriteLine("server-proposal: |"+Encoding.UTF8.GetString(sp)+"|");
                //Console.Error.WriteLine("client-proposal: |"+Encoding.UTF8.GetString(cp)+"|");

                int j = 0;
                int k = 0;
                //Console.Error.WriteLine(Encoding.UTF8.GetString(cp));
                while (j < cp.Length)
                {
                    while (j < cp.Length && cp[j] != ',')
                    {
                        j++;
                    }
                    if (k == j)
                    {
                        return(null);
                    }
                    string algorithm = Encoding.UTF8.GetString(cp, k, j - k);
                    //Console.Error.WriteLine("algorithm: "+algorithm);
                    int l = 0;
                    int m = 0;
                    while (l < sp.Length)
                    {
                        while (l < sp.Length && sp[l] != ',')
                        {
                            l++;
                        }
                        if (m == l)
                        {
                            return(null);
                        }
                        //Console.Error.WriteLine("  "+Encoding.UTF8.GetString(sp, m, l-m));
                        if (algorithm.Equals(Encoding.UTF8.GetString(sp, m, l - m)))
                        {
                            guess[i] = algorithm;
                            //Console.Error.WriteLine("  "+algorithm);
                            goto loop;
                        }
                        l++;
                        m = l;
                    }
                    j++;
                    k = j;
                }
loop:
                if (j == 0)
                {
                    guess[i] = "";
                }
                else if (guess[i] == null)
                {
                    //Console.Error.WriteLine("  fail");
                    return(null);
                }
            }

            if (JSch.getLogger().isEnabled(Logger.INFO))
            {
                JSch.getLogger().log(Logger.INFO,
                                     "kex: server->client" +
                                     " " + guess[PROPOSAL_ENC_ALGS_STOC] +
                                     " " + guess[PROPOSAL_MAC_ALGS_STOC] +
                                     " " + guess[PROPOSAL_COMP_ALGS_STOC]);
                JSch.getLogger().log(Logger.INFO,
                                     "kex: client->server" +
                                     " " + guess[PROPOSAL_ENC_ALGS_CTOS] +
                                     " " + guess[PROPOSAL_MAC_ALGS_CTOS] +
                                     " " + guess[PROPOSAL_COMP_ALGS_CTOS]);
            }

            //    for(int i=0; i<PROPOSAL_MAX; i++){
            //      Console.Error.WriteLine("guess: ["+guess[i]+"]");
            //    }

            return(guess);
        }
        private IdentityFile(string name, byte[] prvkey, byte[] pubkey, JSch jsch)
        {
            this.identity = name;
            this.jsch     = jsch;
            try
            {
                Type c;
                c      = Type.GetType((string)JSch.getConfig("3des-cbc"));
                cipher = (Cipher)(c.newInstance());
                key    = new byte[cipher.getBlockSize()]; // 24
                iv     = new byte[cipher.getIVSize()];    // 8
                c      = Type.GetType((string)JSch.getConfig("md5"));
                hash   = (HASH)(c.newInstance());
                hash.init();

                byte[] buf = prvkey;
                int    len = buf.Length;

                int i = 0;
                while (i < len)
                {
                    if (buf[i] == 'B' && buf[i + 1] == 'E' && buf[i + 2] == 'G' && buf[i + 3] == 'I')
                    {
                        i += 6;
                        if (buf[i] == 'D' && buf[i + 1] == 'S' && buf[i + 2] == 'A')
                        {
                            type = DSS;
                        }
                        else if (buf[i] == 'R' && buf[i + 1] == 'S' && buf[i + 2] == 'A')
                        {
                            type = RSA;
                        }
                        else if (buf[i] == 'S' && buf[i + 1] == 'S' && buf[i + 2] == 'H')
                        { // FSecure
                            type    = UNKNOWN;
                            keytype = FSECURE;
                        }
                        else
                        {
                            //Console.Error.WriteLine("invalid format: "+identity);
                            throw new JSchException("invalid privatekey: " + identity);
                        }
                        i += 3;
                        continue;
                    }
                    if (buf[i] == 'A' && buf[i + 1] == 'E' && buf[i + 2] == 'S' && buf[i + 3] == '-' &&
                        buf[i + 4] == '2' && buf[i + 5] == '5' && buf[i + 6] == '6' && buf[i + 7] == '-')
                    {
                        i += 8;
                        if (Session.checkCipher((string)JSch.getConfig("aes256-cbc")))
                        {
                            c      = Type.GetType((string)JSch.getConfig("aes256-cbc"));
                            cipher = (Cipher)(c.newInstance());
                            key    = new byte[cipher.getBlockSize()];
                            iv     = new byte[cipher.getIVSize()];
                        }
                        else
                        {
                            throw new JSchException("privatekey: aes256-cbc is not available " + identity);
                        }
                        continue;
                    }
                    if (buf[i] == 'C' && buf[i + 1] == 'B' && buf[i + 2] == 'C' && buf[i + 3] == ',')
                    {
                        i += 4;
                        for (int ii = 0; ii < iv.Length; ii++)
                        {
                            iv[ii] = (byte)(((a2b(buf[i++]) << 4) & 0xf0) +
                                            (a2b(buf[i++]) & 0xf));
                        }
                        continue;
                    }
                    if (buf[i] == 0x0d &&
                        i + 1 < buf.Length && buf[i + 1] == 0x0a)
                    {
                        i++;
                        continue;
                    }
                    if (buf[i] == 0x0a && i + 1 < buf.Length)
                    {
                        if (buf[i + 1] == 0x0a)
                        {
                            i += 2; break;
                        }
                        if (buf[i + 1] == 0x0d &&
                            i + 2 < buf.Length && buf[i + 2] == 0x0a)
                        {
                            i += 3; break;
                        }
                        bool inheader = false;
                        for (int j = i + 1; j < buf.Length; j++)
                        {
                            if (buf[j] == 0x0a)
                            {
                                break;
                            }
                            //if(buf[j]==0x0d) break;
                            if (buf[j] == ':')
                            {
                                inheader = true; break;
                            }
                        }
                        if (!inheader)
                        {
                            i++;
                            encrypted = false;    // no passphrase
                            break;
                        }
                    }
                    i++;
                }

                if (type == ERROR)
                {
                    throw new JSchException("invalid privatekey: " + identity);
                }

                int start = i;
                while (i < len)
                {
                    if (buf[i] == 0x0a)
                    {
                        bool xd = (buf[i - 1] == 0x0d);
                        Array.Copy(buf, i + 1,
                                   buf,
                                   i - (xd ? 1 : 0),
                                   len - i - 1 - (xd ? 1 : 0)
                                   );
                        if (xd)
                        {
                            len--;
                        }
                        len--;
                        continue;
                    }
                    if (buf[i] == '-')
                    {
                        break;
                    }
                    i++;
                }
                encoded_data = Util.fromBase64(buf, start, i - start);

                if (encoded_data.Length > 4 &&            // FSecure
                    encoded_data[0] == (byte)0x3f &&
                    encoded_data[1] == (byte)0x6f &&
                    encoded_data[2] == (byte)0xf9 &&
                    encoded_data[3] == (byte)0xeb)
                {
                    Buffer _buf = new Buffer(encoded_data);
                    _buf.getInt();  // 0x3f6ff9be
                    _buf.getInt();
                    byte[] _type = _buf.getString();
                    //Console.Error.WriteLine("type: "+Encoding.UTF8.GetString(_type));
                    byte[] _cipher = _buf.getString();
                    string scipher = Encoding.UTF8.GetString(_cipher);
                    //Console.Error.WriteLine("cipher: "+cipher);
                    if (scipher.Equals("3des-cbc"))
                    {
                        _buf.getInt();
                        byte[] foo = new byte[encoded_data.Length - _buf.getOffSet()];
                        _buf.getByte(foo);
                        encoded_data = foo;
                        encrypted    = true;
                        throw new JSchException("unknown privatekey format: " + identity);
                    }
                    else if (scipher.Equals("none"))
                    {
                        _buf.getInt();
                        //_buf.getInt();

                        encrypted = false;

                        byte[] foo = new byte[encoded_data.Length - _buf.getOffSet()];
                        _buf.getByte(foo);
                        encoded_data = foo;
                    }
                }

                if (pubkey == null)
                {
                    return;
                }

                buf = pubkey;
                len = buf.Length;

                if (buf.Length > 4 &&             // FSecure's public key
                    buf[0] == '-' && buf[1] == '-' && buf[2] == '-' && buf[3] == '-')
                {
                    i = 0;
                    do
                    {
                        i++;
                    } while (len > i && buf[i] != 0x0a);
                    if (len <= i)
                    {
                        return;
                    }
                    while (i < len)
                    {
                        if (buf[i] == 0x0a)
                        {
                            bool inheader = false;
                            for (int j = i + 1; j < len; j++)
                            {
                                if (buf[j] == 0x0a)
                                {
                                    break;
                                }
                                if (buf[j] == ':')
                                {
                                    inheader = true; break;
                                }
                            }
                            if (!inheader)
                            {
                                i++;
                                break;
                            }
                        }
                        i++;
                    }
                    if (len <= i)
                    {
                        return;
                    }

                    start = i;
                    while (i < len)
                    {
                        if (buf[i] == 0x0a)
                        {
                            Array.Copy(buf, i + 1, buf, i, len - i - 1);
                            len--;
                            continue;
                        }
                        if (buf[i] == '-')
                        {
                            break;
                        }
                        i++;
                    }
                    publickeyblob = Util.fromBase64(buf, start, i - start);

                    if (type == UNKNOWN && publickeyblob.Length > 8)
                    {
                        if (publickeyblob[8] == 'd')
                        {
                            type = DSS;
                        }
                        else if (publickeyblob[8] == 'r')
                        {
                            type = RSA;
                        }
                    }
                }
                else
                {
                    if (buf[0] != 's' || buf[1] != 's' || buf[2] != 'h' || buf[3] != '-')
                    {
                        return;
                    }
                    i = 0;
                    while (i < len)
                    {
                        if (buf[i] == ' ')
                        {
                            break;
                        }
                        i++;
                    }
                    i++;
                    if (i >= len)
                    {
                        return;
                    }
                    start = i;
                    while (i < len)
                    {
                        if (buf[i] == ' ' || buf[i] == '\n')
                        {
                            break;
                        }
                        i++;
                    }
                    publickeyblob = Util.fromBase64(buf, start, i - start);
                    if (publickeyblob.Length < 4 + 7)
                    {  // It must start with "ssh-XXX".
                        if (JSch.getLogger().isEnabled(Logger.WARN))
                        {
                            JSch.getLogger().log(Logger.WARN,
                                                 "failed to parse the public key");
                        }
                        publickeyblob = null;
                    }
                }
            }
            catch (Exception e)
            {
                //Console.Error.WriteLine("IdentityFile: "+e);
                if (e is JSchException)
                {
                    throw (JSchException)e;
                }
                throw new JSchException(e.Message, e);
            }
        }
Exemple #5
0
        public override void init(Session session,
                                  byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
        {
            this.session = session;
            this.V_S     = V_S;
            this.V_C     = V_C;
            this.I_S     = I_S;
            this.I_C     = I_C;

            //    sha=new SHA1();
            //    sha.init();
            try
            {
                Type c = Type.GetType(session.getConfig("sha-1"));
                sha = (HASH)(c.newInstance());
                sha.init();
            }
            catch (Exception ee)
            {
                Console.Error.WriteLine(ee);
            }

            buf    = new Buffer();
            packet = new Packet(buf);

            try
            {
                Type c = Type.GetType(session.getConfig("dh"));
                dh = (DH)(c.newInstance());
                dh.init();
            }
            catch (Exception ee)
            {
                //Console.Error.WriteLine(e);
                throw ee;
            }

            dh.setP(p);
            dh.setG(g);

            // The client responds with:
            // byte  SSH_MSG_KEXDH_INIT(30)
            // mpint e <- g^x mod p
            //         x is a random number (1 < x < (p-1)/2)

            e = dh.getE();

            packet.reset();
            buf.putByte((byte)SSH_MSG_KEXDH_INIT);
            buf.putMPInt(e);
            session.write(packet);

            if (JSch.getLogger().isEnabled(Logger.INFO))
            {
                JSch.getLogger().log(Logger.INFO,
                                     "SSH_MSG_KEXDH_INIT sent");
                JSch.getLogger().log(Logger.INFO,
                                     "expecting SSH_MSG_KEXDH_REPLY");
            }

            state = SSH_MSG_KEXDH_REPLY;
        }
Exemple #6
0
        public override bool next(Buffer _buf)
        {
            int i, j;

            switch (state)
            {
            case SSH_MSG_KEXDH_REPLY:
                // The server responds with:
                // byte      SSH_MSG_KEXDH_REPLY(31)
                // string    server public host key and certificates (K_S)
                // mpint     f
                // string    signature of H
                j = _buf.getInt();
                j = _buf.getByte();
                j = _buf.getByte();
                if (j != 31)
                {
                    Console.Error.WriteLine("type: must be 31 " + j);
                    return(false);
                }

                K_S = _buf.getString();
                // K_S is server_key_blob, which includes ....
                // string ssh-dss
                // impint p of dsa
                // impint q of dsa
                // impint g of dsa
                // impint pub_key of dsa
                //System.err.print("K_S: "); //dump(K_S, 0, K_S.Length);
                byte[] f        = _buf.getMPInt();
                byte[] sig_of_H = _buf.getString();

                /*
                 * for(int ii=0; ii<sig_of_H.Length;ii++){
                 * System.err.print(Integer.toHexString(sig_of_H[ii]&0xff));
                 * System.err.print(": ");
                 * }
                 * Console.Error.WriteLine("");
                 */

                dh.setF(f);
                K = dh.getK();

                //The hash H is computed as the HASH hash of the concatenation of the
                //following:
                // string    V_C, the client's version string (CR and NL excluded)
                // string    V_S, the server's version string (CR and NL excluded)
                // string    I_C, the payload of the client's SSH_MSG_KEXINIT
                // string    I_S, the payload of the server's SSH_MSG_KEXINIT
                // string    K_S, the host key
                // mpint     e, exchange value sent by the client
                // mpint     f, exchange value sent by the server
                // mpint     K, the shared secret
                // This value is called the exchange hash, and it is used to authenti-
                // cate the key exchange.
                buf.reset();
                buf.putString(V_C); buf.putString(V_S);
                buf.putString(I_C); buf.putString(I_S);
                buf.putString(K_S);
                buf.putMPInt(e); buf.putMPInt(f);
                buf.putMPInt(K);
                byte[] foo = new byte[buf.getLength()];
                buf.getByte(foo);
                sha.update(foo, 0, foo.Length);
                H = sha.digest();
                //System.err.print("H -> "); //dump(H, 0, H.Length);

                i  = 0;
                j  = 0;
                j  = JavaCompat.ToInt32Big(K_S, i);
                i += 4;
                //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                //((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                string alg = Encoding.UTF8.GetString(K_S, i, j);
                i += j;

                bool result = false;

                if (alg.Equals("ssh-rsa"))
                {
                    byte[] tmp;
                    byte[] ee;
                    byte[] n;

                    type = RSA;

                    j  = JavaCompat.ToInt32Big(K_S, i);
                    i += 4;
                    //j = (int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    ee  = tmp;
                    j   = JavaCompat.ToInt32Big(K_S, i);
                    i  += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    // ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    n   = tmp;

                    //	SignatureRSA sig=new SignatureRSA();
                    //	sig.init();

                    SignatureRSA sig = null;
                    try
                    {
                        Type c = Type.GetType(session.getConfig("signature.rsa"));
                        sig = (SignatureRSA)(c.newInstance());
                        sig.init();
                    }
                    catch (Exception eee)
                    {
                        Console.Error.WriteLine(eee);
                    }

                    sig.setPubKey(ee, n);
                    sig.update(H);
                    result = sig.verify(sig_of_H);

                    if (JSch.getLogger().isEnabled(Logger.INFO))
                    {
                        JSch.getLogger().log(Logger.INFO,
                                             "ssh_rsa_verify: signature " + result);
                    }
                }
                else if (alg.Equals("ssh-dss"))
                {
                    byte[] q = null;
                    byte[] tmp;
                    byte[] p;
                    byte[] g;

                    type = DSS;
                    j    = JavaCompat.ToInt32Big(K_S, i);
                    i   += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    p   = tmp;
                    j   = JavaCompat.ToInt32Big(K_S, i);
                    i  += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    q   = tmp;
                    j   = JavaCompat.ToInt32Big(K_S, i);
                    i  += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    g   = tmp;
                    j   = JavaCompat.ToInt32Big(K_S, i);
                    i  += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    f   = tmp;
                    //	SignatureDSA sig=new SignatureDSA();
                    //	sig.init();
                    SignatureDSA sig = null;
                    try
                    {
                        Type c = Type.GetType(session.getConfig("signature.dss"));
                        sig = (SignatureDSA)(c.newInstance());
                        sig.init();
                    }
                    catch (Exception eeee)
                    {
                        Console.Error.WriteLine(eeee);
                    }
                    sig.setPubKey(f, p, q, g);
                    sig.update(H);
                    result = sig.verify(sig_of_H);

                    if (JSch.getLogger().isEnabled(Logger.INFO))
                    {
                        JSch.getLogger().log(Logger.INFO,
                                             "ssh_dss_verify: signature " + result);
                    }
                }
                else
                {
                    Console.Error.WriteLine("unknown alg");
                }
                state = STATE_END;
                return(result);
            }
            return(false);
        }
Exemple #7
0
        public override bool next(Buffer _buf)
        {
            int i, j;

            switch (state)
            {
            case SSH_MSG_KEX_DH_GEX_GROUP:
                // byte  SSH_MSG_KEX_DH_GEX_GROUP(31)
                // mpint p, safe prime
                // mpint g, generator for subgroup in GF (p)
                _buf.getInt();
                _buf.getByte();
                j = _buf.getByte();
                if (j != SSH_MSG_KEX_DH_GEX_GROUP)
                {
                    Console.Error.WriteLine("type: must be SSH_MSG_KEX_DH_GEX_GROUP " + j);
                    return(false);
                }

                p = _buf.getMPInt();
                g = _buf.getMPInt();

                /*
                 * for(int iii=0; iii<p.Length; iii++){
                 * Console.Error.WriteLine("0x"+Integer.toHexString(p[iii]&0xff)+",");
                 * }
                 * Console.Error.WriteLine("");
                 * for(int iii=0; iii<g.Length; iii++){
                 * Console.Error.WriteLine("0x"+Integer.toHexString(g[iii]&0xff)+",");
                 * }
                 */
                dh.setP(p);
                dh.setG(g);

                // The client responds with:
                // byte  SSH_MSG_KEX_DH_GEX_INIT(32)
                // mpint e <- g^x mod p
                //         x is a random number (1 < x < (p-1)/2)

                e = dh.getE();

                packet.reset();
                buf.putByte((byte)SSH_MSG_KEX_DH_GEX_INIT);
                buf.putMPInt(e);
                session.write(packet);

                if (JSch.getLogger().isEnabled(Logger.INFO))
                {
                    JSch.getLogger().log(Logger.INFO,
                                         "SSH_MSG_KEX_DH_GEX_INIT sent");
                    JSch.getLogger().log(Logger.INFO,
                                         "expecting SSH_MSG_KEX_DH_GEX_REPLY");
                }

                state = SSH_MSG_KEX_DH_GEX_REPLY;
                return(true);

            //break;

            case SSH_MSG_KEX_DH_GEX_REPLY:
                // The server responds with:
                // byte      SSH_MSG_KEX_DH_GEX_REPLY(33)
                // string    server public host key and certificates (K_S)
                // mpint     f
                // string    signature of H
                j = _buf.getInt();
                j = _buf.getByte();
                j = _buf.getByte();
                if (j != SSH_MSG_KEX_DH_GEX_REPLY)
                {
                    Console.Error.WriteLine("type: must be SSH_MSG_KEX_DH_GEX_REPLY " + j);
                    return(false);
                }

                K_S = _buf.getString();
                // K_S is server_key_blob, which includes ....
                // string ssh-dss
                // impint p of dsa
                // impint q of dsa
                // impint g of dsa
                // impint pub_key of dsa
                //System.err.print("K_S: "); dump(K_S, 0, K_S.Length);

                byte[] f        = _buf.getMPInt();
                byte[] sig_of_H = _buf.getString();

                dh.setF(f);
                K = dh.getK();

                //The hash H is computed as the HASH hash of the concatenation of the
                //following:
                // string    V_C, the client's version string (CR and NL excluded)
                // string    V_S, the server's version string (CR and NL excluded)
                // string    I_C, the payload of the client's SSH_MSG_KEXINIT
                // string    I_S, the payload of the server's SSH_MSG_KEXINIT
                // string    K_S, the host key
                // uint32    min, minimal size in bits of an acceptable group
                // uint32   n, preferred size in bits of the group the server should send
                // uint32    max, maximal size in bits of an acceptable group
                // mpint     p, safe prime
                // mpint     g, generator for subgroup
                // mpint     e, exchange value sent by the client
                // mpint     f, exchange value sent by the server
                // mpint     K, the shared secret
                // This value is called the exchange hash, and it is used to authenti-
                // cate the key exchange.

                buf.reset();
                buf.putString(V_C); buf.putString(V_S);
                buf.putString(I_C); buf.putString(I_S);
                buf.putString(K_S);
                buf.putInt(min); buf.putInt(preferred); buf.putInt(max);
                buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f);
                buf.putMPInt(K);

                byte[] foo = new byte[buf.getLength()];
                buf.getByte(foo);
                sha.update(foo, 0, foo.Length);

                H = sha.digest();

                // System.err.print("H -> "); dump(H, 0, H.Length);

                i = 0;
                j = 0;
                j = (int)(((K_S[i++] << 24) & 0xff000000U) | ((K_S[i++] << 16) & 0x00ff0000U) |
                          ((K_S[i++] << 8) & 0x0000ff00U) | ((K_S[i++]) & 0x000000ffU));
                string alg = Encoding.UTF8.GetString(K_S, i, j);
                i += j;

                bool result = false;
                if (alg.Equals("ssh-rsa"))
                {
                    byte[] tmp;
                    byte[] ee;
                    byte[] n;

                    type = RSA;
                    j    = JavaCompat.ToInt32Big(K_S, i);
                    i   += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    ee  = tmp;
                    j   = JavaCompat.ToInt32Big(K_S, i);
                    i  += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    n   = tmp;

                    //	SignatureRSA sig=new SignatureRSA();
                    //	sig.init();

                    SignatureRSA sig = null;
                    try
                    {
                        Type c = Type.GetType(session.getConfig("signature.rsa"));
                        sig = (SignatureRSA)(c.newInstance());
                        sig.init();
                    }
                    catch (Exception eeeee)
                    {
                        Console.Error.WriteLine(eeeee);
                    }

                    sig.setPubKey(ee, n);
                    sig.update(H);
                    result = sig.verify(sig_of_H);

                    if (JSch.getLogger().isEnabled(Logger.INFO))
                    {
                        JSch.getLogger().log(Logger.INFO,
                                             "ssh_rsa_verify: signature " + result);
                    }
                }
                else if (alg.Equals("ssh-dss"))
                {
                    byte[] q = null;
                    byte[] tmp;

                    type = DSS;
                    j    = JavaCompat.ToInt32Big(K_S, i);
                    i   += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    p   = tmp;
                    j   = JavaCompat.ToInt32Big(K_S, i);
                    i  += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    q   = tmp;
                    j   = JavaCompat.ToInt32Big(K_S, i);
                    i  += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    g   = tmp;
                    j   = JavaCompat.ToInt32Big(K_S, i);
                    i  += 4;
                    //j =(int)( ((K_S[i++] << 24) & 0xff000000) | ((K_S[i++] << 16) & 0x00ff0000) |
                    //  ((K_S[i++] << 8) & 0x0000ff00) | ((K_S[i++]) & 0x000000ff));
                    tmp = new byte[j]; Array.Copy(K_S, i, tmp, 0, j); i += j;
                    f   = tmp;

                    //	SignatureDSA sig=new SignatureDSA();
                    //	sig.init();

                    SignatureDSA sig = null;
                    try
                    {
                        Type c = Type.GetType(session.getConfig("signature.dss"));
                        sig = (SignatureDSA)(c.newInstance());
                        sig.init();
                    }
                    catch (Exception eeeeee)
                    {
                        Console.Error.WriteLine(eeeeee);
                    }

                    sig.setPubKey(f, p, q, g);
                    sig.update(H);
                    result = sig.verify(sig_of_H);

                    if (JSch.getLogger().isEnabled(Logger.INFO))
                    {
                        JSch.getLogger().log(Logger.INFO,
                                             "ssh_dss_verify: signature " + result);
                    }
                }
                else
                {
                    Console.Error.WriteLine("unknown alg");
                }
                state = STATE_END;
                return(result);
            }
            return(false);
        }