From d98e52e7585aa964c012c0523077424d98223529 Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 19:50:16 +0100 Subject: [PATCH 01/13] Add very basic PHPUnit test. --- .github/lock.yml | 9 ---- .github/workflows/test.yml | 27 ++++++++++ .gitignore | 3 +- composer.json | 13 +++-- tests/BasicTest.php | 65 +++++++++++++++++++++++++ tests/fixtures/example-certificate.p12 | Bin 0 -> 2589 bytes tests/fixtures/icon.png | Bin 0 -> 6678 bytes 7 files changed, 102 insertions(+), 15 deletions(-) delete mode 100644 .github/lock.yml create mode 100644 .github/workflows/test.yml create mode 100644 tests/BasicTest.php create mode 100644 tests/fixtures/example-certificate.p12 create mode 100644 tests/fixtures/icon.png diff --git a/.github/lock.yml b/.github/lock.yml deleted file mode 100644 index 2761d7b..0000000 --- a/.github/lock.yml +++ /dev/null @@ -1,9 +0,0 @@ -# https://github.com/dessant/lock-threads -daysUntilLock: 90 -exemptLabels: [] -lockLabel: false -lockComment: > - This thread has been automatically locked since there has not been - any recent activity after it was closed. Please open a new issue for - related bugs. -only: issues diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..9e4e40b --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,27 @@ +name: PHPUnit Tests on Multiple PHP Versions + +on: [ push ] + +jobs: + tests: + runs-on: ubuntu-latest + + strategy: + matrix: + php: [ "7.1", "7.4", "8.0", "8.2" ] + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: zip, openssl + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-progress --no-interaction + + - name: Run PHPUnit + run: vendor/bin/phpunit \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5cd2992..a37fdd8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /vendor composer.lock -/Certificates.p12 \ No newline at end of file +/Certificates.p12 +.phpunit.result.cache \ No newline at end of file diff --git a/composer.json b/composer.json index 74c4482..4f105a1 100644 --- a/composer.json +++ b/composer.json @@ -20,15 +20,18 @@ "email": "thomas@includable.com" } ], + "autoload": { + "psr-4": { + "PKPass\\": "src" + } + }, "require": { - "php": ">=5.6", + "php": ">=7.0", "ext-zip": "*", "ext-json": "*", "ext-openssl": "*" }, - "autoload": { - "psr-4": { - "PKPass\\": "src" - } + "require-dev": { + "phpunit/phpunit": "^9.6" } } diff --git a/tests/BasicTest.php b/tests/BasicTest.php new file mode 100644 index 0000000..72637cd --- /dev/null +++ b/tests/BasicTest.php @@ -0,0 +1,65 @@ +assertIsString($pass); + $this->assertGreaterThan(100, strlen($pass)); + $this->assertStringContainsString('icon.png', $pass); + $this->assertStringContainsString('manifest.json', $pass); + + // try to read the ZIP file + $temp_name = tempnam(sys_get_temp_dir(), 'pkpass'); + file_put_contents($temp_name, $pass); + $zip = new ZipArchive(); + $res = $zip->open($temp_name); + $this->assertTrue($res, 'Invalid ZIP file.'); + $this->assertEquals(count($expected_files), $zip->numFiles); + + // extract zip to temp dir + $temp_dir = $temp_name . '_dir'; + mkdir($temp_dir); + $zip->extractTo($temp_dir); + $zip->close(); + echo $temp_dir; + foreach ($expected_files as $file) { + $this->assertFileExists($temp_dir . DIRECTORY_SEPARATOR . $file); + } + } + + public function testBasicGeneration() + { + $pass = new PKPass(__DIR__ . '/fixtures/example-certificate.p12', 'password'); + $data = [ + 'description' => 'Demo pass', + 'formatVersion' => 1, + 'organizationName' => 'Flight Express', + 'passTypeIdentifier' => 'pass.com.scholica.flights', // Change this! + 'serialNumber' => '12345678', + 'teamIdentifier' => 'KN44X8ZLNC', // Change this! + 'barcode' => [ + 'format' => 'PKBarcodeFormatQR', + 'message' => 'Flight-GateF12-ID6643679AH7B', + 'messageEncoding' => 'iso-8859-1', + ], + 'backgroundColor' => 'rgb(32,110,247)', + 'logoText' => 'Flight info', + 'relevantDate' => date('Y-m-d\TH:i:sP') + ]; + $pass->setData($data); + $pass->addFile(__DIR__ . '/fixtures/icon.png'); + $value = $pass->create(); + + $this->validatePass($value, [ + 'icon.png', + 'manifest.json', + 'pass.json', + 'signature', + ]); + } +} \ No newline at end of file diff --git a/tests/fixtures/example-certificate.p12 b/tests/fixtures/example-certificate.p12 new file mode 100644 index 0000000000000000000000000000000000000000..0b6606c38a661ddc349fd438aa47e0d496d54b7c GIT binary patch literal 2589 zcmY+^cQhM}8U}EYAhBYr(W=^F#3)Los;a21#b>o1$y>RMPG~p`JG4Jv;dm(=lV|rfD6(y{(FHLKo4gHf!Cx@Nv)z}1T8I? zCJF^odm8be+4R@~8^1!QY;xDIKdrrLi-TZ-vEaFy4Wcp`3reDhE$VmEx{%TvT`WkzqXwVvLeqzPAhgaq(SAc`py$rvXk$9Zo<>mzw91w=`W zEsvJ}8LTK8ybf_*_kn5Qv%(jfBLZ0U-j<0cGRsXu(zoA4XO+7NnMi_C2_B36S)LM0 z8-SOw^$v_w`4-xCCnX;BBs}L2-@^&-WZ7Yp{*aQh`;OCKq{Dz(*pU1Ub0lSUV5Z|+ z&*SI^v#S2BW8{TFRo`gBI2*wE9`J=L_g`Uy{$I85NyS@YA$9wo(z?I*CUiNK% z^V2x-H z%OiM)J+#T7VN^UIUP-l6y%|ZH0u(hCu<`ORcmR6MzS@OJEPksGSuzZkQim$cBxPTP zDaBs+M(La{xxc)f|L!^}PkdwWj%QQlS$jdZf1S4zI(U?#2=jLTr4p^P#1+B~qpJMc z2yFM*68?S`icEp`0E5aIf{EowUXkX-nn&{tYU40m}TxVYJig z+n;MVci(l3*W7iS{yk8m0KuO>j$%YUzMkt~z*0_`KQ%|{KJ(FxjLhl$W85}ZteM3W z%Cx)v>By5q<<*^Fyo?9>DZ`|Clq>PJv|YYK>CIJ8{OVfMad;nFGjF~ZMw>yN z)Mn z1v*;rvh!^q%EM)am3c{E8UgeCGl#VE6;J-v&AA0lH2ms^)bG6tzPEGb&)PW(Ela^; z&swE!vA}9cKR{XoYDgnAV{dly9RoTITg)4({|E+27!%kaPZn1nv;3$}`C+x%w6d4y z%XvLR_`oG2SN$$8#n59-y&&^f+rdSGPo$qR2hlv2U)^6i{U~C(D*T5mZ^8qW=G$WSM@WE)bG`JF#~l!R+*h~$?c+?rT|?}yxt z@fzDX35QAB&)kgZjf3>A?*Jdmby5EZlzHH9Og*|cpdYKgZ*8(sNkT=&x5sX6e&MN&weu!1vPo;Pjt9^Q=MiO){7P|uo(rRW%^ znI7jNbH1qS>uEpiTkY0VVUM#GUP?S^l)vObm;a=_zBQxv+6>8C^|57N;>v;C@($T( z+@ZCNy&Ao+WhWOx45+K~GiK$Y@>AQ21ujpyGy^&7U5Bsg*r>v1>OHW7$PTd3*mvz@ z;L454r#97Ep_`CXdPU2agvD7d`8=15#xpjzR|-r89l)Vck7qh@?DIjj<^i? zEWjkTTj1KjwtXyL5^k;Nlm$^W>i-PrQY3|?88is)=5xDKJWfw3x0Sb)m#`?)Sg}ul z^+0Bn=M?ubcth0+t0j}!p%^d#`;0CP-{#Jcc`ZKfO>b1HgmwLW38N$Nd{r-iRUb8Z z!VA}f*b&%4?os5G1Kuu>raNa`FBB9yde8apdVWWC)RZb8dz3a=I*`>m{1nc%0&kjs z2@2uV!)&Wxd+~f=4nsHYo7h-3&mb5O3%ml~ak>4_Efs$v*%Wpr?A`uwRkwa=Q%ugy z!S4QXZ{6?T?c*5(qEzepfs2evIcDneJ%3K!W&h>uSQhKkpxCDM;!gMO2XjK!CDdXG z?Dxv%y*8JoK+WrMvhl<}ZgMy8LcJ#LQ_eCPaI4mriqfc?tQ>qJ{=vE}>3Xya(}D+! zvl8D|xp;;}_{MbSGjB;Lh`~kvt0RP4fd|CJ?Iz}Xb+%pUbBFh%xy~MHqPFZDTmdc& xhtSi(Sb?Xu`n2L#8WGDr1)6D_ejKF_1Wr7zbo8QyfBaj?e*uNI&h-EQ literal 0 HcmV?d00001 diff --git a/tests/fixtures/icon.png b/tests/fixtures/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a9fa88aad8d042b77d6fba0a657d3bcbe17588a0 GIT binary patch literal 6678 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 Date: Fri, 21 Apr 2023 19:51:50 +0100 Subject: [PATCH 02/13] Fix PHP versions. --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9e4e40b..4ae6714 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,6 @@ name: PHPUnit Tests on Multiple PHP Versions -on: [ push ] +on: [ push, pull_request ] jobs: tests: @@ -8,7 +8,7 @@ jobs: strategy: matrix: - php: [ "7.1", "7.4", "8.0", "8.2" ] + php: [ "7.3", "7.4", "8.0", "8.2" ] steps: - name: Checkout code @@ -24,4 +24,4 @@ jobs: run: composer install --prefer-dist --no-progress --no-interaction - name: Run PHPUnit - run: vendor/bin/phpunit \ No newline at end of file + run: vendor/bin/phpunit tests \ No newline at end of file From e399d8eb35985de0706085b3c29cb02fb24ffddf Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 19:55:49 +0100 Subject: [PATCH 03/13] Testing our workflow. --- .github/workflows/test.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4ae6714..56947a0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,8 +7,9 @@ jobs: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - php: [ "7.3", "7.4", "8.0", "8.2" ] + php: [ "7.4", "8.0", "8.1", "8.2" ] steps: - name: Checkout code @@ -23,5 +24,8 @@ jobs: - name: Install Composer dependencies run: composer install --prefer-dist --no-progress --no-interaction + - name: Check PHP version + run: php -v + - name: Run PHPUnit - run: vendor/bin/phpunit tests \ No newline at end of file + run: vendor/bin/phpunit tests --coverage-text \ No newline at end of file From 48f24d73e646e67f731cd8928020a72f62083c8c Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:08:38 +0100 Subject: [PATCH 04/13] Try adding error. --- .github/workflows/test.yml | 12 +++++++++--- src/PKPass.php | 11 +++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 56947a0..d303f67 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,13 @@ jobs: - name: Checkout code uses: actions/checkout@v2 +# - name: Use OpenSSL legacy mode +# run: | +# cp /etc/ssl/openssl.cnf openssl.cnf +# sed -i '/^default = default_sect/a legacy = legacy_sect' openssl.cnf +# sed -i '/^\[default_sect\]/a activate = 1' openssl.cnf +# printf "[legacy_sect]\nactivate = 1" >> openssl.cnf + - name: Set up PHP uses: shivammathur/setup-php@v2 with: @@ -24,8 +31,7 @@ jobs: - name: Install Composer dependencies run: composer install --prefer-dist --no-progress --no-interaction - - name: Check PHP version - run: php -v - - name: Run PHPUnit +# env: +# OPENSSL_CONF: openssl.cnf run: vendor/bin/phpunit tests --coverage-text \ No newline at end of file diff --git a/src/PKPass.php b/src/PKPass.php index 902a9a6..e7dec61 100644 --- a/src/PKPass.php +++ b/src/PKPass.php @@ -435,6 +435,13 @@ protected function createSignature($manifest) $certs = []; if (!openssl_pkcs12_read($pkcs12, $certs, $this->certPass)) { + if (strstr(openssl_error_string(), 'digital envelope routines::unsupported')) { + throw new PKPassException( + 'Could not read certificate file. This might be related ' . + 'to using an OpenSSL version that has deprecated some older ' . + 'hashes. More info here: https://schof.link/2Et6z3m' + ); + } throw new PKPassException( 'Invalid certificate file. Make sure you have a ' . 'P12 certificate that also contains a private key, and you ' . @@ -506,11 +513,11 @@ protected function createZip($manifest, $signature) $download_file = file_get_contents($url); $zip->addFromString($name, $download_file); } - + foreach ($this->files_content as $name => $content) { $zip->addFromString($name, $content); } - + $zip->close(); if (!file_exists($filename) || filesize($filename) < 1) { From 2b314d111038b0d42b352b9ff3e4c6b89f0fcc88 Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:09:36 +0100 Subject: [PATCH 05/13] Try seeing if updating OpenSSL config actually helps. --- .github/workflows/test.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d303f67..fd8f68d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,12 +15,12 @@ jobs: - name: Checkout code uses: actions/checkout@v2 -# - name: Use OpenSSL legacy mode -# run: | -# cp /etc/ssl/openssl.cnf openssl.cnf -# sed -i '/^default = default_sect/a legacy = legacy_sect' openssl.cnf -# sed -i '/^\[default_sect\]/a activate = 1' openssl.cnf -# printf "[legacy_sect]\nactivate = 1" >> openssl.cnf + - name: Use OpenSSL legacy mode + run: | + cp /etc/ssl/openssl.cnf openssl.cnf + sed -i '/^default = default_sect/a legacy = legacy_sect' openssl.cnf + sed -i '/^\[default_sect\]/a activate = 1' openssl.cnf + printf "[legacy_sect]\nactivate = 1" >> openssl.cnf - name: Set up PHP uses: shivammathur/setup-php@v2 @@ -32,6 +32,6 @@ jobs: run: composer install --prefer-dist --no-progress --no-interaction - name: Run PHPUnit -# env: -# OPENSSL_CONF: openssl.cnf + env: + OPENSSL_CONF: openssl.cnf run: vendor/bin/phpunit tests --coverage-text \ No newline at end of file From dc48c4ef9abc7c897da661c067bb1468ed92a7dc Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:10:49 +0100 Subject: [PATCH 06/13] Debugging. --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fd8f68d..5fa9a61 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,6 +21,7 @@ jobs: sed -i '/^default = default_sect/a legacy = legacy_sect' openssl.cnf sed -i '/^\[default_sect\]/a activate = 1' openssl.cnf printf "[legacy_sect]\nactivate = 1" >> openssl.cnf + cat openssl.cnf - name: Set up PHP uses: shivammathur/setup-php@v2 @@ -33,5 +34,5 @@ jobs: - name: Run PHPUnit env: - OPENSSL_CONF: openssl.cnf + OPENSSL_CONF: ./openssl.cnf run: vendor/bin/phpunit tests --coverage-text \ No newline at end of file From 6da294dc35804b3b2c3e3a4ffcc05eae3f116e27 Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:12:49 +0100 Subject: [PATCH 07/13] Alternative attempt. --- .github/workflows/test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5fa9a61..b81db5b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,10 +17,7 @@ jobs: - name: Use OpenSSL legacy mode run: | - cp /etc/ssl/openssl.cnf openssl.cnf - sed -i '/^default = default_sect/a legacy = legacy_sect' openssl.cnf - sed -i '/^\[default_sect\]/a activate = 1' openssl.cnf - printf "[legacy_sect]\nactivate = 1" >> openssl.cnf + echo "openssl_conf = openssl_init\n[openssl_init]\nproviders = provider_sect\n[provider_sect]\ndefault = default_sect\nlegacy = legacy_sect\n[default_sect]\nactivate = 1\n[legacy_sect]\nactivate = 1" > openssl.cnf cat openssl.cnf - name: Set up PHP From 20e58034a31f413631bdf689253751ec431386b8 Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:14:06 +0100 Subject: [PATCH 08/13] Fix OpenSSL config. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b81db5b..99a39c5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: - name: Use OpenSSL legacy mode run: | - echo "openssl_conf = openssl_init\n[openssl_init]\nproviders = provider_sect\n[provider_sect]\ndefault = default_sect\nlegacy = legacy_sect\n[default_sect]\nactivate = 1\n[legacy_sect]\nactivate = 1" > openssl.cnf + printf "openssl_conf = openssl_init\n[openssl_init]\nproviders = provider_sect\n[provider_sect]\ndefault = default_sect\nlegacy = legacy_sect\n[default_sect]\nactivate = 1\n[legacy_sect]\nactivate = 1" > openssl.cnf cat openssl.cnf - name: Set up PHP From 1247dce19c8cb692e20b42d993369b7b65ded562 Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:15:52 +0100 Subject: [PATCH 09/13] Fix OpenSSL config. --- src/PKPass.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/PKPass.php b/src/PKPass.php index e7dec61..2d598e2 100644 --- a/src/PKPass.php +++ b/src/PKPass.php @@ -435,11 +435,16 @@ protected function createSignature($manifest) $certs = []; if (!openssl_pkcs12_read($pkcs12, $certs, $this->certPass)) { - if (strstr(openssl_error_string(), 'digital envelope routines::unsupported')) { + $error = ''; + while ($text = openssl_error_string()) { + $error .= $text; + } + if (strstr($error, 'digital envelope routines::unsupported')) { throw new PKPassException( 'Could not read certificate file. This might be related ' . 'to using an OpenSSL version that has deprecated some older ' . - 'hashes. More info here: https://schof.link/2Et6z3m' + 'hashes. More info here: https://schof.link/2Et6z3m\n\n' . + 'OpenSSL error: ' . $error ); } throw new PKPassException( From 214022d1aced59d2eca93246c527d82fa51de06f Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:40:17 +0100 Subject: [PATCH 10/13] Adding alternative way for p12 reading. --- .github/workflows/test.yml | 3 +- src/PKPass.php | 85 ++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 99a39c5..521fb91 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,6 +19,7 @@ jobs: run: | printf "openssl_conf = openssl_init\n[openssl_init]\nproviders = provider_sect\n[provider_sect]\ndefault = default_sect\nlegacy = legacy_sect\n[default_sect]\nactivate = 1\n[legacy_sect]\nactivate = 1" > openssl.cnf cat openssl.cnf + export OPENSSL_CONF=openssl.cnf - name: Set up PHP uses: shivammathur/setup-php@v2 @@ -30,6 +31,4 @@ jobs: run: composer install --prefer-dist --no-progress --no-interaction - name: Run PHPUnit - env: - OPENSSL_CONF: ./openssl.cnf run: vendor/bin/phpunit tests --coverage-text \ No newline at end of file diff --git a/src/PKPass.php b/src/PKPass.php index 2d598e2..b8e1e45 100644 --- a/src/PKPass.php +++ b/src/PKPass.php @@ -418,41 +418,82 @@ protected function convertPEMtoDER($signature) } /** - * Creates a signature and saves it. + * Read a PKCS12 certificate string and turn it into an array. * - * @param string $manifest + * @return array * @throws PKPassException */ - protected function createSignature($manifest) + protected function readP12() { - $manifest_path = tempnam($this->tempPath, 'pkpass'); - $signature_path = tempnam($this->tempPath, 'pkpass'); - file_put_contents($manifest_path, $manifest); - + // Use the built-in reader first if (!$pkcs12 = file_get_contents($this->certPath)) { throw new PKPassException('Could not read the certificate.'); } - $certs = []; - if (!openssl_pkcs12_read($pkcs12, $certs, $this->certPass)) { - $error = ''; - while ($text = openssl_error_string()) { - $error .= $text; - } - if (strstr($error, 'digital envelope routines::unsupported')) { - throw new PKPassException( - 'Could not read certificate file. This might be related ' . - 'to using an OpenSSL version that has deprecated some older ' . - 'hashes. More info here: https://schof.link/2Et6z3m\n\n' . - 'OpenSSL error: ' . $error - ); - } + if (openssl_pkcs12_read($pkcs12, $certs, $this->certPass)) { + return $certs; + } + + // That failed, let's check why + $error = ''; + while ($text = openssl_error_string()) { + $error .= $text; + } + + // General error + if (!strstr($error, 'digital envelope routines::unsupported')) { throw new PKPassException( 'Invalid certificate file. Make sure you have a ' . 'P12 certificate that also contains a private key, and you ' . - 'have specified the correct password!' + 'have specified the correct password!' . PHP_EOL . PHP_EOL . + 'OpenSSL error: ' . $error ); } + + // Try an alternative route using shell_exec + try { + $value = @shell_exec( + "openssl pkcs12 -in " . escapeshellarg($this->certPath) . + " -passin " . escapeshellarg("pass:" . $this->certPass) . + " -passout " . escapeshellarg("pass:" . $this->certPass) . + " -legacy" + ); + if ($value) { + $cert = substr($value, strpos($value, '-----BEGIN CERTIFICATE-----')); + $cert = substr($cert, 0, strpos($cert, '-----END CERTIFICATE-----') + 25); + $key = substr($value, strpos($value, '-----BEGIN ENCRYPTED PRIVATE KEY-----')); + $key = substr($key, 0, strpos($key, '-----END ENCRYPTED PRIVATE KEY-----') + 35); + if (strlen($cert) > 0 && strlen($key) > 0) { + $certs['cert'] = $cert; + $certs['pkey'] = $key; + return $certs; + } + } + } catch (\Throwable $e) { + // no need to do anything + } + + throw new PKPassException( + 'Could not read certificate file. This might be related ' . + 'to using an OpenSSL version that has deprecated some older ' . + 'hashes. More info here: https://schof.link/2Et6z3m ' . PHP_EOL . PHP_EOL . + 'OpenSSL error: ' . $error + ); + } + + /** + * Creates a signature and saves it. + * + * @param string $manifest + * @throws PKPassException + */ + protected function createSignature($manifest) + { + $manifest_path = tempnam($this->tempPath, 'pkpass'); + $signature_path = tempnam($this->tempPath, 'pkpass'); + file_put_contents($manifest_path, $manifest); + + $certs = $this->readP12(); $certdata = openssl_x509_read($certs['cert']); $privkey = openssl_pkey_get_private($certs['pkey'], $this->certPass); From 43f16090b85956d0446571d91d7aa7679c11ae67 Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:41:51 +0100 Subject: [PATCH 11/13] Run Github actions with both legacy OpenSSL and without. --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 521fb91..b1ae4ad 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,12 +10,14 @@ jobs: fail-fast: false matrix: php: [ "7.4", "8.0", "8.1", "8.2" ] + openssl_legacy: [ false, true ] steps: - name: Checkout code uses: actions/checkout@v2 - name: Use OpenSSL legacy mode + if: ${{ matrix.npm }} run: | printf "openssl_conf = openssl_init\n[openssl_init]\nproviders = provider_sect\n[provider_sect]\ndefault = default_sect\nlegacy = legacy_sect\n[default_sect]\nactivate = 1\n[legacy_sect]\nactivate = 1" > openssl.cnf cat openssl.cnf From 7ab593688d0ed1d9f216070a5504fa4f7faf39c8 Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:43:44 +0100 Subject: [PATCH 12/13] Fix openssl legacy. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b1ae4ad..8bd3769 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@v2 - name: Use OpenSSL legacy mode - if: ${{ matrix.npm }} + if: ${{ matrix.openssl_legacy }} run: | printf "openssl_conf = openssl_init\n[openssl_init]\nproviders = provider_sect\n[provider_sect]\ndefault = default_sect\nlegacy = legacy_sect\n[default_sect]\nactivate = 1\n[legacy_sect]\nactivate = 1" > openssl.cnf cat openssl.cnf From c0675cf8032e0891f6399636be07a6ea6d6e4892 Mon Sep 17 00:00:00 2001 From: Thomas Schoffelen Date: Fri, 21 Apr 2023 20:46:08 +0100 Subject: [PATCH 13/13] Update readme. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 80bf403..6a47627 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,10 @@ left, you can select your iPhone. You will then be able to inspect any errors th ## Changelog +**Version 2.1.0 - April 2023** + +* Add alternative method for extracting P12 contents to circumvent issues in recent versions of OpenSSL. + **Version 2.0.2 - October 2022** * Switch to `ZipArchive::OVERWRITE` method of opening ZIP due to PHP 8 deprecation ([#120](https://github.com/includable/php-pkpass/pull/120)).