private void ReloadKeySet() { string keyFile = null; string titleKeyFile = null; string consoleKeyFile = null; string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); LoadSetAtPath(Path.Combine(home, ".switch")); LoadSetAtPath(GetSystemPath()); void LoadSetAtPath(string basePath) { string localKeyFile = Path.Combine(basePath, "prod.keys"); string localTitleKeyFile = Path.Combine(basePath, "title.keys"); string localConsoleKeyFile = Path.Combine(basePath, "console.keys"); if (File.Exists(localKeyFile)) { keyFile = localKeyFile; } if (File.Exists(localTitleKeyFile)) { titleKeyFile = localTitleKeyFile; } if (File.Exists(localConsoleKeyFile)) { consoleKeyFile = localConsoleKeyFile; } } KeySet = ExternalKeyReader.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile); }
public static void generateJson(string firmware, string pathkey, string firmver, string fwint, string output) { Keyset keyset = ExternalKeyReader.ReadKeyFile(pathkey); StringBuilder sb = new StringBuilder(); StringWriter sw = new StringWriter(sb); int files = Directory.GetFiles(firmware).Length; using (JsonWriter writer = new JsonTextWriter(sw)) { writer.Formatting = Formatting.Indented; writer.WriteStartObject(); writer.WritePropertyName("fw_info"); writer.WriteStartObject(); writer.WritePropertyName("version"); writer.WriteValue(firmver); writer.WritePropertyName("IsExfat"); writer.WriteValue(true); writer.WritePropertyName("files"); writer.WriteValue(files); writer.WriteEnd(); writer.WritePropertyName("titleids"); writer.WriteStartArray(); // escribir todos los titleid ListTitleid(firmware, keyset, writer); writer.WriteEndArray(); writer.WritePropertyName("programid"); writer.WriteStartObject(); Listnca(firmware, fwint, keyset, writer); writer.WriteEndObject(); writer.WriteEnd(); } File.WriteAllText(Path.Combine(output, fwint), sb.ToString()); }
public HandlerArgs(string[] raw_args) { Handler[] Handlers = new [] { // Operation modes new Handler(Aliases: new[] { "--get-info", "--info", "-i" }, Fn: () => OperationMode = Mode.GetInfo), new Handler(Aliases: new[] { "--get-latest", "--latest", "-l" }, Fn: () => OperationMode = Mode.GetLatest), new Handler(Aliases: new[] { "--help", "-h" }, Fn: () => OperationMode = Mode.Help), // Args new Handler(Aliases: new[] { "--cert", "-c" }, Fn: x => CertPath = x), new Handler(Aliases: new[] { "--keyset", "-k" }, Fn: x => KeysetPath = x), new Handler(Aliases: new[] { "--out-path", "--out", "-o" }, Fn: x => OutPath = x), new Handler(Aliases: new[] { "--device-id", "-did" }, Fn: x => DeviceID = x), new Handler(Aliases: new[] { "--environment", "-env" }, Fn: x => Env = x), new Handler(Aliases: new[] { "--server", "-s" }, Fn: x => Server = x), new Handler(Aliases: new[] { "--platform", "-p" }, Fn: x => Platform = x), new Handler(Aliases: new[] { "--firmware-version", "-fwver" }, Fn: x => FirmwareVersion = x), new Handler(Aliases: new[] { "--jobs", "-j" }, Fn: x => MaxJobs = Math.Min(int.Parse(x), 1)), new Handler(Aliases: new[] { "--titles" }, Fn: x => TitleFilter = x.Split(',')), new Handler(Aliases: new[] { "-vf" }, Fn: x => FileVerbose = x), // Flags new Handler(Aliases: new[] { "-v" }, Fn: () => ConsoleVerbose = true), new Handler(Aliases: new[] { "--tencent", "-t" }, Fn: () => Tencent = true), new Handler(Aliases: new[] { "--ignore-warnings", "--no-confirm", "-q" }, Fn: () => IgnoreWarnings = true), new Handler(Aliases: new[] { "--only-meta" }, Fn: () => OnlyMeta = true) }; for (int i = 0; i < raw_args.Length; ++i) { var handler = Handlers.FirstOrDefault(x => x.Aliases.Contains(raw_args[i])); if (handler is null) { Console.WriteLine($"Warning: unknown arg {raw_args[i]}"); } else { handler.Invoke(handler.RequiresArg ? raw_args[++i] : null !); } } if (OperationMode is null) { return; } CertPath = Path.GetFullPath(CertPath); KeysetPath = Path.GetFullPath(KeysetPath); if (!String.IsNullOrEmpty(OutPath)) { OutPath = Path.GetFullPath(OutPath); } // keysets are only needed for a full download if (OperationMode == Mode.GetLatest) { Keyset = ExternalKeyReader.ReadKeyFile(KeysetPath); } }
public static void TryLoadKeys() { if (File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "/.switch/prod.keys")) { Console.WriteLine($"Using {Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/.switch/prod.keys"); ExternalKeyReader.ReadKeyFile(Keyset, Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "/.switch/prod.keys"); } else { Console.WriteLine("Couldn't load any keys!"); } }
public bool CopyKeyset() { ExternalKeyReader.ReadKeyFile(HACGUIKeyset.Keyset, KeysetFile.FullName); HACGUIKeyset.Keyset.DeriveKeys(); // derive from keyblobs if (HACGUIKeyset.Keyset.HeaderKey.IsEmpty()) { MessageBox.Show("It seems that you are missing some keys...\nLockpick_RCM requires that Atmosphere's sept be on the SD card to derive every key.\nPlease add it and try again."); return(false); } else { return(true); } }
private static void OpenKeyset(Context ctx) { string keyFileName = ctx.Options.UseDevKeys ? "dev.keys" : "prod.keys"; #if CORERT_NO_REFLECTION string home = HomeFolder.GetFolderPath(Environment.SpecialFolder.UserProfile); #else string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); #endif string homeKeyFile = Path.Combine(home, ".switch", keyFileName); string homeTitleKeyFile = Path.Combine(home, ".switch", "title.keys"); string homeConsoleKeyFile = Path.Combine(home, ".switch", "console.keys"); string keyFile = ctx.Options.Keyfile; string titleKeyFile = ctx.Options.TitleKeyFile; string consoleKeyFile = ctx.Options.ConsoleKeyFile; if (keyFile == null && File.Exists(homeKeyFile)) { keyFile = homeKeyFile; } if (titleKeyFile == null && File.Exists(homeTitleKeyFile)) { titleKeyFile = homeTitleKeyFile; } if (consoleKeyFile == null && File.Exists(homeConsoleKeyFile)) { consoleKeyFile = homeConsoleKeyFile; } ctx.Keyset = ExternalKeyReader.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile, ctx.Logger, ctx.Options.UseDevKeys); if (ctx.Options.SdSeed != null) { ctx.Keyset.SetSdSeed(ctx.Options.SdSeed.ToBytes()); } if (ctx.Options.InFileType == FileType.Keygen && ctx.Options.OutDir != null) { string dir = ctx.Options.OutDir; Directory.CreateDirectory(dir); 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 OpenKeyset(Context ctx) { string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); string homeKeyFile = Path.Combine(home, ".switch", "prod.keys"); string homeDevKeyFile = Path.Combine(home, ".switch", "dev.keys"); string homeTitleKeyFile = Path.Combine(home, ".switch", "title.keys"); string homeConsoleKeyFile = Path.Combine(home, ".switch", "console.keys"); string keyFile = ctx.Options.Keyfile; string titleKeyFile = ctx.Options.TitleKeyFile; string consoleKeyFile = ctx.Options.ConsoleKeyFile; if (keyFile == null && File.Exists(homeKeyFile)) { keyFile = homeKeyFile; } if (titleKeyFile == null && File.Exists(homeTitleKeyFile)) { titleKeyFile = homeTitleKeyFile; } if (consoleKeyFile == null && File.Exists(homeConsoleKeyFile)) { consoleKeyFile = homeConsoleKeyFile; } ctx.Keyset = ExternalKeyReader.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile, ctx.Logger); if (ctx.Options.SdSeed != null) { ctx.Keyset.SetSdSeed(ctx.Options.SdSeed.ToBytes()); } if (File.Exists(homeDevKeyFile)) { ctx.DevKeyset = ExternalKeyReader.ReadKeyFile(homeDevKeyFile, titleKeyFile, consoleKeyFile, ctx.Logger, true); if (ctx.Options.SdSeed != null) { ctx.DevKeyset.SetSdSeed(ctx.Options.SdSeed.ToBytes()); } } }
public void ReloadKeySet() { KeySet ??= KeySet.CreateDefaultKeySet(); string keyFile = null; string titleKeyFile = null; string consoleKeyFile = null; if (AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile) { LoadSetAtPath(AppDataManager.KeysDirPathUser); } LoadSetAtPath(AppDataManager.KeysDirPath); void LoadSetAtPath(string basePath) { string localKeyFile = Path.Combine(basePath, "prod.keys"); string localTitleKeyFile = Path.Combine(basePath, "title.keys"); string localConsoleKeyFile = Path.Combine(basePath, "console.keys"); if (File.Exists(localKeyFile)) { keyFile = localKeyFile; } if (File.Exists(localTitleKeyFile)) { titleKeyFile = localTitleKeyFile; } if (File.Exists(localConsoleKeyFile)) { consoleKeyFile = localConsoleKeyFile; } } ExternalKeyReader.ReadKeyFile(KeySet, keyFile, titleKeyFile, consoleKeyFile, null); }
private void ReloadKeySet() { string keyFile = null; string titleKeyFile = null; string consoleKeyFile = null; if (!AppDataManager.IsCustomBasePath) { LoadSetAtPath(AppDataManager.KeysDirPathAlt); } LoadSetAtPath(AppDataManager.KeysDirPath); void LoadSetAtPath(string basePath) { string localKeyFile = Path.Combine(basePath, "prod.keys"); string localTitleKeyFile = Path.Combine(basePath, "title.keys"); string localConsoleKeyFile = Path.Combine(basePath, "console.keys"); if (File.Exists(localKeyFile)) { keyFile = localKeyFile; } if (File.Exists(localTitleKeyFile)) { titleKeyFile = localTitleKeyFile; } if (File.Exists(localConsoleKeyFile)) { consoleKeyFile = localConsoleKeyFile; } } KeySet = ExternalKeyReader.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile); }
private static void OpenKeySet(Context ctx) { #if CORERT_NO_REFLECTION string home = HomeFolder.GetFolderPath(Environment.SpecialFolder.UserProfile); #else string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); #endif string homeTitleKeyFile = Path.Combine(home, ".switch", "title.keys"); string homeConsoleKeyFile = Path.Combine(home, ".switch", "console.keys"); string prodKeyFile = Path.Combine(home, ".switch", "prod.keys"); string devKeyFile = Path.Combine(home, ".switch", "dev.keys"); string titleKeyFile = ctx.Options.TitleKeyFile; string consoleKeyFile = ctx.Options.ConsoleKeyFile; // Check if the files from the command line exist if (titleKeyFile != null && !File.Exists(titleKeyFile)) { titleKeyFile = null; } if (consoleKeyFile != null && !File.Exists(consoleKeyFile)) { consoleKeyFile = null; } if (!File.Exists(prodKeyFile)) { prodKeyFile = null; } if (!File.Exists(devKeyFile)) { devKeyFile = null; } // Check the home directory if no existing key files were specified if (consoleKeyFile == null && File.Exists(homeConsoleKeyFile)) { consoleKeyFile = homeConsoleKeyFile; } if (titleKeyFile == null && File.Exists(homeTitleKeyFile)) { titleKeyFile = homeTitleKeyFile; } var keySet = KeySet.CreateDefaultKeySet(); // If the user specifies a key file then only load that file into the mode they specified, // otherwise load both prod.keys and dev.keys. // Todo: Should we add a way that both dev-only key files and mixed prod/dev key files // can both be loaded when specifying a key file in dev mode? if (ctx.Options.Keyfile != null && File.Exists(ctx.Options.Keyfile)) { keySet.SetMode(ctx.Options.KeyMode); ExternalKeyReader.ReadKeyFile(keySet, ctx.Options.Keyfile, titleKeyFile, consoleKeyFile, ctx.Logger); } else { ExternalKeyReader.ReadKeyFile(keySet, prodKeyFile, devKeyFile, titleKeyFile, consoleKeyFile, ctx.Logger); } keySet.SetMode(ctx.Options.KeyMode); if (ctx.Options.SdSeed != null) { keySet.SetSdSeed(ctx.Options.SdSeed.ToBytes()); } ctx.KeySet = keySet; }
static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("Pass the path to PRODINFO as the only argument"); return; } FileInfo prodinfoPath = new FileInfo(args[0]); if (!prodinfoPath.Exists) { Console.WriteLine($"Provided path \"{prodinfoPath.FullName}\" doesn't exist."); return; } if (OutputPfxInfo.Exists) { Console.WriteLine($"Output file {OutputPfxInfo.Name} already exists."); return; } Keyset k; if (GlobalProdSwitchKeysInfo.Exists) { k = ExternalKeyReader.ReadKeyFile(GlobalProdSwitchKeysInfo.FullName); } else if (LocalProdSwitchKeysInfo.Exists) { k = ExternalKeyReader.ReadKeyFile(LocalProdSwitchKeysInfo.FullName); } else { Console.WriteLine("Keys couldn't be found. Add to ~/.switch or working directory."); return; } k.DeriveKeys(); if (k.SslRsaKek.IsEmpty()) { Console.WriteLine("You are missing SslRsaKek in your keys file."); return; } Calibration cal0; byte[] certBytes; using (Stream prodinfoFile = prodinfoPath.OpenRead()) { prodinfoFile.Seek(0, SeekOrigin.Begin); cal0 = new Calibration(prodinfoFile); prodinfoFile.Seek(0x0AD0, SeekOrigin.Begin); // seek to certificate length byte[] buffer = new byte[0x4]; prodinfoFile.Read(buffer, 0, buffer.Length); // read cert length uint certLength = BitConverter.ToUInt32(buffer, 0); certBytes = new byte[certLength]; prodinfoFile.Seek(0x0AE0, SeekOrigin.Begin); // seek to cert (should be redundant?) prodinfoFile.Read(certBytes, 0, (int)certLength); // read actual cert } // extract enc private modulus byte[] counter = cal0.SslExtKey.Take(0x10).ToArray(); byte[] privateModulus = cal0.SslExtKey.Skip(0x10).ToArray(); // decrypt private modulus new Aes128CtrTransform(k.SslRsaKek, counter).TransformBlock(privateModulus); // import raw cert var certificate = new X509CertificateParser().ReadCertificate(certBytes); // import private modulus var privateParameter = certificate.RecoverPrivateParameter(privateModulus); // build PFX and add cert var store = new Pkcs12Store(); var certEntry = new X509CertificateEntry(certificate); store.SetCertificateEntry(certificate.SubjectDN.ToString(), certEntry); // add private key params to PFX AsymmetricKeyEntry privateKeyEntry = new AsymmetricKeyEntry(privateParameter); store.SetKeyEntry($"{certificate.SubjectDN}_key", privateKeyEntry, new[] { certEntry }); // output PFX with password using (Stream pfxStream = OutputPfxInfo.Create()) store.Save(pfxStream, "switch".ToCharArray(), new SecureRandom()); Console.WriteLine($"Wrote to {OutputPfxInfo.FullName}"); }
void Start(string keys, string fwPath, bool noExfat, bool verbose, bool showNcaIndex, bool fixHashes) { Config.keyset = ExternalKeyReader.ReadKeyFile(keys); Config.fwPath = fwPath; Config.noExfat = noExfat; Config.normalBisId = (noExfat) ? "0100000000000819" : "010000000000081B"; Config.safeBisId = (noExfat) ? "010000000000081A" : "010000000000081C"; Config.verbose = verbose; Config.fixHashes = fixHashes; int convertCount = 0; foreach (var foldername in Directory.GetDirectories(fwPath, "*.nca")) { convertCount++; File.Move($"{foldername}/00", $"{fwPath}/temp"); Directory.Delete(foldername); File.Move($"{fwPath}/temp", foldername); } if (convertCount > 0) { Console.WriteLine($"Converted folder ncas to files (count: {convertCount})"); } Console.WriteLine("Indexing nca files..."); NcaIndexer ncaIndex = new NcaIndexer(); VersionExtractor versionExtractor = new VersionExtractor(ncaIndex.FindNca("0100000000000809", NcaContentType.Meta)); string destFolder = $"NX-{versionExtractor.Version}"; if (!noExfat) { destFolder += "_exFAT"; } if (showNcaIndex) { ShowNcaIndex(ref ncaIndex, destFolder); return; } Console.WriteLine("\nEmmcHaccGen will now generate firmware files using the following settings:\n" + $"fw: {versionExtractor.Version}\n" + $"Exfat Support: {!noExfat}\n" + $"Key path: {keys}\n" + $"Destination folder: {destFolder}\n"); if (verbose) { Console.WriteLine($"BisIds:\nNormal: {Config.normalBisId}\nSafe: {Config.safeBisId}\n"); } // Folder creation Console.WriteLine("\nCreating folders.."); if (Directory.Exists(destFolder)) { Console.Write("Destenation folder already exists. Delete the old folder?\nY/N: "); string input = Console.ReadLine(); if (input[0].ToString().ToLower() != "y") { return; } Console.WriteLine($"Deleting {destFolder}"); Directory.Delete(destFolder, true); } foreach (string folder in FOLDERSTRUCTURE) { Directory.CreateDirectory($"{destFolder}{folder}"); } // Bis creation Console.WriteLine("\nGenerating bis.."); BisAssembler bisAssembler = new BisAssembler(ref ncaIndex, destFolder); BisFileAssembler bisFileAssembler = new BisFileAssembler($"{versionExtractor.Version}{((!noExfat) ? "_exFAT" : "")}", ref bisAssembler, $"{destFolder}/boot.bis"); // Copy fw files Console.WriteLine("\nCopying files..."); foreach (var file in Directory.EnumerateFiles(fwPath)) { File.Copy(file, $"{destFolder}/SYSTEM/Contents/registered/{file.Split(new char[] { '/', '\\' }).Last().Replace(".cnmt.nca ", ".nca ")}", true); } // Archive bit setting Console.WriteLine("\nSetting archive bits.."); SetArchiveRecursively($"{destFolder}/SYSTEM"); SetArchiveRecursively($"{destFolder}/USER"); //Imkv generation Console.WriteLine("\nGenerating imkvdb.."); Imkv imkvdb = new Imkv(ref ncaIndex); if (verbose) { imkvdb.DumpToFile($"{destFolder}/data.arc"); } File.Copy("save.stub", $"{destFolder}/SYSTEM/save/8000000000000120", true); using (IStorage outfile = new LocalStorage($"{destFolder}/SYSTEM/save/8000000000000120", FileAccess.ReadWrite)) { var save = new SaveDataFileSystem(Config.keyset, outfile, IntegrityCheckLevel.ErrorOnInvalid, true); save.OpenFile(out IFile file, new U8Span("/meta/imkvdb.arc"), OpenMode.AllowAppend | OpenMode.ReadWrite); using (file) { file.Write(0, imkvdb.bytes.ToArray(), WriteOption.Flush).ThrowIfFailure(); } save.Commit(Config.keyset).ThrowIfFailure(); } Console.WriteLine($"Wrote save with an imvkdb size of 0x{imkvdb.bytes.Count:X4}"); }
public MainPage() { InitializeComponent(); Loaded += (_, __) => { void rcmRefresh(bool b) { foreach (MenuItem item in RCMContextMenu.Items.Cast <MenuItem>().Where(i => i.Tag as string == "RequiresRCM")) { item.IsEnabled = b; } }; rcmRefresh(InjectService.LibusbKInstalled); void nandRefresh(bool b) { foreach (MenuItem item in NANDContextMenu.Items.Cast <MenuItem>().Where(i => i.Tag as string == "RequiresNAND")) { item.IsEnabled = b; } }; nandRefresh(false); InjectService.DeviceInserted += () => { if (InjectService.LibusbKInstalled) { Dispatcher.Invoke(() => rcmRefresh(true)); } }; InjectService.DeviceRemoved += () => { Dispatcher.Invoke(() => rcmRefresh(false)); }; NANDService.OnNANDPluggedIn += () => { Dispatcher.Invoke(() => nandRefresh(true)); }; NANDService.OnNANDRemoved += () => { Dispatcher.Invoke(() => nandRefresh(false)); }; SDService.OnSDPluggedIn += (effectiveRoot) => { DirectoryInfo root = SDService.SDRoot; DirectoryInfo switchDir = root.GetDirectory("switch"); if (switchDir.Exists) { FileInfo prodKeysInfo = switchDir.GetFile("prod.keys"); if (prodKeysInfo.Exists) { try { ExternalKeyReader.ReadKeyFile(HACGUIKeyset.Keyset, prodKeysInfo.FullName); new SaveKeysetTask(null).CreateTask().RunSynchronously(); } catch (Exception e) { MessageBox.Show($"An error occured when attempting to import keys from SD card. It could be corrupted.\nError: {e.Message}"); } } } }; // init this first as other pages may request tasks on init TaskManagerView = new TaskManagerPage(); TaskManagerFrame.Content = TaskManagerView; StatusService.Bar = StatusBar; StatusService.CurrentTaskBlock = CurrentTaskBlock; CurrentTaskBlock.Background = StatusBar.Background; TaskManagerView.Queue.Submit(new RunTask("Opening/Deriving keys...", new Task(() => HACGUIKeyset.Keyset.LoadAll()))); DeviceService.Start(); TitleManagerView = new MainTitleManagerPage(); TitleManagerFrame.Content = TitleManagerView; SaveManagerView = new SaveManagerPage(0); SaveManagerFrame.Content = SaveManagerView; StatusService.Start(); if (Native.IsAdministrator) { AdminButton.IsEnabled = false; } }; }