예제 #1
0
        protected override void DecodeDataBytes(ProtocolVersion version, byte[] data)
        {
            CertificateList.Clear();

            MemoryStream    memStream   = new MemoryStream(data);
            HandshakeStream stream      = new HandshakeStream(memStream);
            int             certsLength = (int)stream.ReadUInt24();

            int readBytes = 0;

            while (readBytes < certsLength)
            {
                int    certLength = (int)stream.ReadUInt24();
                byte[] certBytes  = stream.ReadBytes(certLength);
                readBytes += 3 + certLength;

                CertificateList.Add(new X509Certificate(certBytes));
            }
            if (readBytes != certsLength)
            {
                throw new AlertException(AlertDescription.IllegalParameter,
                                         "Certificate total length doesn't match contents");
            }
            stream.ConfirmEndOfStream();
        }
예제 #2
0
        protected override void DecodeDataBytes(ProtocolVersion version, byte[] data)
        {
            CertificateTypes.Clear();
            CertificateAuthorities.Clear();

            MemoryStream    memStream = new MemoryStream(data);
            HandshakeStream stream    = new HandshakeStream(memStream);

            int typesLength = stream.ReadUInt8();

            for (int i = 0; i < typesLength; i++)
            {
                CertificateTypes.Add(stream.ReadUInt8());
            }

            if (version.HasSelectableSighash)
            {
                int sighashLength = stream.ReadUInt16();
                if ((sighashLength % 2) != 0)
                {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "SianatureAndHashAlgorithms length invalid: " + sighashLength);
                }

                byte[] sighashData = stream.ReadBytes(sighashLength);
                for (int i = 0; i < sighashLength; i += 2)
                {
                    SignatureAndHashAlgorithms.Add((UInt16)((sighashData[i] << 8) | sighashData[i + 1]));
                }
            }

            int authsLength = stream.ReadUInt16();

            byte[] authData = stream.ReadBytes(authsLength);
            stream.ConfirmEndOfStream();

            int position = 0;

            while (position < authData.Length)
            {
                int authLength = (authData[position] << 8) | authData[position + 1];
                position += 2;

                if (position > authData.Length)
                {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "Authorities total length doesn't match contents");
                }

                string name = Encoding.ASCII.GetString(authData, position, authLength);
                position += authLength;

                CertificateAuthorities.Add(name);
            }
        }
예제 #3
0
        protected override void DecodeDataBytes(ProtocolVersion ver, byte[] data)
        {
            MemoryStream    memStream = new MemoryStream(data);
            HandshakeStream stream    = new HandshakeStream(memStream);

            byte major = stream.ReadUInt8();
            byte minor = stream.ReadUInt8();

            ServerVersion = new ProtocolVersion(major, minor);

            byte[] randomBytes = stream.ReadBytes(32);
            Random = new HandshakeRandom(randomBytes);

            int idLength = (int)stream.ReadUInt8();

            SessionID = stream.ReadBytes(idLength);

            CipherSuite       = stream.ReadUInt16();
            CompressionMethod = stream.ReadUInt8();

            byte[] extensionList = new byte[0];
            if (!stream.EndOfStream && ServerVersion.HasExtensions)
            {
                UInt16 extensionListLength = stream.ReadUInt16();
                extensionList = stream.ReadBytes(extensionListLength);
            }
            stream.ConfirmEndOfStream();

            int pos = 0;

            while (pos + 4 <= extensionList.Length)
            {
                UInt16 extensionType       = (UInt16)((extensionList[pos] << 8) | extensionList[pos + 1]);
                UInt16 extensionDataLength = (UInt16)((extensionList[pos + 2] << 8) | extensionList[pos + 3]);
                pos += 4;

                if (pos + extensionDataLength > extensionList.Length)
                {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "ServerHello extension data length too large: " + extensionDataLength);
                }

                byte[] extensionData = new byte[extensionDataLength];
                Buffer.BlockCopy(extensionList, pos, extensionData, 0, extensionData.Length);
                pos += extensionData.Length;

                Extensions.Add(new HelloExtension(extensionType, extensionData));
            }
        }
예제 #4
0
        protected override byte[] EncodeDataBytes(ProtocolVersion ver)
        {
            MemoryStream    memStream = new MemoryStream();
            HandshakeStream stream    = new HandshakeStream(memStream);

            stream.WriteUInt8(ServerVersion.Major);
            stream.WriteUInt8(ServerVersion.Minor);

            stream.WriteBytes(Random.GetBytes());

            stream.WriteUInt8((Byte)SessionID.Length);
            stream.WriteBytes(SessionID);

            stream.WriteUInt16(CipherSuite);
            stream.WriteUInt8(CompressionMethod);

            if (Extensions.Count > 0)
            {
                int length = 0;
                foreach (HelloExtension ext in Extensions)
                {
                    if (!ext.SupportsProtocolVersion(ServerVersion))
                    {
                        continue;
                    }
                    length += 4 + ext.Data.Length;
                }
                stream.WriteUInt16((UInt16)length);
                foreach (HelloExtension ext in Extensions)
                {
                    if (!ext.SupportsProtocolVersion(ServerVersion))
                    {
                        continue;
                    }

                    UInt16 type = ext.Type;
                    byte[] data = ext.Data;

                    stream.WriteUInt16(type);
                    stream.WriteUInt16((UInt16)data.Length);
                    stream.WriteBytes(data);
                }
            }

            return(memStream.ToArray());
        }
        protected override void DecodeDataBytes(ProtocolVersion version, byte[] data)
        {
            CertificateTypes.Clear();
            CertificateAuthorities.Clear();

            MemoryStream memStream = new MemoryStream(data);
            HandshakeStream stream = new HandshakeStream(memStream);

            int typesLength = stream.ReadUInt8();
            for (int i=0; i<typesLength; i++) {
                CertificateTypes.Add(stream.ReadUInt8());
            }

            if (version.HasSelectableSighash) {
                int sighashLength = stream.ReadUInt16();
                if ((sighashLength%2) != 0) {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "SianatureAndHashAlgorithms length invalid: " + sighashLength);
                }

                byte[] sighashData = stream.ReadBytes(sighashLength);
                for (int i=0; i<sighashLength; i+=2) {
                    SignatureAndHashAlgorithms.Add((UInt16)((sighashData[i] << 8) | sighashData[i+1]));
                }
            }

            int authsLength = stream.ReadUInt16();
            byte[] authData = stream.ReadBytes(authsLength);
            stream.ConfirmEndOfStream();

            int position=0;
            while (position < authData.Length) {
                int authLength = (authData[position] << 8) | authData[position+1];
                position += 2;

                if (position > authData.Length) {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "Authorities total length doesn't match contents");
                }

                string name = Encoding.ASCII.GetString(authData, position, authLength);
                position += authLength;

                CertificateAuthorities.Add(name);
            }
        }
예제 #6
0
        public byte[] Encode()
        {
            MemoryStream    memStream = new MemoryStream();
            HandshakeStream stream    = new HandshakeStream(memStream);

            byte[] dataBytes;
            try {
                dataBytes = EncodeDataBytes(_version);
            } catch (AlertException ae) {
                throw ae;
            } catch (Exception e) {
                throw new AlertException(AlertDescription.InternalError, e.Message);
            }

            stream.WriteUInt8((byte)Type);
            stream.WriteUInt24((UInt32)dataBytes.Length);
            stream.WriteBytes(dataBytes);

            return(memStream.ToArray());
        }
예제 #7
0
        protected override void DecodeDataBytes(ProtocolVersion version, byte[] data)
        {
            CertificateList.Clear();

            MemoryStream memStream = new MemoryStream(data);
            HandshakeStream stream = new HandshakeStream(memStream);
            int certsLength = (int) stream.ReadUInt24();

            int readBytes = 0;
            while (readBytes<certsLength) {
                int certLength = (int) stream.ReadUInt24();
                byte[] certBytes = stream.ReadBytes(certLength);
                readBytes += 3+certLength;

                CertificateList.Add(new X509Certificate(certBytes));
            }
            if (readBytes != certsLength) {
                throw new AlertException(AlertDescription.IllegalParameter,
                                         "Certificate total length doesn't match contents");
            }
            stream.ConfirmEndOfStream();
        }
예제 #8
0
        public void Decode(byte[] data)
        {
            MemoryStream    memStream = new MemoryStream(data);
            HandshakeStream stream    = new HandshakeStream(memStream);

            int type = (int)stream.ReadUInt8();

            if (type != (int)Type)
            {
                throw new AlertException(AlertDescription.InternalError, "Incorrect message type");
            }

            int fragmentLength = (int)stream.ReadUInt24();

            byte[] fragment = stream.ReadBytes(fragmentLength);

            try {
                DecodeDataBytes(_version, fragment);
            } catch (AlertException ae) {
                throw ae;
            } catch (Exception e) {
                throw new AlertException(AlertDescription.InternalError, e.Message);
            }
        }
예제 #9
0
        protected override byte[] EncodeDataBytes(ProtocolVersion version)
        {
            int certsLength = 0;

            foreach (X509Certificate cert in CertificateList)
            {
                certsLength += 3;
                certsLength += cert.GetRawCertData().Length;
            }

            MemoryStream    memStream = new MemoryStream();
            HandshakeStream stream    = new HandshakeStream(memStream);

            stream.WriteUInt24((UInt32)certsLength);
            foreach (X509Certificate cert in CertificateList)
            {
                byte[] certBytes = cert.GetRawCertData();

                stream.WriteUInt24((UInt32)certBytes.Length);
                stream.WriteBytes(certBytes);
            }

            return(memStream.ToArray());
        }
예제 #10
0
        public byte[] Encode()
        {
            MemoryStream memStream = new MemoryStream();
            HandshakeStream stream = new HandshakeStream(memStream);

            byte[] dataBytes;
            try {
                dataBytes = EncodeDataBytes(_version);
            } catch (AlertException ae) {
                throw ae;
            } catch (Exception e) {
                throw new AlertException(AlertDescription.InternalError, e.Message);
            }

            stream.WriteUInt8((byte) Type);
            stream.WriteUInt24((UInt32) dataBytes.Length);
            stream.WriteBytes(dataBytes);

            return memStream.ToArray();
        }
예제 #11
0
        public void Decode(byte[] data)
        {
            MemoryStream memStream = new MemoryStream(data);
            HandshakeStream stream = new HandshakeStream(memStream);

            int type = (int) stream.ReadUInt8();
            if (type != (int) Type) {
                throw new AlertException(AlertDescription.InternalError, "Incorrect message type");
            }

            int fragmentLength = (int) stream.ReadUInt24();
            byte[] fragment = stream.ReadBytes(fragmentLength);

            try {
                DecodeDataBytes(_version, fragment);
            } catch (AlertException ae) {
                throw ae;
            } catch (Exception e) {
                throw new AlertException(AlertDescription.InternalError, e.Message);
            }
        }
예제 #12
0
        protected override byte[] EncodeDataBytes(ProtocolVersion version)
        {
            int typesLength = 0;
            if (CertificateTypes.Count > 255) {
                throw new Exception("Number of certificate types too large: " + CertificateTypes.Count);
            } else {
                typesLength = CertificateTypes.Count;
            }

            int sighashLength = 0;
            if (version.HasSelectableSighash) {
                if (SignatureAndHashAlgorithms.Count > 65535) {
                    throw new Exception("Number of sighash values too large: " + SignatureAndHashAlgorithms.Count);
                } else {
                    sighashLength = 2*SignatureAndHashAlgorithms.Count;
                }
            }

            int authsLength = 0;
            foreach (string name in CertificateAuthorities) {
                // TODO: Should support punycode as well?
                authsLength += 2;
                authsLength += Encoding.ASCII.GetBytes(name).Length;
                if (authsLength > 65535) {
                    throw new Exception("Certificate authorities length too large");
                }
            }

            MemoryStream memStream = new MemoryStream();
            HandshakeStream stream = new HandshakeStream(memStream);

            stream.WriteUInt8((byte) typesLength);
            foreach (byte type in CertificateTypes) {
                stream.WriteUInt8(type);
            }

            if (version.HasSelectableSighash) {
                stream.WriteUInt16((UInt16) sighashLength);
                foreach (UInt16 sighash in SignatureAndHashAlgorithms) {
                    stream.WriteUInt16(sighash);
                }
            }

            stream.WriteUInt16((UInt16) authsLength);
            foreach (string name in CertificateAuthorities) {
                // TODO: Should support punycode as well?
                int nameLen = Encoding.ASCII.GetBytes(name).Length;
                stream.WriteUInt16((UInt16) nameLen);
                stream.WriteBytes(Encoding.ASCII.GetBytes(name));
            }

            return memStream.ToArray();
        }
예제 #13
0
        protected override void DecodeDataBytes(ProtocolVersion ver, byte[] data)
        {
            CipherSuites.Clear();
            CompressionMethods.Clear();

            MemoryStream memStream = new MemoryStream(data);
            HandshakeStream stream = new HandshakeStream(memStream);

            byte major = stream.ReadUInt8();
            byte minor = stream.ReadUInt8();
            ClientVersion = new ProtocolVersion(major, minor);

            byte[] randomBytes = stream.ReadBytes(32);
            Random = new HandshakeRandom(randomBytes);

            int idLength = (int) stream.ReadUInt8();
            SessionID = stream.ReadBytes(idLength);

            if (ClientVersion.IsUsingDatagrams) {
                int cookieLength = (int) stream.ReadUInt8();
                Cookie = stream.ReadBytes(cookieLength);
            }

            int cipherLength = (int) stream.ReadUInt16();
            for (int i=0; i<cipherLength; i+=2) {
                CipherSuites.Add(stream.ReadUInt16());
            }

            int compressionLength = (int) stream.ReadUInt8();
            for (int i=0; i<compressionLength; i++) {
                CompressionMethods.Add(stream.ReadUInt8());
            }

            byte[] extensionList = new byte[0];
            if (!stream.EndOfStream && ClientVersion.HasExtensions) {
                UInt16 extensionListLength = stream.ReadUInt16();
                extensionList = stream.ReadBytes(extensionListLength);
            }
            stream.ConfirmEndOfStream();

            int pos = 0;
            while (pos+4 <= extensionList.Length) {
                UInt16 extensionType = (UInt16) ((extensionList[pos] << 8) | extensionList[pos+1]);
                UInt16 extensionDataLength = (UInt16) ((extensionList[pos+2] << 8) | extensionList[pos+3]);
                pos += 4;

                if (pos+extensionDataLength > extensionList.Length) {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "ClientHello extension data length too large: " + extensionDataLength);
                }

                byte[] extensionData = new byte[extensionDataLength];
                Buffer.BlockCopy(extensionList, pos, extensionData, 0, extensionData.Length);
                pos += extensionData.Length;

                Extensions.Add(new HelloExtension(extensionType, extensionData));
            }
        }
예제 #14
0
        protected override byte[] EncodeDataBytes(ProtocolVersion ver)
        {
            if (CipherSuites.Count == 0 || CompressionMethods.Count == 0) {
                throw new Exception("No cipher suites or compression methods defined");
            }

            MemoryStream memStream = new MemoryStream();
            HandshakeStream stream = new HandshakeStream(memStream);

            stream.WriteUInt8(ClientVersion.Major);
            stream.WriteUInt8(ClientVersion.Minor);
            stream.WriteBytes(Random.GetBytes());
            stream.WriteUInt8((Byte) SessionID.Length);
            stream.WriteBytes(SessionID);
            if (ClientVersion.IsUsingDatagrams) {
                stream.WriteUInt8((Byte) Cookie.Length);
                stream.WriteBytes(Cookie);
            }

            stream.WriteUInt16((UInt16) (2*CipherSuites.Count));
            foreach (UInt16 cipher in CipherSuites) {
                stream.WriteUInt16(cipher);
            }

            stream.WriteUInt8((Byte) CompressionMethods.Count);
            foreach (Byte compression in CompressionMethods) {
                stream.WriteUInt8(compression);
            }

            if (Extensions.Count > 0) {
                int length = 0;
                foreach (HelloExtension ext in Extensions) {
                    if (!ext.SupportsProtocolVersion(ClientVersion))
                        continue;
                    length += 4 + ext.Data.Length;
                }
                stream.WriteUInt16((UInt16) length);
                foreach (HelloExtension ext in Extensions) {
                    if (!ext.SupportsProtocolVersion(ClientVersion))
                        continue;

                    UInt16 type = ext.Type;
                    byte[] data = ext.Data;

                    stream.WriteUInt16(type);
                    stream.WriteUInt16((UInt16) data.Length);
                    stream.WriteBytes(data);
                }
            }

            return memStream.ToArray();
        }
예제 #15
0
        protected override byte[] EncodeDataBytes(ProtocolVersion version)
        {
            int typesLength = 0;

            if (CertificateTypes.Count > 255)
            {
                throw new Exception("Number of certificate types too large: " + CertificateTypes.Count);
            }
            else
            {
                typesLength = CertificateTypes.Count;
            }

            int sighashLength = 0;

            if (version.HasSelectableSighash)
            {
                if (SignatureAndHashAlgorithms.Count > 65535)
                {
                    throw new Exception("Number of sighash values too large: " + SignatureAndHashAlgorithms.Count);
                }
                else
                {
                    sighashLength = 2 * SignatureAndHashAlgorithms.Count;
                }
            }

            int authsLength = 0;

            foreach (string name in CertificateAuthorities)
            {
                // TODO: Should support punycode as well?
                authsLength += 2;
                authsLength += Encoding.ASCII.GetBytes(name).Length;
                if (authsLength > 65535)
                {
                    throw new Exception("Certificate authorities length too large");
                }
            }

            MemoryStream    memStream = new MemoryStream();
            HandshakeStream stream    = new HandshakeStream(memStream);

            stream.WriteUInt8((byte)typesLength);
            foreach (byte type in CertificateTypes)
            {
                stream.WriteUInt8(type);
            }

            if (version.HasSelectableSighash)
            {
                stream.WriteUInt16((UInt16)sighashLength);
                foreach (UInt16 sighash in SignatureAndHashAlgorithms)
                {
                    stream.WriteUInt16(sighash);
                }
            }

            stream.WriteUInt16((UInt16)authsLength);
            foreach (string name in CertificateAuthorities)
            {
                // TODO: Should support punycode as well?
                int nameLen = Encoding.ASCII.GetBytes(name).Length;
                stream.WriteUInt16((UInt16)nameLen);
                stream.WriteBytes(Encoding.ASCII.GetBytes(name));
            }

            return(memStream.ToArray());
        }
예제 #16
0
        protected override byte[] EncodeDataBytes(ProtocolVersion version)
        {
            int certsLength = 0;
            foreach (X509Certificate cert in CertificateList) {
                certsLength += 3;
                certsLength += cert.GetRawCertData().Length;
            }

            MemoryStream memStream = new MemoryStream();
            HandshakeStream stream = new HandshakeStream(memStream);

            stream.WriteUInt24((UInt32) certsLength);
            foreach (X509Certificate cert in CertificateList) {
                byte[] certBytes = cert.GetRawCertData();

                stream.WriteUInt24((UInt32) certBytes.Length);
                stream.WriteBytes(certBytes);
            }

            return memStream.ToArray();
        }
예제 #17
0
        protected override byte[] EncodeDataBytes(ProtocolVersion ver)
        {
            if (CipherSuites.Count == 0 || CompressionMethods.Count == 0)
            {
                throw new Exception("No cipher suites or compression methods defined");
            }

            MemoryStream    memStream = new MemoryStream();
            HandshakeStream stream    = new HandshakeStream(memStream);

            stream.WriteUInt8(ClientVersion.Major);
            stream.WriteUInt8(ClientVersion.Minor);
            stream.WriteBytes(Random.GetBytes());
            stream.WriteUInt8((Byte)SessionID.Length);
            stream.WriteBytes(SessionID);
            if (ClientVersion.IsUsingDatagrams)
            {
                stream.WriteUInt8((Byte)Cookie.Length);
                stream.WriteBytes(Cookie);
            }

            stream.WriteUInt16((UInt16)(2 * CipherSuites.Count));
            foreach (UInt16 cipher in CipherSuites)
            {
                stream.WriteUInt16(cipher);
            }

            stream.WriteUInt8((Byte)CompressionMethods.Count);
            foreach (Byte compression in CompressionMethods)
            {
                stream.WriteUInt8(compression);
            }

            if (Extensions.Count > 0)
            {
                int length = 0;
                foreach (HelloExtension ext in Extensions)
                {
                    if (!ext.SupportsProtocolVersion(ClientVersion))
                    {
                        continue;
                    }
                    length += 4 + ext.Data.Length;
                }
                stream.WriteUInt16((UInt16)length);
                foreach (HelloExtension ext in Extensions)
                {
                    if (!ext.SupportsProtocolVersion(ClientVersion))
                    {
                        continue;
                    }

                    UInt16 type = ext.Type;
                    byte[] data = ext.Data;

                    stream.WriteUInt16(type);
                    stream.WriteUInt16((UInt16)data.Length);
                    stream.WriteBytes(data);
                }
            }

            return(memStream.ToArray());
        }