@@ -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