Exemple #1
0
        public static R <Licenses, string> Parse(ReadOnlySpan <byte> data)
        {
            if (data.Length < 1)
            {
                return("License too short");
            }
            var version = data[0];

            if (version != 1)
            {
                return("Unsupported version");
            }

            // Read licenses
            var res = new Licenses();

            data = data.Slice(1);
            while (data.Length > 0)
            {
                // Read next license
                var result = LicenseBlock.Parse(data);
                if (!result.Ok)
                {
                    return(result.Error);
                }
                var(license, len) = result.Value;

                // TODO Check valid times

                res.Blocks.Add(license);
                data = data.Slice(len);
            }
            return(res);
        }
Exemple #2
0
#pragma warning restore CS8618

        public static R <(LicenseBlock block, int read), string> Parse(ReadOnlySpan <byte> data)
        {
            if (data.Length < MinBlockLen)
            {
                return("License too short");
            }
            if (data[0] != 0)
            {
                return($"Wrong key kind {data[0]} in license");
            }

            LicenseBlock block;
            int          read;

            switch (data[33])
            {
            case 0:
                var result = ReadNullString(data.Slice(46));
                if (!result.Ok)
                {
                    return(result.Error);
                }
                var nullStr = result.Value;
                block = new IntermediateLicenseBlock(nullStr.str);
                read  = 5 + nullStr.read;
                break;

            case 2:
                if (!Enum.IsDefined(typeof(ServerLicenseType), data[42]))
                {
                    return($"Unknown license type {data[42]}");
                }
                result = ReadNullString(data.Slice(47));
                if (!result.Ok)
                {
                    return(result.Error);
                }
                nullStr = result.Value;
                block   = new ServerLicenseBlock(result.Value.str, (ServerLicenseType)data[42]);
                read    = 6 + nullStr.read;
                break;

            case 32:
                block = new EphemeralLicenseBlock();
                read  = 0;
                break;

            default:
                return($"Invalid license block type {data[33]}");
            }

            block.NotValidBefore = Tools.UnixTimeStart.AddSeconds(BinaryPrimitives.ReadUInt32BigEndian(data.Slice(34)) + 0x50e22700uL);
            block.NotValidAfter  = Tools.UnixTimeStart.AddSeconds(BinaryPrimitives.ReadUInt32BigEndian(data.Slice(38)) + 0x50e22700uL);
            if (block.NotValidAfter < block.NotValidBefore)
            {
                return("License times are invalid");
            }

            block.Key = data.Slice(1, 32).ToArray();

            var allLen = MinBlockLen + read;
            var hash   = TsCrypt.Hash512It(data[1..allLen].ToArray());