예제 #1
0
        private void SendKEXINIT(Mode mode) {
            const string mac_algorithm = "hmac-sha1";
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_KEXINIT);
            byte[] cookie = new byte[16];
            RngManager.GetSecureRng().GetBytes(cookie);
            wr.Write(cookie);
            wr.WriteString(GetSupportedKexAlgorithms()); //    kex_algorithms
            wr.WriteString(FormatHostKeyAlgorithmDescription());            //    server_host_key_algorithms
            wr.WriteString(FormatCipherAlgorithmDescription());      //    encryption_algorithms_client_to_server
            wr.WriteString(FormatCipherAlgorithmDescription());      //    encryption_algorithms_server_to_client
            wr.WriteString(mac_algorithm);                  //    mac_algorithms_client_to_server
            wr.WriteString(mac_algorithm);                  //    mac_algorithms_server_to_client
            wr.WriteString("none");                       //    compression_algorithms_client_to_server
            wr.WriteString("none");                       //    compression_algorithms_server_to_client
            wr.WriteString("");                           //    languages_client_to_server
            wr.WriteString("");                           //    languages_server_to_client
            wr.WriteBool(false); //Indicates whether a guessed key exchange packet follows
            wr.WriteInt32(0);       //reserved for future extension

            _clientKEXINITPayload = wr.ToByteArray();
            _status = Status.WAIT_KEXINIT;
            if (_connection.IsEventTracerAvailable) {
                StringBuilder bld = new StringBuilder();
                bld.Append("kex_algorithm=");
                bld.Append(GetSupportedKexAlgorithms());
                bld.Append("; server_host_key_algorithms=");
                bld.Append(FormatHostKeyAlgorithmDescription());
                bld.Append("; encryption_algorithms_client_to_server=");
                bld.Append(FormatCipherAlgorithmDescription());
                bld.Append("; encryption_algorithms_server_to_client=");
                bld.Append(FormatCipherAlgorithmDescription());
                bld.Append("; mac_algorithms_client_to_server=");
                bld.Append(mac_algorithm);
                bld.Append("; mac_algorithms_server_to_client=");
                bld.Append(mac_algorithm);
                TraceTransmissionNegotiation(PacketType.SSH_MSG_KEXINIT, bld.ToString());
            }
            TransmitRawPayload(_clientKEXINITPayload);
        }
예제 #2
0
        private byte[] DeriveKey(BigInteger key, byte[] hash, char ch, int length) {
            byte[] result = new byte[length];

            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WriteBigInteger(key);
            wr.Write(hash);
            wr.WriteByte((byte)ch);
            wr.Write(_sessionID);
            byte[] h1 = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());
            if (h1.Length >= length) {
                Array.Copy(h1, 0, result, 0, length);
                return result;
            }
            else {
                wr = new SSH2DataWriter();
                wr.WriteBigInteger(key);
                wr.Write(_sessionID);
                wr.Write(h1);
                byte[] h2 = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());
                if (h1.Length + h2.Length >= length) {
                    Array.Copy(h1, 0, result, 0, h1.Length);
                    Array.Copy(h2, 0, result, h1.Length, length - h1.Length);
                    return result;
                }
                else
                    throw new SSHException("necessary key length is too big"); //long key is not supported
            }
        }
예제 #3
0
    public void WritePrivatePartInSECSHStyleFile(Stream dest, string comment,
                                                 SecureString 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)
      {
        var c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES,
                                           PassphraseToKey(passphrase, 24));
        Debug.Assert(encrypted_body.Length%8 == 0);
        var 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);

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

      //step3 write final data
      var 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();
    }