Search code examples
phplaravelgnupg

Laravel GPG - Issue when attemping to Encode


So, I'm attempting to do some encoding using GPG in Laravel. I've found the package https://github.com/jasonhinkle/php-gpg which, while no longer maintained, looks like it should still work for what I need to do. I've installed the code in a custom folder app/Classes/GPG, and included it in the artisan Command that will use it:

class CustomCommand extends Command {
  private $gpg = null;
  private $publicKey = null;

  protected $signature = "custom:command";

  public function __construct() {
    $this->publicKey = new \GPG_Public_Key(file_get_contents(base_path()."/path/to/public/key.asc"));
    $this->gpg = new \GPG();

    parent::__construct();
  }

  public function handle() {
    $this->gpg->encrypt($this->publicKey, "Hello World!");
  }
}

With the above code, all is well; $this->gpg and $this->publicKey are both initialized without issue, but as soon as I try to run php artisan custom:command, I get the following error:

(1/1) ErrorException
String offset cast occurred
in GPG.php line 112

Like 112 of GPG.php is as follows:

private function gpg_session($key_id, $key_type, $session_key, $public_key){
  ...
  $s = base64_decode($public_key);
  $l = floor((ord($s[0]) * 256 + ord($s[1]) + 7) / 8);
  if($key_type) {
    ...
    $l2 = floor((ord($s[$l + 2]) * 256 + ord($s[$l + 3]) + 7) / 8) + 2; // 112
  }
}

Doing a dd($s, $l) results in a jumbled mess of a string which I likely can't post here, and 256.0.

Has anyone seen this issue before?


Solution

  • The issue lies with this line:

    $l = floor((ord($s[0]) * 256 + ord($s[1]) + 7) / 8); // 256.0
    

    As $l is a float, and not an integer, this line:

    $l2 = floor((ord($s[$l + 2]) * 256 + ord($s[$l + 3]) + 7) / 8) + 2; // String offset cast occurred
    

    fails in both cases of trying to access $s[$l ...]. To fix this issue, simply wrap the declaration of $l in an intval() call to explictly set it as an integer:

    $l = intval(floor((ord($s[0]) * 256 + ord($s[1]) + 7) / 8)); // 256
    

    The reason for this error is due to versions of PHP. Prior to PHP 5.4, trying to access an array with a float was valid, due to conversion. Given $l = 256.0, $s[$l] would try to access $s[256]. In PHP 5.4+, this error was introduced, and, due to this package not being maintained, was never handled properly. Hopefully this helps someone else out.