public override void AppendPublicKey(ref SequenceWriter writer) { RSAParameters parameters = _rsa.ExportParameters(includePrivateParameters: false); using var innerData = writer.SequencePool.RentSequence(); var innerWriter = new SequenceWriter(innerData); innerWriter.WriteString(AlgorithmNames.SshRsa); innerWriter.WriteMPInt(parameters.Exponent); innerWriter.WriteMPInt(parameters.Modulus); writer.WriteString(innerData.AsReadOnlySequence()); }
private byte[] CalculateExchangeHash(SequencePool sequencePool, SshConnectionInfo connectionInfo, Packet clientKexInitMsg, Packet serverKexInitMsg, ReadOnlySequence <byte> public_host_key, ECPoint q_c, ECPoint q_s, BigInteger sharedSecret) { /* * string V_C, client's identification string (CR and LF excluded) * string V_S, server's identification string (CR and LF excluded) * string I_C, payload of the client's SSH_MSG_KEXINIT * string I_S, payload of the server's SSH_MSG_KEXINIT * string K_S, server's public host key * string Q_C, client's ephemeral public key octet string * string Q_S, server's ephemeral public key octet string * mpint K, shared secret */ using Sequence sequence = sequencePool.RentSequence(); var writer = new SequenceWriter(sequence); writer.WriteString(connectionInfo.ClientIdentificationString !); writer.WriteString(connectionInfo.ServerIdentificationString !); writer.WriteString(clientKexInitMsg.Payload); writer.WriteString(serverKexInitMsg.Payload); writer.WriteString(public_host_key); writer.WriteString(q_c); writer.WriteString(q_s); writer.WriteMPInt(sharedSecret); using IncrementalHash hash = IncrementalHash.CreateHash(_hashAlgorithmName); foreach (var segment in sequence.AsReadOnlySequence()) { hash.AppendData(segment.Span); } return(hash.GetHashAndReset()); }
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);