예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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();
        }
예제 #4
0
        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);
        }
예제 #5
0
        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;
        }
예제 #6
0
        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;
        }
예제 #7
0
 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 ();
 }