Complex classes like Pkcs12 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Pkcs12, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 20 | class Pkcs12 |
||
| 21 | { |
||
| 22 | /** |
||
| 23 | * Path para o diretorio onde o arquivo pfx está localizado |
||
| 24 | * @var string |
||
| 25 | */ |
||
| 26 | public $pathCerts = ''; |
||
| 27 | |||
| 28 | /** |
||
| 29 | * Path para o arquivo pfx (certificado digital em formato de transporte) |
||
| 30 | * @var string |
||
| 31 | */ |
||
| 32 | public $pfxFileName = ''; |
||
| 33 | |||
| 34 | /** |
||
| 35 | * Conteudo do arquivo pfx |
||
| 36 | * @var string |
||
| 37 | */ |
||
| 38 | public $pfxCert = ''; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * Numero do CNPJ do emitente |
||
| 42 | * @var string |
||
| 43 | */ |
||
| 44 | public $cnpj = ''; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * String que contêm a chave publica em formato PEM |
||
| 48 | * @var string |
||
| 49 | */ |
||
| 50 | public $pubKey = ''; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * String quem contêm a chave privada em formato PEM |
||
| 54 | * @var string |
||
| 55 | */ |
||
| 56 | public $priKey = ''; |
||
| 57 | |||
| 58 | /** |
||
| 59 | * String que conten a combinação da chave publica e privada em formato PEM |
||
| 60 | * e a cadeida completa de certificação caso exista |
||
| 61 | * @var string |
||
| 62 | */ |
||
| 63 | public $certKey = ''; |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Flag para ignorar testes de validade do certificado |
||
| 67 | * isso é usado apenas para fins de testes |
||
| 68 | * @var boolean |
||
| 69 | */ |
||
| 70 | public $ignoreValidCert = false; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * Path para a chave publica em arquivo |
||
| 74 | * @var string |
||
| 75 | */ |
||
| 76 | public $pubKeyFile = ''; |
||
| 77 | |||
| 78 | /** |
||
| 79 | * Path para a chave privada em arquivo |
||
| 80 | * @var string |
||
| 81 | */ |
||
| 82 | public $priKeyFile = ''; |
||
| 83 | |||
| 84 | /** |
||
| 85 | * Path para o certificado em arquivo |
||
| 86 | * @var string |
||
| 87 | */ |
||
| 88 | public $certKeyFile = ''; |
||
| 89 | |||
| 90 | /** |
||
| 91 | * Timestamp da data de validade do certificado |
||
| 92 | * @var float |
||
| 93 | */ |
||
| 94 | public $expireTimestamp = 0; |
||
| 95 | |||
| 96 | /** |
||
| 97 | * CNPJ do certificado |
||
| 98 | * @var string |
||
| 99 | */ |
||
| 100 | public $cnpjCert = ''; |
||
| 101 | |||
| 102 | /** |
||
| 103 | * Mensagem de erro da classe |
||
| 104 | * @var string |
||
| 105 | */ |
||
| 106 | public $error = ''; |
||
| 107 | |||
| 108 | /** |
||
| 109 | * Id do documento sendo assinado |
||
| 110 | * @var string |
||
| 111 | */ |
||
| 112 | public $docId = ''; |
||
| 113 | |||
| 114 | /** |
||
| 115 | * Método de construção da classe |
||
| 116 | * @param string $pathCerts Path para a pasta que contêm os certificados digitais |
||
| 117 | * @param string $cnpj CNPJ do emitente, sem ./-, apenas os numeros |
||
| 118 | * @param string $pubKey Chave publica em formato PEM, não o path mas a chave em si |
||
| 119 | * @param string $priKey Chave privada em formato PEM, não o path mas a chave em si |
||
| 120 | * @param string $certKey Certificado em formato PEM, não o path mas a chave em si |
||
| 121 | * @param bool $ignoreValidCert |
||
| 122 | * @param boolean $ignoreValidCert Ignora a validade do certificado, mais usado para fins de teste |
||
| 123 | */ |
||
| 124 | 24 | public function __construct( |
|
| 162 | |||
| 163 | /** |
||
| 164 | * zInit |
||
| 165 | * Método de inicialização da classe irá verificar |
||
| 166 | * os parâmetros, arquivos e validade dos mesmos |
||
| 167 | * Em caso de erro o motivo da falha será indicada na parâmetro |
||
| 168 | * error da classe, os outros parâmetros serão limpos e os |
||
| 169 | * arquivos inválidos serão removidos da pasta |
||
| 170 | * @param boolean $flagCert indica que as chaves já foram passas como strings |
||
| 171 | * @return boolean |
||
| 172 | */ |
||
| 173 | 21 | private function zInit($flagCert = false) |
|
| 174 | { |
||
| 175 | //se as chaves foram passadas na forma de strings então verificar a validade |
||
| 176 | 21 | if ($flagCert) { |
|
| 177 | //já que o certificado existe, verificar seu prazo de validade |
||
| 178 | //o certificado será removido se estiver vencido |
||
| 179 | 9 | return $this->zValidCerts($this->pubKey); |
|
| 180 | } else { |
||
| 181 | 12 | if (substr($this->pathCerts, -1) !== DIRECTORY_SEPARATOR) { |
|
| 182 | $this->pathCerts .= DIRECTORY_SEPARATOR; |
||
| 183 | } |
||
| 184 | //monta o path completo com o nome da chave privada |
||
| 185 | 12 | $this->priKeyFile = $this->pathCerts.$this->cnpj.'_priKEY.pem'; |
|
| 186 | //monta o path completo com o nome da chave publica |
||
| 187 | 12 | $this->pubKeyFile = $this->pathCerts.$this->cnpj.'_pubKEY.pem'; |
|
| 188 | //monta o path completo com o nome do certificado (chave publica e privada) em formato pem |
||
| 189 | 12 | $this->certKeyFile = $this->pathCerts.$this->cnpj.'_certKEY.pem'; |
|
| 190 | //se as chaves não foram passadas em strings, verifica se os certificados existem |
||
| 191 | 12 | if (is_file($this->priKeyFile) && is_file($this->pubKeyFile) && is_file($this->certKeyFile)) { |
|
| 192 | //se as chaves existem deve ser verificado sua validade |
||
| 193 | $this->pubKey = file_get_contents($this->pubKeyFile); |
||
| 194 | $this->priKey = file_get_contents($this->priKeyFile); |
||
| 195 | $this->certKey = file_get_contents($this->certKeyFile); |
||
| 196 | //já que o certificado existe, verificar seu prazo de validade |
||
| 197 | return $this->zValidCerts($this->pubKey); |
||
| 198 | } |
||
| 199 | } |
||
| 200 | 12 | return true; |
|
| 201 | } |
||
| 202 | |||
| 203 | /** |
||
| 204 | * loadPfxFile |
||
| 205 | * @param string $pathPfx caminho completo para o arquivo pfx |
||
| 206 | * @param string $password senha para abrir o certificado pfx |
||
| 207 | * @param bool $createFiles |
||
| 208 | * @param bool $ignoreValidity |
||
| 209 | * @param bool $ignoreOwner |
||
| 210 | * @return bool |
||
| 211 | */ |
||
| 212 | 3 | public function loadPfxFile( |
|
| 227 | |||
| 228 | /** |
||
| 229 | * loadPfx |
||
| 230 | * Carrega um novo certificado no formato PFX |
||
| 231 | * Isso deverá ocorrer a cada atualização do certificado digital, ou seja, |
||
| 232 | * pelo menos uma vez por ano, uma vez que a validade do certificado |
||
| 233 | * é anual. |
||
| 234 | * Será verificado também se o certificado pertence realmente ao CNPJ |
||
| 235 | * Essa verificação checa apenas se o certificado pertence a matriz ou filial |
||
| 236 | * comparando apenas os primeiros 8 digitos do CNPJ, dessa forma ambas a |
||
| 237 | * matriz e as filiais poderão usar o mesmo certificado indicado na instanciação |
||
| 238 | * da classe, se não for um erro irá ocorrer e |
||
| 239 | * o certificado não será convertido para o formato PEM. |
||
| 240 | * Em caso de erros, será retornado false e o motivo será indicado no |
||
| 241 | * parâmetro error da classe. |
||
| 242 | * Os certificados serão armazenados como <CNPJ>-<tipo>.pem |
||
| 243 | * @param string $pfxContent arquivo PFX |
||
| 244 | * @param string $password Senha de acesso ao certificado PFX |
||
| 245 | * @param boolean $createFiles se true irá criar os arquivos pem das chaves digitais, caso contrario não |
||
| 246 | * @param bool $ignoreValidity |
||
| 247 | * @param bool $ignoreOwner |
||
| 248 | * @return bool |
||
| 249 | */ |
||
| 250 | 9 | public function loadPfx( |
|
| 251 | $pfxContent = '', |
||
| 252 | $password = '', |
||
| 253 | $createFiles = true, |
||
| 254 | $ignoreValidity = false, |
||
| 255 | $ignoreOwner = false |
||
| 256 | ) { |
||
| 257 | 9 | $this->ignoreValidCert = $ignoreValidity; |
|
| 258 | 9 | if ($password == '') { |
|
| 259 | throw new Exception\InvalidArgumentException( |
||
| 260 | "A senha de acesso para o certificado pfx não pode ser vazia." |
||
| 261 | ); |
||
| 262 | } |
||
| 263 | //carrega os certificados e chaves para um array denominado $x509certdata |
||
| 264 | 9 | $x509certdata = array(); |
|
| 265 | 9 | if (!openssl_pkcs12_read($pfxContent, $x509certdata, $password)) { |
|
| 266 | throw new Exception\RuntimeException( |
||
| 267 | "O certificado não pode ser lido!! Senha errada ou arquivo corrompido ou formato inválido!!" |
||
| 268 | ); |
||
| 269 | } |
||
| 270 | 9 | $this->pfxCert = $pfxContent; |
|
| 271 | //verifica sua data de validade |
||
| 272 | 9 | if (! $this->zValidCerts($x509certdata['cert'])) { |
|
| 273 | throw new Exception\RuntimeException($this->error); |
||
| 274 | } |
||
| 275 | 9 | $this->cnpjCert = Asn::getCNPJCert($x509certdata['cert']); |
|
| 276 | 9 | if (!$ignoreOwner) { |
|
| 277 | 3 | if (substr($this->cnpj, 0, 8) != substr($this->cnpjCert, 0, 8)) { |
|
| 278 | 3 | throw new Exception\InvalidArgumentException( |
|
| 279 | "O Certificado fornecido pertence a outro CNPJ!!" |
||
| 280 | 3 | ); |
|
| 281 | } |
||
| 282 | } |
||
| 283 | //monta o path completo com o nome da chave privada |
||
| 284 | 6 | $this->priKeyFile = $this->pathCerts.$this->cnpj.'_priKEY.pem'; |
|
| 285 | //monta o path completo com o nome da chave publica |
||
| 286 | 6 | $this->pubKeyFile = $this->pathCerts.$this->cnpj.'_pubKEY.pem'; |
|
| 287 | //monta o path completo com o nome do certificado (chave publica e privada) em formato pem |
||
| 288 | 6 | $this->certKeyFile = $this->pathCerts.$this->cnpj.'_certKEY.pem'; |
|
| 289 | 6 | $this->zRemovePemFiles(); |
|
| 290 | 6 | if ($createFiles) { |
|
| 291 | $this->zSavePemFiles($x509certdata); |
||
| 292 | } |
||
| 293 | 6 | $this->pubKey=$x509certdata['cert']; |
|
| 294 | 6 | $this->priKey=$x509certdata['pkey']; |
|
| 295 | 6 | $this->certKey=$x509certdata['pkey']."\r\n".$x509certdata['cert']; |
|
| 296 | 6 | return true; |
|
| 297 | } |
||
| 298 | |||
| 299 | /** |
||
| 300 | * zSavePemFiles |
||
| 301 | * @param array $x509certdata |
||
| 302 | * @throws Exception\InvalidArgumentException |
||
| 303 | * @throws Exception\RuntimeException |
||
| 304 | */ |
||
| 305 | private function zSavePemFiles($x509certdata) |
||
| 326 | |||
| 327 | /** |
||
| 328 | * Retorna o timestamp da validade do certificado |
||
| 329 | * @return int |
||
| 330 | */ |
||
| 331 | public function getValidate() |
||
| 335 | |||
| 336 | /** |
||
| 337 | * Retorna o CNPJ do certificado |
||
| 338 | * @return string |
||
| 339 | */ |
||
| 340 | public function getCNPJCert() |
||
| 344 | |||
| 345 | /** |
||
| 346 | * aadChain |
||
| 347 | * @param array $aCerts Array com os caminhos completos para cada certificado da cadeia |
||
| 348 | * ou um array com o conteúdo desses certificados |
||
| 349 | * @return void |
||
| 350 | */ |
||
| 351 | 3 | public function aadChain($aCerts = array()) |
|
| 369 | |||
| 370 | /** |
||
| 371 | * signXML |
||
| 372 | * @param string $docxml |
||
| 373 | * @param string $tagid |
||
| 374 | * @param string $marcador |
||
| 375 | * @param string $algorithm |
||
| 376 | * @return string xml assinado |
||
| 377 | * @throws Exception\InvalidArgumentException |
||
| 378 | * @throws Exception\RuntimeException |
||
| 379 | */ |
||
| 380 | 3 | public function signXML($docxml, $tagid = '', $marcador = 'Id', $algorithm = 'SHA1') |
|
| 426 | |||
| 427 | /** |
||
| 428 | * zSignXML |
||
| 429 | * Método que provê a assinatura do xml conforme padrão SEFAZ |
||
| 430 | * @param DOMDocument $xmldoc |
||
| 431 | * @param DOMElement $root |
||
| 432 | * @param DOMElement $node |
||
| 433 | * @param resource $objSSLPriKey |
||
| 434 | * @param string $marcador |
||
| 435 | * @param string $algorithm |
||
| 436 | * @return string xml assinado |
||
| 437 | * @internal param DOMDocument $xmlDoc |
||
| 438 | */ |
||
| 439 | 3 | private function zSignXML($xmldoc, $root, $node, $objSSLPriKey, $marcador, $algorithm = 'SHA1') |
|
| 556 | |||
| 557 | /** |
||
| 558 | * signatureExists |
||
| 559 | * Check se o xml possi a tag Signature |
||
| 560 | * @param DOMDocument $dom |
||
| 561 | * @return boolean |
||
| 562 | */ |
||
| 563 | 6 | private function zSignatureExists($dom) |
|
| 571 | |||
| 572 | /** |
||
| 573 | * verifySignature |
||
| 574 | * Verifica a validade da assinatura digital contida no xml |
||
| 575 | * @param string $docxml conteudo do xml a ser verificado ou o path completo |
||
| 576 | * @param string $tagid tag que foi assinada no documento xml |
||
| 577 | * @return boolean |
||
| 578 | * @throws Exception\InvalidArgumentException |
||
| 579 | * @throws Exception\RuntimeException |
||
| 580 | */ |
||
| 581 | 3 | public function verifySignature($docxml = '', $tagid = '') |
|
| 601 | |||
| 602 | /** |
||
| 603 | * zSignCheck |
||
| 604 | * @param DOMDocument $dom |
||
| 605 | * @return boolean |
||
| 606 | * @throws Exception\RuntimeException |
||
| 607 | */ |
||
| 608 | 3 | private function zSignCheck($dom) |
|
| 641 | |||
| 642 | /** |
||
| 643 | * zDigCheck |
||
| 644 | * @param DOMDocument $dom |
||
| 645 | * @param string $tagid |
||
| 646 | * @return boolean |
||
| 647 | * @throws Exception\RuntimeException |
||
| 648 | */ |
||
| 649 | 3 | private function zDigCheck($dom, $tagid = '') |
|
| 684 | |||
| 685 | /** |
||
| 686 | * zValidCerts |
||
| 687 | * Verifica a data de validade do certificado digital |
||
| 688 | * e compara com a data de hoje. |
||
| 689 | * Caso o certificado tenha expirado o mesmo será removido das |
||
| 690 | * pastas e o método irá retornar false. |
||
| 691 | * @param string $pubKey chave publica |
||
| 692 | * @return boolean |
||
| 693 | */ |
||
| 694 | 18 | protected function zValidCerts($pubKey) |
|
| 721 | |||
| 722 | /** |
||
| 723 | * zCleanPubKey |
||
| 724 | * Remove a informação de inicio e fim do certificado |
||
| 725 | * contido no formato PEM, deixando o certificado (chave publica) pronta para ser |
||
| 726 | * anexada ao xml da NFe |
||
| 727 | * @return string contendo o certificado limpo |
||
| 728 | */ |
||
| 729 | 3 | protected function zCleanPubKey() |
|
| 747 | |||
| 748 | /** |
||
| 749 | * zSplitLines |
||
| 750 | * Divide a string do certificado publico em linhas |
||
| 751 | * com 76 caracteres (padrão original) |
||
| 752 | * @param string $cntIn certificado |
||
| 753 | * @return string certificado reformatado |
||
| 754 | */ |
||
| 755 | 3 | protected function zSplitLines($cntIn = '') |
|
| 764 | |||
| 765 | /** |
||
| 766 | * zRemovePemFiles |
||
| 767 | * Apaga os arquivos PEM do diretório |
||
| 768 | * Isso deve ser feito quando um novo certificado é carregado |
||
| 769 | * ou quando a validade do certificado expirou. |
||
| 770 | */ |
||
| 771 | 18 | private function zRemovePemFiles() |
|
| 783 | |||
| 784 | /** |
||
| 785 | * zGetOpenSSLError |
||
| 786 | * @param string $msg |
||
| 787 | * @return string |
||
| 788 | */ |
||
| 789 | protected function zGetOpenSSLError($msg = '') |
||
| 796 | } |
||
| 797 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.