예제 #1
0
        private void AddFinished(OutgoingMessageBag outgoingMessages)
        {
            m_localHash.TransformFinalBlock(new byte[0], 0, 0);

            byte[] seed = m_localHash.Hash;
            m_localHash.Dispose();
            m_localHash = null;

            string label;

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                label = ServerFinishedLabel;
            }
            else
            {
                label = ClientFinshedLabel;
            }

            FinishedMessage finishedMessage = new FinishedMessage();

            finishedMessage.VerifyData =
                PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);

            NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage();

            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Finished;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                HashRemote(outgoingMessage);
            }
        }
예제 #2
0
        private void AddFinished(OutgoingMessageBag outgoingMessages)
        {
            m_localHash.TransformFinalBlock(EmptyArray <byte> .Instance, 0, 0);

            byte[] seed = m_localHash.Hash;
            m_localHash.Dispose();
            m_localHash = null;

            var label = SecurityParameters.Entity == ConnectionEnd.Server ? ServerFinishedLabel : ClientFinshedLabel;

            var finishedMessage = new FinishedMessage
            {
                VerifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength)
            };

            NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage();

            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Finished;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                HashRemote(outgoingMessage);
            }
        }
예제 #3
0
        private void AddFinished(OutgoingMessageBag outgoingMessages)
        {
            m_localHash.TransformFinalBlock(EmptyArray <byte> .Instance, 0, 0);

            byte[] seed = m_localHash.Hash;
#if NET40
            m_localHash.Dispose();
#endif
            m_localHash = null;

            var label = SecurityParameters.Entity == ConnectionEnd.Server ? ServerFinishedLabel : ClientFinshedLabel;

            var finishedMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3)?
                                  new V0_2.HandshakeMessages.FinishedMessage():
                                  new FinishedMessage();
            finishedMessage.VerifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);
#if DEBUG
            Debug.WriteLine("[verify_data]:" + BitConverter.ToString(finishedMessage.VerifyData));
#endif
            NetMQMessage outgoingMessage = finishedMessage.ToNetMQMessage();
            outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.Finished;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                HashRemote(outgoingMessage);
            }
        }
예제 #4
0
        // Password-Based Key Derivation Function 2. Used to generate "pseudorandom" keys from a given password and salt using a certain PRF applied a certain amount of times (iterations).
        // dklen specified the "derived key length" in bytes. It is recommended to use a high number for the iterations variable (somewhere around 4096 is the standard for SHA1 currently)
        public static byte[] PBKDF2(PRF function, byte[] password, byte[] salt, int iterations, int dklen)
        {
            byte[] dk   = new byte[0]; // Create a placeholder for the derived key
            uint   iter = 1;           // Track the iterations

            while (dk.Length < dklen)
            {
                // F-function
                // The F-function (PRF) takes the amount of iterations performed in the opposite endianness format from what C# uses, so we have to swap the endianness
                byte[] u    = function(password, Support.Concatenate(salt, Support.WriteToArray(new byte[4], Support.SwapEndian(iter), 0)));
                byte[] ures = new byte[u.Length];
                Array.Copy(u, ures, u.Length);
                for (int i = 1; i < iterations; ++i)
                {
                    // Iteratively apply the PRF
                    u = function(password, u);
                    for (int j = 0; j < u.Length; ++j)
                    {
                        ures[j] ^= u[j];
                    }
                }

                // Concatenate the result to the dk
                dk = Support.Concatenate(dk, ures);

                ++iter;
            }

            // Clip aby bytes past what we needed (yes, that's really what the standard is)
            return(dk.ToLength(dklen));
        }
예제 #5
0
        /// <exception cref="NetMQSecurityException">The Finished message must not be received while expecting a another message.</exception>
        /// <exception cref="NetMQSecurityException">The peer verification data must be valid.</exception>
        private void OnFinished(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (
                (SecurityParameters.Entity == ConnectionEnd.Client &&
                 (!m_secureChannel.ChangeSuiteChangeArrived ||
                  m_lastReceivedMessage != HandshakeType.ServerHelloDone || m_lastSentMessage != HandshakeType.Finished)) ||
                (SecurityParameters.Entity == ConnectionEnd.Server &&
                 (!m_secureChannel.ChangeSuiteChangeArrived ||
                  m_lastReceivedMessage != HandshakeType.ClientKeyExchange || m_lastSentMessage != HandshakeType.ServerHelloDone)))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Finished received when expecting another message");
            }

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                HashLocal(incomingMessage);
            }

            var finishedMessage = SubProtocolVersion.SequenceEqual(Constants.V3_3)?
                                  new V0_2.HandshakeMessages.FinishedMessage():
                                  new FinishedMessage();

            finishedMessage.SetFromNetMQMessage(incomingMessage);

            m_remoteHash.TransformFinalBlock(EmptyArray <byte> .Instance, 0, 0);

            byte[] seed = m_remoteHash.Hash;

#if NET40
            m_remoteHash.Dispose();
#else
            m_remoteHash.Clear();
#endif
            m_remoteHash = null;

            var label = SecurityParameters.Entity == ConnectionEnd.Client ? ServerFinishedLabel : ClientFinshedLabel;

            var verifyData = PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);

#if DEBUG
            Debug.WriteLine("[verify_data]:" + BitConverter.ToString(verifyData));
#endif
            if (!verifyData.SequenceEqual(finishedMessage.VerifyData))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeVerifyData, "peer verify data wrong");
            }

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                AddFinished(outgoingMessages);
#if DEBUG
                Debug.WriteLine("[finish]");
#endif
            }

            m_done = true;
        }
예제 #6
0
        private void OnFinished(NetMQMessage incomingMessage, OutgoingMessageBag outgoingMessages)
        {
            if (
                (SecurityParameters.Entity == ConnectionEnd.Client &&
                 (!m_secureChannel.ChangeSuiteChangeArrived ||
                  m_lastReceivedMessage != HandshakeType.ServerHelloDone || m_lastSentMessage != HandshakeType.Finished)) ||
                (SecurityParameters.Entity == ConnectionEnd.Server &&
                 (!m_secureChannel.ChangeSuiteChangeArrived ||
                  m_lastReceivedMessage != HandshakeType.ClientKeyExchange || m_lastSentMessage != HandshakeType.ServerHelloDone)))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeUnexpectedMessage, "Finished received when expecting another message");
            }

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                HashLocal(incomingMessage);
            }

            FinishedMessage finishedMessage = new FinishedMessage();

            finishedMessage.SetFromNetMQMessage(incomingMessage);

            m_remoteHash.TransformFinalBlock(new byte[0], 0, 0);

            byte[] seed = m_remoteHash.Hash;
            m_remoteHash.Dispose();
            m_remoteHash = null;

            string label;

            if (SecurityParameters.Entity == ConnectionEnd.Client)
            {
                label = ServerFinishedLabel;
            }
            else
            {
                label = ClientFinshedLabel;
            }

            byte[] verifyData =
                PRF.Get(SecurityParameters.MasterSecret, label, seed, FinishedMessage.VerifyDataLength);

            if (!verifyData.SequenceEqual(finishedMessage.VerifyData))
            {
                throw  new NetMQSecurityException(NetMQSecurityErrorCode.HandshakeVerifyData, "peer verify data wrong");
            }

            if (SecurityParameters.Entity == ConnectionEnd.Server)
            {
                AddFinished(outgoingMessages);
            }

            m_done = true;
        }
예제 #7
0
 public byte[] ComputeFinishedVerifyData(bool isServer)
 {
     if (_ver == ProtocolVersion.SSL30)
     {
         return(PRF.GetHandshakeHash());
     }
     else
     {
         return(PRF.Compute(12, MasterSecret, isServer ? "server finished" : "client finished", new byte[][] { PRF.GetHandshakeHash() }));
     }
 }
예제 #8
0
        private void GenerateMasterSecret(byte[] preMasterSecret)
        {
            var seed = new byte[RandomNumberLength * 2];

            Buffer.BlockCopy(SecurityParameters.ClientRandom, 0, seed, 0, RandomNumberLength);
            Buffer.BlockCopy(SecurityParameters.ServerRandom, 0, seed, RandomNumberLength, RandomNumberLength);

            SecurityParameters.MasterSecret =
                PRF.Get(preMasterSecret, MasterSecretLabel, seed, MasterSecretLength);

            Array.Clear(preMasterSecret, 0, preMasterSecret.Length);
        }
        public bool Verify(FinishedMessage message)
        {
            if (_keyConfig.Master is null)
            {
                throw new InvalidOperationException("Key config is not initialized");
            }

            var prfDigest = _cipherSuitesProvider.ResolvePRFHash(_cipherSuiteConfig.CipherSuite);
            var prf       = new PRF(prfDigest);

            var label        = _endConfig.End == ConnectionEnd.Server ? "client finished" : "server finished";
            var expectedData =
                prf.Digest(_keyConfig.Master, label, message.VerifyExpectedHash)
                .Take(FinishedMessage.VerifyDataLength)
                .ToArray();

            return(expectedData.SequenceEqual(message.VerifyActual));
        }
예제 #10
0
        public byte[] Compute(byte[] preMasterSecret)
        {
            if (_randomConfig.Client is null || _randomConfig.Server is null)
            {
                throw new InvalidOperationException("Random config is not initialized");
            }

            var clientRandom = _randomConfig.Client;
            var serverRandom = _randomConfig.Server;

            var random = new byte[clientRandom.Length + serverRandom.Length];

            Array.Copy(clientRandom, 0, random, 0, clientRandom.Length);
            Array.Copy(serverRandom, 0, random, clientRandom.Length, serverRandom.Length);

            var prfDigest = _cipherSuitesProvider.ResolvePRFHash(_cipherSuiteConfig.CipherSuite);
            var prf       = new PRF(prfDigest);

            return(prf.Digest(preMasterSecret, "master secret", random).Take(48).ToArray());
        }
        public FinishedMessage Generate()
        {
            if (_keyConfig.Master is null)
            {
                throw new InvalidOperationException("Key config is not initialized");
            }

            var prfDigest = _cipherSuitesProvider.ResolvePRFHash(_cipherSuiteConfig.CipherSuite);
            var prf       = new PRF(prfDigest);

            var label = _endConfig.End == ConnectionEnd.Server ? "server finished" : "client finished";
            var handshakeVerifyHash = _handshakeConfig.ComputeVerification(prfDigest);

            var verifyData =
                prf.Digest(_keyConfig.Master, label, handshakeVerifyHash)
                .Take(FinishedMessage.VerifyDataLength)
                .ToArray();

            return(new FinishedMessage(verifyData, handshakeVerifyHash));
        }
예제 #12
0
        private void GenerateMasterSecret(byte[] preMasterSecret)
        {
            var seed = new byte[RandomNumberLength * 2];

#if DEBUG
            Debug.WriteLine("[preMasterSecret]:" + BitConverter.ToString(preMasterSecret));
            Debug.WriteLine("[ClientRandom]:" + BitConverter.ToString(SecurityParameters.ClientRandom));
            Debug.WriteLine("[ServerRandom]:" + BitConverter.ToString(SecurityParameters.ServerRandom));
#endif
            Buffer.BlockCopy(SecurityParameters.ClientRandom, 0, seed, 0, RandomNumberLength);
            Buffer.BlockCopy(SecurityParameters.ServerRandom, 0, seed, RandomNumberLength, RandomNumberLength);

            SecurityParameters.MasterSecret =
                PRF.Get(preMasterSecret, MasterSecretLabel, seed, MasterSecretLength);

#if DEBUG
            Debug.WriteLine("[MasterSecret]:" + BitConverter.ToString(SecurityParameters.MasterSecret));
#endif
            Array.Clear(preMasterSecret, 0, preMasterSecret.Length);
        }
예제 #13
0
        public ActionResult <IEnumerable <ProfilesFunc> > GetUserProf()
        {
            List <ProfilesFunc> profilesFuncs = new List <ProfilesFunc>();

            var profiles = new ProfilesController(_context).GetProfiles().Result;

            if (profiles == null)
            {
                return(NotFound());
            }

            foreach (var profilex in profiles.Value)
            {
                var result = from func in _context.Functionalities
                             join prf in _context.Profile_Functionalities
                             on func.idFunctionalities equals prf.idFunctionalities into PRF
                             from prf in PRF.DefaultIfEmpty()
                             where prf.idProfile == profilex.idProfile
                             select new
                {
                    func.idFunctionalities,
                    func.Type
                };

                ProfilesFunc x = new ProfilesFunc();

                x.idProfile       = profilex.idProfile;
                x.Type            = profilex.Type;
                x.functionalities = result.Select(a => new Functionalities {
                    idFunctionalities = a.idFunctionalities, Type = a.Type
                }).ToList();

                profilesFuncs.Add(x);
            }

            return(Ok(profilesFuncs));
        }
예제 #14
0
        public void ComputeKeysAndUpdateConfig(byte[] masterSecret)
        {
            if (_randomConfig.Client is null || _randomConfig.Server is null)
            {
                throw new InvalidOperationException("Random config is not initialized");
            }

            _keyConfig.Master = masterSecret;

            var cipherSuite = _cipherSuiteConfig.CipherSuite;

            var clientRandom = _randomConfig.Client;
            var serverRandom = _randomConfig.Server;

            var cipher = _cipherSuitesProvider.ResolveCipherAlgorithm(cipherSuite);
            var mac    = _cipherSuitesProvider.ResolveHashAlgorithm(cipherSuite);

            var prfDigest = _cipherSuitesProvider.ResolvePRFHash(_cipherSuiteConfig.CipherSuite);
            var prf       = new PRF(prfDigest);

            var random = new byte[serverRandom.Length + clientRandom.Length];

            Array.Copy(serverRandom, 0, random, 0, serverRandom.Length);
            Array.Copy(clientRandom, 0, random, serverRandom.Length, clientRandom.Length);

            var macKeyLength = mac.HashSize / 8;
            var encKeyLength = cipher.KeySize;
            // for AEAD - TODO is it constant?
            var implicitIVLength = 4;

            var keyBlockLength = 2 * macKeyLength + 2 * encKeyLength + 2 * implicitIVLength;

            var keyBlock = prf.Digest(masterSecret, "key expansion", random).Take(keyBlockLength).ToArray();

            var offset = 0;

            // TODO technically AEAD has no mac (i.e. length == 0)
            if (!_cipherSuitesProvider.IsAEADCipher(cipherSuite))
            {
                var clientMACKey = new byte[macKeyLength];
                Array.Copy(keyBlock, offset, clientMACKey, 0, macKeyLength);
                offset += macKeyLength;
                _blockConfig.ClientMACKey = clientMACKey;

                var serverMACKey = new byte[macKeyLength];
                Array.Copy(keyBlock, offset, serverMACKey, 0, macKeyLength);
                offset += macKeyLength;
                _blockConfig.ServerMACKey = serverMACKey;
            }

            var clientKey = new byte[encKeyLength];

            Array.Copy(keyBlock, offset, clientKey, 0, encKeyLength);
            offset           += encKeyLength;
            _keyConfig.Client = clientKey;

            var serverKey = new byte[encKeyLength];

            Array.Copy(keyBlock, offset, serverKey, 0, encKeyLength);
            offset           += encKeyLength;
            _keyConfig.Server = serverKey;

            if (_cipherSuitesProvider.IsAEADCipher(cipherSuite))
            {
                var clientIV = new byte[implicitIVLength];
                Array.Copy(keyBlock, offset, clientIV, 0, implicitIVLength);
                offset += implicitIVLength;
                _aeadConfig.ClientIV = clientIV;

                var serverIV = new byte[implicitIVLength];
                Array.Copy(keyBlock, offset, serverIV, 0, implicitIVLength);
                offset += implicitIVLength;
                _aeadConfig.ServerIV = serverIV;
            }
        }