예제 #1
0
        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());
        }
예제 #2
0
        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());
        }
예제 #3
0
        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);