/* * eID Applet Project. * Copyright (C) 2009 FedICT. * * 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 test.unit.be.fedict.eid.applet.service; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import java.security.KeyPair; import java.security.Signature; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.List; 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 org.easymock.EasyMock; import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; import be.fedict.eid.applet.service.AppletServiceServlet; import be.fedict.eid.applet.service.EIdData; import be.fedict.eid.applet.service.Identity; import be.fedict.eid.applet.service.impl.RequestContext; import be.fedict.eid.applet.service.impl.handler.IdentityDataMessageHandler; import be.fedict.eid.applet.service.spi.IdentityIntegrityService; import be.fedict.eid.applet.shared.IdentityDataMessage; public class IdentityDataMessageHandlerTest { private static final Log LOG = LogFactory.getLog(IdentityDataMessageHandlerTest.class); private IdentityDataMessageHandler testedInstance; @Before public void setUp() throws Exception { this.testedInstance = new IdentityDataMessageHandler(); IdentityIntegrityTestService.reset(); AuditTestService.reset(); } @Test public void testHandleMessage() throws Exception { // setup ServletConfig mockServletConfig = EasyMock.createMock(ServletConfig.class); Map<String, String> httpHeaders = new HashMap<String, String>(); HttpSession mockHttpSession = EasyMock.createMock(HttpSession.class); HttpServletRequest mockServletRequest = EasyMock.createMock(HttpServletRequest.class); EasyMock.expect(mockServletConfig.getInitParameter("IdentityIntegrityService")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("IdentityIntegrityServiceClass")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("AuditService")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("AuditServiceClass")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("SkipNationalNumberCheck")).andStubReturn(null); mockHttpSession.setAttribute(EasyMock.eq("eid.identity"), EasyMock.isA(Identity.class)); EasyMock.expect(mockHttpSession.getAttribute("eid")).andStubReturn(null); mockHttpSession.setAttribute(EasyMock.eq("eid"), EasyMock.isA(EIdData.class)); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_ADDRESS_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_CERTIFICATES_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_PHOTO_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockServletConfig.getInitParameter(IdentityDataMessageHandler.INCLUDE_DATA_FILES)) .andReturn(null); byte[] idFile = "foobar-id-file".getBytes(); IdentityDataMessage message = new IdentityDataMessage(); message.idFile = idFile; // prepare EasyMock.replay(mockServletConfig, mockHttpSession, mockServletRequest); // operate AppletServiceServlet.injectInitParams(mockServletConfig, this.testedInstance); this.testedInstance.init(mockServletConfig); this.testedInstance.handleMessage(message, httpHeaders, mockServletRequest, mockHttpSession); // verify EasyMock.verify(mockServletConfig, mockHttpSession, mockServletRequest); } @Test public void testHandleMessageWithIntegrityCheck() throws Exception { // setup KeyPair rootKeyPair = MiscTestUtils.generateKeyPair(); KeyPair rrnKeyPair = MiscTestUtils.generateKeyPair(); DateTime notBefore = new DateTime(); DateTime notAfter = notBefore.plusYears(1); X509Certificate rootCertificate = MiscTestUtils.generateCertificate(rootKeyPair.getPublic(), "CN=TestRootCA", notBefore, notAfter, null, rootKeyPair.getPrivate(), true, 0, null, null); X509Certificate rrnCertificate = MiscTestUtils.generateCertificate(rrnKeyPair.getPublic(), "CN=TestNationalRegistration", notBefore, notAfter, null, rootKeyPair.getPrivate(), false, 0, null, null); ServletConfig mockServletConfig = EasyMock.createMock(ServletConfig.class); Map<String, String> httpHeaders = new HashMap<String, String>(); HttpSession mockHttpSession = EasyMock.createMock(HttpSession.class); HttpServletRequest mockServletRequest = EasyMock.createMock(HttpServletRequest.class); EasyMock.expect(mockServletConfig.getInitParameter("IdentityIntegrityService")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("IdentityIntegrityServiceClass")) .andStubReturn(IdentityIntegrityTestService.class.getName()); EasyMock.expect(mockServletConfig.getInitParameter("AuditService")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("AuditServiceClass")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("SkipNationalNumberCheck")).andStubReturn(null); EasyMock.expect(mockHttpSession.getAttribute("eid.identifier")).andStubReturn(null); mockHttpSession.setAttribute(EasyMock.eq("eid.identity"), EasyMock.isA(Identity.class)); EasyMock.expect(mockHttpSession.getAttribute("eid")).andStubReturn(null); mockHttpSession.setAttribute(EasyMock.eq("eid"), EasyMock.isA(EIdData.class)); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_ADDRESS_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_CERTIFICATES_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_PHOTO_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockServletConfig.getInitParameter(IdentityDataMessageHandler.INCLUDE_DATA_FILES)) .andReturn(null); byte[] idFile = "foobar-id-file".getBytes(); IdentityDataMessage message = new IdentityDataMessage(); message.idFile = idFile; Signature signature = Signature.getInstance("SHA1withRSA"); signature.initSign(rrnKeyPair.getPrivate()); signature.update(idFile); byte[] idFileSignature = signature.sign(); message.identitySignatureFile = idFileSignature; message.rrnCertFile = rrnCertificate.getEncoded(); message.rootCertFile = rootCertificate.getEncoded(); // prepare EasyMock.replay(mockServletConfig, mockHttpSession, mockServletRequest); // operate AppletServiceServlet.injectInitParams(mockServletConfig, this.testedInstance); this.testedInstance.init(mockServletConfig); this.testedInstance.handleMessage(message, httpHeaders, mockServletRequest, mockHttpSession); // verify EasyMock.verify(mockServletConfig, mockHttpSession, mockServletRequest); assertEquals(rrnCertificate, IdentityIntegrityTestService.getCertificate()); } @Test public void testHandleMessageInvalidIntegritySignature() throws Exception { // setup KeyPair keyPair = MiscTestUtils.generateKeyPair(); DateTime notBefore = new DateTime(); DateTime notAfter = notBefore.plusYears(1); X509Certificate certificate = MiscTestUtils.generateCertificate(keyPair.getPublic(), "CN=TestNationalRegistration", notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null); ServletConfig mockServletConfig = EasyMock.createMock(ServletConfig.class); Map<String, String> httpHeaders = new HashMap<String, String>(); HttpSession mockHttpSession = EasyMock.createMock(HttpSession.class); HttpServletRequest mockServletRequest = EasyMock.createMock(HttpServletRequest.class); EasyMock.expect(mockServletConfig.getInitParameter("IdentityIntegrityService")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("IdentityIntegrityServiceClass")) .andStubReturn(IdentityIntegrityTestService.class.getName()); EasyMock.expect(mockServletConfig.getInitParameter("AuditService")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("AuditServiceClass")) .andStubReturn(AuditTestService.class.getName()); EasyMock.expect(mockServletConfig.getInitParameter("SkipNationalNumberCheck")).andStubReturn(null); EasyMock.expect(mockServletRequest.getRemoteAddr()).andStubReturn("remote-address"); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_ADDRESS_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_CERTIFICATES_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_PHOTO_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockServletConfig.getInitParameter(IdentityDataMessageHandler.INCLUDE_DATA_FILES)) .andReturn(null); byte[] idFile = "foobar-id-file".getBytes(); IdentityDataMessage message = new IdentityDataMessage(); message.idFile = idFile; KeyPair intruderKeyPair = MiscTestUtils.generateKeyPair(); Signature signature = Signature.getInstance("SHA1withRSA"); signature.initSign(intruderKeyPair.getPrivate()); signature.update(idFile); byte[] idFileSignature = signature.sign(); message.identitySignatureFile = idFileSignature; message.rrnCertFile = certificate.getEncoded(); // prepare EasyMock.replay(mockServletConfig, mockHttpSession, mockServletRequest); // operate AppletServiceServlet.injectInitParams(mockServletConfig, this.testedInstance); this.testedInstance.init(mockServletConfig); try { this.testedInstance.handleMessage(message, httpHeaders, mockServletRequest, mockHttpSession); fail(); } catch (ServletException e) { LOG.debug("expected exception: " + e.getMessage()); // verify EasyMock.verify(mockServletConfig, mockHttpSession, mockServletRequest); assertNull(IdentityIntegrityTestService.getCertificate()); assertEquals("remote-address", AuditTestService.getAuditIntegrityRemoteAddress()); } } @Test public void testHandleMessageCorruptIntegritySignature() throws Exception { // setup KeyPair keyPair = MiscTestUtils.generateKeyPair(); DateTime notBefore = new DateTime(); DateTime notAfter = notBefore.plusYears(1); X509Certificate certificate = MiscTestUtils.generateCertificate(keyPair.getPublic(), "CN=TestNationalRegistration", notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null); ServletConfig mockServletConfig = EasyMock.createMock(ServletConfig.class); Map<String, String> httpHeaders = new HashMap<String, String>(); HttpSession mockHttpSession = EasyMock.createMock(HttpSession.class); HttpServletRequest mockServletRequest = EasyMock.createMock(HttpServletRequest.class); EasyMock.expect(mockServletConfig.getInitParameter("IdentityIntegrityService")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("IdentityIntegrityServiceClass")) .andStubReturn(IdentityIntegrityTestService.class.getName()); EasyMock.expect(mockServletConfig.getInitParameter("AuditService")).andStubReturn(null); EasyMock.expect(mockServletConfig.getInitParameter("AuditServiceClass")) .andStubReturn(AuditTestService.class.getName()); EasyMock.expect(mockServletConfig.getInitParameter("SkipNationalNumberCheck")).andStubReturn(null); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_ADDRESS_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_CERTIFICATES_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockHttpSession.getAttribute(RequestContext.INCLUDE_PHOTO_SESSION_ATTRIBUTE)) .andStubReturn(false); EasyMock.expect(mockServletConfig.getInitParameter(IdentityDataMessageHandler.INCLUDE_DATA_FILES)) .andReturn(null); EasyMock.expect(mockServletRequest.getRemoteAddr()).andStubReturn("remote-address"); byte[] idFile = "foobar-id-file".getBytes(); IdentityDataMessage message = new IdentityDataMessage(); message.idFile = idFile; message.identitySignatureFile = "foobar-signature".getBytes(); message.rrnCertFile = certificate.getEncoded(); // prepare EasyMock.replay(mockServletConfig, mockHttpSession, mockServletRequest); // operate AppletServiceServlet.injectInitParams(mockServletConfig, this.testedInstance); this.testedInstance.init(mockServletConfig); try { this.testedInstance.handleMessage(message, httpHeaders, mockServletRequest, mockHttpSession); fail(); } catch (ServletException e) { LOG.debug("expected exception: " + e.getMessage(), e); LOG.debug("exception type: " + e.getClass().getName()); // verify EasyMock.verify(mockServletConfig, mockHttpSession, mockServletRequest); assertNull(IdentityIntegrityTestService.getCertificate()); assertEquals("remote-address", AuditTestService.getAuditIntegrityRemoteAddress()); } } public static class IdentityIntegrityTestService implements IdentityIntegrityService { private static X509Certificate certificate; public static void reset() { IdentityIntegrityTestService.certificate = null; } public static X509Certificate getCertificate() { return IdentityIntegrityTestService.certificate; } public void checkNationalRegistrationCertificate(List<X509Certificate> certificateChain) throws SecurityException { IdentityIntegrityTestService.certificate = certificateChain.get(0); } } }