logo upd; TitleKEKs added
This commit is contained in:
parent
f7777012b9
commit
a6b46660d8
6 changed files with 80 additions and 50 deletions
|
@ -50,6 +50,9 @@ public class AppPreferences {
|
|||
public String getSystemKey(int number){ return preferences.get("key_area_key_system_0"+number, "");}
|
||||
public void setSystemKey(int number, String key){ preferences.put("key_area_key_system_0"+number, key); }
|
||||
|
||||
public String getTitleKek(int number){ return preferences.get("titlekek_"+number, "");}
|
||||
public void setTitleKek(int number, String key){ preferences.put("titlekek_"+number, key); }
|
||||
|
||||
|
||||
|
||||
public int getTitleKeysCount(){ // TODO: do the same for other multi-keys and single
|
||||
|
|
|
@ -76,11 +76,11 @@ public class NCAController implements TabController {
|
|||
this.selectedFile = file;
|
||||
HashMap<String, String> keysMap = new HashMap<>();
|
||||
keysMap.put("header_key", AppPreferences.getInstance().getHeaderKey());
|
||||
for (int i = 0; i < 8; i++){
|
||||
for (int i = 0; i < 8; i++){ // TODO: FIX!!!!!!!!! URGENT!
|
||||
keysMap.put("key_area_key_application_0"+i, AppPreferences.getInstance().getApplicationKey(i));
|
||||
keysMap.put("key_area_key_ocean_0"+i, AppPreferences.getInstance().getOceanKey(i));
|
||||
keysMap.put("key_area_key_system_0"+i, AppPreferences.getInstance().getSystemKey(i));
|
||||
// TODO: Add titlekeys
|
||||
keysMap.put("titlekek_0"+i, AppPreferences.getInstance().getTitleKek(i));
|
||||
}
|
||||
for (int i = 0; i < AppPreferences.getInstance().getTitleKeysCount(); i++){
|
||||
String[] pair = AppPreferences.getInstance().getTitleKeyPair(i);
|
||||
|
|
|
@ -25,6 +25,7 @@ public class SettingsController implements Initializable {
|
|||
ListSelectorKAEKAppController,
|
||||
ListSelectorKAEKOceanController,
|
||||
ListSelectorKAEKSysController,
|
||||
ListSelectorTitleKeksController,
|
||||
ListSelectorTitleKeysController;
|
||||
|
||||
@FXML
|
||||
|
@ -37,6 +38,7 @@ public class SettingsController implements Initializable {
|
|||
ListSelectorKAEKAppController.initSelector(32, "key_area_key_application_");
|
||||
ListSelectorKAEKOceanController.initSelector(32, "key_area_key_ocean_");
|
||||
ListSelectorKAEKSysController.initSelector(32, "key_area_key_system_");
|
||||
ListSelectorTitleKeksController.initSelector(32, "titlekek_");
|
||||
ListSelectorTitleKeysController.initSelector(32, null); // 32 required
|
||||
|
||||
LinkedHashMap<String, String> preparedPairsMapInit = new LinkedHashMap<>();
|
||||
|
@ -57,6 +59,14 @@ public class SettingsController implements Initializable {
|
|||
}
|
||||
ListSelectorKAEKOceanController.setList(preparedPairsMapInit);
|
||||
|
||||
preparedPairsMapInit.clear();
|
||||
cnt = 0;
|
||||
while (!(kaekApp = AppPreferences.getInstance().getTitleKek(cnt)).isEmpty()){
|
||||
preparedPairsMapInit.put("titlekek_"+String.format("%02d", cnt), kaekApp);
|
||||
cnt++;
|
||||
}
|
||||
ListSelectorTitleKeksController.setList(preparedPairsMapInit);
|
||||
|
||||
preparedPairsMapInit.clear();
|
||||
cnt = 0;
|
||||
while (!(kaekApp = AppPreferences.getInstance().getSystemKey(cnt)).isEmpty()){
|
||||
|
@ -129,6 +139,14 @@ public class SettingsController implements Initializable {
|
|||
counter++;
|
||||
}
|
||||
ListSelectorKAEKSysController.setList(kaekSingle);
|
||||
|
||||
kaekSingle.clear();
|
||||
counter = 0;
|
||||
while ((keyParsed = fileMap.get("titlekek_"+String.format("%02d", counter))) != null){
|
||||
kaekSingle.put("titlekek_"+String.format("%02d", counter), keyParsed);
|
||||
counter++;
|
||||
}
|
||||
ListSelectorTitleKeksController.setList(kaekSingle);
|
||||
}
|
||||
catch (IOException ioe){
|
||||
ioe.printStackTrace();
|
||||
|
@ -198,6 +216,12 @@ public class SettingsController implements Initializable {
|
|||
AppPreferences.getInstance().setSystemKey(i, kaekSysKeySet[i].split("\\s=\\s", 2)[1]);
|
||||
}
|
||||
|
||||
String[] titleKekSet = ListSelectorTitleKeksController.getList();
|
||||
if (titleKekSet != null){
|
||||
for (int i = 0; i < titleKekSet.length; i++)
|
||||
AppPreferences.getInstance().setTitleKek(i, titleKekSet[i].split("\\s=\\s", 2)[1]);
|
||||
}
|
||||
|
||||
String[] titleKeysSet = ListSelectorTitleKeysController.getList();
|
||||
if (titleKeysSet != null){
|
||||
AppPreferences.getInstance().setTitleKeysCount(titleKeysSet.length);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package konogonka.Tools.NCA;
|
||||
|
||||
import konogonka.LoperConverter;
|
||||
import konogonka.Tools.NCA.NCASectionTableBlock.NCASectionBlock;
|
||||
import konogonka.xtsaes.XTSAESCipher;
|
||||
import org.bouncycastle.crypto.params.KeyParameter;
|
||||
|
@ -11,6 +12,7 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static konogonka.LoperConverter.byteArrToHexString;
|
||||
import static konogonka.LoperConverter.getLElong;
|
||||
|
||||
// TODO: check file size
|
||||
|
@ -32,6 +34,8 @@ public class NCAProvider {
|
|||
private byte cryptoType2; // keyblob index. Considering as number within application/ocean/system
|
||||
private byte[] rightsId;
|
||||
|
||||
private byte cryptoTypeReal;
|
||||
|
||||
private byte[] sha256hash0;
|
||||
private byte[] sha256hash1;
|
||||
private byte[] sha256hash2;
|
||||
|
@ -152,32 +156,28 @@ public class NCAProvider {
|
|||
encryptedKey2 = Arrays.copyOfRange(encryptedKeysArea, 0x20, 0x30);
|
||||
encryptedKey3 = Arrays.copyOfRange(encryptedKeysArea, 0x30, 0x40);
|
||||
|
||||
//todo: if nca3 proceed
|
||||
// If no rights ID (ticket?) exists
|
||||
if (Arrays.equals(rightsId, new byte[0x10])) {
|
||||
byte realCryptoType;
|
||||
// Calculate real Crypto Type
|
||||
if (cryptoType1 < cryptoType2)
|
||||
realCryptoType = cryptoType2;
|
||||
cryptoTypeReal = cryptoType2;
|
||||
else
|
||||
realCryptoType = cryptoType1;
|
||||
|
||||
if (realCryptoType > 0) // TODO: CLARIFY WHY THEH FUCK IS IT FAIR????
|
||||
realCryptoType -= 1;
|
||||
cryptoTypeReal = cryptoType1;
|
||||
|
||||
if (cryptoTypeReal > 0) // TODO: CLARIFY WHY THEH FUCK IS IT FAIR????
|
||||
cryptoTypeReal -= 1;
|
||||
|
||||
//todo: if nca3 proceed
|
||||
// Decrypt keys if encrypted
|
||||
if (Arrays.equals(rightsId, new byte[0x10])) {
|
||||
String keyAreaKey;
|
||||
switch (keyIndex){
|
||||
case 0:
|
||||
keyAreaKey = keys.get("key_area_key_application_0"+realCryptoType);
|
||||
System.out.println("Using key_area_key_application_0"+realCryptoType);
|
||||
keyAreaKey = keys.get("key_area_key_application_"+String.format("%02d", cryptoTypeReal));
|
||||
break;
|
||||
case 1:
|
||||
keyAreaKey = keys.get("key_area_key_ocean_0"+realCryptoType);
|
||||
System.out.println("Using key_area_key_ocean_0"+realCryptoType);
|
||||
keyAreaKey = keys.get("key_area_key_ocean_"+String.format("%02d", cryptoTypeReal));
|
||||
break;
|
||||
case 2:
|
||||
keyAreaKey = keys.get("key_area_key_system_0"+realCryptoType);
|
||||
System.out.println("Using key_area_key_system_0"+realCryptoType);
|
||||
keyAreaKey = keys.get("key_area_key_system_"+String.format("%02d", cryptoTypeReal));
|
||||
break;
|
||||
default:
|
||||
keyAreaKey = null;
|
||||
|
@ -193,11 +193,6 @@ public class NCAProvider {
|
|||
decryptedKey3 = cipher.doFinal(encryptedKey3);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// TODO
|
||||
|
||||
}
|
||||
|
||||
tableEntry0 = new NCAHeaderTableEntry(tableBytes);
|
||||
tableEntry1 = new NCAHeaderTableEntry(Arrays.copyOfRange(tableBytes, 0x10, 0x20));
|
||||
|
@ -253,33 +248,39 @@ public class NCAProvider {
|
|||
* @param sectionNumber should be 1-4
|
||||
* */
|
||||
public NCAContentPFS0 getNCAContentPFS0(int sectionNumber){
|
||||
// TODO: provide titleKey if needed
|
||||
byte[] key;
|
||||
|
||||
// If empty Rights ID
|
||||
if (Arrays.equals(rightsId, new byte[0x10])) {
|
||||
key = decryptedKey2; // TODO: Just remember this dumb hach
|
||||
}
|
||||
else {
|
||||
byte[] rightsIDkey = hexStrToByteArray(keys.get(byteArrToHexString(rightsId)));
|
||||
|
||||
try {
|
||||
SecretKeySpec skSpec = new SecretKeySpec(
|
||||
hexStrToByteArray(keys.get("titlekek_"+String.format("%02d", cryptoTypeReal))
|
||||
), "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, skSpec);
|
||||
key = cipher.doFinal(rightsIDkey);
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
switch (sectionNumber) {
|
||||
case 0:
|
||||
return new NCAContentPFS0(file, offset, sectionBlock0, tableEntry0, decryptedKey2); // TODO: remove decryptedKey2
|
||||
return new NCAContentPFS0(file, offset, sectionBlock0, tableEntry0, key); // TODO: remove decryptedKey2
|
||||
case 1:
|
||||
return new NCAContentPFS0(file, offset, sectionBlock1, tableEntry1, decryptedKey2);
|
||||
return new NCAContentPFS0(file, offset, sectionBlock1, tableEntry1, key);
|
||||
case 2:
|
||||
return new NCAContentPFS0(file, offset, sectionBlock2, tableEntry2, decryptedKey2);
|
||||
return new NCAContentPFS0(file, offset, sectionBlock2, tableEntry2, key);
|
||||
case 3:
|
||||
return new NCAContentPFS0(file, offset, sectionBlock3, tableEntry3, decryptedKey2);
|
||||
return new NCAContentPFS0(file, offset, sectionBlock3, tableEntry3, key);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 0 OR 2 crypto type
|
||||
// 0,1,2 kaek index
|
||||
//settings.keyset.key_area_keys[ctx->crypto_type][ctx->header.kaek_ind]
|
||||
/*
|
||||
0x207 =
|
||||
0: key_area_key_application_ 0x206 range:[0-6]; usually used 0 or 2
|
||||
1: key_area_key_ocean [0-6]
|
||||
2: key_area_key_system [0-6]
|
||||
|
||||
if(ncahdr_x206 < ncahdr_x220){ret = ncahdr_x220; } else { ret = ncahdr_x206; } return ret;
|
||||
|
||||
ret > 0? ret--
|
||||
|
||||
*/
|
|
@ -48,15 +48,18 @@
|
|||
<Label disable="true" text="Length should be 64 symbols" wrapText="true" />
|
||||
<Pane VBox.vgrow="ALWAYS" />
|
||||
<Separator prefWidth="200.0" />
|
||||
<Label text="Label" />
|
||||
<Label text="Key area key "Application"" />
|
||||
<fx:include fx:id="ListSelectorKAEKApp" source="ListSelectorLayout.fxml" VBox.vgrow="ALWAYS" />
|
||||
<Separator prefWidth="200.0" />
|
||||
<Label text="Label" />
|
||||
<Label text="Key area key "Ocean"" />
|
||||
<fx:include fx:id="ListSelectorKAEKOcean" source="ListSelectorLayout.fxml" VBox.vgrow="ALWAYS" />
|
||||
<Separator prefWidth="200.0" />
|
||||
<Label text="Label" />
|
||||
<Label text="Key area key "System"" />
|
||||
<fx:include fx:id="ListSelectorKAEKSys" source="ListSelectorLayout.fxml" VBox.vgrow="ALWAYS" />
|
||||
<Separator prefWidth="200.0" />
|
||||
<Label text="Title KEKs" />
|
||||
<fx:include fx:id="ListSelectorTitleKeks" source="ListSelectorLayout.fxml" VBox.vgrow="ALWAYS" />
|
||||
<Separator prefWidth="200.0" />
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
|
@ -108,7 +111,6 @@
|
|||
</TabPane>
|
||||
<ButtonBar>
|
||||
<buttons>
|
||||
|
||||
<Button fx:id="okBtn" mnemonicParsing="false" text="Ok" />
|
||||
<Button fx:id="cancelBtn" mnemonicParsing="false" text="Cancel" />
|
||||
</buttons>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 24 KiB |
Loading…
Reference in a new issue