ushort WriteCipherMessage(ContentType type, TLSMessage msg) { if (_ver == ProtocolVersion.TLS11 || _ver == ProtocolVersion.TLS12) { throw new NotImplementedException(); } int offset = 5; int init_offset = 5; ushort length = WritePlainMessage(type, msg, offset); _sendHMAC.Initialize(); if (_ver == ProtocolVersion.SSL30) { byte[] temp = new byte[11]; BitConverterBE.WriteUInt64(_sendSeq, temp, 0); temp[8] = (byte)type; BitConverterBE.WriteUInt16((ushort)length, temp, 9); _sendHMAC.TransformBlock(temp, 0, temp.Length, temp, 0); } else { byte[] temp = new byte[13]; BitConverterBE.WriteUInt64(_sendSeq, temp, 0); temp[8] = (byte)type; BitConverterBE.WriteUInt16((ushort)_ver, temp, 9); BitConverterBE.WriteUInt16((ushort)length, temp, 11); _sendHMAC.TransformBlock(temp, 0, temp.Length, temp, 0); } _sendHMAC.TransformBlock(_sendBuffer, offset, length, _sendBuffer, offset); _sendHMAC.TransformFinalBlock(Utility.EmptyByteArray, 0, 0); offset += length; Buffer.BlockCopy(_sendHMAC.Hash, 0, _sendBuffer, offset, _sparams.MACLength); Console.WriteLine("Record MAC"); Utility.Dump(_sendBuffer, offset, _sparams.MACLength); offset += _sparams.MACLength; byte padding_length = (byte)((_sparams.BlockLength - ((length + _sparams.MACLength + 1) % _sparams.BlockLength)) % _sparams.BlockLength); for (int i = 0; i < padding_length; i++) { _sendBuffer[offset++] = padding_length; } _sendBuffer[offset++] = padding_length; length += (ushort)(_sparams.MACLength + padding_length + 1); int encrypted = 0; while (encrypted < length) { int tmp = _encryptor.TransformBlock(_sendBuffer, init_offset + encrypted, length - encrypted, _sendBuffer, init_offset + encrypted); if (tmp == 0) { throw new CryptographicException(); } encrypted += tmp; } _sendSeq++; return(length); }
public void ComputeKeyBlock() { int bytes = (_mac_key_length << 1) + (_enc_key_length << 1) + (_fixed_iv_length << 1); byte[] key_block = _prf.Compute(bytes, _master_secret, "key expansion", new byte[][] { _server_random, _client_random }); Console.WriteLine("KeyBlock"); Utility.Dump(key_block); _client_write_MAC_key = new byte[_mac_key_length]; _server_write_MAC_key = new byte[_mac_key_length]; _client_write_key = new byte[_enc_key_length]; _server_write_key = new byte[_enc_key_length]; _client_write_IV = new byte[_fixed_iv_length]; _server_write_IV = new byte[_fixed_iv_length]; int idx = 0; Buffer.BlockCopy(key_block, idx, _client_write_MAC_key, 0, _mac_key_length); idx += _mac_key_length; Buffer.BlockCopy(key_block, idx, _server_write_MAC_key, 0, _mac_key_length); idx += _mac_key_length; Buffer.BlockCopy(key_block, idx, _client_write_key, 0, _enc_key_length); idx += _enc_key_length; Buffer.BlockCopy(key_block, idx, _server_write_key, 0, _enc_key_length); idx += _enc_key_length; Buffer.BlockCopy(key_block, idx, _client_write_IV, 0, _fixed_iv_length); idx += _fixed_iv_length; Buffer.BlockCopy(key_block, idx, _server_write_IV, 0, _fixed_iv_length); idx += _fixed_iv_length; }
void ProcessHandshake() { ClientHello clientHello = _recordLayer.Read() as ClientHello; if (clientHello == null) { throw new Exception(); } Console.WriteLine("[TLSServer] Receive ClientHello Version: {0}", clientHello.Version); Console.WriteLine("[TLSServer] CipherSuites"); for (int i = 0; i < clientHello.CipherSuites.Length; i++) { Console.WriteLine(" {0}", clientHello.CipherSuites[i]); } CipherSuite selected = _selector.Select(clientHello.CipherSuites); Console.WriteLine("[TLSServer] CipherSuite Selected. {0}", selected); if (selected == CipherSuite.NONE) { // Alertを送るべき? throw new Exception(); } CipherSuiteInfo selectedInfo = SupportedCipherSuites.GetSuiteInfo(selected); _sparams.SetVersion(clientHello.Version); _sparams.SetCipherSuite(selected, _signAlgo); _sparams.ClientRandom = clientHello.Random; _recordLayer.ProtocolVersion = clientHello.Version; byte[] serverRandom = new byte[RandomData.Size]; Extension[] serverExtensions = null; if (selectedInfo.IsECC) { serverExtensions = new Extension[] { new Extension(ExtensionType.EcPointFormats, new byte[] { 1, 0 }) } } ; RandomData.CreateRandomData(serverRandom, 0); _sparams.ServerRandom = serverRandom; ServerHello serverHello = new ServerHello(clientHello.Version, serverRandom, Utility.EmptyByteArray, selected, CompressionMethod.Null, serverExtensions); _recordLayer.Write(serverHello); Certificate serverCert = new Certificate(_certs); _recordLayer.Write(serverCert); if (Utility.IsNeedServerKeyExchangeMessage(_states.SecurityParameters.KeyExchangeAlgorithm)) { ServerKeyExchange serverExchange = new ServerKeyExchange(_sparams); _recordLayer.Write(serverExchange); } _recordLayer.Write(new ServerHelloDone()); TLSMessage msg = _recordLayer.Read(); ClientKeyExchange clientExchange = (ClientKeyExchange)msg; clientExchange.ComputeServerMasterSecret(_sparams); Console.WriteLine("MasterSecret"); Utility.Dump(_sparams.MasterSecret); _sparams.ComputeKeyBlock(); ChangeCipherSpec changeCipherSpec = (ChangeCipherSpec)_recordLayer.Read(); _recordLayer.EnableReceiveCipher(_sparams.CreateServerDecryptor(), _sparams.CreateClientWriteHMAC()); Finished finished = (Finished)_recordLayer.Read(); Console.WriteLine("VerifyData"); Utility.Dump(finished.VerifyData); Console.WriteLine("Computed VerifyData"); byte[] verifyData = _sparams.ComputeFinishedVerifyData(false); Utility.Dump(verifyData); if (!Utility.Equals(finished.VerifyData, 0, verifyData, 0, verifyData.Length)) { throw new Exception(); } _recordLayer.Write(ChangeCipherSpec.Instance); _recordLayer.EnableSendCipher(_sparams.CreateServerEncryptor(), _sparams.CreateServerWriteHMAC()); _recordLayer.ComputeHandshakeHash(true); verifyData = _sparams.ComputeFinishedVerifyData(true); Console.WriteLine("Finished VerifyData"); Utility.Dump(verifyData); finished = new Finished(_recordLayer.ProtocolVersion, verifyData); _recordLayer.Write(finished); }
TLSMessage ReadCipherText(ContentType type, ProtocolVersion ver, int offset, ushort length) { if (ver == ProtocolVersion.TLS11 && ver == ProtocolVersion.TLS12) { throw new NotImplementedException(); } Console.WriteLine("Encrypted"); Utility.Dump(_recvBuffer, offset, length); int decrypted = 0; while (decrypted < length) { int tmp = _decryptor.TransformBlock(_recvBuffer, offset + decrypted, length - decrypted, _recvBuffer, decrypted); if (tmp == 0) { throw new CryptographicException(); } decrypted += tmp; } Console.WriteLine("Decrypted"); Utility.Dump(_recvBuffer, 0, length); int fragLen = length - _recvBuffer[length - 1] - _sparams.MACLength - 1; if (fragLen < 0) { throw new Exception(); // Decrypt Error } Console.WriteLine("Fragment"); Utility.Dump(_recvBuffer, 0, fragLen); Console.WriteLine("HMAC"); Utility.Dump(_recvBuffer, fragLen, _sparams.MACLength); _recvHMAC.Initialize(); if (_ver == ProtocolVersion.SSL30) { byte[] temp = new byte[11]; BitConverterBE.WriteUInt64(_recvSeq, temp, 0); temp[8] = (byte)type; BitConverterBE.WriteUInt16((ushort)fragLen, temp, 9); _recvHMAC.TransformBlock(temp, 0, temp.Length, temp, 0); } else { byte[] temp = new byte[13]; BitConverterBE.WriteUInt64(_recvSeq, temp, 0); temp[8] = (byte)type; BitConverterBE.WriteUInt16((ushort)ver, temp, 9); BitConverterBE.WriteUInt16((ushort)fragLen, temp, 11); _recvHMAC.TransformBlock(temp, 0, temp.Length, temp, 0); } _recvHMAC.TransformBlock(_recvBuffer, 0, fragLen, _recvBuffer, 0); _recvHMAC.TransformFinalBlock(Utility.EmptyByteArray, 0, 0); Console.WriteLine("Comaputed HMAC"); Utility.Dump(_recvHMAC.Hash); _recvSeq++; return(ReadPlainText(type, ver, 0, (ushort)fragLen)); }