/** * Copyright (c) Codice Foundation * <p> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p> * This program 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. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.ddf.security.validator.pki; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.InputStream; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Properties; import org.apache.commons.io.IOUtils; import org.apache.cxf.sts.STSPropertiesMBean; import org.apache.cxf.sts.request.ReceivedToken; import org.apache.cxf.sts.token.validator.TokenValidatorParameters; import org.apache.cxf.sts.token.validator.TokenValidatorResponse; import org.apache.cxf.ws.security.sts.provider.model.secext.BinarySecurityTokenType; import org.apache.wss4j.common.crypto.Merlin; import org.apache.wss4j.dom.WSConstants; import org.codice.ddf.security.handler.api.PKIAuthenticationToken; import org.codice.ddf.security.handler.api.PKIAuthenticationTokenFactory; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import ddf.security.PropertiesLoader; import ddf.security.SecurityConstants; import ddf.security.SubjectUtils; public class TestPKITokenValidator { private static Properties properties; PKITokenValidator pkiTokenValidator; X509Certificate[] certificates; X509Certificate[] badCertificates; Merlin merlin; @BeforeClass public static void setUpBeforeClass() { properties = System.getProperties(); System.setProperty(SecurityConstants.KEYSTORE_TYPE, "jks"); } @AfterClass public static void tearDownAfterClass() { System.setProperties(properties); } @Before public void setup() { pkiTokenValidator = new PKITokenValidator(); pkiTokenValidator.setSignaturePropertiesPath(TestPKITokenValidator.class.getResource( "/signature.properties") .getPath()); pkiTokenValidator.setRealms(Arrays.asList("karaf")); pkiTokenValidator.init(); try { KeyStore trustStore = KeyStore.getInstance(System.getProperty( "javax.net.ssl.keyStoreType")); InputStream trustFIS = TestPKITokenValidator.class.getResourceAsStream( "/serverKeystore.jks"); try { trustStore.load(trustFIS, "changeit".toCharArray()); } catch (CertificateException e) { fail(e.getMessage()); } finally { IOUtils.closeQuietly(trustFIS); } Certificate[] certs = trustStore.getCertificateChain("localhost"); certificates = new X509Certificate[certs.length]; for (int i = 0; i < certs.length; i++) { certificates[i] = (X509Certificate) certs[i]; } trustStore = KeyStore.getInstance(System.getProperty(SecurityConstants.KEYSTORE_TYPE)); trustFIS = TestPKITokenValidator.class.getResourceAsStream("/badKeystore.jks"); try { trustStore.load(trustFIS, "changeit".toCharArray()); } catch (CertificateException e) { fail(e.getMessage()); } finally { IOUtils.closeQuietly(trustFIS); } certs = trustStore.getCertificateChain("badhost"); badCertificates = new X509Certificate[certs.length]; for (int i = 0; i < certs.length; i++) { badCertificates[i] = (X509Certificate) certs[i]; } merlin = new Merlin(PropertiesLoader.loadProperties(TestPKITokenValidator.class.getResource( "/signature.properties") .getPath()), PKITokenValidator.class.getClassLoader(), null); } catch (Exception e) { fail(e.getMessage()); } } @Test public void testCanHandleToken() { BinarySecurityTokenType binarySecurityTokenType = new BinarySecurityTokenType(); binarySecurityTokenType.setEncodingType(WSConstants.SOAPMESSAGE_NS + "#Base64Binary"); binarySecurityTokenType.setValueType(PKIAuthenticationToken.PKI_TOKEN_VALUE_TYPE); PKIAuthenticationTokenFactory pkiAuthenticationTokenFactory = new PKIAuthenticationTokenFactory(); pkiAuthenticationTokenFactory.setSignaturePropertiesPath(TestPKITokenValidator.class.getResource( "/signature.properties") .getPath()); pkiAuthenticationTokenFactory.init(); PKIAuthenticationToken pkiAuthenticationToken = pkiAuthenticationTokenFactory.getTokenFromCerts(certificates, "karaf"); binarySecurityTokenType.setValue(pkiAuthenticationToken.getEncodedCredentials()); ReceivedToken receivedToken = mock(ReceivedToken.class); when(receivedToken.getToken()).thenReturn(binarySecurityTokenType); boolean result = pkiTokenValidator.canHandleToken(receivedToken); assertEquals(true, result); } @Test public void testCanHandleAnyRealmToken() { BinarySecurityTokenType binarySecurityTokenType = new BinarySecurityTokenType(); binarySecurityTokenType.setEncodingType(WSConstants.SOAPMESSAGE_NS + "#Base64Binary"); binarySecurityTokenType.setValueType(PKIAuthenticationToken.PKI_TOKEN_VALUE_TYPE); PKIAuthenticationTokenFactory pkiAuthenticationTokenFactory = new PKIAuthenticationTokenFactory(); pkiAuthenticationTokenFactory.setSignaturePropertiesPath(TestPKITokenValidator.class.getResource( "/signature.properties") .getPath()); pkiAuthenticationTokenFactory.init(); PKIAuthenticationToken pkiAuthenticationToken = pkiAuthenticationTokenFactory.getTokenFromCerts(certificates, "*"); binarySecurityTokenType.setValue(pkiAuthenticationToken.getEncodedCredentials()); ReceivedToken receivedToken = mock(ReceivedToken.class); when(receivedToken.getToken()).thenReturn(binarySecurityTokenType); boolean result = pkiTokenValidator.canHandleToken(receivedToken); assertEquals(true, result); } @Test public void testCanNotHandleToken() { BinarySecurityTokenType binarySecurityTokenType = new BinarySecurityTokenType(); binarySecurityTokenType.setEncodingType(WSConstants.SOAPMESSAGE_NS + "#Base64Binary"); binarySecurityTokenType.setValueType("randomvaluetype"); PKIAuthenticationTokenFactory pkiAuthenticationTokenFactory = new PKIAuthenticationTokenFactory(); pkiAuthenticationTokenFactory.setSignaturePropertiesPath(TestPKITokenValidator.class.getResource( "/signature.properties") .getPath()); pkiAuthenticationTokenFactory.init(); PKIAuthenticationToken pkiAuthenticationToken = pkiAuthenticationTokenFactory.getTokenFromCerts(certificates, "karaf"); binarySecurityTokenType.setValue(pkiAuthenticationToken.getEncodedCredentials()); ReceivedToken receivedToken = mock(ReceivedToken.class); when(receivedToken.getToken()).thenReturn(binarySecurityTokenType); boolean result = pkiTokenValidator.canHandleToken(receivedToken); assertEquals(false, result); } @Test public void testValidateToken() { BinarySecurityTokenType binarySecurityTokenType = new BinarySecurityTokenType(); binarySecurityTokenType.setEncodingType(WSConstants.SOAPMESSAGE_NS + "#Base64Binary"); binarySecurityTokenType.setValueType(PKIAuthenticationToken.PKI_TOKEN_VALUE_TYPE); PKIAuthenticationTokenFactory pkiAuthenticationTokenFactory = new PKIAuthenticationTokenFactory(); pkiAuthenticationTokenFactory.setSignaturePropertiesPath(TestPKITokenValidator.class.getResource( "/signature.properties") .getPath()); pkiAuthenticationTokenFactory.init(); PKIAuthenticationToken pkiAuthenticationToken = pkiAuthenticationTokenFactory.getTokenFromCerts(certificates, "karaf"); binarySecurityTokenType.setValue(pkiAuthenticationToken.getEncodedCredentials()); ReceivedToken receivedToken = mock(ReceivedToken.class); when(receivedToken.getToken()).thenReturn(binarySecurityTokenType); TokenValidatorParameters tokenValidatorParameters = mock(TokenValidatorParameters.class); STSPropertiesMBean stsPropertiesMBean = mock(STSPropertiesMBean.class); when(stsPropertiesMBean.getSignatureCrypto()).thenReturn(merlin); when(tokenValidatorParameters.getStsProperties()).thenReturn(stsPropertiesMBean); when(tokenValidatorParameters.getToken()).thenReturn(receivedToken); doCallRealMethod().when(receivedToken) .setState(any(ReceivedToken.STATE.class)); doCallRealMethod().when(receivedToken) .getState(); TokenValidatorResponse tokenValidatorResponse = pkiTokenValidator.validateToken( tokenValidatorParameters); assertEquals(ReceivedToken.STATE.VALID, tokenValidatorResponse.getToken() .getState()); assertEquals("US", tokenValidatorResponse.getAdditionalProperties() .get(SubjectUtils.COUNTRY_CLAIM_URI)); assertEquals("localhost@example.org", tokenValidatorResponse.getAdditionalProperties() .get(SubjectUtils.EMAIL_ADDRESS_CLAIM_URI)); } @Test public void testValidateAnyRealmToken() { BinarySecurityTokenType binarySecurityTokenType = new BinarySecurityTokenType(); binarySecurityTokenType.setEncodingType(WSConstants.SOAPMESSAGE_NS + "#Base64Binary"); binarySecurityTokenType.setValueType(PKIAuthenticationToken.PKI_TOKEN_VALUE_TYPE); PKIAuthenticationTokenFactory pkiAuthenticationTokenFactory = new PKIAuthenticationTokenFactory(); pkiAuthenticationTokenFactory.setSignaturePropertiesPath(TestPKITokenValidator.class.getResource( "/signature.properties") .getPath()); pkiAuthenticationTokenFactory.init(); PKIAuthenticationToken pkiAuthenticationToken = pkiAuthenticationTokenFactory.getTokenFromCerts(certificates, "*"); binarySecurityTokenType.setValue(pkiAuthenticationToken.getEncodedCredentials()); ReceivedToken receivedToken = mock(ReceivedToken.class); when(receivedToken.getToken()).thenReturn(binarySecurityTokenType); TokenValidatorParameters tokenValidatorParameters = mock(TokenValidatorParameters.class); STSPropertiesMBean stsPropertiesMBean = mock(STSPropertiesMBean.class); when(stsPropertiesMBean.getSignatureCrypto()).thenReturn(merlin); when(tokenValidatorParameters.getStsProperties()).thenReturn(stsPropertiesMBean); when(tokenValidatorParameters.getToken()).thenReturn(receivedToken); doCallRealMethod().when(receivedToken) .setState(any(ReceivedToken.STATE.class)); doCallRealMethod().when(receivedToken) .getState(); TokenValidatorResponse tokenValidatorResponse = pkiTokenValidator.validateToken( tokenValidatorParameters); assertEquals(ReceivedToken.STATE.VALID, tokenValidatorResponse.getToken() .getState()); assertEquals("US", tokenValidatorResponse.getAdditionalProperties() .get(SubjectUtils.COUNTRY_CLAIM_URI)); assertEquals("localhost@example.org", tokenValidatorResponse.getAdditionalProperties() .get(SubjectUtils.EMAIL_ADDRESS_CLAIM_URI)); } @Test public void testNoValidateToken() { BinarySecurityTokenType binarySecurityTokenType = new BinarySecurityTokenType(); binarySecurityTokenType.setEncodingType(WSConstants.SOAPMESSAGE_NS + "#Base64Binary"); binarySecurityTokenType.setValueType(PKIAuthenticationToken.PKI_TOKEN_VALUE_TYPE); PKIAuthenticationTokenFactory pkiAuthenticationTokenFactory = new PKIAuthenticationTokenFactory(); pkiAuthenticationTokenFactory.setSignaturePropertiesPath(TestPKITokenValidator.class.getResource( "/badSignature.properties") .getPath()); pkiAuthenticationTokenFactory.init(); PKIAuthenticationToken pkiAuthenticationToken = pkiAuthenticationTokenFactory.getTokenFromCerts(badCertificates, "karaf"); binarySecurityTokenType.setValue(pkiAuthenticationToken.getEncodedCredentials()); ReceivedToken receivedToken = mock(ReceivedToken.class); when(receivedToken.getToken()).thenReturn(binarySecurityTokenType); TokenValidatorParameters tokenValidatorParameters = mock(TokenValidatorParameters.class); STSPropertiesMBean stsPropertiesMBean = mock(STSPropertiesMBean.class); when(stsPropertiesMBean.getSignatureCrypto()).thenReturn(merlin); when(tokenValidatorParameters.getStsProperties()).thenReturn(stsPropertiesMBean); when(tokenValidatorParameters.getToken()).thenReturn(receivedToken); doCallRealMethod().when(receivedToken) .setState(any(ReceivedToken.STATE.class)); doCallRealMethod().when(receivedToken) .getState(); TokenValidatorResponse tokenValidatorResponse = pkiTokenValidator.validateToken( tokenValidatorParameters); assertEquals(ReceivedToken.STATE.INVALID, tokenValidatorResponse.getToken() .getState()); } }