예제 #1
0
        TLSMessage ReadPlainText(ContentType type, ProtocolVersion ver, int offset, ushort length)
        {
            switch (type)
            {
            case ContentType.Alert:
                return(new Alert((AlertLevel)_recvBuffer[offset], (AlertDescription)_recvBuffer[offset + 1]));

            case ContentType.ChangeCipherSpec:
                _recvSeq = 0;
                return(ChangeCipherSpec.Instance);

            case ContentType.Handshake:
                HandshakeType htype   = (HandshakeType)_recvBuffer[offset];
                uint          hlength = BitConverterBE.ReadUInt24(_recvBuffer, offset + 1);
                if (hlength > MaxFragmentSize - 9)
                {
                    throw new Exception();                              // TODO
                }
                if (htype == HandshakeType.Finished)
                {
                    ComputeHandshakeHash(false);
                }
                byte[] temp = new byte[length];
                Buffer.BlockCopy(_recvBuffer, offset, temp, 0, length);
                _handshakePackets.Add(temp);
                return(Handshake.HandshakeMessage.Create(ver, htype, _recvBuffer, offset + 4, hlength));

            case ContentType.ApplicationData:
                return(new ApplicationData(_recvBuffer, offset, length));

            default:
                throw new Exception();
            }
        }
예제 #2
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);
        }
예제 #3
0
        public TLSMessage Read()
        {
            ReadComplete(_headerBuffer, 0, _headerBuffer.Length);
            ContentType     type = (ContentType)_headerBuffer[0];
            ProtocolVersion ver;
            ushort          length;

            if (type == ContentType.SSL20Compatible)
            {
                _handshakePackets.Add(new byte[] { _headerBuffer[2], _headerBuffer[3], _headerBuffer[4] });

                length = (ushort)(_headerBuffer[1] - 3);
                if (_headerBuffer[2] != 1)
                {
                    throw new Exception();
                }
                ver = (ProtocolVersion)BitConverterBE.ReadUInt16(_headerBuffer, 3);
            }
            else
            {
                ver    = (ProtocolVersion)BitConverterBE.ReadUInt16(_headerBuffer, 1);
                length = BitConverterBE.ReadUInt16(_headerBuffer, 3);
            }
            if (ver != ProtocolVersion.SSL30 && ver != ProtocolVersion.TLS10 && ver != ProtocolVersion.TLS11 && ver != ProtocolVersion.TLS12)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("[RecordLayer] Unknown Version {0:x4}", (ushort)ver), DEBUG_CATEGORY);
                throw new Exception();
            }
            if (length > MaxFragmentSize)
            {
                throw new Exception();
            }
            ReadComplete(_recvBuffer, 0, length);

            // SSL2.0互換ClientHelloのみ例外的な処理
            if (type == ContentType.SSL20Compatible)
            {
                byte[] tmp = new byte[length];
                Buffer.BlockCopy(_recvBuffer, 0, tmp, 0, length);
                _handshakePackets.Add(tmp);
                return(Handshake.ClientHello.CreateFromSSL2CompatibleData(ver, _recvBuffer, 0, length));
            }

            TLSMessage msg;

            if (_recordType == RecordState.PlainText || _recordType == RecordState.CipherTextSendOnly)
            {
                msg = ReadPlainText(type, ver, 0, length);
            }
            else
            {
                msg = ReadCipherText(type, ver, 0, length);
            }
            Console.WriteLine("[RecordLayer] Receive {0}", msg);
            return(msg);
        }
예제 #4
0
        public static void CreateRandomData(byte[] buffer, int offset)
        {
            uint unixTime = (uint)((DateTime.UtcNow.Ticks - UnixTimeStart) / TimeSpan.TicksPerSecond);

            BitConverterBE.WriteUInt32(unixTime, buffer, offset);
            lock (_randBuffer) {
                RNG.GetBytes(_randBuffer);
                Buffer.BlockCopy(_randBuffer, 0, buffer, offset + 4, _randBuffer.Length);
            }
        }
예제 #5
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();
        }
예제 #6
0
        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));
        }