package gov.pr.celepar.tabeliao.client.autenticacao;
/*
Este programa � licenciado de acordo com a
LPG-AP (LICEN�A P�BLICA GERAL PARA PROGRAMAS DE COMPUTADOR DA ADMINISTRA��O P�BLICA),
vers�o 1.1 ou qualquer vers�o posterior.
A LPG-AP deve acompanhar todas PUBLICA��ES, DISTRIBUI��ES e REPRODU��ES deste Programa.
Caso uma c�pia da LPG-AP n�o esteja dispon�vel junto com este Programa, voc� pode contatar o LICENCIANTE ou ent�o acessar diretamente:
http://www.celepar.pr.gov.br/licenca/LPG-AP.pdf
Para poder USAR, PUBLICAR, DISTRIBUIR, REPRODUZIR ou ALTERAR este Programa
� preciso estar de acordo com os termos da LPG-AP
*/
import gov.pr.celepar.sentinela.client.SentinelaXml;
import gov.pr.celepar.sentinela.client.autenticacao.AutenticacaoInterface;
import gov.pr.celepar.sentinela.client.pojo.UsuarioAutenticado;
import gov.pr.celepar.sentinela.excecao.SentinelaException;
import gov.pr.celepar.tabeliao.core.TabeliaoCertificate;
import gov.pr.celepar.tabeliao.core.validacao.TabeliaoResultadoValidacao;
import gov.pr.celepar.tabeliao.facade.CertificadoFacade;
import gov.pr.celepar.tabeliao.pojo.CertificadoAc;
import gov.pr.celepar.tabeliao.pojo.CertificadoPublico;
import gov.pr.celepar.tabeliao.util.Base64Utils;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;
import net.sourceforge.jcetaglib.lib.X509Cert;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.jboss.logging.Logger;
/**
* Classe de autenticacao para uso com o proto-agente SENTINELA
* implementa gov.pr.celepar.sentinela.client.autenticacao.AutenticacaoInterface
* @author Thiago Meneghello - GIC/CELEPAR
* @author Emerson Sachio Saito (alteracoes) - GIC/CELEPAR
*
*/
public class AutenticacaoTabeliao implements AutenticacaoInterface {
private static Logger log = Logger.getLogger(AutenticacaoTabeliao.class);
// private static final String SESSION_CERTIFICADO = "TABELIAO_SESSION_CERTIFICADO";
private String nivelAcesso = null;
private String validaCadeiaCertificado = null;
private String validaLCR = null;
private String validaCertificadoExpirado = null;
private String validaNivelAcesso = null;
private static String diasMensagemExpirando = null;
private static String LCRTempo = null;
private static String LCRProxy = null;
private static String LCRProxyUsuario = null;
private static String LCRProxySenha = null;
private static String LCRProxyPorta = null;
/**
* Recupera o tempo de atualizacao das LCRs, configurado em sentinela.xml
* @return Tempo em milisegundos
*/
public static String getLCRTempo(){
return LCRTempo;
}
/**
* Recupera o endereco de proxy configurado em sentinela.xml
* @return endereco do proxy
*/
public static String getLCRProxy(){
return LCRProxy;
}
/**
* Recupera o usuario de proxy configurado em sentinela.xml
* @return nome do usuario do proxy
*/
public static String getLCRProxyUsuario(){
return LCRProxyUsuario;
}
/**
* Recupera a senha do usuario de proxy configurado em sentinela.xml
* @return senha do usuario do proxy
*/
public static String getLCRProxySenha(){
return LCRProxySenha;
}
/**
* Recupera o numero da porta usada pelo proxy configurado em sentinela.xml
* @return numero da porta usada pelo proxy
*/
public static String getLCRProxyPorta(){
return LCRProxyPorta;
}
/**
* retorna a quantidade de dias que a mensagem de aviso de expiracao eh emitida.
* @return numero de dias antes da expiracao do certificado
*/
public static String getDiasMensagemExpirando(){
return diasMensagemExpirando;
}
/**
* @param certificado
* @param CPF
* @param securityCode
* @param trocandoSenha
* @param arg5
* @param arg6
* @return UsuarioAutenticado
* @throws SentinelaException
* @see gov.pr.celepar.sentinela.client.pojo.UsuarioAutenticado
*/
@Override
@SuppressWarnings("unchecked")
public UsuarioAutenticado autentica(String certificado, String CPF, String securityCode, boolean trocandoSenha, String arg5, Long arg6) throws SentinelaException {
if(certificado == null) {
log.info("Exce��o: Sem Certificado");
throw new SentinelaException("A assinatura do usuario nao foi repassada para realizar a autenticacao.");
}
if(securityCode == null) {
log.info("Exce��o: Sem securityCode");
throw new SentinelaException("O sentinela nao repassou o securityCode para autenticacao.");
}
UsuarioTabeliao usuarioTabeliao = null;
log.info("Chamando metodo autentica AutenticacaoTabeliao");
try {
byte[] assinatura = Base64Utils.base64Decode(certificado);
CMSSignedData sig;
sig = new CMSSignedData(assinatura);
String uuidAssinado = new String((byte[]) sig.getSignedContent().getContent());
log.info("UUID da assinatura: " + uuidAssinado);
//UUID
if(! securityCode.equals(uuidAssinado)){
log.info("Exce��o: UUID diferentes");
throw new SentinelaException("Erro ao realizar a autenticacao.\nOs ids gerado e assinado nao sao iguais.");
}
X509Certificate cert = null;
CertStore certStore = sig.getCertificatesAndCRLs("Collection", "SUN");
SignerInformationStore sis = sig.getSignerInfos();
for(SignerInformation si : (Collection<SignerInformation>)sis.getSigners()) {
Collection<?> c2 = certStore.getCertificates(si.getSID());
Iterator<?> it2 = c2.iterator();
if(it2.hasNext()) {
cert = (X509Certificate) it2.next();
}
}
if(cert != null) {
log.info("Inst�ncia o Certificado no Tabeli�o.");
TabeliaoCertificate tc = new TabeliaoCertificate(cert);
log.info("Executa a valida��o da Cadeia do Certificado.");
TabeliaoResultadoValidacao tabResVal = tc.valida();
//Verifica a cadeia de certificados
try {
String valida = validaCadeiaCertificado;
if("1".equals(valida)) {
String res = tabResVal.getMensagem(TabeliaoResultadoValidacao.VAL_CADEIA);
log.info("Verificando a cadeia de certificados.");
if(TabeliaoResultadoValidacao.MSG_ERRO.equals(res)) {
log.info("Erro na cadeia");
throw new Exception(tabResVal.getDescricao(TabeliaoResultadoValidacao.VAL_CADEIA));
}
if(TabeliaoResultadoValidacao.MSG_EXCECAO.equals(res)) {
log.info("Exce��o para cadeia");
throw new Exception(tabResVal.getDescricao(TabeliaoResultadoValidacao.VAL_CADEIA));
}
} else {
log.info("Nao est� verificando a cadeia de certificados.");
}
} catch (Exception e) {
throw new SentinelaException("Erro ao realizar a autenticacao.\nEste certificado nao est� na cadeia de certificados ICP Brasil.", e);
}
//Verifica se o certificado esta revogado
try {
String valida = validaLCR;
if("1".equals(valida)) {
String res = tabResVal.getMensagem(TabeliaoResultadoValidacao.VAL_LCR);
log.info("Verificando lista na base ou web.");
if(TabeliaoResultadoValidacao.MSG_EXCECAO.equals(res)) {
log.info("Exce��o");
throw new Exception(tabResVal.getDescricao(TabeliaoResultadoValidacao.VAL_LCR));
}
log.info("Verificando se o certificado esta revogado.");
if(TabeliaoResultadoValidacao.MSG_ERRO.equals(res)) {
log.info("Certificado Revogado");
throw new Exception(tabResVal.getDescricao(TabeliaoResultadoValidacao.VAL_LCR));
}
log.info("Verificando se a lista est� atualizada.");
if(TabeliaoResultadoValidacao.MSG_AVISO.equals(res)) {
log.info("Aviso na LCR");
throw new Exception(tabResVal.getDescricao(TabeliaoResultadoValidacao.VAL_LCR));
}
} else {
log.info("Nao est� verificando se o certificado esta revogado.");
}
} catch (Exception e) {
throw new SentinelaException("Erro ao realizar a autenticacao.\n" +
"Problema encontrado ao validar LCR.", e);
}
//Verifica a validade do certificado
try {
String valida = validaCertificadoExpirado;
String res = tabResVal.getMensagem(TabeliaoResultadoValidacao.VAL_VALIDADE);
if("1".equals(valida)) {
log.info("Verificando a data de validade do certificado.");
if(TabeliaoResultadoValidacao.MSG_ERRO.equals(res)) {
log.info("Certificado Vencido");
throw new Exception(tabResVal.getDescricao(TabeliaoResultadoValidacao.VAL_VALIDADE));
}
if(TabeliaoResultadoValidacao.MSG_EXCECAO.equals(res)) {
log.info("Exce��o na validade");
throw new Exception(tabResVal.getDescricao(TabeliaoResultadoValidacao.VAL_VALIDADE));
}
//
// if(TabeliaoResultadoValidacao.MSG_AVISO.equals(res)) {
// httpRequest.setAttribute(Constants.TABELIAO_MENSAGEM_AVISO, tabResVal.getDescricao(TabeliaoResultadoValidacao.VAL_VALIDADE));
// }
} else {
log.info("Nao est� verificando a data de validade do certificado.");
}
} catch (Exception e) {
throw new SentinelaException("Erro ao realizar a autenticacao.\nEste certificado est� com a validade expirada.", e);
}
//Verifica se o tipo de certificado utilizado esta dentro do esperado
try {
String valida = validaNivelAcesso;
if("1".equals(valida)) {
log.info("Verificando se o tipo do certificado pode ser utilizado.");
String tipoCertificado = tc.getTipoCertificado();
String tipoCertificadoApp = nivelAcesso;
if(tipoCertificadoApp == null || tipoCertificado.equals("")) {
tipoCertificadoApp = "A3";
}
if(tipoCertificadoApp.length() != 2) {
throw new Exception("Tipo de certificado inv�lido na aplica��o.");
}
if(tipoCertificado.charAt(0) != tipoCertificadoApp.charAt(0)) {
throw new Exception("Tipo de certificado n�o compat�vel com a aplica��o.");
}
if(tipoCertificado.charAt(1) < tipoCertificadoApp.charAt(1)) {
throw new Exception("Tipo de certificado do usu�rio '" + tipoCertificado + "' n�o compat�vel com o esperado '" + tipoCertificadoApp + "' ou superior.");
}
} else {
log.info("N�o est� verificando se o tipo do certificado pode ser utilizado.");
}
} catch (Exception e) {
throw new SentinelaException("Erro ao realizar a autentica��o.\n" + e.getMessage(), e);
}
//Grava o certificado publico no tabeliao
log.info("Verificando o certificado publico para incluir no banco de dados.");
try {
CertificadoAc certificadoAc = CertificadoFacade.buscarCertificadoAcPorKeyId(tc.getAuthorityKeyIdentifier());
CertificadoPublico cp = CertificadoFacade.buscarCertificadoPublico(certificadoAc, tc.getSerialNumber());
if(cp == null){
log.info("Este certificado nao existe. Incluindo no banco de dados.");
cp = new CertificadoPublico();
String pem = X509Cert.getCertificateAsPem(cert);
cp.setArquivo(pem.getBytes());
CertificadoFacade.inserirCertificadoPublico(cp);
log.info("Certificado incluido com sucesso.");
} else {
log.info("Certificado j� existe, pulando o passo de incluir certificado.");
}
} catch (Exception e) {
System.err.println("N�o foi poss�vel inserir o certificado p�blico '" + cert.getSubjectDN().getName() + "' no banco de dados.\n" +
"Motivo: " + e.getMessage());
}
if (! tc.hasDadosPF()) {
throw new SentinelaException("O certificado do usu�rio n�o possui dados de Pessoa F�sica.");
}
usuarioTabeliao = new UsuarioTabeliao(
tc.getNome(),
tc.getEmail(),
tc.getTabeliaoDadosPF().getCPF());
log.info("Usuario autenticado.");
}
} catch (CMSException e) {
throw new SentinelaException("Erro ao autenticar usuario.",e);
} catch (NoSuchAlgorithmException e) {
throw new SentinelaException("Erro ao autenticar usuario.",e);
} catch (NoSuchProviderException e) {
throw new SentinelaException("Erro ao autenticar usuario.",e);
} catch (CertStoreException e) {
throw new SentinelaException("Erro ao autenticar usuario.",e);
} catch (Exception e) {
throw new SentinelaException("Erro ao autenticar usuario.",e);
}
return usuarioTabeliao;
}
/**
* Inicializa com as informacoes contidas no arquivo de configuracao do sentinela.
* @param sentinelaXml
* @see gov.pr.celepar.sentinela.client.SentinelaXml
* @throws SentinelaException
*/
@Override
public void inicializar(SentinelaXml sentinelaXml) throws SentinelaException {
log.info("Chamando metodo inicializar AutenticacaoTabeliao");
this.nivelAcesso = sentinelaXml.recupera("tabeliao.client.nivel.acesso");
this.validaCadeiaCertificado = sentinelaXml.recupera("tabeliao.client.valida.cadeia.certificado");
this.validaLCR = sentinelaXml.recupera("tabeliao.client.valida.LCR");
this.validaCertificadoExpirado = sentinelaXml.recupera("tabeliao.client.valida.certificado.expirado");
this.validaNivelAcesso = sentinelaXml.recupera("tabeliao.client.valida.nivel.acesso");
LCRTempo = sentinelaXml.recupera("tabeliao.client.lcr.tempo");
LCRProxy = sentinelaXml.recupera("tabeliao.client.lcr.proxy");
LCRProxyUsuario = sentinelaXml.recupera("tabeliao.client.lcr.proxy.usuario");
LCRProxySenha = sentinelaXml.recupera("tabeliao.client.lcr.proxy.senha");
LCRProxyPorta = sentinelaXml.recupera("tabeliao.client.lcr.proxy.porta");
diasMensagemExpirando = sentinelaXml.recupera("tabeliao.client.dias.mensagem.expirando");
}
/**
* Nao permitido por estar utilizando Certificado Digital
*/
@Override
public boolean permitirTrocarSenha() {
return false;
}
/**
* Nao permitido por estar utilizando Certificado Digital
*/
@Override
public boolean permitirEnvioNovaSenha() {
return false;
}
/**
* Nao permitido por estar utilizando Certificado Digital
*/
@Override
public String enviarNovaSenha(String arg0, String arg1, String arg2,
long arg3, long arg4) throws SentinelaException {
throw new SentinelaException("Funcionalidade n�o dispon�vel, com uso do TABELI�O!");
}
/**
* Nao permitido por estar utilizando Certificado Digital
*/
@Override
public boolean trocarSenha(String arg0, String arg1, String arg2,
String arg3, long arg4, long arg5) throws SentinelaException {
throw new SentinelaException("Funcionalidade n�o dispon�vel, com uso do TABELI�O!");
}
}