From 811000073721021e0031d2ed3a9cd64d88a17793 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Thu, 20 Sep 2018 21:15:27 -0500 Subject: [PATCH] Parse title key files with pipes as delimiters --- LibHac/Keyset.cs | 31 ++++++++++++++++++----- LibHac/Util.cs | 65 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/LibHac/Keyset.cs b/LibHac/Keyset.cs index afe105a1..7bda6eca 100644 --- a/LibHac/Keyset.cs +++ b/LibHac/Keyset.cs @@ -1,5 +1,4 @@ - -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -350,11 +349,31 @@ namespace LibHac string line; while ((line = reader.ReadLine()) != null) { - var a = line.Split(',', '='); - if (a.Length != 2) continue; + string[] splitLine; - var rightsId = a[0].Trim().ToBytes(); - var titleKey = a[1].Trim().ToBytes(); + // Some people use pipes as delimiters + if (line.Contains('|')) + { + splitLine = line.Split('|'); + } + else + { + splitLine = line.Split(',', '='); + } + + if (splitLine.Length < 2) continue; + + if(!splitLine[0].Trim().TryToBytes(out byte[] rightsId)) + { + progress?.LogMessage($"Invalid rights ID \"{splitLine[0].Trim()}\" in title key file"); + continue; + } + + if(!splitLine[1].Trim().TryToBytes(out byte[] titleKey)) + { + progress?.LogMessage($"Invalid title key \"{splitLine[1].Trim()}\" in title key file"); + continue; + } if (rightsId.Length != TitleKeySize) { diff --git a/LibHac/Util.cs b/LibHac/Util.cs index 3b51a33c..60ae9e1f 100644 --- a/LibHac/Util.cs +++ b/LibHac/Util.cs @@ -161,51 +161,54 @@ namespace LibHac return fullFile.Substring(fullDirectory.Length + 1); } - private static int HexToInt(char c) + private static bool TryHexToInt(char c, out int value) { switch (c) { case '0': - return 0; + value = 0; break; case '1': - return 1; + value = 1; break; case '2': - return 2; + value = 2; break; case '3': - return 3; + value = 3; break; case '4': - return 4; + value = 4; break; case '5': - return 5; + value = 5; break; case '6': - return 6; + value = 6; break; case '7': - return 7; + value = 7; break; case '8': - return 8; + value = 8; break; case '9': - return 9; + value = 9; break; case 'a': case 'A': - return 10; + value = 10; break; case 'b': case 'B': - return 11; + value = 11; break; case 'c': case 'C': - return 12; + value = 12; break; case 'd': case 'D': - return 13; + value = 13; break; case 'e': case 'E': - return 14; + value = 14; break; case 'f': case 'F': - return 15; + value = 15; break; default: - throw new FormatException("Unrecognized hex char " + c); + value = 0; + return false; } + + return true; } private static readonly byte[,] ByteLookup = { @@ -220,11 +223,35 @@ namespace LibHac int lastchar = input.Length - 1; for (int i = 0; i < input.Length; i++) { - result[lastcell - (i >> 1)] |= ByteLookup[i & 1, HexToInt(input[lastchar - i])]; + if (!TryHexToInt(input[lastchar - i], out int hexInt)) + { + throw new FormatException($"Unrecognized hex char {input[lastchar - i]}"); + } + + result[lastcell - (i >> 1)] |= ByteLookup[i & 1, hexInt]; } return result; } + public static bool TryToBytes(this string input, out byte[] bytes) + { + var result = new byte[(input.Length + 1) >> 1]; + int lastcell = result.Length - 1; + int lastchar = input.Length - 1; + for (int i = 0; i < input.Length; i++) + { + if (!TryHexToInt(input[lastchar - i], out int hexInt)) + { + bytes = null; + return false; + } + + result[lastcell - (i >> 1)] |= ByteLookup[i & 1, hexInt]; + } + bytes = result; + return true; + } + private static readonly uint[] Lookup32 = CreateLookup32(); private static uint[] CreateLookup32()