示例#1
0
        //writer util
        private SSH2DataWriter OpenWriter(AgentForwadPacketType pt)
        {
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(0); //length field
            wr.Write((byte)pt);
            return(wr);
        }
示例#2
0
        private void SendSign(SSH2DataReader r)
        {
            byte[] blob = r.ReadString();
            byte[] data = r.ReadString();
            //Debug.WriteLine(String.Format("SignRequest blobsize={0} datasize={1}", blob.Length, data.Length));

            SSH2UserAuthKey[] keys = _client.GetAvailableSSH2UserAuthKeys();
            SSH2UserAuthKey   key  = FindKey(keys, blob);

            if (key == null)
            {
                TransmitWriter(OpenWriter(AgentForwadPacketType.SSH_AGENT_FAILURE));
                _client.NotifyPublicKeyDidNotMatch();
            }
            else
            {
                SSH2DataWriter signpack = new SSH2DataWriter();
                signpack.Write(SSH2Util.PublicKeyAlgorithmName(key.Algorithm));
                signpack.WriteAsString(key.Sign(data));

                SSH2DataWriter wr = OpenWriter(AgentForwadPacketType.SSH2_AGENT_SIGN_RESPONSE);
                wr.WriteAsString(signpack.ToByteArray());
                TransmitWriter(wr);
            }
        }
示例#3
0
        public byte[] GetPublicKeyBlob()
        {
            SSH2DataWriter w = new SSH2DataWriter();

            w.Write(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm));
            _keypair.PublicKey.WriteTo(w);
            return(w.ToByteArray());
        }
示例#4
0
        private void TransmitWriter(SSH2DataWriter wr)
        {
            int o = wr.Length;

            wr.SetOffset(0);
            wr.Write(o - 4); //length of int32
            _channel.Transmit(wr.UnderlyingBuffer, 0, o);
        }
        private byte[] WriteToDataWriter()
        {
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(SSH2Util.PublicKeyAlgorithmName(_hostkey.Algorithm));
            if (_hostkey.Algorithm == PublicKeyAlgorithm.RSA)
            {
                RSAPublicKey rsa = (RSAPublicKey)_hostkey;
                wr.Write(rsa.Exponent);
                wr.Write(rsa.Modulus);
            }
            else if (_hostkey.Algorithm == PublicKeyAlgorithm.DSA)
            {
                DSAPublicKey dsa = (DSAPublicKey)_hostkey;
                wr.Write(dsa.P);
                wr.Write(dsa.Q);
                wr.Write(dsa.G);
                wr.Write(dsa.Y);
            }
            else
            {
                throw new SSHException("Host key algorithm is unsupported");
            }

            return(wr.ToByteArray());
        }
示例#6
0
        private string FormatBase64EncodedPublicKeyBody()
        {
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm));
            _keypair.PublicKey.WriteTo(wr);

            return(Encoding.ASCII.GetString(Base64.Encode(wr.ToByteArray())));
        }
示例#7
0
        // Derived class can override this method to modify the buffer.
        public virtual DataFragment Close(Cipher cipher, MAC mac, int sequence)
        {
            if (!_isOpen)
            {
                throw new SSHException("internal state error");
            }

            int blocksize     = cipher == null ? 8 : cipher.BlockSize;
            int payloadLength = _writer.Length - (SEQUENCE_MARGIN + LENGTH_MARGIN + PADDING_MARGIN);
            int paddingLength = 11 - payloadLength % blocksize;

            while (paddingLength < 4)
            {
                paddingLength += blocksize;
            }
            int packetLength = PADDING_MARGIN + payloadLength + paddingLength;
            int imageLength  = packetLength + LENGTH_MARGIN;

            //fill padding
            byte[] tmp = new byte[4];
            Rng    rng = RngManager.GetSecureRng();

            for (int i = 0; i < paddingLength; i += 4)
            {
                rng.GetBytes(tmp);
                _writer.Write(tmp);
            }

            //manipulate stream
            byte[] rawbuf = _writer.UnderlyingBuffer;
            SSHUtil.WriteIntToByteArray(rawbuf, 0, sequence);
            SSHUtil.WriteIntToByteArray(rawbuf, SEQUENCE_MARGIN, packetLength);
            rawbuf[SEQUENCE_MARGIN + LENGTH_MARGIN] = (byte)paddingLength;

            //mac
            if (mac != null)
            {
                byte[] macCode = mac.ComputeHash(rawbuf, 0, packetLength + LENGTH_MARGIN + SEQUENCE_MARGIN);
                Array.Copy(macCode, 0, rawbuf, packetLength + LENGTH_MARGIN + SEQUENCE_MARGIN, macCode.Length);
                imageLength += macCode.Length;
            }

            //encrypt
            if (cipher != null)
            {
                cipher.Encrypt(rawbuf, SEQUENCE_MARGIN, packetLength + LENGTH_MARGIN, rawbuf, SEQUENCE_MARGIN);
            }

            _dataFragment.Init(rawbuf, SEQUENCE_MARGIN, imageLength);
            _isOpen = false;
            return(_dataFragment);
        }
示例#8
0
        public void Close(Cipher cipher, Random rnd, MAC mac, int sequence, DataFragment result)
        {
            if (!_is_open)
            {
                throw new SSHException("internal state error");
            }

            int blocksize      = cipher == null? 8 : cipher.BlockSize;
            int payload_length = _writer.Length - (SEQUENCE_MARGIN + LENGTH_MARGIN + PADDING_MARGIN);
            int r = 11 - payload_length % blocksize;

            while (r < 4)
            {
                r += blocksize;
            }
            _paddingLength = r;
            _packetLength  = PADDING_MARGIN + payload_length + _paddingLength;
            int image_length = _packetLength + LENGTH_MARGIN;

            //fill padding
            for (int i = 0; i < _paddingLength; i += 4)
            {
                _writer.Write(rnd.Next());
            }

            //manipulate stream
            byte[] rawbuf = _writer.UnderlyingBuffer;
            SSHUtil.WriteIntToByteArray(rawbuf, 0, sequence);
            SSHUtil.WriteIntToByteArray(rawbuf, SEQUENCE_MARGIN, _packetLength);
            rawbuf[SEQUENCE_MARGIN + LENGTH_MARGIN] = (byte)_paddingLength;

            //mac
            if (mac != null)
            {
                _mac = mac.ComputeHash(rawbuf, 0, _packetLength + LENGTH_MARGIN + SEQUENCE_MARGIN);
                Array.Copy(_mac, 0, rawbuf, _packetLength + LENGTH_MARGIN + SEQUENCE_MARGIN, _mac.Length);
                image_length += _mac.Length;
            }

            //encrypt
            if (cipher != null)
            {
                cipher.Encrypt(rawbuf, SEQUENCE_MARGIN, _packetLength + LENGTH_MARGIN, rawbuf, SEQUENCE_MARGIN);
            }

            result.Init(rawbuf, SEQUENCE_MARGIN, image_length);
            _is_open = false;
        }
示例#9
0
        private void SendKeyList()
        {
            SSH2DataWriter wr = OpenWriter(AgentForwadPacketType.SSH2_AGENT_IDENTITIES_ANSWER);

            // keycount, ((blob-len, pubkey-blob, comment-len, comment) * keycount)
            SSH2UserAuthKey[] keys = _client.GetAvailableSSH2UserAuthKeys();
            wr.Write(keys.Length);
            foreach (SSH2UserAuthKey key in keys)
            {
                byte[] blob = key.GetPublicKeyBlob();
                wr.WriteAsString(blob);
                Debug.WriteLine("Userkey comment=" + key.Comment);
                wr.WriteAsString(Encoding.UTF8.GetBytes(key.Comment));
            }
            TransmitWriter(wr);
        }
示例#10
0
        internal void dump(SSH2DataWriter writer)
        {
            writer.Write(flags);

            if ((flags & SSH_FILEXFER_ATTR_SIZE) != 0)
            {
                writer.WriteLong(size);
            }
            if ((flags & SSH_FILEXFER_ATTR_UIDGID) != 0)
            {
                writer.Write(uid);
                writer.Write(gid);
            }
            if ((flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0)
            {
                writer.Write(permissions);
            }
            if ((flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0)
            {
                writer.Write(atime);
            }
            if ((flags & SSH_FILEXFER_ATTR_ACMODTIME) != 0)
            {
                writer.Write(mtime);
            }
            if ((flags & SSH_FILEXFER_ATTR_EXTENDED) != 0)
            {
                int count = extended.Length / 2;
                if (count > 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        writer.Write(extended[i * 2].GetBytes());
                        writer.Write(extended[i * 2 + 1].GetBytes());
                    }
                }
            }
        }
示例#11
0
        public void WritePrivatePartInSECSHStyleFile(Stream dest, string comment, string passphrase)
        {
            //step1 key body
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.WriteInt32(0); //this field is filled later
            if (_keypair.Algorithm == PublicKeyAlgorithm.RSA)
            {
                RSAKeyPair   rsa = (RSAKeyPair)_keypair;
                RSAPublicKey pub = (RSAPublicKey)_keypair.PublicKey;
                wr.WriteBigIntWithBits(pub.Exponent);
                wr.WriteBigIntWithBits(rsa.D);
                wr.WriteBigIntWithBits(pub.Modulus);
                wr.WriteBigIntWithBits(rsa.U);
                wr.WriteBigIntWithBits(rsa.P);
                wr.WriteBigIntWithBits(rsa.Q);
            }
            else
            {
                DSAKeyPair   dsa = (DSAKeyPair)_keypair;
                DSAPublicKey pub = (DSAPublicKey)_keypair.PublicKey;
                wr.WriteInt32(0);
                wr.WriteBigIntWithBits(pub.P);
                wr.WriteBigIntWithBits(pub.G);
                wr.WriteBigIntWithBits(pub.Q);
                wr.WriteBigIntWithBits(pub.Y);
                wr.WriteBigIntWithBits(dsa.X);
            }

            int padding_len = 0;

            if (passphrase != null)
            {
                padding_len = 8 - (int)wr.Length % 8;
                wr.Write(new byte[padding_len]);
            }
            byte[] encrypted_body = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(encrypted_body, 0, encrypted_body.Length - padding_len - 4);

            //encrypt if necessary
            if (passphrase != null)
            {
                Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase, 24));
                Debug.Assert(encrypted_body.Length % 8 == 0);
                byte[] tmp = new Byte[encrypted_body.Length];
                c.Encrypt(encrypted_body, 0, encrypted_body.Length, tmp, 0);
                encrypted_body = tmp;
            }

            //step2 make binary key data
            wr = new SSH2DataWriter();
            wr.WriteInt32(MAGIC_VAL);
            wr.WriteInt32(0); //for total size
            wr.WriteString(_keypair.Algorithm == PublicKeyAlgorithm.RSA ?
                           "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" :
                           "dl-modp{sign{dsa-nist-sha1},dh{plain}}");

            wr.WriteString(passphrase == null ? "none" : "3des-cbc");
            wr.WriteAsString(encrypted_body);

            byte[] rawdata = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(rawdata, 4, rawdata.Length); //fix total length

            //step3 write final data
            StreamWriter sw = new StreamWriter(dest, Encoding.ASCII);

            sw.WriteLine("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----");
            if (comment != null)
            {
                WriteKeyFileBlock(sw, "Comment: " + comment, true);
            }
            WriteKeyFileBlock(sw, Encoding.ASCII.GetString(Base64.Encode(rawdata)), false);
            sw.WriteLine("---- END SSH2 ENCRYPTED PRIVATE KEY ----");
            sw.Close();
        }
示例#12
0
        public byte[] ToByteArray(string passphrase)
        {
            //step1 key body
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(0); //this field is filled later
            if (_keypair.Algorithm == PublicKeyAlgorithm.RSA)
            {
                RSAKeyPair   rsa = (RSAKeyPair)_keypair;
                RSAPublicKey pub = (RSAPublicKey)_keypair.PublicKey;
                wr.WriteBigIntWithBits(pub.Exponent);
                wr.WriteBigIntWithBits(rsa.D);
                wr.WriteBigIntWithBits(pub.Modulus);
                wr.WriteBigIntWithBits(rsa.U);
                wr.WriteBigIntWithBits(rsa.P);
                wr.WriteBigIntWithBits(rsa.Q);
            }
            else
            {
                DSAKeyPair   dsa = (DSAKeyPair)_keypair;
                DSAPublicKey pub = (DSAPublicKey)_keypair.PublicKey;
                wr.Write(0);
                wr.WriteBigIntWithBits(pub.P);
                wr.WriteBigIntWithBits(pub.G);
                wr.WriteBigIntWithBits(pub.Q);
                wr.WriteBigIntWithBits(pub.Y);
                wr.WriteBigIntWithBits(dsa.X);
            }

            int padding_len = 0;

            if (passphrase != null)
            {
                padding_len = 8 - (int)wr.Length % 8;
                wr.Write(new byte[padding_len]);
            }
            byte[] encrypted_body = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(encrypted_body, 0, encrypted_body.Length - padding_len - 4);

            //encrypt if necessary
            if (passphrase != null)
            {
                Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase, 24));
                Debug.Assert(encrypted_body.Length % 8 == 0);
                byte[] tmp = new Byte[encrypted_body.Length];
                c.Encrypt(encrypted_body, 0, encrypted_body.Length, tmp, 0);
                encrypted_body = tmp;
            }

            //step2 make binary key data
            wr = new SSH2DataWriter();
            wr.Write(MAGIC_VAL);
            wr.Write(0); //for total size
            wr.Write(_keypair.Algorithm == PublicKeyAlgorithm.RSA ?
                     "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" :
                     "dl-modp{sign{dsa-nist-sha1},dh{plain}}");

            wr.Write(passphrase == null ? "none" : "3des-cbc");
            wr.WriteAsString(encrypted_body);

            byte[] rawdata = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(rawdata, 4, rawdata.Length); //fix total length

            return(rawdata);
        }