diff --git a/src/LibHac/Fs/ExternalKeys.cs b/src/LibHac/Fs/ExternalKeys.cs new file mode 100644 index 00000000..8ee8b883 --- /dev/null +++ b/src/LibHac/Fs/ExternalKeys.cs @@ -0,0 +1,38 @@ +using LibHac.FsService; +using LibHac.Ncm; +using LibHac.Spl; + +namespace LibHac.Fs +{ + public static class ExternalKeys + { + public static Result GetRightsId(this FileSystemClient fs, out RightsId rightsId, TitleId programId, + StorageId storageId) + { + IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); + + return fsProxy.GetRightsId(out rightsId, programId, storageId); + } + + public static Result RegisterExternalKey(this FileSystemClient fs, ref RightsId rightsId, ref AccessKey key) + { + IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); + + return fsProxy.RegisterExternalKey(ref rightsId, ref key); + } + + public static Result UnregisterExternalKey(this FileSystemClient fs, ref RightsId rightsId) + { + IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); + + return fsProxy.UnregisterExternalKey(ref rightsId); + } + + public static Result UnregisterAllExternalKey(this FileSystemClient fs) + { + IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject(); + + return fsProxy.UnregisterAllExternalKey(); + } + } +} diff --git a/src/LibHac/FsService/FileSystemProxy.cs b/src/LibHac/FsService/FileSystemProxy.cs index f6c4a0d6..adc67c3c 100644 --- a/src/LibHac/FsService/FileSystemProxy.cs +++ b/src/LibHac/FsService/FileSystemProxy.cs @@ -451,18 +451,25 @@ namespace LibHac.FsService public Result RegisterExternalKey(ref RightsId rightsId, ref AccessKey externalKey) { - throw new NotImplementedException(); + // Missing permission check + + return FsProxyCore.RegisterExternalKey(ref rightsId, ref externalKey); } public Result UnregisterExternalKey(ref RightsId rightsId) { - throw new NotImplementedException(); + // Missing permission check + + return FsProxyCore.UnregisterExternalKey(ref rightsId); } public Result UnregisterAllExternalKey() { - throw new NotImplementedException(); + // Missing permission check + + return FsProxyCore.UnregisterAllExternalKey(); } + public Result SetSdCardEncryptionSeed(ReadOnlySpan seed) { // todo: use struct instead of byte span diff --git a/src/LibHac/FsService/FileSystemProxyCore.cs b/src/LibHac/FsService/FileSystemProxyCore.cs index b3df317f..8bda0eaf 100644 --- a/src/LibHac/FsService/FileSystemProxyCore.cs +++ b/src/LibHac/FsService/FileSystemProxyCore.cs @@ -3,12 +3,14 @@ using LibHac.Fs; using LibHac.FsSystem; using LibHac.FsSystem.Save; using LibHac.FsService.Creators; +using LibHac.Spl; namespace LibHac.FsService { public class FileSystemProxyCore { private FileSystemCreators FsCreators { get; } + private ExternalKeySet ExternalKeys { get; } private byte[] SdEncryptionSeed { get; } = new byte[0x10]; private const string NintendoDirectoryName = "Nintendo"; @@ -16,9 +18,10 @@ namespace LibHac.FsService private GlobalAccessLogMode LogMode { get; set; } - public FileSystemProxyCore(FileSystemCreators fsCreators) + public FileSystemProxyCore(FileSystemCreators fsCreators, ExternalKeySet externalKeys) { FsCreators = fsCreators; + ExternalKeys = externalKeys ?? new ExternalKeySet(); } public Result OpenBisFileSystem(out IFileSystem fileSystem, string rootPath, BisPartitionId partitionId) @@ -122,6 +125,25 @@ namespace LibHac.FsService } } + public Result RegisterExternalKey(ref RightsId rightsId, ref AccessKey externalKey) + { + return ExternalKeys.Add(rightsId, externalKey); + } + + public Result UnregisterExternalKey(ref RightsId rightsId) + { + ExternalKeys.Remove(rightsId); + + return Result.Success; + } + + public Result UnregisterAllExternalKey() + { + ExternalKeys.Clear(); + + return Result.Success; + } + public Result SetSdCardEncryptionSeed(ReadOnlySpan seed) { seed.CopyTo(SdEncryptionSeed); diff --git a/src/LibHac/FsService/FileSystemServer.cs b/src/LibHac/FsService/FileSystemServer.cs index 09d17f40..7e6338c0 100644 --- a/src/LibHac/FsService/FileSystemServer.cs +++ b/src/LibHac/FsService/FileSystemServer.cs @@ -15,16 +15,17 @@ namespace LibHac.FsService /// Creates a new with a new default . /// /// The used for creating filesystems. - public FileSystemServer(FileSystemCreators fsCreators) : this(fsCreators, new StopWatchTimeSpanGenerator()) { } + public FileSystemServer(FileSystemCreators fsCreators) : this(fsCreators, null, new StopWatchTimeSpanGenerator()) { } /// /// Creates a new . /// /// The used for creating filesystems. + /// A keyset containing rights IDs and title keys. If null, an empty set will be created. /// The to use for access log timestamps. - public FileSystemServer(FileSystemCreators fsCreators, ITimeSpanGenerator timer) + public FileSystemServer(FileSystemCreators fsCreators, ExternalKeySet externalKeys, ITimeSpanGenerator timer) { - FsProxyCore = new FileSystemProxyCore(fsCreators); + FsProxyCore = new FileSystemProxyCore(fsCreators, externalKeys); FsClient = new FileSystemClient(this, timer); Timer = timer; } diff --git a/src/LibHac/Keyset.cs b/src/LibHac/Keyset.cs index 7b51d616..15513df2 100644 --- a/src/LibHac/Keyset.cs +++ b/src/LibHac/Keyset.cs @@ -382,7 +382,7 @@ namespace LibHac } } - public static class ExternalKeys + public static class ExternalKeyReader { private const int TitleKeySize = 0x10; @@ -390,7 +390,7 @@ namespace LibHac public static readonly Dictionary UniqueKeyDict; public static readonly Dictionary AllKeyDict; - static ExternalKeys() + static ExternalKeyReader() { List commonKeys = CreateCommonKeyList(); List uniqueKeys = CreateUniqueKeyList(); diff --git a/src/hactoolnet/Program.cs b/src/hactoolnet/Program.cs index 84ed4fb8..c352c039 100644 --- a/src/hactoolnet/Program.cs +++ b/src/hactoolnet/Program.cs @@ -174,7 +174,7 @@ namespace hactoolnet consoleKeyFile = homeConsoleKeyFile; } - ctx.Keyset = ExternalKeys.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile, ctx.Logger); + ctx.Keyset = ExternalKeyReader.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile, ctx.Logger); if (ctx.Options.SdSeed != null) { ctx.Keyset.SetSdSeed(ctx.Options.SdSeed.ToBytes()); @@ -185,15 +185,15 @@ namespace hactoolnet string dir = ctx.Options.OutDir; Directory.CreateDirectory(dir); - File.WriteAllText(Path.Combine(dir, keyFileName), ExternalKeys.PrintCommonKeys(ctx.Keyset)); - File.WriteAllText(Path.Combine(dir, "console.keys"), ExternalKeys.PrintUniqueKeys(ctx.Keyset)); - File.WriteAllText(Path.Combine(dir, "title.keys"), ExternalKeys.PrintTitleKeys(ctx.Keyset)); + File.WriteAllText(Path.Combine(dir, keyFileName), ExternalKeyReader.PrintCommonKeys(ctx.Keyset)); + File.WriteAllText(Path.Combine(dir, "console.keys"), ExternalKeyReader.PrintUniqueKeys(ctx.Keyset)); + File.WriteAllText(Path.Combine(dir, "title.keys"), ExternalKeyReader.PrintTitleKeys(ctx.Keyset)); } } private static void ProcessKeygen(Context ctx) { - Console.WriteLine(ExternalKeys.PrintCommonKeys(ctx.Keyset)); + Console.WriteLine(ExternalKeyReader.PrintCommonKeys(ctx.Keyset)); } // For running random stuff