(packet)
| 107 | } |
| 108 | |
| 109 | function onEncryptionKeyResponse (packet) { |
| 110 | if (client.profileKeys) { |
| 111 | if (options.enforceSecureProfile && packet.hasVerifyToken) { |
| 112 | raise('multiplayer.disconnect.missing_public_key') |
| 113 | return // Unexpected - client has profile keys, and we expect secure profile |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | const keyRsa = new NodeRSA(server.serverKey.exportKey('pkcs1'), 'private', { encryptionScheme: 'pkcs1' }) |
| 118 | keyRsa.setOptions({ environment: 'browser' }) |
| 119 | |
| 120 | if (packet.hasVerifyToken === false) { |
| 121 | // 1.19, hasVerifyToken is set and equal to false IF chat signing is enabled |
| 122 | // This is the default action starting in 1.19.1. |
| 123 | const signable = concat('buffer', client.verifyToken, 'i64', packet.crypto.salt) |
| 124 | if (!crypto.verify('sha256WithRSAEncryption', signable, client.profileKeys.public, packet.crypto.messageSignature)) { |
| 125 | raise('multiplayer.disconnect.invalid_public_key_signature') |
| 126 | return |
| 127 | } |
| 128 | } else { |
| 129 | const encryptedToken = packet.hasVerifyToken ? packet.crypto.verifyToken : packet.verifyToken |
| 130 | try { |
| 131 | const decryptedToken = keyRsa.decrypt(encryptedToken) |
| 132 | |
| 133 | if (!client.verifyToken.equals(decryptedToken)) { |
| 134 | client.end('DidNotEncryptVerifyTokenProperly') |
| 135 | return |
| 136 | } |
| 137 | } catch { |
| 138 | client.end('DidNotEncryptVerifyTokenProperly') |
| 139 | return |
| 140 | } |
| 141 | } |
| 142 | let sharedSecret |
| 143 | try { |
| 144 | sharedSecret = keyRsa.decrypt(packet.sharedSecret) |
| 145 | } catch (e) { |
| 146 | client.end('DidNotEncryptVerifyTokenProperly') |
| 147 | return |
| 148 | } |
| 149 | |
| 150 | client.setEncryption(sharedSecret) |
| 151 | |
| 152 | const isException = !!server.onlineModeExceptions[client.username.toLowerCase()] |
| 153 | const needToVerify = (onlineMode && !isException) || (!onlineMode && isException) |
| 154 | const nextStep = needToVerify ? verifyUsername : loginClient |
| 155 | nextStep() |
| 156 | |
| 157 | function verifyUsername () { |
| 158 | yggdrasilServer.hasJoined(client.username, serverId, sharedSecret, client.publicKey, function (err, profile) { |
| 159 | if (err) { |
| 160 | client.end('Failed to verify username!') |
| 161 | return |
| 162 | } |
| 163 | // Convert to a valid UUID until the session server updates and does |
| 164 | // it automatically |
| 165 | client.uuid = profile.id.replace(/(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})/, '$1-$2-$3-$4-$5') |
| 166 | client.username = profile.name |
nothing calls this directly
no test coverage detected