From 275275f7ac1c365e84e36df4e4382d0ac64292af Mon Sep 17 00:00:00 2001 From: Mary Date: Tue, 11 Jan 2022 09:22:20 +0100 Subject: [PATCH] account: Rework LoadIdTokenCache to auto generate a random JWT token (#2991) This improve correctness of that call while possibly spoofing possible recognizable patterns. --- .../Acc/AccountService/ManagerServer.cs | 60 +++++++++++++++++-- Ryujinx.HLE/Ryujinx.HLE.csproj | 1 + 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs index 471942f1..9c406a08 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs @@ -1,7 +1,11 @@ -using Ryujinx.Common.Logging; -using Ryujinx.Cpu; +using Microsoft.IdentityModel.Tokens; +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext; +using System; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Cryptography; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -19,6 +23,51 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService _userId = userId; } + private static string GenerateIdToken() + { + using RSA provider = RSA.Create(2048); + + RSAParameters parameters = provider.ExportParameters(true); + + RsaSecurityKey secKey = new RsaSecurityKey(parameters); + + SigningCredentials credentials = new SigningCredentials(secKey, "RS256"); + + credentials.Key.KeyId = parameters.ToString(); + + var header = new JwtHeader(credentials) + { + { "jku", "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com/1.0.0/certificates" } + }; + + byte[] rawUserId = new byte[0x10]; + RandomNumberGenerator.Fill(rawUserId); + + byte[] deviceId = new byte[0x10]; + RandomNumberGenerator.Fill(deviceId); + + byte[] deviceAccountId = new byte[0x10]; + RandomNumberGenerator.Fill(deviceId); + + var payload = new JwtPayload + { + { "sub", BitConverter.ToString(rawUserId).Replace("-", "").ToLower() }, + { "aud", "ed9e2f05d286f7b8" }, + { "di", BitConverter.ToString(deviceId).Replace("-", "").ToLower() }, + { "sn", "XAW10000000000" }, + { "bs:did", BitConverter.ToString(deviceAccountId).Replace("-", "").ToLower() }, + { "iss", "https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com" }, + { "typ", "id_token" }, + { "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds() }, + { "jti", Guid.NewGuid().ToString() }, + { "exp", (DateTimeOffset.UtcNow + TimeSpan.FromHours(3)).ToUnixTimeSeconds() } + }; + + JwtSecurityToken securityToken = new JwtSecurityToken(header, payload); + + return new JwtSecurityTokenHandler().WriteToken(securityToken); + } + public ResultCode CheckAvailability(ServiceCtx context) { // NOTE: This opens the file at "su/baas/USERID_IN_UUID_STRING.dat" where USERID_IN_UUID_STRING is formatted as "%08x-%04x-%04x-%02x%02x-%08x%04x". @@ -92,11 +141,10 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService } */ - int idTokenCacheSize = 0; + byte[] tokenData = Encoding.ASCII.GetBytes(GenerateIdToken()); - MemoryHelper.FillWithZeros(context.Memory, bufferPosition, (int)bufferSize); - - context.ResponseData.Write(idTokenCacheSize); + context.Memory.Write(bufferPosition, tokenData); + context.ResponseData.Write(tokenData.Length); return ResultCode.Success; } diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj index a30bc36e..1b011d42 100644 --- a/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -23,6 +23,7 @@ +