Skip to content

Commit

Permalink
Adding alternative way for p12 reading.
Browse files Browse the repository at this point in the history
  • Loading branch information
tschoffelen committed Apr 21, 2023
1 parent 1247dce commit 214022d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 24 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Expand Up @@ -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
Expand All @@ -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
85 changes: 63 additions & 22 deletions src/PKPass.php
Expand Up @@ -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);

Expand Down

0 comments on commit 214022d

Please sign in to comment.