ACT Services

ACT Services

The ACT module handles NNID accounts. This module behaves very similarly to the 🔗 Wii U implementation (nn::act)

ACT User Service “act:u” #

These commands are used generally by most titles, and are also present in act:a.

Command HeaderDescription
0x00010084Initialize
0x00020040GetErrorCode
0x00030000GetLastResponseResult
0x00040000Cancel
0x00050082GetCommonInfo
0x000600C2GetAccountDataBlock/GetAccountInfo
0x00070082GetAsyncResult
0x000800C2GetMiiImage
0x00090180SetNfsPassword
0x000A0000SetIsApplicationUpdateRequired
0x000B0042AcquireEulaList
0x000C0082AcquireTimeZoneList
0x000D0040GenerateUuid
0x000E0080GetUuid
0x000F0140FindSlotNoByUuid
0x00100000Save
0x00110080GetTransferableId
0x00120102AcquireNexServiceToken
0x00130002GetNexServiceToken
0x00140382AcquireIndependentServiceToken
0x00150002GetIndependentServiceToken
0x00160082AcquireAccountInfo
0x00170084AcquireAccountIdByPrincipalId
0x00180044AcquirePrincipalIdByAccountId
0x00190044AcquireMii
0x001A0042AcquireAccountInfoRaw
0x001B0084AcquireOtherTypePrincipalID (stubbed)
0x001C0342GetCachedIndependentServiceToken
0x001D0004InquireMailAddressAvailability
0x001E0082AcquireEula
0x001F0082AcquireEulaLanguageList
0x00200382AcquireIndependentServiceTokenV2
0x00210002GetIndepdendentServiceTokenV2
0x00220342GetCachedIndependentServiceTokenV2

ACT Admin Service “act:a” #

This service is used mainly by the Nintendo Network ID Settings application accessible in System Settings.

Command HeaderDescription
0x04010080SwapAccounts
0x04020000CreateConsoleAccount
0x04030040CommitConsoleAccount
0x04040080UnbindServerAccount
0x04050040DeleteConsoleAccount
0x04060240LoadConsoleAccount
0x04070000UnloadConsoleAccount
0x04080080EnableAccountPasswordCache
0x04090040SetDefaultAccount
0x040A0040ReplaceAccountId
0x040B0040GetSupportContext
0x040C0100SetHostServerSettings
0x040D00C0SetDefaultHostServerSettings
0x040E02C0SetHostServerSettingsStr
0x040F0280SetDefaultHostServerSettingsStr
0x04100040SetPersistentIdHead
0x04110040SetTransferableIdCounter
0x041207C0UpdateMiiData
0x041300C2UpdateMiiImage
0x04140182InquireAccountIdAvailability
0x04150EC4BindToNewServerAccount
0x041602C4BindToExistentServerAccount
0x041702C4InquireBindingToExistentServerAccount
0x04180042DeleteServerAccount
0x04190042AcquireAccountToken (stubbed)
0x041A01C2AcquireAccountTokenEx
0x041B0142AgreeEula
0x041C0042SyncAccountInfo
0x041D0080InvalidateAccountToken
0x041E0182UpdateAccountPassword
0x041F0042ReissueAccountPassword
0x04200180SetAccountPasswordInput
0x04210042UploadMii
0x04220042InactivateDeviceAssociation
0x04230082ValidateMailAddress
0x04240044SendPostingApprovalMail
0x04250042SendConfirmationMail
0x04260044SendConfirmationMailForPin
0x04270084SendMasterKeyMailForPin
0x04280044ApproveByCreditCard
0x04290082SendCoppaCodeMail
0x042A0080SetIsMiiUpdated
0x042B01C4ReserveTransfer
0x042C0042CompleteTransfer
0x042D0042InactivateAccountDeviceAssociation
0x042E0080SetNetworkTime
0x042F0084UpdateAccountInfo
0x04300044UpdateAccountMailAddress
0x04310042DeleteDeviceAssociation
0x04320042DeleteAccountDeviceAssociation
0x04330042CancelTransfer
0x04340003ReloadAndBlockSaveData
0x04350042ReserveServerAccountDeletion

Account slots #

Like the friends sysmodule, the ACT module has support for multiple console accounts. The ACT sysmodule has support for 8 account “slots”, which are 1-indexed numbers (n) referring the to the nth account. This means that up to 8 different console accounts can be used with the ACT sysmodule, unlike the Wii U, which has support for 12. This multi-account functionality is not exposed to users, and the Nintendo Network ID Settings application only ever uses the default account slot.

When the ACT sysmodule is started, it loads the default account slot. The default account can be set using ACTA:SetDefaultAccount.

It is also possible to change the account slot number of an account by using ACTA:SwapAccounts.

Account slot -2 (0xFE) always refers to the currently loaded account.

Console Accounts #

A “console account” refers to a specific account slot, and may or may not be associated with a Nintendo Network ID (server account). By default, there is only one console account.

More console accounts can be created using ACTA:CreateConsoleAccount, loaded using ACTA:LoadConsoleAccount, unloaded using ACTA:UnloadConsoleAccount, or deleted using ACTA:DeleteConsoleAccount.

Server Accounts #

A “server account” is essentially a Nintendo Network ID.

Associating a console account with a Nintendo Network ID (server-side) is facilitated by the commands ACTA:BindToNewServerAccount (to create and link an NNID) or ACTA:BindToExistentServerAccount (to log into an existing linked NNID).

Nintendo Network IDs can be transferred to other consoles using ACTA:ReserveTransfer initially, and then ACTA:CompleteTransfer.

NNIDs can be deleted using either ACTA:DeleteServerAccount, ACTA:InactivateAccountDeviceAssociation, ACTA:DeleteAccountDeviceAssociation or ACTA:ReserveServerAccountDeletion.

Password Management #

The ACT sysmodule uses a distinct password management system.

Password Hashing Algorithm #

Passwords are not stored in plaintext. Instead, they are hashed using the following algorithm:

void hash_password(void *out_hash, void *input, int input_size, unsigned int num_iterations, unsigned int principal_id) {
    static const unsigned char constant[4] = { 0x02, 0x65, 0x43, 0x46 };

    unsigned char hash_data[8 + 32] = { 0 };
    unsigned int bswap_pid = bswap32(principal_id);

    while ( num_iterations-- ) {
        memcpy(&hash_data[0], &bswap_pid, 4);
        memcpy(&hash_data[4], &constant, 4);
        memcpy(&hash_data[8], input, input_size);

        /* output, input, size */
        sha256(out_hash, hash_data, 8 + input_size);
        input_size = 32;
        input = out_hash;
    }
}

Account Password Hash #

The AccountPasswordHash field in the account data is the result of one iteration of the above algorithm, using the plaintext password as the input. It is generally used to verify the input password in ACTA:LoadConsoleAccount.

This field in the account data is set when ACTA:BindToNewServerAccount, ACTA:BindToExistentServerAccount, or ACTA:UpdateAccountPassword is used.

Account Password Cache #

It is possible to cache the password for an account so the user isn’t asked for it every time. This can be configured in Nintendo Network ID settings or during an NNID login prompt (e.g. in the eShop). The AccountPasswordCache field in the account data is the result of two iterations of the above algorithm, using the plaintext password as the input.

Account Password Input #

The account password input represents the in-memory input value of the password. It can be thought of as the value that will be autofilled by default in a login form. When the ACT sysmodule is started and the default account is loaded, the AccountPasswordCache is copied to the AccountPasswordInput, allowing automatic login.

However, it is possible to override this value using ACTA:SetAccountPasswordInput. The AccountPasswordInput value set using this command can then be saved to the account password cache by using ACTA:EnableAccountPasswordCache.

The account password cache can be enabled or disabled through ACTA:EnableAccountPasswordCache.

The AccountPasswordInput is always loaded into memory and is not saved to the system save data.

Server Types #

The ACT sysmodule uses two different server types for Nintendo Network accounts.

See below how these types are determined by default. These types can also be overridden using ACTA:SetHostServerSettings, ACTA:SetDefaultHostServerSettings, ACTA:SetHostServerSettingsStr, and ACTA:SetDefaultHostServerSettingsStr.

The base URL for the Nintendo Network Account Server (NNAS) is: 🔗 https://[]account.nintendo.net.

NNAS (Nintendo Network Authentication Server) Types #

This is used to determine the NNAS subdomain used for the account server.

ValueDescriptionNNAS SubdomainComplete NNAS URL
0Production(None)https://account.nintendo.net
1Game Development (also the default for debug mode on developer units)game-dev.https://game-dev.account.nintendo.net
2System Developmentsystem-dev.https://system-dev.account.nintendo.net
3Library Developmentlibrary-dev.https://library-dev.account.nintendo.net
4Stagingstaging.https://staging.account.nintendo.net

Values beyond 4 are considered invalid.

Default NNAS Server Types #

By default, ACT uses the letter value from FRDU:GetServerTypes to determine the correct NNAS subdomain when a Nintendo Network ID is created.

Value from FRDU:GetServerTypesNNAS Server TypeCorresponding NNAS SubdomainCorresponding complete NNAS URL
0 (L)Production (default on retail units)(None)https://account.nintendo.net
2 (S)Stagingstaging.https://staging.account.nintendo.net
3 (D)Game Development (also the default for debug mode on developer units)game-dev.https://game-dev.account.nintendo.net
5 (T)Library Developmentlibrary-dev.https://library-dev.account.nintendo.net
7 (J)System Developmentsystem-dev.https://system-dev.account.nintendo.net

NFS (Nintendo Friend Server) Types #

ACT uses the same Server Types as the friends sysmodule as the NfsType.

A small subset of these types are used in ACTA:SetHostServerSettings, ACTA:SetDefaultHostServerSettings, ACTA:SetHostServerSettingsStr, and ACTA:SetDefaultHostServerSettingsStr:

Input value used in ACT commandsCorresponding Friends Server Type value
00 (L)
13 (D)
22 (S)
35 (T)
47 (J)

Default NFS Server Types #

By default, ACT uses FRDU:GetServerTypes to obtain the correct NFS (Nintendo Friend Server) environment to create Nintendo Network IDs.

This is necessary to ensure proper online play functionality, because the friends server account is tied to the Nintendo Network ID when one is linked.

UUIDs #

The ACT service generates UUIDs for accounts and for the console in general.

All UUIDs generated by the service are 🔗 RFC9562 Version 1 UUIDs.

Node Data #

In general, the following 48-bit node data is used.

OffsetSizeDescription
0x00x1Always set to 1
0x10x1Always set to 0 (related to parental controls?)
0x20x4Byte-Swapped value from AM:GetDeviceId

UUID Types #

Regular UUIDs #

These are just standard 🔗 RFC9562 Version 1 UUIDs with the above node data.

Title-specific UUIDs #

These UUIDs are specific to the title that requested them to be generated, specifically, using the unique ID portion of the title ID of that title.

The following technique is used internally to generate these UUIDs:

- Generate or use an existing regular UUID the with the above mentioned node data (regular_uuid)

- hash = SHA256 ( byte-swapped unique ID (thus, big endian) + 095E273A + 48-bit node data from regular_uuid )

- output_uuid = regular_uuid[0:9] + hash[10] | 0x1 + hash[11:16]

Independent Service Tokens #

In addition to NEX tokens for gameserver authentication in combination with Nintendo Network, app developers have the ability to use their own independent services. For authenticating with such services through Nintendo Network, the service’s client ID is used to request a token from the account server.

Independent Service Token Versions #

There are two versions of independent service tokens.

V1 Independent Service Token #

These are more basic, consisting of only a base64 token. These can be requested and cached using ACTU:AcquireIndependentServiceToken, retrieved either immediately after requesting them using ACTU:GetIndependentServiceToken or from an internal cache using ACTU:GetCachedIndependentServiceToken.

OffsetSizeDescription
0x00x200 + 1base64 NULL-terminated Token

V2 Independent Service Token #

V2 indpendent service tokens include more fields like an IV, signature, and account server environment compared to V1 tokens.

They can be requested and cached using ACTU:AcquireIndependentServiceTokenV2, retrieved either immediately after requesting them using ACTU:GetIndependentServiceTokenV2 or from an internal cache using ACTU:GetCachedIndependentServiceTokenV2.

OffsetSizeDescription
0x00x200 + 1base64 NULL-terminated Token
0x2010x18 + 1base64 NULL-terminated IV
0x21A0x158 + 1base64 NULL-terminated Signature
0x3730x2 + 1ASCII Server Environment type and number

DataBlocks #

Data blocks can be accessed from specific commands depending on the data that is requested. These follow a similar order to the Wii U 🔗 ACTInfoTypes.

BlkIDSizeCommand neededDescription
0x10x1GetCommonInfoNumber of accounts
0x20x1GetCommonInfoCurrent account slot
0x30x1GetCommonInfoDefault account slot
0x40x8GetCommonInfoNetworkTimeDifference: Difference between server time and UTC device time (in nanoseconds)
0x50x4GetAccountInfoPersistentId
0x60x8GetCommonInfo/GetAccountInfoCommonTransferableIdBase on GetCommonInfo / TransferableIdBase on GetAccountInfo
0x70x60GetAccountInfoMii CFLStoreData
0x80x11GetAccountInfoAccountId (ASCII NULL-terminated Nintendo Network ID)
0x90x101AcquireAccountInfoMail address
0xA0x4GetAccountInfoBirth Date
0xB0x3GetAccountInfoASCII NULL-terminated Country Name
0xC0x4GetAccountInfoPrincipalId
0xE0x1GetAccountInfoIsPasswordCacheEnabled
0xF0x1GetAccountInfoDoes not return anything.
0x110xA0GetAccountInfo
OffsetSizeDescription
0x00x4u32 PersistentID
0x40x4padding
0x80x8u64 TransferableIDBase
0x100x60Mii CFLStoreData
0x70(10 + 1) * 210-character UTF-16 Mii Display Name
0x860x11ASCII NULL-terminated NNID Account ID (username)
0x971padding
0x980x4Birth Date
0x9C0x4u32, PrincipalID
0x120x4GetAccountInfoAccount server types

OffsetSizeDescription
0x00x1NNAS (Nintendo Network Authentication Server) Type
0x10x1NFS (Nintendo Friend Server) Type Value
0x20x1NFS (Nintendo Friend Server) Number
0x30x1padding (0)
0x130x1GetAccountInfoGender
0x140x1GetAccountInfoLastAuthenticationResult
0x150x11GetAccountInfoAssignedAccountId (ASCII NULL-terminated Nintendo Network ID)
0x160x1GetAccountInfoParentalControlSlotNo
0x170x4GetAccountInfoSimpleAddressId (CountryInfo)
0x190x8GetAccountInfoUtcOffset
0x1A0x1GetAccountInfoIsCommitted
0x1B0x16GetAccountInfo10-character UTF-16 Mii Name (10 characters + NULL termination)
0x1C0x11GetAccountInfoASCII NULL-terminated NfsPassword
0x1D0x1GetAccountInfoHasEciVirtualAccount (checks whether EciVirtualAccount has a value)
0x1E0x41GetAccountInfoTimeZoneId (ASCII Time Zone Location)
0x1F0x1GetAccountInfoIsMiiUpdated
0x200x1GetAccountInfoIsMailAddressValidated
0x210x4CGetAccountInfo(Developer units only) Account access token

OffsetSizeDescription
0x00x1Access token state (0: uninitialized, 1: expired, 2: valid)
0x10x21ASCII NULL-terminated access token
0x220x29ASCII NULL-terminated refresh token
0x4B0x1padding
0x220x1GetCommonInfoIsApplicationUpdateRequired
0x230x4GetCommonInfoDefault account server types

OffsetSizeDescription
0x00x1NNAS (Nintendo Network Authentication Server) Type
0x10x1NFS (Nintendo Friend Server) Type Value
0x20x1NFS (Nintendo Friend Server) Number
0x30x1padding (0)
0x240x1GetAccountInfoIsServerAccountDeleted
0x250x101GetAccountInfoMiiImageUrl (ASCII NULL-terminated URL to account mii image)
0x260x4GetAccountInfoAssignedPrincipalId
0x270x4GetAccountInfoAccount Access token state, only accessible with account slot = 0xFE: (0: uninitialized, 1: expired, 2: valid)
0x280x24GetAccountInfoAccount server environment

OffsetSizeDescription
0x00x21ASCII NULL-terminated NNAS subdomain
0x210x3NFS (Nintendo Friend Server) Type
0x290x24GetCommonInfoServer environment of default account

OffsetSizeDescription
0x00x21ASCII NULL-terminated NNAS subdomain
0x210x3NFS (Nintendo Friend Server) Type
0x2A0x8GetCommonInfoDeviceHash: first 8 bytes of SHA256 ( AM:GetDeviceId() as 4 little endian bytes + A2257354 )
0x2B0x1GetAccountInfoFpLocalAccountId (local account ID of friends sysmodule)
0x2C0x2GetAccountInfoAge (calculated using server time, not device time)
0x2D0x1GetAccountInfoIsEnabledReceiveAds
0x2E0x1GetAccountInfoIsOffDeviceAccessEnabled
0x2F0x4GetAccountInfoTranslated SimpleAddressId (CountryInfo)

Types #

Birthdate #

OffsetSizeDescription
0x00x2u16, Year
0x20x1u8, Month
0x30x1u8, Day

CFLStoreData #

This is the Mii format used in ACT commands.

OffsetSizeDescription
0x00x5CMii Data
0x5C0x2padding
0x5E0x2CRC16 over the above 0x5E bytes (see Mii Checksum for details on the algorithm)

Mii Image Types #

ValueDescription
0Primary Mii Image
1Unknown
2Unknown
3Unknown
4Unknown
5Unknown
6Unknown
7Unknown
8Unknown

Timezone #

OffsetSizeDescription
0x00x40 + 1ASCII NULL-terminated TimezoneArea (max. 64 characters + NULL termination)
0x410x3padding
0x440x40 + 1ASCII NULL-terminated TimezoneId (max. 64 characters + NULL termination)
0x850x3padding
0x880x8s64, UtcOffset in seconds

AcquireTimeZoneListData #

OffsetSizeDescription
0x00x4u32, Capacity (32)
0x40x4u32, Count
0x80x90 * CapacityTimezones

EulaInfo #

OffsetSizeDescription
0x00x2 + 1ASCII NULL-terminated two-letter country code (2 characters + NULL termination)
0x30x2 + 1ASCII NULL-terminated two-letter language code (2 characters + NULL termination)
0x60x2u16, EULA version

InquireBindingToExistentServerAccountData #

Represents the device information for the console linked to the NNID.

OffsetSizeDescription
0x00x1bool, HasMii
0x10x3padding
0x40x60Mii CFLStoreData
0x640x4u32, PrincipalId
0x680x1bool, CoppaRequiredFlag
0x690x3padding
0x6C0x5 + 1ASCII 5-character CoppaCode + NULL termination
0x720x100 + 1ASCII 256-character ParentEmail + NULL termination
0x1730x1padding
0x1740x4Birth Date

SendCoppaCodeMailData #

OffsetSizeDescription
0x00x5 + 15-character ASCII CoppaCode + NULL termination
0x60x100 + 1256-character ASCII ParentEmail + NULL termination

AcquireEulaData/AcquireEulaListData #

Data returned from ACTU:AcquireEula and ACTU:AcquireEulaList uses a special format.

EulaHeader #

OffsetSizeDescription
0x00x32-character Country code + NULL termination
0x30x1padding
0x40x32-character Language code + NULL termination
0x70x1padding
0x80x2u16, Version
0xA0x2padding
0xC0x4u32, end offset of this EULA within full data blob
0x100x4EulaType offset
0x140x4AgreeText offset
0x180x4NonAgreeText offset
0x1C0x4LanguageName offset
0x200x4MainTitle offset
0x240x4MainText offset
0x280x4SubTitle offset
0x2C0x4SubText offset

X offset refers to an offset to a NULL-terminated ASCII string value for X within the full EULA data blob (see below).

EulaList #

This is the full data blob retrieved using ACTU:GetAsyncResult. Each EULA list entry is appended at the very end of the previous one. The end offset in the header can be used to get to subsequent EULA list entries.

OffsetSizeDescription
0x00x1u8, Number of EULA list entries (n)
0x1n * (...)concatenated EULA list entries

OffsetSizeDescription
0x00x30EulaHeader
0x30...EULA data

HTTPS Requests #

With each request, ACT-sysmodule specifies request-header “X-Nintendo-Device-Model”. This is the only *dedicated* request-header that’s contains anything Old3DS/New3DS specific. This was implemented with 9.0.0-X, and presumably 8.1.0-0_New3DS. The value is from a string initialized during ACT-sysmodule startup. The value-string is the codename string for all 5 of the model values from Cfg:GetSystemModel. When the output from GetSystemModel is >=5(switch statement default case), it runs this: “len = snprintf(outstr, outmaxsize, “3DS-%u”, model);”

Trusted Root CAs #

ACT module uses a RootCertChain for all HTTPS requests, the only trusted root CA is default CertID 0x3.

New3DS #

Even though ACT-sysmodule uses ptm:s, it doesn’t use CheckNew3DS at all.

Category:Services