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); }
ushort WritePlainMessage(ContentType type, TLSMessage msg, int offset) { ushort size = msg.Write(_sendBuffer, offset); if (type == ContentType.Handshake) { byte[] temp = new byte[size]; Buffer.BlockCopy(_sendBuffer, offset, temp, 0, size); _handshakePackets.Add(temp); } return(size); }
void Write(ContentType type, TLSMessage msg) { Console.WriteLine("[RecordLayer] {0} {1}", type, msg); _sendBuffer[0] = (byte)type; BitConverterBE.WriteUInt16((ushort)_ver, _sendBuffer, 1); ushort size; if (_recordType == RecordState.PlainText || _recordType == RecordState.CipherTextReceiveOnly) { size = WritePlainMessage(type, msg, 5); } else { size = WriteCipherMessage(type, msg); } BitConverterBE.WriteUInt16(size, _sendBuffer, 3); _strm.Write(_sendBuffer, 0, size + 5); _strm.Flush(); }
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); }
ushort WritePlainMessage(ContentType type, TLSMessage msg, int offset) { ushort size = msg.Write (_sendBuffer, offset); if (type == ContentType.Handshake) { byte[] temp = new byte[size]; Buffer.BlockCopy (_sendBuffer, offset, temp, 0, size); _handshakePackets.Add (temp); } return size; }
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; }
void Write(ContentType type, TLSMessage msg) { Console.WriteLine ("[RecordLayer] {0} {1}", type, msg); _sendBuffer[0] = (byte)type; BitConverterBE.WriteUInt16 ((ushort)_ver, _sendBuffer, 1); ushort size; if (_recordType == RecordState.PlainText || _recordType == RecordState.CipherTextReceiveOnly) size = WritePlainMessage (type, msg, 5); else size = WriteCipherMessage (type, msg); BitConverterBE.WriteUInt16 (size, _sendBuffer, 3); _strm.Write (_sendBuffer, 0, size + 5); _strm.Flush (); }