Skip to content

Commit 9c6945d

Browse files
authored
Merge pull request #19 from JSignPdf/fix/prevent-error-when-read-old-cert
fix: prevent error when read legacy cert
2 parents 58c9be3 + 2db25ae commit 9c6945d

1 file changed

Lines changed: 47 additions & 2 deletions

File tree

src/Sign/JSignService.php

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,57 @@ private function throwIf($condition, $message)
136136

137137
private function isPasswordCertificateValid($certificate, $password)
138138
{
139-
return openssl_pkcs12_read($certificate, $certInfo, $password);
139+
return $this->pkcs12Read($certificate, $password);
140+
}
141+
142+
/**
143+
* Prevent error to read certificate generated with old version of
144+
* openssl and using a newest version of openssl.
145+
*
146+
* To check the password is necessary to repack the certificate using
147+
* openssl command. If the command don't exists, will consider that
148+
* the password is invalid.
149+
*
150+
* Reference:
151+
*
152+
* https://github.com/php/php-src/issues/12128
153+
* https://www.php.net/manual/en/function.openssl-pkcs12-read.php#128992
154+
*/
155+
private function pkcs12Read($certificate, $password)
156+
{
157+
if (openssl_pkcs12_read($certificate, $certInfo, $password)) {
158+
return $certInfo;
159+
}
160+
$msg = openssl_error_string();
161+
if ($msg === 'error:0308010C:digital envelope routines::unsupported') {
162+
if (!shell_exec('openssl version')) {
163+
return [];
164+
}
165+
$tempPassword = tempnam(sys_get_temp_dir(), 'pfx');
166+
$tempEncriptedOriginal = tempnam(sys_get_temp_dir(), 'original');
167+
$tempEncriptedRepacked = tempnam(sys_get_temp_dir(), 'repacked');
168+
$tempDecrypted = tempnam(sys_get_temp_dir(), 'decripted');
169+
file_put_contents($tempPassword, $password);
170+
file_put_contents($tempEncriptedOriginal, $certificate);
171+
shell_exec(<<<REPACK_COMMAND
172+
cat $tempPassword | openssl pkcs12 -legacy -in $tempEncriptedOriginal -nodes -out $tempDecrypted -passin stdin &&
173+
cat $tempPassword | openssl pkcs12 -in $tempDecrypted -export -out $tempEncriptedRepacked -passout stdin
174+
REPACK_COMMAND
175+
);
176+
$certificateRepacked = file_get_contents($tempEncriptedRepacked);
177+
unlink($tempPassword);
178+
unlink($tempEncriptedOriginal);
179+
unlink($tempEncriptedRepacked);
180+
unlink($tempDecrypted);
181+
openssl_pkcs12_read($certificateRepacked, $certInfo, $password);
182+
return $certInfo;
183+
}
184+
return [];
140185
}
141186

142187
private function isExpiredCertificate($certificate, $password)
143188
{
144-
openssl_pkcs12_read($certificate, $certInfo, $password);
189+
$certInfo = $this->pkcs12Read($certificate, $password);
145190
$certificate = openssl_x509_parse($certInfo['cert']);
146191
$dateCert = date_create()->setTimestamp($certificate['validTo_time_t']);
147192
return $dateCert <= date_create();

0 commit comments

Comments
 (0)