Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update some authentication related checks #111

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,17 @@ export async function getPNIDByBasicAuth(token: string): Promise<HydratedPNIDDoc
return pnid;
}

export async function getPNIDByTokenAuth(token: string): Promise<HydratedPNIDDocument | null> {
export async function getPNIDByTokenAuth(token: string, allowedTypes?: number[]): Promise<HydratedPNIDDocument | null> {
verifyConnected();

try {
const decryptedToken = decryptToken(Buffer.from(token, 'hex'));
const unpackedToken = unpackToken(decryptedToken);

if (allowedTypes && !allowedTypes.includes(unpackedToken.system_type)) {
return null;
}

const pnid = await getPNIDByPID(unpackedToken.pid);

if (pnid) {
Expand Down
1 change: 1 addition & 0 deletions src/middleware/device-certificate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ function deviceCertificateMiddleware(request: express.Request, _response: expres
return next();
}

// TODO - Replace this with https://github.com/PretendoNetwork/nintendo-file-formats
request.certificate = new NintendoCertificate(certificate);

return next();
Expand Down
1 change: 1 addition & 0 deletions src/middleware/nasc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ async function NASCMiddleware(request: express.Request, response: express.Respon
return;
}

// TODO - Replace this with https://github.com/PretendoNetwork/nintendo-file-formats maybe?
const cert = new NintendoCertificate(fcdcert);

if (!cert.valid) {
Expand Down
9 changes: 5 additions & 4 deletions src/middleware/pnid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ async function PNIDMiddleware(request: express.Request, response: express.Respon
const parts = authHeader.split(' ');
const type = parts[0];
let token = parts[1];
let pnid: HydratedPNIDDocument | null;
let pnid: HydratedPNIDDocument | null = null;

if (request.isCemu) {
token = Buffer.from(token, 'hex').toString('base64');
}

if (type === 'Basic') {
if (type === 'Basic' && request.path.includes('v1/api/people/@me/devices')) {
pnid = await getPNIDByBasicAuth(token);
} else {
pnid = await getPNIDByTokenAuth(token);
} else if (type === 'Bearer') {
// TODO - This "accepted types list" is mostly a hack. Change this
pnid = await getPNIDByTokenAuth(token, [1, 2]);
}

if (!pnid) {
Expand Down
13 changes: 11 additions & 2 deletions src/nintendo-certificate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const SIGNATURE_SIZES = {
}
} as const;

// TODO - Replace this with https://github.com/PretendoNetwork/nintendo-file-formats
class NintendoCertificate {
_certificate: Buffer;
_certificateBody: Buffer;
Expand Down Expand Up @@ -123,8 +124,16 @@ class NintendoCertificate {
const signatureTypeSizes = this._signatureTypeSizes(this.signatureType);

this._certificateBody = this._certificate.subarray(0x4 + signatureTypeSizes.SIZE + signatureTypeSizes.PADDING_SIZE);

this.signature = this._certificate.subarray(0x4, 0x4 + signatureTypeSizes.SIZE);

const padding = this._certificate.subarray(0x4 + signatureTypeSizes.SIZE, 0x4 + signatureTypeSizes.SIZE + signatureTypeSizes.PADDING_SIZE);

this.valid = padding.every(byte => byte === 0);

if (!this.valid) {
return;
}

this.issuer = this._certificate.subarray(0x80, 0xC0).toString().split('\0')[0];
this.keyType = this._certificate.readUInt32BE(0xC0);
this.certificateName = this._certificate.subarray(0xC4, 0x104).toString().split('\0')[0];
Expand All @@ -137,7 +146,7 @@ class NintendoCertificate {
this.consoleType = '3ds';
}

this._verifySignature();
this._verifySignatureECDSA(); // * Force it to use the expected certificate type
}
}

Expand Down