Exemple #1
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());
        }
        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());
        }
Exemple #3
0
        public override void AppendSignature(ref SequenceWriter writer, ReadOnlySequence <byte> data)
        {
            using var innerData = writer.SequencePool.RentSequence();
            var innerWriter = new SequenceWriter(innerData);

            innerWriter.WriteString(AlgorithmNames.SshRsa);
            int signatureLength = _rsa.KeySize / 8;

            byte[] signature = new byte[signatureLength];
            if (!_rsa.TrySignData(data.ToArray(), signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1, out int bytesWritten) ||
                bytesWritten != signatureLength)
            {
                throw new InvalidOperationException("Unable to sign data.");
            }
            innerWriter.WriteString(signature);

            writer.WriteString(innerData.AsReadOnlySequence());
        }
Exemple #4
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());
        }