< Summary

Information
Class: Renci.SshNet.Security.KeyExchangeECDH
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\KeyExchangeECDH.cs
Line coverage
100%
Covered lines: 42
Uncovered lines: 0
Coverable lines: 42
Total lines: 106
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
Start(...)100%1100%
Finish()100%1100%
Session_KeyExchangeEcdhReplyMessageReceived(...)100%1100%
HandleServerEcdhReply(...)100%1100%

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\KeyExchangeECDH.cs

#LineLine coverage
 1using System;
 2using Renci.SshNet.Common;
 3using Renci.SshNet.Messages.Transport;
 4
 5using Renci.SshNet.Security.Org.BouncyCastle.Asn1.X9;
 6using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Agreement;
 7using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Generators;
 8using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Parameters;
 9using Renci.SshNet.Security.Org.BouncyCastle.Math.EC;
 10using Renci.SshNet.Security.Org.BouncyCastle.Security;
 11
 12namespace Renci.SshNet.Security
 13{
 14    internal abstract class KeyExchangeECDH : KeyExchangeEC
 15    {
 16        /// <summary>
 17        /// Gets the parameter of the curve.
 18        /// </summary>
 19        /// <value>
 20        /// The parameter of the curve.
 21        /// </value>
 22        protected abstract X9ECParameters CurveParameter { get; }
 23
 24        private ECDHCBasicAgreement _keyAgreement;
 25        private ECDomainParameters _domainParameters;
 26
 27        /// <summary>
 28        /// Starts key exchange algorithm.
 29        /// </summary>
 30        /// <param name="session">The session.</param>
 31        /// <param name="message">Key exchange init message.</param>
 32        public override void Start(Session session, KeyExchangeInitMessage message)
 933        {
 934            base.Start(session, message);
 35
 936            Session.RegisterMessage("SSH_MSG_KEX_ECDH_REPLY");
 37
 938            Session.KeyExchangeEcdhReplyMessageReceived += Session_KeyExchangeEcdhReplyMessageReceived;
 39
 940            _domainParameters = new ECDomainParameters(CurveParameter.Curve,
 941                                                      CurveParameter.G,
 942                                                      CurveParameter.N,
 943                                                      CurveParameter.H,
 944                                                      CurveParameter.GetSeed());
 45
 946            var g = new ECKeyPairGenerator();
 947            g.Init(new ECKeyGenerationParameters(_domainParameters, new SecureRandom()));
 48
 949            var aKeyPair = g.GenerateKeyPair();
 950            _keyAgreement = new ECDHCBasicAgreement();
 951            _keyAgreement.Init(aKeyPair.Private);
 952            _clientExchangeValue = ((ECPublicKeyParameters)aKeyPair.Public).Q.GetEncoded();
 53
 954            SendMessage(new KeyExchangeEcdhInitMessage(_clientExchangeValue));
 955        }
 56
 57        /// <summary>
 58        /// Finishes key exchange algorithm.
 59        /// </summary>
 60        public override void Finish()
 961        {
 962            base.Finish();
 63
 964            Session.KeyExchangeEcdhReplyMessageReceived -= Session_KeyExchangeEcdhReplyMessageReceived;
 965        }
 66
 67        private void Session_KeyExchangeEcdhReplyMessageReceived(object sender, MessageEventArgs<KeyExchangeEcdhReplyMes
 968        {
 969            var message = e.Message;
 70
 71            // Unregister message once received
 972            Session.UnRegisterMessage("SSH_MSG_KEX_ECDH_REPLY");
 73
 974            HandleServerEcdhReply(message.KS, message.QS, message.Signature);
 75
 76            // When SSH_MSG_KEXDH_REPLY received key exchange is completed
 977            Finish();
 978        }
 79
 80        /// <summary>
 81        /// Handles the server DH reply message.
 82        /// </summary>
 83        /// <param name="hostKey">The host key.</param>
 84        /// <param name="serverExchangeValue">The server exchange value.</param>
 85        /// <param name="signature">The signature.</param>
 86        private void HandleServerEcdhReply(byte[] hostKey, byte[] serverExchangeValue, byte[] signature)
 987        {
 988            _serverExchangeValue = serverExchangeValue;
 989            _hostKey = hostKey;
 990            _signature = signature;
 91
 992            var cordSize = (serverExchangeValue.Length - 1) / 2;
 993            var x = new byte[cordSize];
 994            Buffer.BlockCopy(serverExchangeValue, 1, x, 0, x.Length); // first byte is format. should be checked and pas
 995            var y = new byte[cordSize];
 996            Buffer.BlockCopy(serverExchangeValue, cordSize + 1, y, 0, y.Length);
 97
 998            var c = (FpCurve)_domainParameters.Curve;
 999            var q = c.CreatePoint(new Org.BouncyCastle.Math.BigInteger(1, x), new Org.BouncyCastle.Math.BigInteger(1, y)
 9100            var publicKey = new ECPublicKeyParameters("ECDH", q, _domainParameters);
 101
 9102            var k1 = _keyAgreement.CalculateAgreement(publicKey);
 9103            SharedKey = k1.ToByteArray().ToBigInteger2().ToByteArray().Reverse();
 9104        }
 105    }
 106}