Beispiel #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 { Blocks = new List<LicenseBlock>() };
			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;
		}
Beispiel #2
0
		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 { Issuer = 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 { Issuer = result.Value.str, LicenseType = (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 = Util.UnixTimeStart.AddSeconds(BinaryPrimitives.ReadUInt32BigEndian(data.Slice(34)) + 0x50e22700uL);
			block.NotValidAfter = Util.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 = Ts3Crypt.Hash512It(data.Slice(1, allLen - 1).ToArray());
			block.Hash = hash.AsSpan(0, 32).ToArray();

			return (block, allLen);
		}