original_string: public function getIdentity()
      {
          if ($this->identity) {
              return $this->identity;
          }
  
          if (!isset($_COOKIE[self::COOKIE_VERIFY_A], $_COOKIE[self::COOKIE_VERIFY_B], $_COOKIE[self::COOKIE_USER])) {
              return null;
          }
  
          $systemKey = new EncryptionKey($this->systemEncryptionKey);
          $verificationCookie = $_COOKIE[self::COOKIE_VERIFY_A];
          $hashPass = hash_equals(
              hash_hmac('sha256', $_COOKIE[self::COOKIE_USER], $systemKey),
              $verificationCookie
          );
  
          //
          // 1. Is the verify cookie still equivalent to the user cookie, if so, do not decrypt
          //
          if (!$hashPass) {
              return null;
          }
  
          //
          // 2. If the user cookie was not tampered with, decrypt its contents with the system key
          //
          try {
  
              $userTuple = Crypto::decrypt(base64_decode($_COOKIE[self::COOKIE_USER]), $systemKey);
  
              if (strpos($userTuple, ':') === false) {
                  throw new \Exception();
              }
  
              // paranoid, make sure we have everything we need
              @list($cookieUserId, $hashCookieSuffix) = @explode(":", $userTuple, 2);
              if (!isset($cookieUserId, $hashCookieSuffix) || !is_numeric($cookieUserId) || !trim($hashCookieSuffix)) {
                  throw new \Exception();
              }
  
              /** @var AuthenticationRecordInterface $auth */
              if (!($auth = $this->authenticationProvider->findByUserId($cookieUserId))) {
                  throw new \Exception();
              }
  
              $hashCookieName = self::COOKIE_HASH_PREFIX . $hashCookieSuffix;
  
              //
              // 2. Check the hashCookie for corroborating data
              //
              if (!isset($_COOKIE[$hashCookieName])) {
                  throw new \Exception();
              }
  
              $userKey = new EncryptionKey(new HiddenString($auth->getSessionKey()));
              $hashPass = hash_equals(
                  hash_hmac('sha256', $_COOKIE[$hashCookieName], $userKey),
                  $_COOKIE[self::COOKIE_VERIFY_B]
              );
  
              if (!$hashPass) {
                  throw new \Exception();
              }
  
              //
              // 3. Decrypt the hash cookie with the user key
              //
              $hashedCookieContents = Crypto::decrypt(base64_decode($_COOKIE[$hashCookieName]), $userKey);
              if (!substr_count($hashedCookieContents, ':') === 2) {
                  throw new \Exception();
              }
  
              list(, $hashedUserId, $hashedUsername) = explode(':', $hashedCookieContents);
              if ($hashedUserId !== $cookieUserId) {
                  throw new \Exception();
              }
  
              if ($hashedUsername !== $auth->getUsername()) {
                  throw new \Exception();
              }
  
              $this->purgeHashCookies($hashCookieName);
  
              //
              // 4. Cookies check out - it's up to the user provider now
              //
              $user = $this->userProvider->getUser($auth->getUserId());
              if ($user) {
                  $this->setIdentity($user);
  
                  return $this->identity;
              }
  
          } catch (\Exception $x) {
              $this->purgeHashCookies();
          }
  
          return null;
      }
code: public function getIdentity()
      {
          if ($this->identity) {
              return $this->identity;
          }
  
          if (!isset($_COOKIE[self::COOKIE_VERIFY_A], $_COOKIE[self::COOKIE_VERIFY_B], $_COOKIE[self::COOKIE_USER])) {
              return null;
          }
  
          $systemKey = new EncryptionKey($this->systemEncryptionKey);
          $verificationCookie = $_COOKIE[self::COOKIE_VERIFY_A];
          $hashPass = hash_equals(
              hash_hmac('sha256', $_COOKIE[self::COOKIE_USER], $systemKey),
              $verificationCookie
          );
  
          //
          // 1. Is the verify cookie still equivalent to the user cookie, if so, do not decrypt
          //
          if (!$hashPass) {
              return null;
          }
  
          //
          // 2. If the user cookie was not tampered with, decrypt its contents with the system key
          //
          try {
  
              $userTuple = Crypto::decrypt(base64_decode($_COOKIE[self::COOKIE_USER]), $systemKey);
  
              if (strpos($userTuple, ':') === false) {
                  throw new \Exception();
              }
  
              // paranoid, make sure we have everything we need
              @list($cookieUserId, $hashCookieSuffix) = @explode(":", $userTuple, 2);
              if (!isset($cookieUserId, $hashCookieSuffix) || !is_numeric($cookieUserId) || !trim($hashCookieSuffix)) {
                  throw new \Exception();
              }
  
              /** @var AuthenticationRecordInterface $auth */
              if (!($auth = $this->authenticationProvider->findByUserId($cookieUserId))) {
                  throw new \Exception();
              }
  
              $hashCookieName = self::COOKIE_HASH_PREFIX . $hashCookieSuffix;
  
              //
              // 2. Check the hashCookie for corroborating data
              //
              if (!isset($_COOKIE[$hashCookieName])) {
                  throw new \Exception();
              }
  
              $userKey = new EncryptionKey(new HiddenString($auth->getSessionKey()));
              $hashPass = hash_equals(
                  hash_hmac('sha256', $_COOKIE[$hashCookieName], $userKey),
                  $_COOKIE[self::COOKIE_VERIFY_B]
              );
  
              if (!$hashPass) {
                  throw new \Exception();
              }
  
              //
              // 3. Decrypt the hash cookie with the user key
              //
              $hashedCookieContents = Crypto::decrypt(base64_decode($_COOKIE[$hashCookieName]), $userKey);
              if (!substr_count($hashedCookieContents, ':') === 2) {
                  throw new \Exception();
              }
  
              list(, $hashedUserId, $hashedUsername) = explode(':', $hashedCookieContents);
              if ($hashedUserId !== $cookieUserId) {
                  throw new \Exception();
              }
  
              if ($hashedUsername !== $auth->getUsername()) {
                  throw new \Exception();
              }
  
              $this->purgeHashCookies($hashCookieName);
  
              //
              // 4. Cookies check out - it's up to the user provider now
              //
              $user = $this->userProvider->getUser($auth->getUserId());
              if ($user) {
                  $this->setIdentity($user);
  
                  return $this->identity;
              }
  
          } catch (\Exception $x) {
              $this->purgeHashCookies();
          }
  
          return null;
      }
code_tokens: public function getIdentity ( ) { if ( $ this -> identity ) { return $ this -> identity ; } if ( ! isset ( $ _COOKIE [ self :: COOKIE_VERIFY_A ] , $ _COOKIE [ self :: COOKIE_VERIFY_B ] , $ _COOKIE [ self :: COOKIE_USER ] ) ) { return null ; } $ systemKey = new EncryptionKey ( $ this -> systemEncryptionKey ) ; $ verificationCookie = $ _COOKIE [ self :: COOKIE_VERIFY_A ] ; $ hashPass = hash_equals ( hash_hmac ( 'sha256' , $ _COOKIE [ self :: COOKIE_USER ] , $ systemKey ) , $ verificationCookie ) ; // // 1. Is the verify cookie still equivalent to the user cookie, if so, do not decrypt // if ( ! $ hashPass ) { return null ; } // // 2. If the user cookie was not tampered with, decrypt its contents with the system key // try { $ userTuple = Crypto :: decrypt ( base64_decode ( $ _COOKIE [ self :: COOKIE_USER ] ) , $ systemKey ) ; if ( strpos ( $ userTuple , ':' ) === false ) { throw new \ Exception ( ) ; } // paranoid, make sure we have everything we need @ list ( $ cookieUserId , $ hashCookieSuffix ) = @ explode ( ":" , $ userTuple , 2 ) ; if ( ! isset ( $ cookieUserId , $ hashCookieSuffix ) || ! is_numeric ( $ cookieUserId ) || ! trim ( $ hashCookieSuffix ) ) { throw new \ Exception ( ) ; } /** @var AuthenticationRecordInterface $auth */ if ( ! ( $ auth = $ this -> authenticationProvider -> findByUserId ( $ cookieUserId ) ) ) { throw new \ Exception ( ) ; } $ hashCookieName = self :: COOKIE_HASH_PREFIX . $ hashCookieSuffix ; // // 2. Check the hashCookie for corroborating data // if ( ! isset ( $ _COOKIE [ $ hashCookieName ] ) ) { throw new \ Exception ( ) ; } $ userKey = new EncryptionKey ( new HiddenString ( $ auth -> getSessionKey ( ) ) ) ; $ hashPass = hash_equals ( hash_hmac ( 'sha256' , $ _COOKIE [ $ hashCookieName ] , $ userKey ) , $ _COOKIE [ self :: COOKIE_VERIFY_B ] ) ; if ( ! $ hashPass ) { throw new \ Exception ( ) ; } // // 3. Decrypt the hash cookie with the user key // $ hashedCookieContents = Crypto :: decrypt ( base64_decode ( $ _COOKIE [ $ hashCookieName ] ) , $ userKey ) ; if ( ! substr_count ( $ hashedCookieContents , ':' ) === 2 ) { throw new \ Exception ( ) ; } list ( , $ hashedUserId , $ hashedUsername ) = explode ( ':' , $ hashedCookieContents ) ; if ( $ hashedUserId !== $ cookieUserId ) { throw new \ Exception ( ) ; } if ( $ hashedUsername !== $ auth -> getUsername ( ) ) { throw new \ Exception ( ) ; } $ this -> purgeHashCookies ( $ hashCookieName ) ; // // 4. Cookies check out - it's up to the user provider now // $ user = $ this -> userProvider -> getUser ( $ auth -> getUserId ( ) ) ; if ( $ user ) { $ this -> setIdentity ( $ user ) ; return $ this -> identity ; } } catch ( \ Exception $ x ) { $ this -> purgeHashCookies ( ) ; } return null ; }
docstring: Rifle through 4 cookies, ensuring that all details line up.  If they do, we accept that the cookies authenticate
  a specific user.
  
  Some notes:
  
  - COOKIE_VERIFY_A is a do-not-decrypt check of COOKIE_USER
  - COOKIE_VERIFY_B is a do-not-decrypt check of the random-named-cookie specified by COOKIE_USER
  - COOKIE_USER has its contents encrypted by the system key
  - the random-named-cookie has its contents encrypted by the user key
  
  @see self::setSessionCookies
  @return User|null
docstring_tokens: Rifle through 4 cookies ensuring that all details line up . If they do we accept that the cookies authenticate a specific user .