singpolyma / openpgp-php

OpenPGP.php is a pure-PHP implementation of the OpenPGP Message Format (RFC 4880).
http://singpolyma.github.io/openpgp-php/
The Unlicense
180 stars 69 forks source link

Strange error (Invalid argument supplied for foreach) on PRIVATE KEY BLOCK while Decrypting #84

Closed beshoo closed 3 years ago

beshoo commented 5 years ago

Warning: Invalid argument supplied for foreach() in encryptDecrypt.php on line 53

<?php

require_once dirname(__FILE__).'/vendor/autoload.php';

function test_decrypt(){
        // data for test    
        $pgppublickey='-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: SERVER PUBLIC KEY

xv8AAAENBF0QFPMBCADhtVAZn+RfW5eKrQMnJkRedR6v3CUtyciLC21KIme0yi5bXX7vjB1e4oPh0pN2sVffFwwHj2YPmsHzf6DxF0XB8U50BBSIVbKGpBCI7+j/XUAIBOd5KfRNPzQs7LxHsuK/kl4TAWsms8/8BqEBYwlwb17vCY7KgUw7FV1TbFptJ8miIQbFnPj0s3XtmzIkM8JwJv0pG6zXkLYDsnsElA4h5pnjgGdiqfdQ7bFT1WdbK68SgSJ7YcE/AjYpOc8OPSBznS92VHWvm/JYWkedUhjPeF7lww22c/n7rlbGufpHrzrPwiVzGdTJKoGTGm5mNfs5WAP7vKCdGItTYskTTZBlABEBAAHN/wAAACJpbnN0YUdyb3VwIDxzZXJ2ZXJAaW5zdGFncm91cC5hcHA+wv8AAAErBBMBCAAf/wAAAAUCXRAU8/8AAAACGwP/AAAACRBXRYlGHBwxNQAAStAH/0rQco5vGbY/CNZnyhZmzvkZvKzRnf4/12/N4xBxj3YeX6I1e0lggJ2dwywQqmA4mBM/O+6mzkAkk+zXqMmdRN05yGkO3U8WFUSLhycj40QcUiPhmTW1wBFEdOX0AAnl07Qh5ACX6H26fuWdeWIN9QqoTbeyopjVacgJUfjDnAAFMpcU7xeX7RTPNb6i+2l7vex0Fk9QgkjoqZV/PF1plwGFV0+AV0tPAdm+vHBUWX2BnvE7uhXehvLiVvvVi9XbjH8K7dnHLhMP64aqd2UtB8fj42b2OMj4Q65iRIDoh0G1ecAXCkcM4+DH+y1eMBIpGW09p/bl95BEOZ8/tLW2toA=
-----END PGP PUBLIC KEY BLOCK-----';

        $pgpprivatekey='-----BEGIN PGP PRIVATE KEY BLOCK-----
Comment: CLIENT PRIVATE KEY

xf8AAAOYBF0QFQUBCAC3ZpLDzQF2cFka2Bjs4b6xM+7k1CvFk7akEg/Nj0GgwJ/di0fyqLeZzTHUrvrEiwXsxEce1PqtjgKtmZPgc336fCoiaDixftS4E/j3gHl0fr7aOcAVbF7Z4y1GBh3TqMGh+eS6foKvdQ3ELdhPwMoamFgBv840Ik2iEu5Vtdd6ZRMHjXIe66GPNLyjum+Gplz9cKjfHvWyqP0zGz6yWJF71Ev17SXF7C/rlNT/lZT+Az99SGKgbhNml1bVdecOLxCaG70zA2IdW6XPLslo+zHATEHu6i3A+P+3WlB9ni5UEhVDtsIzROwwIbCBzb/3FfKXxoGdzrxtQ10A2aPRFUSrABEBAAEAB/0Y1ggsAdgf3OkELJ17frqfLqQ8Uss2r2E9aMDBGpRNm6hKjTEKGHT8nAASiDunYBhGTvI+p6Lm2+Na9QBElf9Ka4QdMrXyu3U9FF9TzQ8lioB39vgfLpTNtukLoYpqfmDyeW/THYy/C//4QCkZ68aywUyxt/LJtpeCykOCUeTDSy/9JeSaTrwb4bQ4f3sM9s0UfeJAbWwG357X5eBAF6xyepvFq6PEFNVaQCTODO40hXtZNJddANby0EmEegyhzhVRbjjBO/I5WNSF/XBWjf3CvxCGs/9sw0X9chxZsio+1T4uR9g6lY32y3PT3sHR9EVvSpwwhvS1bhxeeS7jDXjxBADjvO8oHIP2ZlsCeu43ZofwkV2n7pbo7AD208o9Abefaw53Tux0qrl8t3y0zuC7nhVIlUdsZK4+Vi4aJkAY7HaNytva5F9+O4/IrGbqhTulDK9aBk52TnbsgAdGC/JzWTyDrQSqLmS46xqKxG0O6xCaX4eMiI6wyneBOkt+z2TcMwQAzikTLS/4bhOnns70NiazJb5IolGawdtZMxE2SrKfBrbVDbqMO0+fADBFumtTxzB1p8sS6nnu92231I9+O2arLlYdEArVhPHGYxGXFY0d80+kFJip2NP0mN0JUZTgM4X/ZMbz51DyTJXlwXcJW475kImz/yzBNPWzx1YhTT0ZfakEANccQyDAGNqwYO0+ri3CeQiUmREzjf0n/J5WynVY99meFl/ihMdmB13ZogBtGQIAVNxYk7xgPTk6YUWUBo7q1kWUXCnHFnb3CO/baxAbeTvpb4sxf3ghx62XSzS4HiOv0/M3GfhEf6YR09BFtZPt3tMzBeTrIaWJ8DZyeROeJo2LQNXN/wAAACJpbnN0YUdyb3VwIDxzZXJ2ZXJAaW5zdGFncm91cC5hcHA+wv8AAAErBBMBCAAf/wAAAAUCXRAVBf8AAAACGwP/AAAACRD5JnkZGprXQwAAfsMH/37Dv1fNKni9CsSqypImmyhO8aJI782Z2BLTNwn7GAVkT3TP7wKOfEERw3HR+uh0Bz8aMvwIwjj86x3UkEL7Ab83t40wJ+8nBUE0J9FNHoutpklYCL2O0kt2eIAkXZhiEfkCpYrmWUOP1omVUbvCt+FSmmwYG2x7lTo0uhjma1PzBC/YSmgK/fdY4EUxMCEty+lbCfarKUF0RQYRRSXh9iO3qtmB3PFUPhl/W7ckb0wb12mZPtLml2KlAHloJX1x3Nv0BLwNxXX5iqNGv22UsijwJTzHfDW9/opARLyJFoi4hnbK8UwFxrQHjqDObFha1/sH7McHlYTchvay/u6Ium8=
-----END PGP PRIVATE KEY BLOCK-----';

$pgpmessage='-----BEGIN PGP MESSAGE-----
Version: Keybase OpenPGP v2.0.76
Comment: https://keybase.io/crypto

yMCXAnicO8LLzMDFGO7a6SYjY2jKeFqhlCFWQLQpKbU4Iz9fISe/LFUByC5OzdCF
gkMHYlgYGLkY2FiZQAoZuDgFYLqjX7H/lVm1619MtsS/PbkzxRcsKtvu+vKg0izj
VN+vrN2f2JpefZFN5drPHLL55sZ+xwnpWt/U405nvtKL6tiee2XprU/pQnEPztZ9
+zX/LTfnjerwuMvml2p/h4U2t+xep+YvaP4/w2r9V4tj8Q9mFoTxbrvt+vNc1mYH
RuGVbO6lDyQ3fWMqN8/cwyN9X3bPwVlrRDQi3e5FWoc8DwvR0six+H5miqCpDFdP
L/+LBV8bLxT2XCvaLKhWOkn5C89RibvbN5ube9nPk+7v7lKJ1WIMi/YLsv9nM41x
yt0bDcca+i3PKOSVdfVNODmrutPFNdu86C5Tc9nxFZV3Qu+8+HM/uCM/K9s9wrbI
qUjO+BUAa96Rkg==
=tyk/
-----END PGP MESSAGE-----';

    // -------------------
    $decrypted=false;
    $keyEncrypted = OpenPGP_Message::parse(
        OpenPGP::unarmor($pgpprivatekey, 'PGP PRIVATE KEY BLOCK')
    );  
    $msg = OpenPGP_Message::parse(
        OpenPGP::unarmor($pgpmessage, 'PGP MESSAGE')
    );    
    foreach($keyEncrypted as $p) {
        if(!($p instanceof OpenPGP_SecretKeyPacket)) continue;   

        $key = new OpenPGP_SecretKeyPacket($p->key);
        $decryptor = new OpenPGP_Crypt_RSA($key);            
        $decrypted = $decryptor->decrypt($msg);    //<-- it does not return     
    }        
    return $decrypted;
}

$start = microtime(true);
print(test_decrypt()->packets[0]->data."\n");
$stop = microtime(true);
echo 'Elapsed time:' . ($stop - $start)." sec\n";
singpolyma commented 3 years ago

These key blocks are not valid OpenPGP armor -- they are missing the CRC at the end. I have pushed a version to master that makes this case just a notice instead of a full return-NULL level error.

The other problem with this example is that the included message is not encrypted at all. This would previously result in NULL being returned but will now result in an exception.