PHPDaemon\Clients\Mongo\Pool::saslScrumSHA1Step PHP Method

saslScrumSHA1Step() public method

public saslScrumSHA1Step ( $session, $input = null )
    public function saslScrumSHA1Step($session, $input = null)
    {
        $session['step']++;
        $query = [];
        if (!is_null($input) && (!empty($input['$err']) || !empty($input['errmsg']))) {
            $session['cb']($input);
            return;
        }
        if ($session['step'] == 1) {
            $session['nonce'] = base64_encode(openssl_random_pseudo_bytes(24));
            $payload = 'n,,n=' . $session['user'] . ',r=' . $session['nonce'];
            $query = ['saslStart' => 1, 'mechanism' => 'SCRAM-SHA-1', 'payload' => base64_encode($payload)];
            $session['auth_message'] .= 'n=' . $session['user'] . ',r=' . $session['nonce'] . ',';
        } elseif ($session['step'] == 2) {
            $in_payload = $this->saslScrumSHA1ExtractPayload($input['payload']);
            $error = null;
            if (count($in_payload) != 3) {
                $error = 'Incorrect number of arguments for first SCRAM-SHA-1 server message, got ' . count($in_payload) . 'expected 3';
            } elseif (mb_orig_strlen($in_payload['r']) < 2) {
                $error = 'Incorrect SCRAM-SHA-1 client|server nonce: ' . $in_payload['r'];
            } elseif (mb_orig_strlen($in_payload['s']) < 6) {
                $error = 'Incorrect SCRAM-SHA-1 salt: ' . $in_payload['s'];
            } elseif (mb_orig_strlen($in_payload['i']) < 3) {
                $error = 'Incorrect SCRAM-SHA-1 iteration count: ' . $in_payload['i'];
            } elseif (mb_orig_strpos($in_payload['r'], $session['nonce']) !== 0) {
                $error = 'Server SCRAM-SHA-1 nonce does not match client nonce';
            }
            if (!empty($error)) {
                $session['cb'](['ok' => 0, 'errmsg' => $error]);
                return;
            } else {
                $session['conversation_id'] = $input['conversationId'];
                $session['nonce'] = $in_payload['r'];
            }
            $payload = 'c=biws,r=' . $session['nonce'];
            $session['auth_message'] .= base64_decode($input['payload']) . ',' . $payload;
            $decoded_salt = base64_decode($in_payload['s']);
            $password = md5($session['user'] . ':mongo:' . $session['password']);
            $salted_password = hash_pbkdf2('sha1', $password, $decoded_salt, (int) $in_payload['i'], 0, true);
            $client_key = hash_hmac('sha1', 'Client Key', $salted_password, true);
            $stored_key = sha1($client_key, true);
            $client_sign = hash_hmac('sha1', $session['auth_message'], $stored_key, true);
            $client_proof = $client_key ^ $client_sign;
            $payload .= ',p=' . base64_encode($client_proof);
            $query = ['saslContinue' => 1, 'conversationId' => $session['conversation_id'], 'payload' => base64_encode($payload)];
        } elseif ($session['step'] == 3) {
            $in_payload = $this->saslScrumSHA1ExtractPayload($input['payload']);
            if (!empty($in_payload['v'])) {
                $session['server_signature'] = $in_payload['v'];
                $query = ['saslContinue' => 1, 'conversationId' => $session['conversation_id'], 'payload' => base64_encode('')];
            }
        } elseif ($session['step'] == 4) {
            $in_payload = $this->saslScrumSHA1ExtractPayload($input['payload']);
            $res = $input['done'] ? ['ok' => 1, 'server_signature' => $session['server_signature']] : ['ok' => 0, 'errmsg' => 'Authentication failed.'];
            $session['cb']($res);
            return;
        }
        $this->saslScrumSHA1Conversation($session['dbname'], $query, function ($res) use($session) {
            $this->saslScrumSHA1Step($session, $res);
        }, $session['conn']);
    }