dados = array(); $this->dados_xml = ''; $this->apresentado = false; $this->erros_ssl = array(); $this->cert_assinante = ''; $this->msg_sem_assinatura = ''; $this->arquivos_para_deletar = array(); } public function __destruct() { #Remover arquivos temporarios..... deleta_arquivos_temporarios($this->arquivos_para_deletar); } # Recupera dados de um certificado no formato pem function certificado($certificado_pem) { if (!$certificado_pem) { $this->apresentado = False; return False; # Sem parametro ... } $this->dados = recupera_dados_do_ceritificado_digital($certificado_pem); $this->dados_xml = gera_xml_com_dados_do_certificado($this->dados); # Certificado foi processado, as informacoes obtidas estao em $this->dados. $this->apresentado = true; } # Encriptar senha ...... public function encriptar_senha($s,$c) { if($s == '') return false; if($c == '') return false; $senha_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar); //echo $senha_arquivo_temporario.'
'; if(!grava_arquivo($senha_arquivo_temporario,$s)) { return false; } $cert_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar); //echo $cert_arquivo_temporario.'
'; if(!grava_arquivo($cert_arquivo_temporario,$c)) { return false; } $senha_criptografada_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar); //echo $senha_criptografada_arquivo_temporario.'
'; $w = exec('openssl rsautl -in ' . $senha_arquivo_temporario . ' -out ' . $senha_criptografada_arquivo_temporario . ' -inkey ' . $cert_arquivo_temporario . ' -certin -pkcs -keyform PEM -encrypt',$saida); if(!file_exists($senha_criptografada_arquivo_temporario)) { deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return false; } # Recupera a senha criptada, binario..... $retorno = file_get_contents($senha_criptografada_arquivo_temporario); deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); //if(strlen($retorno) != 128) return false; return base64_encode($retorno); } # Encriptar uma msg($m) para o(s) destinatario(s) $c(array com certificados)com os headers passados em $h. public function encriptar($m,$c,$h) { if($m == '') return false; if(!is_array($c)) return false; $aux = count($c); if($aux < 1) return false; if(!is_array($h) ) return false; # Tem de verificar todos os certificados que serao utilizados para criptografar a msg.. # Inserir a rotina aqui.... $m_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar); //echo $m_arquivo_temporario.'
'; if(!grava_arquivo($m_arquivo_temporario,$m)) { return false; } $enc_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar); //echo $enc_arquivo_temporario.'
'; // LIMPA ERROS ... Pode ser um problema para outras aplicacoes que usam openssl(fonte de erros unica). while ($erro = openssl_error_string()); // Limpa buffer de erros anteriores...... $this->erros_ssl = array(); // Se he PHP 5.4 , ou maior, usar "OPENSSL_CIPHER_AES_256_CBC" . $cipher_id = ((double)phpversion() >= 5.4 ? OPENSSL_CIPHER_AES_256_CBC : OPENSSL_CIPHER_DES); $resultado = openssl_pkcs7_encrypt($m_arquivo_temporario,$enc_arquivo_temporario,$c,$h,$flags=0,$cipherid=$cipher_id); //$resultado = openssl_pkcs7_encrypt($m_arquivo_temporario,$enc_arquivo_temporario,$c,$h); if(!$resultado) { // Guarda msgs de erro ... while ($erro = openssl_error_string()) { $this->erros_ssl[] = $erro; } deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return false; } # Recupera a msg criptada...... $retorno = file_get_contents($enc_arquivo_temporario); deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return $retorno; } # Verifica uma msg($m) assinada... public function verificar($m) { if($m == '') { $this->erros_ssl[] = 'Não foi possível verificar a assinatura gerada. Contate o administrador'; return false; } if(!$m_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar)) { $this->erros_ssl[] = 'Não foi possível verificar a assinatura gerada. Contate o administrador'; $this->arquivos_para_deletar = array(); return false; } if(!grava_arquivo($m_arquivo_temporario,$m)) { $this->erros_ssl[] = 'Não foi possível verificar a assinatura gerada. Contate o administrador'; deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return false; } if(!$vrf_cert_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar)) { $this->erros_ssl[] = 'Não foi possível verificar a assinatura gerada. Contate o administrador'; $this->arquivos_para_deletar = array(); return false; } if(!$vrf_msg_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar)) { $this->erros_ssl[] = 'Não foi possível verificar a assinatura gerada. Contate o administrador'; $this->arquivos_para_deletar = array(); return false; } $this->erros_ssl = array(); while ($erro = openssl_error_string()); // Limpa buffer de erros anteriores...... $resultado = openssl_pkcs7_verify($m_arquivo_temporario,0, $vrf_cert_arquivo_temporario,array($GLOBALS['CAs']),$GLOBALS['CAs'],$vrf_msg_arquivo_temporario); if($resultado === -1) { $this->erros_ssl[] = 'Erro verificando assinatura. Contate o administrador'; while ($erro = openssl_error_string()) { $this->erros_ssl[] = $erro; } $retorno = false; } if($resultado === False) { while ($erro = openssl_error_string()) { if(substr($erro, 0,20) === 'error:21075075:PKCS7') { $this->erros_ssl = array(); while ($erro = openssl_error_string()); // Limpa buffer de erros anteriores...... $resultado = openssl_pkcs7_verify($m_arquivo_temporario,PKCS7_NOVERIFY, $vrf_cert_arquivo_temporario,array($GLOBALS['CAs']),$GLOBALS['CAs'],$vrf_msg_arquivo_temporario); break; } $this->erros_ssl[] = $erro; } } $retorno = true; if($resultado === False) { # Indica ocorrencia de erro ... $this->erros_ssl[] = 'Erro. '; $retorno = false; // Guarda msgs de erro ... while ($erro = openssl_error_string()) { $this->erros_ssl[] = $erro; } If(file_exists($vrf_msg_arquivo_temporario)) { $this->msg_sem_assinatura = file_get_contents($vrf_msg_arquivo_temporario); } else { $this->msg_sem_assinatura = 'Nao pode exibir a msg(CD-1)'; $this->erros_ssl[] = 'Nao pode exibir a msg(CD-1)'; } # Reexecuta o comando com um nivel menor de criticas. $this->cert_assinante = $this->extrai_certificado_da_msg_assinada($m); if(!$this->cert_assinante) { # Se nao foi possivel obter o certificado retorna com falso ..... If(file_exists($vrf_msg_arquivo_temporario)) { $this->msg_sem_assinatura = file_get_contents($vrf_msg_arquivo_temporario); } else { $this->msg_sem_assinatura = 'Nao pode exibir a msg(CD-2)'; $this->erros_ssl[] = 'Nao pode exibir a msg(CD-2)'; } deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return false; } } else { # Guarda o certificado usado para assinar a msg $this->cert_assinante = file_get_contents($vrf_cert_arquivo_temporario); } If(file_exists($vrf_msg_arquivo_temporario)) $this->msg_sem_assinatura = file_get_contents($vrf_msg_arquivo_temporario); $this->certificado($this->cert_assinante); if (!$this->apresentado) { $this->erros_ssl[] = 'Certificado da Msg nao pode ser tratado.'; $retorno = false; } else { while ($erro = openssl_error_string()); // Limpa buffer de erros anteriores...... # Certificado poderia ter assinado um email?? if(!($this->dados['KEYUSAGE']['digitalSignature'])) { $this->erros_ssl[] = 'Certificado nao poderia ter sido utilizado para assinar email.'; while ($erro = openssl_error_string()) { $this->erros_ssl[] = $erro; } $retorno = false; } $revogado = new Verifica_Certificado($this->dados,$this->cert_assinante); $this->dados['REVOGADO'] = false; if(!$revogado->status){ $this->erros_ssl[] = $revogado->msgerro; foreach ($revogado->erros_ssl as $item) { $this->erros_ssl[] = $item; } if ($revogado->revogado) $this->dados['REVOGADO'] = true; $retorno = false; } } deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return $retorno; } public function extrai_certificado_da_msg_assinada($m) { $retorno = false; if(!$m) { return $retorno; } $m_arquivo_temporario = gera_nome_arquivo_temporario(&$this->arquivos_para_deletar); if(!grava_arquivo($m_arquivo_temporario,$m)) { deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return $retorno; } $w=''; $saida = array(); $w = exec('cat ' . $m_arquivo_temporario . ' | openssl smime -pk7out | openssl pkcs7 -print_certs',$saida); if(!$w=='') { deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return $retorno; } $aux1 = ''; // gera uma unica string com o conteudo retornado pelo comando... foreach($saida as $linha) { $aux1 .= $linha.chr(0x0A); } // cria um array com os certificados retornados.. $aux2 = explode('-----BEGIN CERTIFICATE-----',$aux1); array_shift($aux2); // isolando certificados.. $aux5 = array(); foreach($aux2 as $item) { $aux3 = explode('-----END CERTIFICATE-----',$item); $aux4 = '-----BEGIN CERTIFICATE-----' . $aux3[0] . '-----END CERTIFICATE-----'; $aux5[] = $aux4; } // Testa qual dos certificados nao he uma CA .... foreach($aux5 as $item) { $Dados_cert = recupera_dados_do_ceritificado_digital($item); if(!$Dados_cert['CA']) { $retorno = $item; break; } } deleta_arquivos_temporarios($this->arquivos_para_deletar); $this->arquivos_para_deletar = array(); return $retorno; } } ?>