private void AddFinished(OutgoingMessageBag outgoingMessages) { //m_localHash.TransformFinalBlock(EmptyArray<byte>.Instance, 0, 0); byte[] seed = new byte[m_localHashBytes.Length]; Buffer.BlockCopy(m_localHashBytes, 0, seed, 0, m_localHashBytes.Length); //.Hash; m_localHash.Dispose(); m_localHash = null; m_localHashBytes = 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); } }
/// <summary> /// Dispose of all contained resources. /// </summary> public void Dispose() { if (m_decryptionBulkAlgorithm != null) { m_decryptionBulkAlgorithm.Dispose(); m_decryptionBulkAlgorithm = null; } if (m_encryptionBulkAlgorithm != null) { m_encryptionBulkAlgorithm.Dispose(); m_encryptionBulkAlgorithm = null; } if (m_decryptionHMAC != null) { m_decryptionHMAC.Dispose(); m_decryptionHMAC = null; } if (m_encryptionHMAC != null) { m_encryptionHMAC.Dispose(); m_encryptionHMAC = null; } if (PRF != null) { PRF.Dispose(); PRF = null; } }
/// <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 = new FinishedMessage(); finishedMessage.SetFromNetMQMessage(incomingMessage); //m_remoteHash.TransformFinalBlock(EmptyArray<byte>.Instance, 0, 0); byte[] seed = new byte[m_remoteHashBytes.Length]; Buffer.BlockCopy(m_remoteHashBytes, 0, seed, 0, m_remoteHashBytes.Length); //.Hash; m_remoteHash.Dispose(); m_remoteHash = null; m_remoteHashBytes = null; var label = SecurityParameters.Entity == ConnectionEnd.Client ? ServerFinishedLabel : ClientFinshedLabel; var 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 static void ModifyAfterHMACDispose() { using (IncrementalHash hash = IncrementalHash.CreateHMAC(HashAlgorithmName.SHA256, s_hmacKey)) { hash.Dispose(); Assert.Throws <ObjectDisposedException>(() => hash.AppendData(Array.Empty <byte>())); Assert.Throws <ObjectDisposedException>(() => hash.GetHashAndReset()); } }
protected override void Dispose(bool disposing) { CloseIfNotAlreadyClosedFromDispose(disposing); if (!_disposed) { _disposed = true; if (disposing) { if (_md5 != null) { _md5.Dispose(); } _binding.Dispose(); } } base.Dispose(disposing); }
protected virtual void Dispose(bool disposing) { if (disposing) { if (_inner != null) { _inner.Dispose(); _inner = null; } if (_hmac != null) { _hmac.Dispose(); _hmac = null; } if (_aes != null) { _aes.Dispose(); _aes = null; } } }
public void Dispose() { _hasher.Dispose(); }
private static void Derive( ReadOnlySpan <char> password, HashAlgorithmName hashAlgorithm, int iterationCount, byte id, ReadOnlySpan <byte> salt, Span <byte> destination) { // https://tools.ietf.org/html/rfc7292#appendix-B.2 Debug.Assert(iterationCount >= 1); if (!s_uvLookup.TryGetValue(hashAlgorithm, out Tuple <int, int>?uv)) { throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name); } (int u, int v) = uv; Debug.Assert(v <= 1024); // 1. Construct a string, D (the "diversifier"), by concatenating v/8 copies of ID. int vBytes = v >> 3; Span <byte> D = stackalloc byte[vBytes]; D.Fill(id); // 2. Concatenate copies of the salt together to create a string S of // length v(ceiling(s/ v)) bits(the final copy of the salt may be // truncated to create S). Note that if the salt is the empty // string, then so is S. int SLen = ((salt.Length - 1 + vBytes) / vBytes) * vBytes; // The password is a null-terminated UTF-16BE version of the input. int passLen = checked ((password.Length + 1) * 2); // If password == default then the span represents the null string (as opposed to // an empty string), and the P block should then have size 0 in the next step. if (password == default) { passLen = 0; } // 3. Concatenate copies of the password together to create a string P // of length v(ceiling(p/v)) bits (the final copy of the password // may be truncated to create P). Note that if the password is the // empty string, then so is P. // // (The RFC quote considers the trailing '\0' to be part of the string, // so "empty string" from this RFC means "null string" in C#, and C#'s // "empty string" is not 'empty' in this context.) int PLen = ((passLen - 1 + vBytes) / vBytes) * vBytes; // 4. Set I=S||P to be the concatenation of S and P. int ILen = SLen + PLen; Span <byte> I = stackalloc byte[0]; byte[]? IRented = null; if (ILen <= 1024) { I = stackalloc byte[ILen]; } else { IRented = CryptoPool.Rent(ILen); I = IRented.AsSpan(0, ILen); } IncrementalHash hash = IncrementalHash.CreateHash(hashAlgorithm); try { CircularCopy(salt, I.Slice(0, SLen)); CircularCopyUtf16BE(password, I.Slice(SLen)); int uBytes = u >> 3; Span <byte> hashBuf = stackalloc byte[uBytes]; Span <byte> bBuf = stackalloc byte[vBytes]; // 5. Set c=ceiling(n/u). // 6. For i=1, 2, ..., c, do the following: // (later we're going to start writing A_i values as output, // they mean "while work remains"). while (true) { // A. Set A_i=H^r(D||I). (i.e., the r-th hash of D||I, // H(H(H(... H(D || I)))) hash.AppendData(D); hash.AppendData(I); for (int j = iterationCount; j > 0; j--) { if (!hash.TryGetHashAndReset(hashBuf, out int bytesWritten) || bytesWritten != hashBuf.Length) { Debug.Fail($"Hash output wrote {bytesWritten} bytes when {hashBuf.Length} was expected"); throw new CryptographicException(); } if (j != 1) { hash.AppendData(hashBuf); } } // 7. Concatenate A_1, A_2, ..., A_c together to form a pseudorandom // bit string, A. // // 8. Use the first n bits of A as the output of this entire process. if (hashBuf.Length >= destination.Length) { hashBuf.Slice(0, destination.Length).CopyTo(destination); return; } hashBuf.CopyTo(destination); destination = destination.Slice(hashBuf.Length); // B. Concatenate copies of A_i to create a string B of length v // bits(the final copy of Ai may be truncated to create B). CircularCopy(hashBuf, bBuf); // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit // blocks, where k = ceiling(s / v) + ceiling(p / v), modify I by // setting I_j = (I_j + B + 1) mod 2 ^ v for each j. for (int j = (I.Length / vBytes) - 1; j >= 0; j--) { Span <byte> I_j = I.Slice(j * vBytes, vBytes); AddPlusOne(I_j, bBuf); } } } finally { CryptographicOperations.ZeroMemory(I); if (IRented != null) { CryptoPool.Return(IRented, clearSize: 0); } hash.Dispose(); } }
protected override void Dispose(bool disposing) { _md5.Dispose(); _sha1.Dispose(); }
public void Dispose() { _incrementalHash.Dispose(); }
public void Dispose() { _hasher.Dispose(); GC.SuppressFinalize(this); }
public void Dispose() { _hasher.Dispose(); ArrayPool <byte> .Shared.Return(_buffer); }
public void Dispose() { hasher.Dispose(); slimLock.Dispose(); }
protected override void Dispose(bool disposing) => _incrementalHash.Dispose();
public override void Dispose() { _incrementalHash.Dispose(); }
public override void Dispose() { _md5.Dispose(); _sha1.Dispose(); }
public void Dispose() { _hash.Dispose(); _hash = null; }