nnas: link 3ds device certificate to document from NASC

This commit is contained in:
Jonathan Barrow
2024-04-14 20:56:33 -04:00
parent 82d353357b
commit 7ff47d8e26

View File

@@ -68,70 +68,88 @@ async function consoleStatusVerificationMiddleware(request: express.Request, res
return;
}
// * This is kinda temp for now. Needs to be redone to handle linking this data to existing 3DS devices in the DB
// TODO - 3DS consoles are created in the NASC middleware. They need special handling to link them up with the data in the NNID API!
if (request.certificate.consoleType === 'wiiu') {
const certificateDeviceID = parseInt(request.certificate.certificateName.slice(2), 16);
let device = await Device.findOne({
serial: serialNumber,
});
if (deviceID !== certificateDeviceID) {
// TODO - Change this to a different error
response.status(400).send(xmlbuilder.create({
error: {
cause: 'Bad Request',
code: '1600',
message: 'Unable to process request'
}
}).end());
if (!device && request.certificate.consoleType === '3ds') {
// * A 3DS console document will ALWAYS be created by NASC before
// * Hitting the NNAS server. NASC stores the serial number at
// * the time the device document was created. Therefore we can
// * know that serial tampering happened on the 3DS if this fails
// * to find a device document.
response.status(400).send(xmlbuilder.create({
error: {
code: '0002',
message: 'serialNumber format is invalid'
}
}).end());
return;
}
// * Only store a hash of the certificate in case of a breach
const certificateHash = crypto.createHash('sha256').update(request.certificate._certificate).digest('base64');
let device = await Device.findOne({
certificate_hash: certificateHash,
});
if (!device) {
device = await Device.create({
model: 'wup',
device_id: deviceID,
serial: serialNumber,
linked_pids: [],
certificate_hash: certificateHash
});
}
if (device.serial !== serialNumber) {
// TODO - Change this to a different error
response.status(400).send(xmlbuilder.create({
error: {
cause: 'Bad Request',
code: '1600',
message: 'Unable to process request'
}
}).end());
return;
}
if (device.access_level < 0) {
response.status(400).send(xmlbuilder.create({
errors: {
error: {
code: '0012',
message: 'Device has been banned by game server' // TODO - This is not the right error message
}
}
}).end());
return;
}
request.device = device;
return;
}
const certificateHash = crypto.createHash('sha256').update(request.certificate._certificate).digest('base64');
if (!device) {
// * Device must be a fresh Wii U
device = await Device.create({
model: 'wup',
device_id: deviceID,
serial: serialNumber,
linked_pids: [],
certificate_hash: certificateHash
});
}
if (!device.certificate_hash && request.certificate.consoleType === '3ds') {
device.certificate_hash = certificateHash;
await device.save();
}
if (device.serial !== serialNumber) {
// TODO - Change this to a different error
response.status(400).send(xmlbuilder.create({
error: {
cause: 'Bad Request',
code: '1600',
message: 'Unable to process request'
}
}).end());
return;
}
const certificateDeviceID = parseInt(request.certificate.certificateName.slice(2).split('-')[0], 16);
if (deviceID !== certificateDeviceID) {
// TODO - Change this to a different error
response.status(400).send(xmlbuilder.create({
error: {
cause: 'Bad Request',
code: '1600',
message: 'Unable to process request'
}
}).end());
return;
}
if (device.access_level < 0) {
response.status(400).send(xmlbuilder.create({
errors: {
error: {
code: '0012',
message: 'Device has been banned by game server' // TODO - This is not the right error message
}
}
}).end());
return;
}
request.device = device;
return next();
}