From d0da01c7799ffb8d8a1e8117dbb664f743c54634 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Fri, 9 Aug 2024 19:35:16 -0400 Subject: [PATCH] fix: validate padding in certificates --- src/middleware/device-certificate.ts | 1 + src/middleware/nasc.ts | 1 + src/nintendo-certificate.ts | 13 +++++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/middleware/device-certificate.ts b/src/middleware/device-certificate.ts index 4080d89..87ed947 100644 --- a/src/middleware/device-certificate.ts +++ b/src/middleware/device-certificate.ts @@ -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(); diff --git a/src/middleware/nasc.ts b/src/middleware/nasc.ts index 7ef7053..50bd3d9 100644 --- a/src/middleware/nasc.ts +++ b/src/middleware/nasc.ts @@ -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) { diff --git a/src/nintendo-certificate.ts b/src/nintendo-certificate.ts index 38e7a1a..2e2f31f 100644 --- a/src/nintendo-certificate.ts +++ b/src/nintendo-certificate.ts @@ -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; @@ -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]; @@ -137,7 +146,7 @@ class NintendoCertificate { this.consoleType = '3ds'; } - this._verifySignature(); + this._verifySignatureECDSA(); // * Force it to use the expected certificate type } }