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); } }
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); } }
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); } }
// 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)); }
/// <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; }
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; }
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() })); } }
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)); }
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)); }
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); }
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)); }
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; } }