/*
* eID Applet Project.
* Copyright (C) 2008-2009 FedICT.
* Copyright (C) 2009-2014 e-Contract.be BVBA.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version
* 3.0 as published by the Free Software Foundation.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, see
* http://www.gnu.org/licenses/.
*/
package be.fedict.eid.applet.service.impl.handler;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import be.fedict.eid.applet.service.impl.AuthenticationChallenge;
import be.fedict.eid.applet.service.impl.RequestContext;
import be.fedict.eid.applet.service.impl.ServiceLocator;
import be.fedict.eid.applet.service.spi.AuthenticationService;
import be.fedict.eid.applet.service.spi.AuthorizationException;
import be.fedict.eid.applet.service.spi.DigestInfo;
import be.fedict.eid.applet.service.spi.IdentityIntegrityService;
import be.fedict.eid.applet.service.spi.IdentityRequest;
import be.fedict.eid.applet.service.spi.IdentityService;
import be.fedict.eid.applet.service.spi.PrivacyService;
import be.fedict.eid.applet.service.spi.SecureCardReaderService;
import be.fedict.eid.applet.service.spi.SecureClientEnvironmentService;
import be.fedict.eid.applet.service.spi.SignatureService;
import be.fedict.eid.applet.shared.AdministrationMessage;
import be.fedict.eid.applet.shared.AuthenticationRequestMessage;
import be.fedict.eid.applet.shared.CheckClientMessage;
import be.fedict.eid.applet.shared.ErrorCode;
import be.fedict.eid.applet.shared.FilesDigestRequestMessage;
import be.fedict.eid.applet.shared.FinishedMessage;
import be.fedict.eid.applet.shared.HelloMessage;
import be.fedict.eid.applet.shared.IdentificationRequestMessage;
import be.fedict.eid.applet.shared.SignCertificatesRequestMessage;
import be.fedict.eid.applet.shared.SignRequestMessage;
/**
* Message handler for hello message.
*
* @author Frank Cornelis
*
*/
@HandlesMessage(HelloMessage.class)
public class HelloMessageHandler implements MessageHandler<HelloMessage> {
private static final Log LOG = LogFactory.getLog(HelloMessageHandler.class);
public static final String INCLUDE_IDENTITY_INIT_PARAM_NAME = "IncludeIdentity";
public static final String INCLUDE_PHOTO_INIT_PARAM_NAME = "IncludePhoto";
public static final String INCLUDE_CERTS_INIT_PARAM_NAME = "IncludeCertificates";
public static final String INCLUDE_ADDRESS_INIT_PARAM_NAME = "IncludeAddress";
public static final String SECURE_CLIENT_ENV_SERVICE_INIT_PARAM_NAME = "SecureClientEnvironmentService";
public static final String IDENTITY_INTEGRITY_SERVICE_INIT_PARAM_NAME = "IdentityIntegrityService";
public static final String SIGNATURE_SERVICE_INIT_PARAM_NAME = "SignatureService";
public static final String PRIVACY_SERVICE_INIT_PARAM_NAME = "PrivacyService";
public static final String REMOVE_CARD_INIT_PARAM_NAME = "RemoveCard";
public static final String HOSTNAME_INIT_PARAM_NAME = "Hostname";
public static final String INET_ADDRESS_INIT_PARAM_NAME = "InetAddress";
public static final String CHANGE_PIN_INIT_PARAM_NAME = "ChangePin";
public static final String UNBLOCK_PIN_INIT_PARAM_NAME = "UnblockPin";
public static final String LOGOFF_INIT_PARAM_NAME = "Logoff";
public static final String PRE_LOGOFF_INIT_PARAM_NAME = "PreLogoff";
public static final String SESSION_ID_CHANNEL_BINDING_INIT_PARAM_NAME = "SessionIdChannelBinding";
public static final String CHANNEL_BINDING_SERVER_CERTIFICATE = "ChannelBindingServerCertificate";
public static final String CHANNEL_BINDING_SERVICE = "ChannelBindingService";
public static final String REQUIRE_SECURE_READER_INIT_PARAM_NAME = "RequireSecureReader";
public static final String IDENTITY_SERVICE_INIT_PARAM_NAME = "IdentityService";
public static final String SECURE_CARD_READER_SERVICE_INIT_PARAM_NAME = "SecureCardReaderService";
@InitParam(INCLUDE_PHOTO_INIT_PARAM_NAME)
private boolean includePhoto;
@InitParam(INCLUDE_ADDRESS_INIT_PARAM_NAME)
private boolean includeAddress;
@InitParam(INCLUDE_IDENTITY_INIT_PARAM_NAME)
private boolean includeIdentity;
@InitParam(REMOVE_CARD_INIT_PARAM_NAME)
private boolean removeCard;
private boolean includeHostname;
private boolean includeInetAddress;
@InitParam(CHANGE_PIN_INIT_PARAM_NAME)
private boolean changePin;
@InitParam(UNBLOCK_PIN_INIT_PARAM_NAME)
private boolean unblockPin;
@InitParam(LOGOFF_INIT_PARAM_NAME)
private boolean logoff;
@InitParam(PRE_LOGOFF_INIT_PARAM_NAME)
private boolean preLogoff;
@InitParam(INCLUDE_CERTS_INIT_PARAM_NAME)
private boolean includeCertificates;
@InitParam(SESSION_ID_CHANNEL_BINDING_INIT_PARAM_NAME)
private boolean sessionIdChannelBinding;
private boolean serverCertificateChannelBinding;
@InitParam(REQUIRE_SECURE_READER_INIT_PARAM_NAME)
private boolean requireSecureReader;
@InitParam(SECURE_CLIENT_ENV_SERVICE_INIT_PARAM_NAME)
private ServiceLocator<SecureClientEnvironmentService> secureClientEnvServiceLocator;
@InitParam(IDENTITY_INTEGRITY_SERVICE_INIT_PARAM_NAME)
private ServiceLocator<IdentityIntegrityService> identityIntegrityServiceLocator;
@InitParam(AuthenticationDataMessageHandler.AUTHN_SERVICE_INIT_PARAM_NAME)
private ServiceLocator<AuthenticationService> authenticationServiceLocator;
@InitParam(SIGNATURE_SERVICE_INIT_PARAM_NAME)
private ServiceLocator<SignatureService> signatureServiceLocator;
@InitParam(PRIVACY_SERVICE_INIT_PARAM_NAME)
private ServiceLocator<PrivacyService> privacyServiceLocator;
@InitParam(IDENTITY_SERVICE_INIT_PARAM_NAME)
private ServiceLocator<IdentityService> identityServiceLocator;
@InitParam(SECURE_CARD_READER_SERVICE_INIT_PARAM_NAME)
private ServiceLocator<SecureCardReaderService> secureCardReaderServiceLocator;
public Object handleMessage(HelloMessage message, Map<String, String> httpHeaders, HttpServletRequest request,
HttpSession session) throws ServletException {
LOG.debug("hello message received");
storeClientLanguage(message.language, session);
SecureClientEnvironmentService secureClientEnvService = this.secureClientEnvServiceLocator.locateService();
if (null != secureClientEnvService) {
CheckClientMessage checkClientMessage = new CheckClientMessage();
return checkClientMessage;
}
if (this.changePin || this.unblockPin) {
AdministrationMessage administrationMessage = new AdministrationMessage(this.changePin, this.unblockPin,
this.logoff, this.removeCard, this.requireSecureReader);
return administrationMessage;
}
SignatureService signatureService = this.signatureServiceLocator.locateService();
if (null != signatureService) {
String filesDigestAlgo = signatureService.getFilesDigestAlgorithm();
if (null != filesDigestAlgo) {
LOG.debug("files digest algo: " + filesDigestAlgo);
FilesDigestRequestMessage filesDigestRequestMessage = new FilesDigestRequestMessage();
filesDigestRequestMessage.digestAlgo = filesDigestAlgo;
return filesDigestRequestMessage;
}
if (true == this.includeCertificates) {
LOG.debug("include signing certificate chain during pre-sign");
IdentityIntegrityService identityIntegrityService = this.identityIntegrityServiceLocator
.locateService();
boolean includeIntegrityData = null != identityIntegrityService;
IdentityService identityService = this.identityServiceLocator.locateService();
boolean includeIdentity;
boolean includeAddress;
boolean includePhoto;
if (null != identityService) {
IdentityRequest identityRequest = identityService.getIdentityRequest();
includeIdentity = identityRequest.includeIdentity();
includeAddress = identityRequest.includeAddress();
includePhoto = identityRequest.includePhoto();
} else {
includeIdentity = this.includeIdentity;
includeAddress = this.includeAddress;
includePhoto = this.includePhoto;
}
RequestContext requestContext = new RequestContext(session);
requestContext.setIncludeIdentity(includeIdentity);
requestContext.setIncludeAddress(includeAddress);
requestContext.setIncludePhoto(includePhoto);
SignCertificatesRequestMessage signCertificatesRequestMessage = new SignCertificatesRequestMessage(
includeIdentity, includeAddress, includePhoto, includeIntegrityData);
return signCertificatesRequestMessage;
}
DigestInfo digestInfo;
try {
digestInfo = signatureService.preSign(null, null, null, null, null);
} catch (NoSuchAlgorithmException e) {
throw new ServletException("no such algo: " + e.getMessage(), e);
} catch (AuthorizationException e) {
return new FinishedMessage(ErrorCode.AUTHORIZATION);
}
// also save it in the session for later verification
SignatureDataMessageHandler.setDigestValue(digestInfo.digestValue, digestInfo.digestAlgo, session);
IdentityService identityService = this.identityServiceLocator.locateService();
boolean removeCard;
if (null != identityService) {
IdentityRequest identityRequest = identityService.getIdentityRequest();
removeCard = identityRequest.removeCard();
} else {
removeCard = this.removeCard;
}
SignRequestMessage signRequestMessage = new SignRequestMessage(digestInfo.digestValue,
digestInfo.digestAlgo, digestInfo.description, this.logoff, removeCard, this.requireSecureReader);
return signRequestMessage;
}
AuthenticationService authenticationService = this.authenticationServiceLocator.locateService();
if (null != authenticationService) {
byte[] challenge = AuthenticationChallenge.generateChallenge(session);
IdentityIntegrityService identityIntegrityService = this.identityIntegrityServiceLocator.locateService();
boolean includeIntegrityData = null != identityIntegrityService;
boolean includeIdentity;
boolean includeAddress;
boolean includePhoto;
boolean includeCertificates;
boolean removeCard;
IdentityService identityService = this.identityServiceLocator.locateService();
if (null != identityService) {
IdentityRequest identityRequest = identityService.getIdentityRequest();
includeIdentity = identityRequest.includeIdentity();
includeAddress = identityRequest.includeAddress();
includePhoto = identityRequest.includePhoto();
includeCertificates = identityRequest.includeCertificates();
removeCard = identityRequest.removeCard();
} else {
includeIdentity = this.includeIdentity;
includeAddress = this.includeAddress;
includePhoto = this.includePhoto;
includeCertificates = this.includeCertificates;
removeCard = this.removeCard;
}
RequestContext requestContext = new RequestContext(session);
requestContext.setIncludeIdentity(includeIdentity);
requestContext.setIncludeAddress(includeAddress);
requestContext.setIncludePhoto(includePhoto);
requestContext.setIncludeCertificates(includeCertificates);
String transactionMessage = null;
SecureCardReaderService secureCardReaderService = this.secureCardReaderServiceLocator.locateService();
if (null != secureCardReaderService) {
transactionMessage = secureCardReaderService.getTransactionMessage();
if (null != transactionMessage
&& transactionMessage.length() > SecureCardReaderService.TRANSACTION_MESSAGE_MAX_SIZE) {
transactionMessage = transactionMessage.substring(0,
SecureCardReaderService.TRANSACTION_MESSAGE_MAX_SIZE);
}
LOG.debug("transaction message: " + transactionMessage);
}
requestContext.setTransactionMessage(transactionMessage);
AuthenticationRequestMessage authenticationRequestMessage = new AuthenticationRequestMessage(challenge,
this.includeHostname, this.includeInetAddress, this.logoff, this.preLogoff, removeCard,
this.sessionIdChannelBinding, this.serverCertificateChannelBinding, includeIdentity,
includeCertificates, includeAddress, includePhoto, includeIntegrityData, this.requireSecureReader,
transactionMessage);
return authenticationRequestMessage;
}
IdentityIntegrityService identityIntegrityService = this.identityIntegrityServiceLocator.locateService();
boolean includeIntegrityData = null != identityIntegrityService;
PrivacyService privacyService = this.privacyServiceLocator.locateService();
String identityDataUsage;
if (null != privacyService) {
identityDataUsage = privacyService.getIdentityDataUsage(message.language);
} else {
identityDataUsage = null;
}
boolean includeAddress;
boolean includePhoto;
boolean includeCertificates;
boolean removeCard;
IdentityService identityService = this.identityServiceLocator.locateService();
if (null != identityService) {
IdentityRequest identityRequest = identityService.getIdentityRequest();
includeAddress = identityRequest.includeAddress();
includePhoto = identityRequest.includePhoto();
includeCertificates = identityRequest.includeCertificates();
removeCard = identityRequest.removeCard();
} else {
includeAddress = this.includeAddress;
includePhoto = this.includePhoto;
includeCertificates = this.includeCertificates;
removeCard = this.removeCard;
}
RequestContext requestContext = new RequestContext(session);
requestContext.setIncludeAddress(includeAddress);
requestContext.setIncludePhoto(includePhoto);
requestContext.setIncludeCertificates(includeCertificates);
IdentificationRequestMessage responseMessage = new IdentificationRequestMessage(includeAddress, includePhoto,
includeIntegrityData, includeCertificates, removeCard, identityDataUsage);
return responseMessage;
}
private static final String CLIENT_LANGUAGE_SESSION_ATTRIBUTE = HelloMessageHandler.class.getName()
+ ".clientLanguage";
private void storeClientLanguage(String language, HttpSession httpSession) {
httpSession.setAttribute(CLIENT_LANGUAGE_SESSION_ATTRIBUTE, language);
}
public static String getClientLanguage(HttpSession httpSession) {
String clientLanguage = (String) httpSession.getAttribute(CLIENT_LANGUAGE_SESSION_ATTRIBUTE);
return clientLanguage;
}
public void init(ServletConfig config) throws ServletException {
String hostname = config.getInitParameter(HOSTNAME_INIT_PARAM_NAME);
if (null != hostname) {
this.includeHostname = true;
}
String inetAddress = config.getInitParameter(INET_ADDRESS_INIT_PARAM_NAME);
if (null != inetAddress) {
this.includeInetAddress = true;
}
String channelBindingServerCertificate = config.getInitParameter(CHANNEL_BINDING_SERVER_CERTIFICATE);
if (null != channelBindingServerCertificate) {
this.serverCertificateChannelBinding = true;
}
String channelBindingService = config.getInitParameter(CHANNEL_BINDING_SERVICE);
if (null != channelBindingService) {
this.serverCertificateChannelBinding = true;
}
}
}