Exemple #1
0
        public byte[] GetDecryptedTitleKey()
        {
            int keyRevision = Utilities.GetMasterKeyRevision(Header.KeyGeneration);

            byte[] titleKek = KeySet.TitleKeks[keyRevision].DataRo.ToArray();

            var rightsId = new RightsId(Header.RightsId);

            if (KeySet.ExternalKeySet.Get(rightsId, out AccessKey accessKey).IsFailure())
            {
                throw new MissingKeyException("Missing NCA title key.", rightsId.ToString(), KeyType.Title);
            }

            if (titleKek.IsZeros())
            {
                string keyName = $"titlekek_{keyRevision:x2}";
                throw new MissingKeyException("Unable to decrypt title key.", keyName, KeyType.Common);
            }

            byte[] encryptedKey = accessKey.Value.ToArray();
            byte[] decryptedKey = new byte[Aes.KeySize128];

            Aes.DecryptEcb128(encryptedKey, decryptedKey, titleKek);

            return(decryptedKey);
        }
Exemple #2
0
        public byte[] GetDecryptedTitleKey()
        {
            int keyRevision = Util.GetMasterKeyRevision(Header.KeyGeneration);

            byte[] titleKek = Keyset.TitleKeks[keyRevision];

            var rightsId = new RightsId(Header.RightsId);

            if (Keyset.ExternalKeySet.Get(rightsId, out AccessKey accessKey).IsFailure())
            {
                throw new MissingKeyException("Missing NCA title key.", rightsId.ToString(), KeyType.Title);
            }

            if (titleKek.IsEmpty())
            {
                string keyName = $"titlekek_{keyRevision:x2}";
                throw new MissingKeyException("Unable to decrypt title key.", keyName, KeyType.Common);
            }

            byte[] encryptedKey = accessKey.Value.ToArray();
            var    decryptedKey = new byte[CryptoOld.Aes128Size];

            CryptoOld.DecryptEcb(titleKek, encryptedKey, decryptedKey, CryptoOld.Aes128Size);

            return(decryptedKey);
        }
Exemple #3
0
        private void BuildChildItems(PartitionFileSystemItemBase parentItem)
        {
            try
            {
                var partitionFileSystem = parentItem.PartitionFileSystem;

                var remainingEntries = new List <PartitionFileEntry>();

                // First loop on *.tik files to inject title keys in KeySet
                foreach (var partitionFileEntry in partitionFileSystem.Files)
                {
                    var fileName = partitionFileEntry.Name;
                    if (!fileName.EndsWith(".tik", StringComparison.OrdinalIgnoreCase))
                    {
                        remainingEntries.Add(partitionFileEntry);
                        continue;
                    }

                    IFile file;
                    try
                    {
                        file = partitionFileSystem.OpenFile(partitionFileEntry, OpenMode.Read);
                    }
                    catch (Exception ex)
                    {
                        OnLoadingException(ex, parentItem);

                        var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToOpenPartitionFile.SafeFormat(ex.Message);
                        parentItem.Errors.Add(TREE_LOADING_CATEGORY, message);
                        _logger.LogError(ex, message);
                        continue;
                    }

                    Ticket ticket;
                    try
                    {
                        using var asStream = file.AsStream();
                        ticket             = new Ticket(asStream);
                    }
                    catch (Exception ex)
                    {
                        OnLoadingException(ex, parentItem);

                        var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToLoadTicketFile.SafeFormat(ex.Message);
                        parentItem.Errors.Add(TREE_LOADING_CATEGORY, message);
                        _logger.LogError(ex, message);
                        continue;
                    }

                    var ticketItem = new TicketItem(ticket, partitionFileEntry, file, parentItem);

                    try
                    {
                        var rightsId  = new RightsId(ticket.RightsId);
                        var accessKey = new AccessKey(ticket.TitleKeyBlock);

                        ticketItem.RightsId  = rightsId;
                        ticketItem.AccessKey = accessKey;

                        if (parentItem.KeySet.ExternalKeySet.Get(rightsId, out var existingAccessKey) == Result.Success)
                        {
                            // Here RightID key is already defined
                            if (existingAccessKey != accessKey)
                            {
                                // Replaces the RightID key with the one defined in the ticket
                                parentItem.KeySet.ExternalKeySet.Remove(rightsId);
                                parentItem.KeySet.ExternalKeySet.Add(rightsId, accessKey).ThrowIfFailure();
                                _logger.LogWarning(LocalizationManager.Instance.Current.Keys.LoadingWarning_TitleIdKeyReplaced.SafeFormat(rightsId.ToString(), accessKey.ToString(), fileName, existingAccessKey));
                            }
                            else
                            {
                                _logger.LogDebug(LocalizationManager.Instance.Current.Keys.LoadingDebug_TitleIdKeyAlreadyExists.SafeFormat(rightsId.ToString(), accessKey.ToString(), fileName));
                            }
                        }
                        else
                        {
                            parentItem.KeySet.ExternalKeySet.Add(rightsId, accessKey).ThrowIfFailure();
                            _logger.LogInformation(LocalizationManager.Instance.Current.Keys.LoadingInfo_TitleIdKeySuccessfullyInjected.SafeFormat(rightsId.ToString(), accessKey.ToString(), fileName));
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, LocalizationManager.Instance.Current.Keys.LoadingError_FailedToLoadTitleIdKey.SafeFormat(fileName, ex.Message));
                    }

                    parentItem.TicketChildItems.Add(ticketItem);
                }

                foreach (var partitionFileEntry in remainingEntries)
                {
                    IFile file;
                    try
                    {
                        file = partitionFileSystem.OpenFile(partitionFileEntry, OpenMode.Read);
                    }
                    catch (Exception ex)
                    {
                        OnLoadingException(ex, parentItem);

                        var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToOpenPartitionFile.SafeFormat(ex.Message);
                        parentItem.Errors.Add(TREE_LOADING_CATEGORY, message);
                        _logger.LogError(ex, message);
                        continue;
                    }

                    var fileName = partitionFileEntry.Name;
                    if (fileName.EndsWith(".nca", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".ncz", StringComparison.OrdinalIgnoreCase))
                    {
                        Nca nca;
                        try
                        {
                            nca = new Nca(parentItem.KeySet, new FileStorage(file));
                        }
                        catch (Exception ex)
                        {
                            OnLoadingException(ex, parentItem);

                            var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToLoadNcaFile.SafeFormat(ex.Message);
                            parentItem.Errors.Add(TREE_LOADING_CATEGORY, message);
                            _logger.LogError(ex, message);
                            continue;
                        }

                        var ncaItem = new NcaItem(nca, partitionFileEntry, file, parentItem);
                        BuildChildItems(ncaItem);
                        parentItem.NcaChildItems.Add(ncaItem);
                    }
                    else
                    {
                        var partitionFileEntryItem = new PartitionFileEntryItem(partitionFileEntry, file, parentItem);
                        parentItem.PartitionFileEntryChildItems.Add(partitionFileEntryItem);
                    }
                }
            }
            catch (Exception ex)
            {
                OnLoadingException(ex, parentItem);

                var message = LocalizationManager.Instance.Current.Keys.LoadingError_FailedToLoadPartitionFileSystemContent.SafeFormat(ex.Message);
                parentItem.Errors.Add(TREE_LOADING_CATEGORY, message);
                _logger.LogError(ex, message);
            }
        }