private byte[] Hash(SequencePool sequencePool, BigInteger sharedSecret, byte[] exchangeHash, byte c, byte[] sessionId, int hashLength) { // https://tools.ietf.org/html/rfc4253#section-7.2 byte[] hashRv = new byte[hashLength]; int hashOffset = 0; // TODO: handle 'If the key length needed is longer than the output of the HASH' // HASH(K || H || c || session_id) using Sequence sequence = sequencePool.RentSequence(); var writer = new SequenceWriter(sequence); writer.WriteMPInt(sharedSecret); writer.Write(exchangeHash); writer.WriteByte(c); writer.Write(sessionId); using IncrementalHash hash = IncrementalHash.CreateHash(_hashAlgorithmName); foreach (var segment in sequence.AsReadOnlySequence()) { hash.AppendData(segment.Span); } byte[] K1 = hash.GetHashAndReset(); Append(hashRv, K1, ref hashOffset); while (hashOffset != hashRv.Length) { // TODO: handle 'If the key length needed is longer than the output of the HASH' // K3 = HASH(K || H || K1 || K2) throw new NotSupportedException(); } return(hashRv);
private static Packet CreatePublicKeyRequestMessage(SequencePool sequencePool, string userName, byte[] sessionId, PrivateKey privateKey) { /* * byte SSH_MSG_USERAUTH_REQUEST * string user name * string service name * string "publickey" * boolean TRUE * string public key algorithm name * string public key to be used for authentication * string signature */ using var packet = sequencePool.RentPacket(); var writer = packet.GetWriter(); writer.WriteByte(MessageNumber.SSH_MSG_USERAUTH_REQUEST); writer.WriteString(userName); writer.WriteString("ssh-connection"); writer.WriteString("publickey"); writer.WriteBoolean(true); writer.WriteString(privateKey.Format); privateKey.AppendPublicKey(ref writer); { /* * string session identifier * byte SSH_MSG_USERAUTH_REQUEST * string user name * string service name * string "publickey" * boolean TRUE * string public key algorithm name * string public key to be used for authentication */ using var signatureData = sequencePool.RentSequence(); var signatureWriter = new SequenceWriter(signatureData); signatureWriter.WriteString(sessionId); signatureWriter.WriteByte(MessageNumber.SSH_MSG_USERAUTH_REQUEST); signatureWriter.WriteString(userName); signatureWriter.WriteString("ssh-connection"); signatureWriter.WriteString("publickey"); signatureWriter.WriteBoolean(true); signatureWriter.WriteString(privateKey.Format); privateKey.AppendPublicKey(ref signatureWriter); privateKey.AppendSignature(ref writer, signatureData.AsReadOnlySequence()); } return(packet.Move()); }