From ce4c5d98705ad3a8a4582f0d2eac6caa7ce63be6 Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Wed, 8 Apr 2020 04:17:45 +0300 Subject: [PATCH] Bugfix for dumb issue with key_area_key_[all] to support Lockpick dump: hex representation instead of dec %) --- src/main/java/konogonka/AppPreferences.java | 24 ++-- .../Controllers/NCA/NCAController.java | 114 +++++++++--------- .../Settings/ListSelectorController.java | 4 +- .../Settings/SettingsController.java | 24 ++-- .../java/konogonka/Tools/NCA/NCAProvider.java | 10 +- .../FXML/Settings/SettingsLayout.fxml | 36 +++--- 6 files changed, 104 insertions(+), 108 deletions(-) diff --git a/src/main/java/konogonka/AppPreferences.java b/src/main/java/konogonka/AppPreferences.java index 3e97e52..4620e83 100644 --- a/src/main/java/konogonka/AppPreferences.java +++ b/src/main/java/konogonka/AppPreferences.java @@ -77,7 +77,7 @@ public class AppPreferences { public void setKAKAppCount(int number){ if (this.kakAppCount > number){ for (int i = number; i < this.kakAppCount; i++) { - preferences.remove(String.format("key_area_key_application_%02d", number)); + preferences.remove(String.format("key_area_key_application_%02x", number)); } } preferences.putInt("key_area_key_application_count", number); @@ -86,7 +86,7 @@ public class AppPreferences { public void setKAKOceanCount(int number){ if (this.kakOceanCount > number){ for (int i = number; i < this.kakOceanCount; i++) { - preferences.remove(String.format("key_area_key_ocean_%02d", number)); + preferences.remove(String.format("key_area_key_ocean_%02x", number)); } } preferences.putInt("key_area_key_ocean_count", number); @@ -95,7 +95,7 @@ public class AppPreferences { public void setKAKSysCount(int number){ if (this.kakSysCount > number){ for (int i = number; i < this.kakSysCount; i++) { - preferences.remove(String.format("key_area_key_system_%02d", number)); + preferences.remove(String.format("key_area_key_system_%02x", number)); } } preferences.putInt("key_area_key_system_count", number); @@ -105,7 +105,7 @@ public class AppPreferences { public void setTitleKeksCount(int number){ if (this.titleKeksCount > number){ for (int i = number; i < this.titleKeksCount; i++) { - preferences.remove(String.format("titlekek_%02d", number)); + preferences.remove(String.format("titlekek_%02x", number)); } } preferences.putInt("titlekek_count", number); @@ -117,17 +117,17 @@ public class AppPreferences { public int getKAKSysCount(){ return preferences.getInt("key_area_key_system_count", 0); } public int getTitleKeksCount(){ return preferences.getInt("titlekek_count", 0); } - public String getApplicationKey(int number){ return preferences.get(String.format("key_area_key_application_%02d", number), "");} - public void setApplicationKey(int number, String key){ preferences.put(String.format("key_area_key_application_%02d", number), key); } + public String getApplicationKey(int number){ return preferences.get(String.format("key_area_key_application_%02x", number), "");} + public void setApplicationKey(int number, String key){ preferences.put(String.format("key_area_key_application_%02x", number), key); } - public String getOceanKey(int number){ return preferences.get(String.format("key_area_key_ocean_%02d", number), "");} - public void setOceanKey(int number, String key){ preferences.put(String.format("key_area_key_ocean_%02d", number), key); } + public String getOceanKey(int number){ return preferences.get(String.format("key_area_key_ocean_%02x", number), "");} + public void setOceanKey(int number, String key){ preferences.put(String.format("key_area_key_ocean_%02x", number), key); } - public String getSystemKey(int number){ return preferences.get(String.format("key_area_key_system_%02d", number), "");} - public void setSystemKey(int number, String key){ preferences.put(String.format("key_area_key_system_%02d", number), key); } + public String getSystemKey(int number){ return preferences.get(String.format("key_area_key_system_%02x", number), "");} + public void setSystemKey(int number, String key){ preferences.put(String.format("key_area_key_system_%02x", number), key); } - public String getTitleKek(int number){ return preferences.get(String.format("titlekek_%02d", number), "");} - public void setTitleKek(int number, String key){ preferences.put(String.format("titlekek_%02d", number), key); } + public String getTitleKek(int number){ return preferences.get(String.format("titlekek_%02x", number), "");} + public void setTitleKek(int number, String key){ preferences.put(String.format("titlekek_%02x", number), key); } // Title keys diff --git a/src/main/java/konogonka/Controllers/NCA/NCAController.java b/src/main/java/konogonka/Controllers/NCA/NCAController.java index ba9967d..395abef 100644 --- a/src/main/java/konogonka/Controllers/NCA/NCAController.java +++ b/src/main/java/konogonka/Controllers/NCA/NCAController.java @@ -101,13 +101,13 @@ public class NCAController implements ITabController { keysMap.put("header_key", AppPreferences.getInstance().getHeaderKey()); for (int i = 0; i < AppPreferences.getInstance().getKAKAppCount(); i++) - keysMap.put(String.format("key_area_key_application_%02d", i), AppPreferences.getInstance().getApplicationKey(i)); + keysMap.put(String.format("key_area_key_application_%02x", i), AppPreferences.getInstance().getApplicationKey(i)); for (int i = 0; i < AppPreferences.getInstance().getKAKOceanCount(); i++) - keysMap.put(String.format("key_area_key_ocean_%02d", i), AppPreferences.getInstance().getOceanKey(i)); + keysMap.put(String.format("key_area_key_ocean_%02x", i), AppPreferences.getInstance().getOceanKey(i)); for (int i = 0; i < AppPreferences.getInstance().getKAKSysCount(); i++) - keysMap.put(String.format("key_area_key_system_%02d", i), AppPreferences.getInstance().getSystemKey(i)); + keysMap.put(String.format("key_area_key_system_%02x", i), AppPreferences.getInstance().getSystemKey(i)); for (int i = 0; i < AppPreferences.getInstance().getTitleKeksCount(); i++) - keysMap.put(String.format("titlekek_%02d", i), AppPreferences.getInstance().getTitleKek(i)); + keysMap.put(String.format("titlekek_%02x", i), AppPreferences.getInstance().getTitleKek(i)); for (int i = 0; i < AppPreferences.getInstance().getTitleKeysCount(); i++){ String[] pair = AppPreferences.getInstance().getTitleKeyPair(i); if ( ! pair[0].equals("0") && ! pair[1].equals("0")) @@ -180,59 +180,59 @@ public class NCAController implements ITabController { } private void populateFields(NCAProvider ncaProvider){ - if (ncaProvider != null){ - rsa2048oneTF.setText(byteArrToHexString(ncaProvider.getRsa2048one())); - rsa2048twoTF.setText(byteArrToHexString(ncaProvider.getRsa2048two())); - magicnumLbl.setText(ncaProvider.getMagicnum()); - systemOrGcIndLbl.setText(Byte.toString(ncaProvider.getSystemOrGcIndicator())); - contentTypeLbl.setText(Byte.toString(ncaProvider.getContentType())); - cryptoType1Lbl.setText(Byte.toString(ncaProvider.getCryptoType1())); - keyIndexLbl.setText(Byte.toString(ncaProvider.getKeyIndex())); - ncaSizeLbl.setText(Long.toString(ncaProvider.getNcaSize())); - titleIdLbl.setText(byteArrToHexString(ncaProvider.getTitleId())); - contentIndexLbl.setText(byteArrToHexString(ncaProvider.getContentIndx())); // - sdkVersionLbl.setText(ncaProvider.getSdkVersion()[3] - +"."+ncaProvider.getSdkVersion()[2] - +"."+ncaProvider.getSdkVersion()[1] - +"."+ncaProvider.getSdkVersion()[0]); - cryptoType2Lbl.setText(Byte.toString(ncaProvider.getCryptoType2())); - header1SignatureKeyGenerationLbl.setText(Byte.toString(ncaProvider.getHeader1SignatureKeyGeneration())); - keyGenerationReservedLbl.setText(byteArrToHexString(ncaProvider.getKeyGenerationReserved())); - ticketLbl.setText(byteArrToHexString(ncaProvider.getRightsId())); - sha256section1TF.setText(byteArrToHexString(ncaProvider.getSha256hash0())); - sha256section2TF.setText(byteArrToHexString(ncaProvider.getSha256hash1())); - sha256section3TF.setText(byteArrToHexString(ncaProvider.getSha256hash2())); - sha256section4TF.setText(byteArrToHexString(ncaProvider.getSha256hash3())); - keyAreaEnKey0TF.setText(byteArrToHexString(ncaProvider.getEncryptedKey0())); - keyAreaEnKey1TF.setText(byteArrToHexString(ncaProvider.getEncryptedKey1())); - keyAreaEnKey2TF.setText(byteArrToHexString(ncaProvider.getEncryptedKey2())); - keyAreaEnKey3TF.setText(byteArrToHexString(ncaProvider.getEncryptedKey3())); + if (ncaProvider == null) + return; + rsa2048oneTF.setText(byteArrToHexString(ncaProvider.getRsa2048one())); + rsa2048twoTF.setText(byteArrToHexString(ncaProvider.getRsa2048two())); + magicnumLbl.setText(ncaProvider.getMagicnum()); + systemOrGcIndLbl.setText(Byte.toString(ncaProvider.getSystemOrGcIndicator())); + contentTypeLbl.setText(Byte.toString(ncaProvider.getContentType())); + cryptoType1Lbl.setText(Byte.toString(ncaProvider.getCryptoType1())); + keyIndexLbl.setText(Byte.toString(ncaProvider.getKeyIndex())); + ncaSizeLbl.setText(Long.toString(ncaProvider.getNcaSize())); + titleIdLbl.setText(byteArrToHexString(ncaProvider.getTitleId())); + contentIndexLbl.setText(byteArrToHexString(ncaProvider.getContentIndx())); // + sdkVersionLbl.setText(ncaProvider.getSdkVersion()[3] + +"."+ncaProvider.getSdkVersion()[2] + +"."+ncaProvider.getSdkVersion()[1] + +"."+ncaProvider.getSdkVersion()[0]); + cryptoType2Lbl.setText(Byte.toString(ncaProvider.getCryptoType2())); + header1SignatureKeyGenerationLbl.setText(Byte.toString(ncaProvider.getHeader1SignatureKeyGeneration())); + keyGenerationReservedLbl.setText(byteArrToHexString(ncaProvider.getKeyGenerationReserved())); + ticketLbl.setText(byteArrToHexString(ncaProvider.getRightsId())); + sha256section1TF.setText(byteArrToHexString(ncaProvider.getSha256hash0())); + sha256section2TF.setText(byteArrToHexString(ncaProvider.getSha256hash1())); + sha256section3TF.setText(byteArrToHexString(ncaProvider.getSha256hash2())); + sha256section4TF.setText(byteArrToHexString(ncaProvider.getSha256hash3())); + keyAreaEnKey0TF.setText(byteArrToHexString(ncaProvider.getEncryptedKey0())); + keyAreaEnKey1TF.setText(byteArrToHexString(ncaProvider.getEncryptedKey1())); + keyAreaEnKey2TF.setText(byteArrToHexString(ncaProvider.getEncryptedKey2())); + keyAreaEnKey3TF.setText(byteArrToHexString(ncaProvider.getEncryptedKey3())); - keyAreaDecKey0TF.setText(byteArrToHexString(ncaProvider.getDecryptedKey0())); - keyAreaDecKey1TF.setText(byteArrToHexString(ncaProvider.getDecryptedKey1())); - keyAreaDecKey2TF.setText(byteArrToHexString(ncaProvider.getDecryptedKey2())); - keyAreaDecKey3TF.setText(byteArrToHexString(ncaProvider.getDecryptedKey3())); - // Tables - NCATable1Controller.populateTab(ncaProvider.getTableEntry0()); - NCATable2Controller.populateTab(ncaProvider.getTableEntry1()); - NCATable3Controller.populateTab(ncaProvider.getTableEntry2()); - NCATable4Controller.populateTab(ncaProvider.getTableEntry3()); - // Table blocks - NCASectionHeaderFirstController.populateTab(ncaProvider.getSectionBlock0()); - NCASectionHeaderSecondController.populateTab(ncaProvider.getSectionBlock1()); - NCASectionHeaderThirdController.populateTab(ncaProvider.getSectionBlock2()); - NCASectionHeaderFourthController.populateTab(ncaProvider.getSectionBlock3()); - // Section content blocks - // TODO: FIX: This code executes getNCAContentPFS0() method twice - NCAContentPFS0 ncaContentPFS0; - ncaContentPFS0 = ncaProvider.getNCAContentPFS0(0); - NCASectionContentFirstController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes()); - ncaContentPFS0 = ncaProvider.getNCAContentPFS0(1); - NCASectionContentSecondController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes()); - ncaContentPFS0 = ncaProvider.getNCAContentPFS0(2); - NCASectionContentThirdController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes()); - ncaContentPFS0 = ncaProvider.getNCAContentPFS0(3); - NCASectionContentFourthController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes()); - } + keyAreaDecKey0TF.setText(byteArrToHexString(ncaProvider.getDecryptedKey0())); + keyAreaDecKey1TF.setText(byteArrToHexString(ncaProvider.getDecryptedKey1())); + keyAreaDecKey2TF.setText(byteArrToHexString(ncaProvider.getDecryptedKey2())); + keyAreaDecKey3TF.setText(byteArrToHexString(ncaProvider.getDecryptedKey3())); + // Tables + NCATable1Controller.populateTab(ncaProvider.getTableEntry0()); + NCATable2Controller.populateTab(ncaProvider.getTableEntry1()); + NCATable3Controller.populateTab(ncaProvider.getTableEntry2()); + NCATable4Controller.populateTab(ncaProvider.getTableEntry3()); + // Table blocks + NCASectionHeaderFirstController.populateTab(ncaProvider.getSectionBlock0()); + NCASectionHeaderSecondController.populateTab(ncaProvider.getSectionBlock1()); + NCASectionHeaderThirdController.populateTab(ncaProvider.getSectionBlock2()); + NCASectionHeaderFourthController.populateTab(ncaProvider.getSectionBlock3()); + // Section content blocks + // TODO: FIX: This code executes getNCAContentPFS0() method twice + NCAContentPFS0 ncaContentPFS0; + ncaContentPFS0 = ncaProvider.getNCAContentPFS0(0); + NCASectionContentFirstController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes()); + ncaContentPFS0 = ncaProvider.getNCAContentPFS0(1); + NCASectionContentSecondController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes()); + ncaContentPFS0 = ncaProvider.getNCAContentPFS0(2); + NCASectionContentThirdController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes()); + ncaContentPFS0 = ncaProvider.getNCAContentPFS0(3); + NCASectionContentFourthController.populateFields(ncaContentPFS0.getPfs0(), ncaContentPFS0.getSHA256hashes()); } } diff --git a/src/main/java/konogonka/Settings/ListSelectorController.java b/src/main/java/konogonka/Settings/ListSelectorController.java index f555643..a6f036e 100644 --- a/src/main/java/konogonka/Settings/ListSelectorController.java +++ b/src/main/java/konogonka/Settings/ListSelectorController.java @@ -70,7 +70,7 @@ public class ListSelectorController implements Initializable { newRecordName.setText(predictionPattern); newRecordName.setTextFormatter(new TextFormatter(change -> { - if (change.getControlNewText().matches("^"+predictionPattern+"[0-9]{0,2}$")) + if (change.getControlNewText().matches("^"+predictionPattern+"[a-fA-F0-9]{0,2}$")) return change; return null; })); @@ -110,7 +110,7 @@ public class ListSelectorController implements Initializable { newRecordValue.clear(); } else { - if (newRecordName.getText().matches("^"+predictionPattern+"[0-9]{2}$")){ + if (newRecordName.getText().matches("^"+predictionPattern+"[a-fA-F0-9]{2}$")){ validateAndAdd(newRecordName.getText() + " = " + newRecordValue.getText()); newRecordName.setText(predictionPattern); newRecordValue.clear(); diff --git a/src/main/java/konogonka/Settings/SettingsController.java b/src/main/java/konogonka/Settings/SettingsController.java index 6abb22b..fe62db4 100644 --- a/src/main/java/konogonka/Settings/SettingsController.java +++ b/src/main/java/konogonka/Settings/SettingsController.java @@ -78,25 +78,25 @@ public class SettingsController implements Initializable { LinkedHashMap preparedPairsMapInit = new LinkedHashMap<>(); for (int i = 0; i < AppPreferences.getInstance().getKAKAppCount(); i++){ - preparedPairsMapInit.put(String.format("key_area_key_application_%02d", i), AppPreferences.getInstance().getApplicationKey(i)); + preparedPairsMapInit.put(String.format("key_area_key_application_%02x", i), AppPreferences.getInstance().getApplicationKey(i)); } ListSelectorKAEKAppController.setList(preparedPairsMapInit); preparedPairsMapInit.clear(); for (int i = 0; i < AppPreferences.getInstance().getKAKOceanCount(); i++){ - preparedPairsMapInit.put(String.format("key_area_key_ocean_%02d", i), AppPreferences.getInstance().getOceanKey(i)); + preparedPairsMapInit.put(String.format("key_area_key_ocean_%02x", i), AppPreferences.getInstance().getOceanKey(i)); } ListSelectorKAEKOceanController.setList(preparedPairsMapInit); preparedPairsMapInit.clear(); for (int i = 0; i < AppPreferences.getInstance().getKAKSysCount(); i++){ - preparedPairsMapInit.put(String.format("key_area_key_system_%02d", i), AppPreferences.getInstance().getSystemKey(i)); + preparedPairsMapInit.put(String.format("key_area_key_system_%02x", i), AppPreferences.getInstance().getSystemKey(i)); } ListSelectorKAEKSysController.setList(preparedPairsMapInit); preparedPairsMapInit.clear(); for (int i = 0; i < AppPreferences.getInstance().getTitleKeksCount(); i++){ - preparedPairsMapInit.put(String.format("titlekek_%02d", i), AppPreferences.getInstance().getTitleKek(i)); + preparedPairsMapInit.put(String.format("titlekek_%02x", i), AppPreferences.getInstance().getTitleKek(i)); } ListSelectorTitleKeksController.setList(preparedPairsMapInit); preparedPairsMapInit.clear(); @@ -143,32 +143,32 @@ public class SettingsController implements Initializable { String keyParsed; int counter = 0; - while ((keyParsed = fileMap.get(String.format("key_area_key_application_%02d", counter))) != null){ - kaekSingle.put(String.format("key_area_key_application_%02d", counter), keyParsed); + while ((keyParsed = fileMap.get(String.format("key_area_key_application_%02x", counter))) != null){ + kaekSingle.put(String.format("key_area_key_application_%02x", counter), keyParsed); counter++; } ListSelectorKAEKAppController.setList(kaekSingle); kaekSingle.clear(); counter = 0; - while ((keyParsed = fileMap.get(String.format("key_area_key_ocean_%02d", counter))) != null){ - kaekSingle.put(String.format("key_area_key_ocean_%02d", counter), keyParsed); + while ((keyParsed = fileMap.get(String.format("key_area_key_ocean_%02x", counter))) != null){ + kaekSingle.put(String.format("key_area_key_ocean_%02x", counter), keyParsed); counter++; } ListSelectorKAEKOceanController.setList(kaekSingle); kaekSingle.clear(); counter = 0; - while ((keyParsed = fileMap.get(String.format("key_area_key_system_%02d", counter))) != null){ - kaekSingle.put(String.format("key_area_key_system_%02d", counter), keyParsed); + while ((keyParsed = fileMap.get(String.format("key_area_key_system_%02x", counter))) != null){ + kaekSingle.put(String.format("key_area_key_system_%02x", counter), keyParsed); counter++; } ListSelectorKAEKSysController.setList(kaekSingle); kaekSingle.clear(); counter = 0; - while ((keyParsed = fileMap.get(String.format("titlekek_%02d", counter))) != null){ - kaekSingle.put(String.format("titlekek_%02d", counter), keyParsed); + while ((keyParsed = fileMap.get(String.format("titlekek_%02x", counter))) != null){ + kaekSingle.put(String.format("titlekek_%02x", counter), keyParsed); counter++; } ListSelectorTitleKeksController.setList(kaekSingle); diff --git a/src/main/java/konogonka/Tools/NCA/NCAProvider.java b/src/main/java/konogonka/Tools/NCA/NCAProvider.java index 1b86f85..52f3526 100644 --- a/src/main/java/konogonka/Tools/NCA/NCAProvider.java +++ b/src/main/java/konogonka/Tools/NCA/NCAProvider.java @@ -194,13 +194,13 @@ public class NCAProvider { String keyAreaKey; switch (keyIndex){ case 0: - keyAreaKey = keys.get(String.format("key_area_key_application_%02d", cryptoTypeReal)); + keyAreaKey = keys.get(String.format("key_area_key_application_%02x", cryptoTypeReal)); break; case 1: - keyAreaKey = keys.get(String.format("key_area_key_ocean_%02d", cryptoTypeReal)); + keyAreaKey = keys.get(String.format("key_area_key_ocean_%02x", cryptoTypeReal)); break; case 2: - keyAreaKey = keys.get(String.format("key_area_key_system_%02d", cryptoTypeReal)); + keyAreaKey = keys.get(String.format("key_area_key_system_%02x", cryptoTypeReal)); break; default: keyAreaKey = null; @@ -231,7 +231,7 @@ public class NCAProvider { exceptionStringBuilder.append(keyIndex); exceptionStringBuilder.append("[UNKNOWN]_"); } - exceptionStringBuilder.append(String.format("%02d", cryptoTypeReal)); + exceptionStringBuilder.append(String.format("%02x", cryptoTypeReal)); exceptionStringBuilder.append(" requested. Not supported or not found."); throw new Exception(exceptionStringBuilder.toString()); @@ -312,7 +312,7 @@ public class NCAProvider { byte[] rightsIDkey = hexStrToByteArray(keys.get(byteArrToHexString(rightsId))); // throws NullPointerException SecretKeySpec skSpec = new SecretKeySpec( - hexStrToByteArray(keys.get(String.format("titlekek_%02d", cryptoTypeReal)) + hexStrToByteArray(keys.get(String.format("titlekek_%02x", cryptoTypeReal)) ), "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, skSpec); diff --git a/src/main/resources/FXML/Settings/SettingsLayout.fxml b/src/main/resources/FXML/Settings/SettingsLayout.fxml index 7ca1282..3139fe8 100644 --- a/src/main/resources/FXML/Settings/SettingsLayout.fxml +++ b/src/main/resources/FXML/Settings/SettingsLayout.fxml @@ -107,26 +107,6 @@ - - - - - - - - - - - - - @@ -135,6 +115,22 @@ + + + + + + + + +