Example #1
0
 private static bool ReadFixedData(ref ArrayOffset <byte> input, int length, out byte[] data)
 {
     if (input.Length < length)
     {
         data = null;
         return(false);
     }
     data = new byte[length];
     input.CopyTo(data, 0, length);
     input += length;
     return(true);
 }
Example #2
0
        public static IList <SctSignature> DecodeData(byte[] rawData)
        {
            var signatures = new List <SctSignature>();
            var rData      = new ArrayOffset <byte>(rawData, 0);
            ArrayOffset <byte> list;

            if (!ReadChunkUInt16Header(ref rData, out list))
            {
                return(signatures);
            }
            ArrayOffset <byte> sct;
            int index = 0;

            while (ReadChunkUInt16Header(ref list, out sct))
            {
                var                   originalSct = sct;
                SctVersion            version;
                byte[]                logId;
                DateTime              timestamp;
                byte[]                extensions;
                SctHashAlgorithm      hashAlgorithm;
                SctSignatureAlgorithm signatureAlgorithm;
                byte[]                signature;
                if (
                    !ReadByteEnumeration(ref sct, out version) ||
                    !ReadFixedData(ref sct, LOG_ID_SIZE, out logId) ||
                    !ReadTimestamp(ref sct, out timestamp) ||
                    !ReadVariableDataUInt16Header(ref sct, out extensions) ||
                    !ReadByteEnumeration(ref sct, out hashAlgorithm) ||
                    !ReadByteEnumeration(ref sct, out signatureAlgorithm) ||
                    !ReadVariableDataUInt16Header(ref sct, out signature)
                    )
                {
                    continue;
                }
                signatures.Add(new SctSignature
                {
                    LogId              = logId,
                    Timestamp          = timestamp,
                    HashAlgorithm      = hashAlgorithm,
                    SignatureAlgorithm = signatureAlgorithm,
                    Extensions         = extensions,
                    Signature          = signature,
                    Index              = index++
                });
            }
            return(signatures);
        }
Example #3
0
        private static bool ReadTimestamp(ref ArrayOffset <byte> input, out DateTime timestamp)
        {
            const int size = sizeof(ulong);

            if (input.Length < size)
            {
                timestamp = default(DateTime);
                return(false);
            }
            var epochTime = 0UL;

            for (int i = 0, shift = size - 1; i < size; i++, shift--)
            {
                epochTime |= ((ulong)input[i] << (shift * 8));
            }
            timestamp = Epoch.UNIX_EPOCH.AddMilliseconds(epochTime);
            input    += size;
            return(true);
        }
Example #4
0
        private static bool ReadByteEnumeration <TEnumType>(ref ArrayOffset <byte> input, out TEnumType value)
        {
            if (!typeof(TEnumType).IsEnum || typeof(TEnumType).GetEnumUnderlyingType() != typeof(byte))
            {
                throw new ArgumentException(nameof(TEnumType));
            }
            const int size = sizeof(byte);

            if (input.Length < size)
            {
                value = default(TEnumType);
                return(false);
            }
            var val = input[0];

            value  = (TEnumType)(object)val;
            input += size;
            return(true);
        }
Example #5
0
        private static bool ReadChunkUInt16Header(ref ArrayOffset <byte> input, out ArrayOffset <byte> output)
        {
            var       inputCopy  = input;
            const int headerSize = sizeof(ushort);

            if (inputCopy.Length < headerSize)
            {
                output = default(ArrayOffset <byte>);
                return(false);
            }
            var chunkSize = (ushort)(inputCopy[0] << 8 | inputCopy[1]); //TLS records are big endian.

            if (chunkSize > inputCopy.Length - headerSize)
            {
                output = default(ArrayOffset <byte>);
                return(false);
            }
            var amountToConsume = headerSize + chunkSize;

            output = inputCopy + headerSize;
            input += amountToConsume;
            return(true);
        }
Example #6
0
        private static bool ReadVariableDataUInt16Header(ref ArrayOffset <byte> input, out byte[] data)
        {
            const int headerSize = sizeof(ushort);

            if (input.Length < headerSize)
            {
                data = null;
                return(false);
            }
            var chunkSize = (ushort)(input[0] << 8 | input[1]); //Big endian read

            input += headerSize;
            if (chunkSize == 0)
            {
                data = new byte[0];
                return(true);
            }
            var result = new byte[chunkSize];

            input.CopyTo(result, 0, chunkSize);
            input += chunkSize;
            data   = result;
            return(true);
        }