NintendoClients
NintendoClients copied to clipboard
Add support for system version 15.0.0
AAuth was updated.
For digital titles, the cert_key
parameter was removed and it is no longer necessary to dump the application certificate. Instead, the Switch requests a contents authorization token from the dragons server.
I implemented 15.0.0 and 15.0.1 support locally. Things to do:
- Update the example scripts. Test them.
- Update the documentation.
Let me know when you push these changes
@TheGreatRambler I pushed my changes. It's become a bit more complicated because of the dragons thing (6 requests are required instead of 4 now).
Thank you for your awesome reverse engineering work, I'll take a look
Quick question about getting elicenses, what is the device id or did
needed to obtain them? In this header NintendoSDK Firmware/%s (platform:NX; did:%016x; eid:lp1)
.
Figured it out. For anyone else its
# Obtain device ID from prodinfo
device_id = None
with open("ConsoleData/PRODINFO.dec", mode="rb") as file:
data = file.read()
device_id = int(data[0x546:0x556].decode("ascii"), 16)
I'm still unsure about NA_ID
however
ERROR:nintendo.dragons:Dragons server returned an error: {'type': 'https://problems.dragons.nintendo.net/errors/v1/400/invalid_parameter', 'title': 'Parameter is invalid', 'detail': '', 'number': 400}
with account_id
.
Huh weird, I hope you're not banned. On my system, the na_id
is indeed the same as the account_id
of the elicense. Maybe check if you got it right with a man-in-the-middle on your Switch?
I can't actually MITM this one since the physical switch is with someone else, oh no
Which elicense_id
should I use since there are many? I've been doing the first
None of them work anyway.
Did you check the rights id? This should be the same as the title id.
There are some exceptions, but in general, I have only one elicense for a given rights id.
I just tested it again, with Tetris 99. Works fine here.
Interesting, it does not.
Aha, apparently Super Mario Maker 2 is not on this switch (anymore?) I think I'll figure this out now
Okay I've confirmed Super Mario Maker 2 is on the switch, the only games that have elicenses however are Smash Ultimate DLCs and Among Us. Do elicenses not get automatically generated for every game you go online in?
When downloaded Tetris99 does not show up as an elicense either.
I think I got the elicense right after I downloaded the game. I have no idea why it doesn't work for you :confused:
I would really recommend doing a mitm if there is any way that you can get your hands on the Switch. That is the safest way to figure out what your Switch is doing, and what's different.
I can't do it myself but I'll help the owner do that
Do you have some example code of using publish_device_linked_elicenses
btw?
I've isolated it down to the header AccountAuthorization in /v1/rights/publish_elicenses. Getting a token with dauth.ACCOUNT returns invalid token however. The request returns no elicenses currently. [image: image.png]
On Sat, Nov 19, 2022 at 2:18 PM Yannik Marchand @.***> wrote:
I would really recommend doing a mitm if there is any way that you can get your hands on the Switch. That is the safest way to figure out what your Switch is doing, and what's different.
— Reply to this email directly, view it on GitHub https://github.com/kinnay/NintendoClients/issues/90#issuecomment-1320961424, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHTNY2GUX3BP7ODWHWGDUATWJEYYLANCNFSM6AAAAAARDGSXCM . You are receiving this because you were mentioned.Message ID: @.***>
Yeah the AccountAuthorization
header is not a dauth token. It is an id token from https://accounts.nintendo.com.
I can't see your image btw.
Do you have some example code of using publish_device_linked_elicenses btw?
Maybe something like this:
from nintendo.dauth import DAuthClient
from nintendo.dragons import DragonsClient
from nintendo import switch
import anyio
async def main():
keys = switch.load_keys("/path/to/prod.keys")
info = switch.ProdInfo(keys, "/path/to/PRODINFO")
cert = info.get_tls_cert()
pkey = info.get_tls_key()
dauth = DAuthClient(keys)
dauth.set_certificate(cert, pkey)
response = await dauth.device_token(dauth.DRAGONS)
device_token = response["device_auth_token"]
dragons = DragonsClient(info.get_device_id())
dragons.set_certificate(cert, pkey)
print(await dragons.publish_device_linked_elicenses(device_token))
anyio.run(main)
It looked exactly like that (I've since removed it from my codebase but it did follow that structure), but I learned why my elicense doesn't show. Mine is marked as temporary and not a device elicense, so it can only be seen in publish_elicences which shows more than just device elicenses. publish_elicences also have expiration times you have to respect. The image I shared is here, it's just the headers captured during this session https://imgur.com/a/hp6ZkWU. How can I obtain that id token btw?
On Thu, Dec 1, 2022 at 4:27 PM Yannik Marchand @.***> wrote:
Yeah the AccountAuthorization header is not a dauth token. It is an id token from https://accounts.nintendo.com.
I can't see your image btw.
Do you have some example code of using publish_device_linked_elicenses btw?
Maybe something like this:
from nintendo.dauth import DAuthClientfrom nintendo.dragons import DragonsClientfrom nintendo import switchimport anyio async def main(): keys = switch.load_keys("/path/to/prod.keys")
info = switch.ProdInfo(keys, "/path/to/PRODINFO") cert = info.get_tls_cert() pkey = info.get_tls_key() dauth = DAuthClient(keys) dauth.set_certificate(cert, pkey) response = await dauth.device_token(dauth.DRAGONS) device_token = response["device_auth_token"] dragons = DragonsClient(info.get_device_id()) dragons.set_certificate(cert, pkey) print(await dragons.publish_device_linked_elicenses(device_token))anyio.run(main)
— Reply to this email directly, view it on GitHub https://github.com/kinnay/NintendoClients/issues/90#issuecomment-1334527762, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHTNY2ELCP5WO3TIJEL6PRDWLEQ5XANCNFSM6AAAAAARDGSXCM . You are receiving this because you were mentioned.Message ID: @.***>