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); }
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 } }
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(); }