//* Licensed Materials - Property of * //* IBM * //* Miracle A/S * //* Alexandra Instituttet A/S * //* * //* eu.abc4trust.pabce.1.34 * //* * //* (C) Copyright IBM Corp. 2014. All Rights Reserved. * //* (C) Copyright Miracle A/S, Denmark. 2014. All Rights Reserved. * //* (C) Copyright Alexandra Instituttet A/S, Denmark. 2014. All * //* Rights Reserved. * //* US Government Users Restricted Rights - Use, duplication or * //* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * //* * //* This file is licensed under the Apache License, Version 2.0 (the * //* "License"); you may not use this file except in compliance with * //* the License. You may obtain a copy of the License at: * //* http://www.apache.org/licenses/LICENSE-2.0 * //* Unless required by applicable law or agreed to in writing, * //* software distributed under the License is distributed on an * //* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * //* KIND, either express or implied. See the License for the * //* specific language governing permissions and limitations * //* under the License. * //*/**/**************************************************************** package eu.abc4trust.abce.integrationtests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; import javax.xml.bind.JAXBException; import org.junit.Test; import org.xml.sax.SAXException; import com.google.inject.Guice; import com.google.inject.Injector; import com.ibm.zurich.idmx.interfaces.util.Pair; import eu.abc4trust.TestConfiguration; import eu.abc4trust.abce.external.inspector.InspectorAbcEngine; import eu.abc4trust.abce.external.issuer.IssuerAbcEngine; import eu.abc4trust.abce.external.revocation.RevocationAbcEngine; import eu.abc4trust.abce.external.verifier.VerifierAbcEngine; import eu.abc4trust.abce.internal.inspector.credentialManager.CredentialManagerException; import eu.abc4trust.abce.internal.user.credentialManager.CredentialManager; import eu.abc4trust.abce.testharness.IntegrationModuleFactory; import eu.abc4trust.abce.testharness.IssuanceHelper; import eu.abc4trust.cryptoEngine.CryptoEngineException; import eu.abc4trust.cryptoEngine.inspector.CryptoEngineInspector; import eu.abc4trust.exceptions.TokenVerificationException; import eu.abc4trust.guice.ProductionModuleFactory.CryptoEngine; import eu.abc4trust.keyManager.KeyManager; import eu.abc4trust.keyManager.KeyManagerException; import eu.abc4trust.revocationProxy.revauth.RevocationProxyAuthority; import eu.abc4trust.util.CryptoUriUtil; import eu.abc4trust.util.attributeEncoding.MyAttributeEncodingFactory; import eu.abc4trust.util.attributeTypes.MyAttributeValue; import eu.abc4trust.xml.Attribute; import eu.abc4trust.xml.CredentialDescription; import eu.abc4trust.xml.CredentialSpecification; import eu.abc4trust.xml.FriendlyDescription; import eu.abc4trust.xml.InspectorPublicKey; import eu.abc4trust.xml.IssuancePolicy; import eu.abc4trust.xml.IssuerParameters; import eu.abc4trust.xml.PresentationPolicyAlternatives; import eu.abc4trust.xml.PresentationToken; import eu.abc4trust.xml.Reference; import eu.abc4trust.xml.RevocationAuthorityParameters; import eu.abc4trust.xml.RevocationInformation; import eu.abc4trust.xml.SystemParameters; import eu.abc4trust.xml.util.XmlUtils; /** * This test checks 3 things: * That a user can get issued a simple identity card with firstname, lastname, and birthday. * That the cryptoengines can handle inspectable attributes. * That the inspection engine can decrypt an inspectable attribute of a presentationtoken. */ public class InspectionTest { private static final String USERNAME = "defaultUser"; private static final String NAME = "John"; private static final String LASTNAME = "Dow"; private static final String BIRTHDAY = "1990-02-06Z"; private static final String CREDENTIAL_SPECIFICATION_ID_CARD = "/eu/abc4trust/sampleXml/credspecs/credentialSpecificationSimpleIdentitycard.xml"; private static final String CREDENTIAL_SPECIFICATION_ID_CARD_UTF = "/eu/abc4trust/sampleXml/credspecs/credentialSpecificationSimpleIdentitycardUTFEncoded.xml"; private static final String CREDENTIAL_SPECIFICATION_REVOKABLE_ID_CARD = "/eu/abc4trust/sampleXml/credspecs/credentialSpecificationRevocationSimpleIdentitycard.xml"; private static final String CREDENTIAL_SPECIFICATION_STUDENT_CARD = "/eu/abc4trust/sampleXml/credspecs/credentialSpecificationStudentCard.xml"; private static final String ISSUANCE_POLICY_ID_CARD = "/eu/abc4trust/sampleXml/issuance/issuancePolicySimpleIdentitycard.xml"; private static final String ISSUANCE_POLICY_STUDENT_CARD = "/eu/abc4trust/sampleXml/issuance/issuancePolicyStudentCard.xml"; private static final String PRESENTATION_POLICY_CREDENTIALS = "/eu/abc4trust/sampleXml/presentationPolicies/presentationPolicySimpleIdentitycardWithInspection.xml"; private static final String PRESENTATION_POLICY_MULTIPLE_ATTRIBUTES_SAME_INSPECTOR = "/eu/abc4trust/sampleXml/presentationPolicies/presentationPolicyMultipleAttributesInspection.xml"; private static final String PRESENTATION_POLICY_MULTIPLE_ATTRIBUTES_DIFFERENT_INSPECTORS = "/eu/abc4trust/sampleXml/presentationPolicies/presentationPolicyMultipleAttributesDifferentInspectors.xml"; private static final String PRESENTATION_POLICY_INSPECT_AND_REVOKABLE = "/eu/abc4trust/sampleXml/presentationPolicies/presentationPolicyInspectionAndRevocation.xml"; private static final String PRESENTATION_POLICY_TWO_CREDS_SAME_ATTRIBUTE = "/eu/abc4trust/sampleXml/presentationPolicies/presentationPolicyInspectSameAttributeTwoCredentials.xml"; private static final String PRESENTATION_POLICY_SIMPLE_STUDENT_CARD = "/eu/abc4trust/sampleXml/presentationPolicies/presentationPolicySimpleStudentCard.xml"; private static final URI INSPECTOR_URI = URI.create("http://thebestbank.com/inspector/pub_key_v1"); private static final URI SECOND_INSPECTOR_URI = URI.create("http://inspector.com/inspector/pub_key_v1"); private static final URI REVOCATION_PARAMETERS_UID = URI.create("revocationUID1"); @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void simpleInspectionIdemixTest() throws Exception { URI cl_technology = Helper.getSignatureTechnologyURI("cl"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("GOVERNMENT", cl_technology, false); entities.addEntity("USER"); entities.addEntity("VERIFIER"); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsSingle(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void simpleInspectionUProveTest() throws Exception { URI uprove_technology = Helper.getSignatureTechnologyURI("brands"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("GOVERNMENT", uprove_technology, false); entities.addEntity("USER"); entities.addEntity("VERIFIER"); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsSingle(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void multiInspectionUProveTest() throws Exception{ URI uprove_technology = Helper.getSignatureTechnologyURI("brands"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("GOVERNMENT", uprove_technology, false); entities.addEntity("USER"); entities.addEntity("VERIFIER"); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsMulti(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void multiInspectionIdemixTest() throws Exception{ URI cl_technology = Helper.getSignatureTechnologyURI("cl"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("GOVERNMENT", cl_technology, false); entities.addEntity("USER"); entities.addEntity("VERIFIER"); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsMulti(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void revocationInspectionIdemixTest() throws Exception{ URI cl_technology = Helper.getSignatureTechnologyURI("cl"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("GOVERNMENT", cl_technology, true); entities.addEntity("USER", true); entities.addEntity("VERIFIER", true); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsRevocation(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void revocationInspectionUProveTest() throws Exception{ URI uprove_technology = Helper.getSignatureTechnologyURI("brands"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("GOVERNMENT", uprove_technology, true); entities.addEntity("USER", true); entities.addEntity("VERIFIER", true); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsRevocation(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void revocationMultipleCredsInspectionIdemixTest() throws Exception{ URI cl_technology = Helper.getSignatureTechnologyURI("cl"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("ISSUER", cl_technology, true); entities.addEntity("USER", true); entities.addEntity("VERIFIER", true); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsMultipleCredsRevocation(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void idemixTwoAttributesTwoInspectorsTest() throws Exception{ URI cl_technology = Helper.getSignatureTechnologyURI("cl"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("ISSUER", cl_technology, false); entities.addEntity("USER", false); entities.addEntity("VERIFIER", false); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); entities.addEntity("INSPECTOR2", CryptoUriUtil.getIdemixMechanism(), false); runTestsDifferentInspectors(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void uproveTwoAttributesTwoInspectorsTest() throws Exception{ URI uprove_technology = Helper.getSignatureTechnologyURI("brands"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("ISSUER", uprove_technology, false); entities.addEntity("USER", false); entities.addEntity("VERIFIER", false); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); entities.addEntity("INSPECTOR2", CryptoUriUtil.getIdemixMechanism(), false); runTestsDifferentInspectors(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void idemixTwoCredentialSameAttributeNameTest() throws Exception{ URI cl_technology = Helper.getSignatureTechnologyURI("cl"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("ISSUER", cl_technology, true); entities.addEntity("USER", true); entities.addEntity("VERIFIER", true); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsTwoCredSameAttribute(keyLength, entities); } @Test(timeout=TestConfiguration.TEST_TIMEOUT) public void uproveTwoCredentialSameAttributeNameTest() throws Exception{ URI uprove_technology = Helper.getSignatureTechnologyURI("brands"); int keyLength = 1024; Entities entities = new Entities(); entities.addEntity("ISSUER", uprove_technology, true); entities.addEntity("USER", true); entities.addEntity("VERIFIER", true); entities.addEntity("INSPECTOR", CryptoUriUtil.getIdemixMechanism(), false); runTestsTwoCredSameAttribute(keyLength, entities); } private void runTestsSingle(int keyLength, Entities entities) throws Exception { // Setp up engines Collection<Injector> injectors = createEntities(entities); SystemParameters systemParameters = Entities.setupSystemParameters(entities, keyLength); List<Object> parametersList = new ArrayList<Object>(); // Setup issuers URI credentialTechnology = entities.getTechnology("GOVERNMENT"); URI inspectorTechnology = entities.getTechnology("INSPECTOR"); URI issuerParametersGovernmentUID = getIssuanceParametersUIDFromIssuancePolicy(ISSUANCE_POLICY_ID_CARD); parametersList.add(setupIssuer(entities.getInjector("GOVERNMENT"), systemParameters, credentialTechnology, issuerParametersGovernmentUID, 3)); parametersList.add(setupInspector(entities.getInjector("INSPECTOR"), InspectionTest.INSPECTOR_URI, systemParameters, inspectorTechnology)); // Store all issuer parameters to all key managers entities.storePublicParametersToKeyManagers(parametersList); // Store all credential specifications to all key managers storeCredentialSpecificationToKeyManagers(injectors, CREDENTIAL_SPECIFICATION_ID_CARD); IssuanceHelper issuanceHelper = new IssuanceHelper(); // Step 1. Get an idcard. System.out.println(">> Get idcard."); this.issueAndStoreIdcard(entities.getInjector("GOVERNMENT"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_ID_CARD); // Step 2. Use the idcard to create (and verify) a presentationtoken. System.out.println(">> Verify."); PresentationToken pt = this.createPresentationToken( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), PRESENTATION_POLICY_CREDENTIALS); assertNotNull(pt); // Step 3. Inspect the presentationtoken to reveal the name on the idcard. System.out.println(">> Inspect."); this.inspectSingle(pt, entities.getInjector("INSPECTOR")); } private void runTestsMulti(int keyLength, Entities entities) throws Exception { // Setp up engines Collection<Injector> injectors = createEntities(entities); SystemParameters systemParameters = Entities.setupSystemParameters(entities, keyLength); List<Object> parametersList = new ArrayList<Object>(); // Setup issuers URI credentialTechnology = entities.getTechnology("GOVERNMENT"); URI inspectorTechnology = entities.getTechnology("INSPECTOR"); URI issuerParametersGovernmentUID = getIssuanceParametersUIDFromIssuancePolicy(ISSUANCE_POLICY_ID_CARD); parametersList.add(setupIssuer(entities.getInjector("GOVERNMENT"), systemParameters, credentialTechnology, issuerParametersGovernmentUID, 3)); parametersList.add(setupInspector(entities.getInjector("INSPECTOR"), InspectionTest.INSPECTOR_URI, systemParameters, inspectorTechnology)); // Store all issuer parameters to all key managers entities.storePublicParametersToKeyManagers(parametersList); // Store all credential specifications to all key managers storeCredentialSpecificationToKeyManagers(injectors, CREDENTIAL_SPECIFICATION_ID_CARD); IssuanceHelper issuanceHelper = new IssuanceHelper(); // Step 1. Get an idcard. System.out.println(">> Get idcard."); this.issueAndStoreIdcard(entities.getInjector("GOVERNMENT"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_ID_CARD); // Step 2. Use the idcard to create (and verify) a presentationtoken. System.out.println(">> Verify."); PresentationToken pt = this.createPresentationToken( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), PRESENTATION_POLICY_MULTIPLE_ATTRIBUTES_SAME_INSPECTOR); assertNotNull(pt); // Step 3. Inspect the presentationtoken to reveal the name on the idcard. System.out.println(">> Inspect."); this.inspectFirstNameAndBirthday(pt, entities.getInjector("INSPECTOR")); } private void runTestsRevocation(int keyLength, Entities entities) throws Exception { // Setp up engines Injector revocationInjector = Guice .createInjector(IntegrationModuleFactory.newModule(new Random(1231), CryptoEngine.IDEMIX)); RevocationProxyAuthority revocationProxyAuthority = revocationInjector .getInstance(RevocationProxyAuthority.class); KeyManager revocationKeyManager = revocationInjector .getInstance(KeyManager.class); Collection<Injector> injectors = createEntities(entities, revocationProxyAuthority); SystemParameters systemParameters = Entities.setupSystemParameters(entities, keyLength); revocationKeyManager.storeSystemParameters(systemParameters); List<Object> parametersList = new ArrayList<Object>(); RevocationAbcEngine revocationEngine = revocationInjector .getInstance(RevocationAbcEngine.class); RevocationAuthorityParameters revocationAuthorityParameters = this.setupRevocationEngine(revocationInjector, REVOCATION_PARAMETERS_UID, keyLength); // Setup issuer and inspector URI credentialTechnology = entities.getTechnology("GOVERNMENT"); URI inspectorTechnology = entities.getTechnology("INSPECTOR"); URI issuerParametersGovernmentUID = getIssuanceParametersUIDFromIssuancePolicy(ISSUANCE_POLICY_ID_CARD); parametersList.add(setupIssuer(entities.getInjector("GOVERNMENT"), systemParameters, credentialTechnology, issuerParametersGovernmentUID, 4, REVOCATION_PARAMETERS_UID)); parametersList.add(setupInspector(entities.getInjector("INSPECTOR"), InspectionTest.INSPECTOR_URI, systemParameters, inspectorTechnology)); // Store all issuer and inspector parameters to all key managers entities.storePublicParametersToKeyManagers(parametersList); // Store all credential specifications to all key managers storeCredentialSpecificationToKeyManagers(injectors, CREDENTIAL_SPECIFICATION_REVOKABLE_ID_CARD); addRevocationKeyManagers(entities, revocationAuthorityParameters); IssuanceHelper issuanceHelper = new IssuanceHelper(); // Step 1. Get an idcard. System.out.println(">> Get idcard."); CredentialDescription cd = this.issueAndStoreIdcard(entities.getInjector("GOVERNMENT"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_REVOKABLE_ID_CARD); // Step 2. Use the idcard to create (and verify) a presentationtoken. System.out.println(">> Verify."); PresentationToken pt = this.createPresentationTokenWithRevocation( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), PRESENTATION_POLICY_INSPECT_AND_REVOKABLE, REVOCATION_PARAMETERS_UID); assertNotNull(pt); // Step 3. Inspect the presentationtoken to reveal the name on the idcard. System.out.println(">> Inspect."); Attribute revocationHandleAttribute = this.inspectRevocation(pt, entities.getInjector("INSPECTOR")); // Step 4. Revoke the credential. this.revokeCredential(revocationInjector, issuanceHelper, REVOCATION_PARAMETERS_UID, revocationHandleAttribute); RevocationInformation revocationInformation = revocationEngine .updateRevocationInformation(REVOCATION_PARAMETERS_UID); // Step 5. Verify revoked credential is revoked. this.revokedCredentialsShouldNotBeAllowed( entities.getInjector("USER"), entities.getInjector("VERIFIER"), issuanceHelper, revocationInformation, cd.getCredentialUID()); } private void runTestsMultipleCredsRevocation(int keyLength, Entities entities) throws Exception { // Setp up engines Injector revocationInjector = Guice .createInjector(IntegrationModuleFactory.newModule(new Random(1231), CryptoEngine.IDEMIX)); RevocationProxyAuthority revocationProxyAuthority = revocationInjector .getInstance(RevocationProxyAuthority.class); KeyManager revocationKeyManager = revocationInjector .getInstance(KeyManager.class); Collection<Injector> injectors = createEntities(entities, revocationProxyAuthority); SystemParameters systemParameters = Entities.setupSystemParameters(entities, keyLength); revocationKeyManager.storeSystemParameters(systemParameters); List<Object> parametersList = new ArrayList<Object>(); RevocationAbcEngine revocationEngine = revocationInjector .getInstance(RevocationAbcEngine.class); RevocationAuthorityParameters revocationAuthorityParameters = this.setupRevocationEngine(revocationInjector, REVOCATION_PARAMETERS_UID, keyLength); // Setup issuer and inspector URI credentialTechnology = entities.getTechnology("ISSUER"); URI inspectorTechnology = entities.getTechnology("INSPECTOR"); URI issuerParametersGovernmentUID = getIssuanceParametersUIDFromIssuancePolicy(ISSUANCE_POLICY_ID_CARD); parametersList.add(setupIssuer(entities.getInjector("ISSUER"), systemParameters, credentialTechnology, issuerParametersGovernmentUID, 4, REVOCATION_PARAMETERS_UID)); URI issuerParametersStudentcardUID = getIssuanceParametersUIDFromIssuancePolicy(ISSUANCE_POLICY_STUDENT_CARD); parametersList.add(setupIssuer(entities.getInjector("ISSUER"), systemParameters, credentialTechnology, issuerParametersStudentcardUID, 7, REVOCATION_PARAMETERS_UID)); parametersList.add(setupInspector(entities.getInjector("INSPECTOR"), InspectionTest.INSPECTOR_URI, systemParameters, inspectorTechnology)); // Store all issuer and inspector parameters to all key managers entities.storePublicParametersToKeyManagers(parametersList); // Store all credential specifications to all key managers storeCredentialSpecificationToKeyManagers(injectors, CREDENTIAL_SPECIFICATION_REVOKABLE_ID_CARD); storeCredentialSpecificationToKeyManagers(injectors, CREDENTIAL_SPECIFICATION_STUDENT_CARD); addRevocationKeyManagers(entities, revocationAuthorityParameters); IssuanceHelper issuanceHelper = new IssuanceHelper(); // Step 1. Get two idcards and a studentcard. System.out.println(">> Get idcard."); CredentialDescription cd = this.issueAndStoreIdcard(entities.getInjector("ISSUER"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_REVOKABLE_ID_CARD); CredentialDescription cd2 = this.issueAndStoreIdcard(entities.getInjector("ISSUER"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_REVOKABLE_ID_CARD); System.out.println(">> Get studentcard."); CredentialDescription cd3 = this.issueAndStoreStudentCard(entities.getInjector("ISSUER"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_STUDENT_CARD); // Step 2a. Use the idcard to create (and verify) a presentationtoken. System.out.println(">> Verify."); PresentationToken pt = this.createPresentationTokenWithRevocation( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), cd.getCredentialUID(), PRESENTATION_POLICY_INSPECT_AND_REVOKABLE, REVOCATION_PARAMETERS_UID); PresentationToken pt2 = this.createPresentationTokenWithRevocation( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), cd2.getCredentialUID(), PRESENTATION_POLICY_INSPECT_AND_REVOKABLE, REVOCATION_PARAMETERS_UID); // Step 2b. Use Studentcard to create (and verify) a presentationtoken. PresentationToken studentCardPT = this.createPresentationTokenWithRevocation( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), cd3.getCredentialUID(), PRESENTATION_POLICY_SIMPLE_STUDENT_CARD, REVOCATION_PARAMETERS_UID); assertNotNull(pt); // Step 3. Inspect the presentationtoken to reveal the revocation handle. System.out.println(">> Inspect."); Attribute revocationHandleAttribute = this.inspectRevocation(pt, entities.getInjector("INSPECTOR")); // Step 4. Revoke the credential. this.revokeCredential(revocationInjector, issuanceHelper, REVOCATION_PARAMETERS_UID, revocationHandleAttribute); RevocationInformation revocationInformation = revocationEngine .updateRevocationInformation(REVOCATION_PARAMETERS_UID); KeyManager hotelKeyManager = entities.getInjector("VERIFIER").getInstance(KeyManager.class); KeyManager userKeyManager = entities.getInjector("USER").getInstance(KeyManager.class); // Step 5. Verify revoked credential is revoked. this.revokedCredentialsShouldNotBeAllowed( entities.getInjector("USER"), entities.getInjector("VERIFIER"), issuanceHelper, revocationInformation, cd.getCredentialUID()); userKeyManager.getLatestRevocationInformation(REVOCATION_PARAMETERS_UID); hotelKeyManager.getLatestRevocationInformation(REVOCATION_PARAMETERS_UID); entities.getInjector("USER").getInstance(CredentialManager.class).updateNonRevocationEvidence(USERNAME); // Step 6. Verify that studentCredential is still valid. studentCardPT = this.createPresentationTokenWithRevocation( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), cd3.getCredentialUID(), PRESENTATION_POLICY_SIMPLE_STUDENT_CARD, REVOCATION_PARAMETERS_UID); // Step 6b. Verify that id card 2 is still valid this.createPresentationTokenWithRevocation( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), cd2.getCredentialUID(), PRESENTATION_POLICY_INSPECT_AND_REVOKABLE, REVOCATION_PARAMETERS_UID); } private void runTestsDifferentInspectors(int keyLength, Entities entities) throws Exception { // Setp up engines Collection<Injector> injectors = createEntities(entities); SystemParameters systemParameters = Entities.setupSystemParameters(entities, keyLength); List<Object> parametersList = new ArrayList<Object>(); // Setup issuers URI credentialTechnology = entities.getTechnology("ISSUER"); URI inspectorTechnology = entities.getTechnology("INSPECTOR"); URI secondInspectorTechnology = entities.getTechnology("INSPECTOR2"); URI issuerParametersGovernmentUID = getIssuanceParametersUIDFromIssuancePolicy(ISSUANCE_POLICY_ID_CARD); parametersList.add(setupIssuer(entities.getInjector("ISSUER"), systemParameters, credentialTechnology, issuerParametersGovernmentUID, 3)); parametersList.add(setupInspector(entities.getInjector("INSPECTOR"), InspectionTest.INSPECTOR_URI, systemParameters, inspectorTechnology)); parametersList.add(setupInspector(entities.getInjector("INSPECTOR2"), InspectionTest.SECOND_INSPECTOR_URI, systemParameters, secondInspectorTechnology)); // Store all issuer parameters to all key managers entities.storePublicParametersToKeyManagers(parametersList); // Store all credential specifications to all key managers storeCredentialSpecificationToKeyManagers(injectors, CREDENTIAL_SPECIFICATION_ID_CARD_UTF); IssuanceHelper issuanceHelper = new IssuanceHelper(); // Step 1. Get an idcard. System.out.println(">> Get idcard."); this.issueAndStoreIdcard(entities.getInjector("ISSUER"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_ID_CARD_UTF); // Step 2. Use the idcard to create (and verify) a presentationtoken. System.out.println(">> Verify."); PresentationToken pt = this.createPresentationToken( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), PRESENTATION_POLICY_MULTIPLE_ATTRIBUTES_DIFFERENT_INSPECTORS); assertNotNull(pt); // Step 3. Inspect the presentationtoken to reveal the name on the idcard. System.out.println(">> Inspect."); this.inspectDifferentInspectors(pt, entities.getInjector("INSPECTOR"), entities.getInjector("INSPECTOR2")); } private void runTestsTwoCredSameAttribute(int keyLength, Entities entities) throws Exception{ // Setp up engines Injector revocationInjector = Guice .createInjector(IntegrationModuleFactory.newModule(new Random(1231), CryptoEngine.IDEMIX)); RevocationProxyAuthority revocationProxyAuthority = revocationInjector .getInstance(RevocationProxyAuthority.class); KeyManager revocationKeyManager = revocationInjector .getInstance(KeyManager.class); Collection<Injector> injectors = createEntities(entities, revocationProxyAuthority); SystemParameters systemParameters = Entities.setupSystemParameters(entities, keyLength); revocationKeyManager.storeSystemParameters(systemParameters); List<Object> parametersList = new ArrayList<Object>(); RevocationAuthorityParameters revocationAuthorityParameters = this.setupRevocationEngine(revocationInjector, REVOCATION_PARAMETERS_UID, keyLength); addRevocationKeyManagers(entities, revocationAuthorityParameters); // Setup issuers URI credentialTechnology = entities.getTechnology("ISSUER"); URI inspectorTechnology = entities.getTechnology("INSPECTOR"); URI issuerParametersGovernmentUID = getIssuanceParametersUIDFromIssuancePolicy(ISSUANCE_POLICY_ID_CARD); parametersList.add(setupIssuer(entities.getInjector("ISSUER"), systemParameters, credentialTechnology, issuerParametersGovernmentUID, 3)); parametersList.add(setupInspector(entities.getInjector("INSPECTOR"), InspectionTest.SECOND_INSPECTOR_URI, systemParameters, inspectorTechnology)); URI issuerParametersStudentcardUID = getIssuanceParametersUIDFromIssuancePolicy(ISSUANCE_POLICY_STUDENT_CARD); parametersList.add(setupIssuer(entities.getInjector("ISSUER"), systemParameters, credentialTechnology, issuerParametersStudentcardUID, 7, REVOCATION_PARAMETERS_UID)); // Store all issuer parameters to all key managers entities.storePublicParametersToKeyManagers(parametersList); // Store all credential specifications to all key managers storeCredentialSpecificationToKeyManagers(injectors, CREDENTIAL_SPECIFICATION_ID_CARD_UTF); storeCredentialSpecificationToKeyManagers(injectors, CREDENTIAL_SPECIFICATION_STUDENT_CARD); IssuanceHelper issuanceHelper = new IssuanceHelper(); // Step 1. Get an idcard and studentcard. System.out.println(">> Get idcard."); CredentialDescription cd1 = this.issueAndStoreIdcard(entities.getInjector("ISSUER"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_ID_CARD_UTF); System.out.println(">> Get studentcard."); CredentialDescription cd2 = this.issueAndStoreStudentCard(entities.getInjector("ISSUER"), entities.getInjector("USER"), issuanceHelper, CREDENTIAL_SPECIFICATION_STUDENT_CARD); // Step 2. Use the idcard to create (and verify) a presentationtoken. System.out.println(">> Verify."); PresentationToken pt = this.createPresentationToken( issuanceHelper, entities.getInjector("VERIFIER"), entities.getInjector("USER"), PRESENTATION_POLICY_TWO_CREDS_SAME_ATTRIBUTE); assertNotNull(pt); // Step 3. Inspect the presentationtoken to reveal the name on the idcard. System.out.println(">> Inspect."); this.inspectIdenticalAttributeInDifferentCredentials(pt, entities.getInjector("INSPECTOR")); } private CredentialDescription issueAndStoreIdcard(Injector governmentInjector, Injector userInjector, IssuanceHelper issuanceHelper, String credSpec) throws Exception { Map<String, Object> passportAtts = this.populateIdcardAttributes(); return issuanceHelper.issueCredential(USERNAME, governmentInjector, userInjector, credSpec, ISSUANCE_POLICY_ID_CARD, passportAtts, null); } private CredentialDescription issueAndStoreStudentCard(Injector governmentInjector, Injector userInjector, IssuanceHelper issuanceHelper, String credSpec) throws Exception { Map<String, Object> studentAtts = this.populateStudentcardAttributes(); return issuanceHelper.issueCredential(USERNAME, governmentInjector, userInjector, credSpec, ISSUANCE_POLICY_STUDENT_CARD, studentAtts, null); } private RevocationAuthorityParameters setupRevocationEngine(Injector revocationInjector, URI revParamsUid, int keyLength) throws Exception{ RevocationAbcEngine revocationEngine = revocationInjector .getInstance(RevocationAbcEngine.class); Reference revocationInfoReference = new Reference(); revocationInfoReference.setReferenceType(URI.create("url")); revocationInfoReference.getReferences().add(URI.create("https://example.org/")); Reference nonRevocationEvidenceReference = new Reference(); nonRevocationEvidenceReference.setReferenceType(URI.create("url")); nonRevocationEvidenceReference.getReferences().add(URI.create("https://example.org/")); Reference nonRrevocationUpdateReference = new Reference(); nonRrevocationUpdateReference.setReferenceType(URI.create("url")); nonRrevocationUpdateReference.getReferences().add(URI.create("https://example.org/")); return revocationEngine.setupRevocationAuthorityParameters(keyLength, Helper.getRevocationTechnologyURI("cl"), revParamsUid, revocationInfoReference, nonRevocationEvidenceReference, nonRrevocationUpdateReference); } private Map<String, Object> populateIdcardAttributes() { Map<String, Object> att = new HashMap<String, Object>(); att.put("FirstName", NAME); att.put("LastName", LASTNAME); att.put("Birthday", BIRTHDAY); return att; } private Map<String, Object> populateStudentcardAttributes() { Map<String, Object> att = new HashMap<String, Object>(); att.put("Name", NAME); att.put("LastName", LASTNAME); att.put("StudentNumber", 1000); att.put("Issued", "2012-11-11Z"); att.put("Expires", "2015-11-11Z"); att.put("IssuedBy", "University of X"); return att; } private PresentationToken createPresentationTokenWithRevocation(IssuanceHelper issuanceHelper, Injector hotelInjector, Injector userInjector, String presentationPolicy, URI revParamsUid) throws Exception { return createPresentationTokenWithRevocation(issuanceHelper, hotelInjector, userInjector, null, presentationPolicy, revParamsUid); } private PresentationToken createPresentationTokenWithRevocation(IssuanceHelper issuanceHelper, Injector hotelInjector, Injector userInjector, URI selectedCredential, String presentationPolicy, URI revParamsUid) throws Exception { VerifierAbcEngine verifierEngine = hotelInjector .getInstance(VerifierAbcEngine.class); RevocationInformation revocationInformation = verifierEngine .getLatestRevocationInformation(revParamsUid); Pair<PresentationToken, PresentationPolicyAlternatives> p = issuanceHelper .createPresentationToken(USERNAME, userInjector, presentationPolicy, revocationInformation, null); PresentationToken pt = p.first; assertNotNull(pt); return issuanceHelper.verify(hotelInjector, p.second, p.first); } private PresentationToken createPresentationToken(IssuanceHelper issuanceHelper, Injector verifierInjector, Injector userInjector, String presentationPolicy) throws Exception { Pair<PresentationToken, PresentationPolicyAlternatives> p = issuanceHelper .createPresentationToken(USERNAME, userInjector, presentationPolicy, null, null); PresentationToken pt = p.first; assertNotNull(pt); return issuanceHelper.verify(verifierInjector, p.second, p.first); } private void inspectFirstNameAndBirthday(PresentationToken pt, Injector inspectorInjector){ CryptoEngineInspector engine = inspectorInjector.getInstance(CryptoEngineInspector.class); try { List<Attribute> inspectedAttributes = engine.inspect(pt); assertEquals(inspectedAttributes.size(), 2); Attribute inspectedFirstName = inspectedAttributes.get(1); Attribute inspectedBirthday = inspectedAttributes.get(0); assertEquals(NAME, inspectedFirstName.getAttributeValue()); assertEquals(BIRTHDAY, inspectedBirthday.getAttributeValue().toString()); } catch (Exception e) { e.printStackTrace(); throw new IllegalStateException("Test should not fail here!", e); } } private void inspectSingle(PresentationToken pt, Injector inspectorInjector){ CryptoEngineInspector engine = inspectorInjector.getInstance(CryptoEngineInspector.class); try { List<Attribute> inspectedAttributes = engine.inspect(pt); assertEquals(inspectedAttributes.size(), 1); Attribute inspectedAttr = inspectedAttributes.get(0); assertEquals(NAME, inspectedAttr.getAttributeValue()); } catch (Exception e) { e.printStackTrace(); } } private void inspectIdenticalAttributeInDifferentCredentials(PresentationToken pt, Injector inspectorInjector){ CryptoEngineInspector engine = inspectorInjector.getInstance(CryptoEngineInspector.class); try { List<Attribute> inspectedAttributes = engine.inspect(pt); assertEquals(inspectedAttributes.size(), 2); Attribute inspectedAttr = inspectedAttributes.get(0); Attribute inspectedAttr2 = inspectedAttributes.get(1); assertEquals(LASTNAME, inspectedAttr.getAttributeValue()); assertEquals(LASTNAME, inspectedAttr2.getAttributeValue()); } catch (Exception e) { e.printStackTrace(); } } private Attribute inspectRevocation(PresentationToken pt, Injector inspectorInjector){ CryptoEngineInspector engine = inspectorInjector.getInstance(CryptoEngineInspector.class); Attribute revokedHandle = null; try { List<Attribute> inspectedAttributes = engine.inspect(pt); assertEquals(inspectedAttributes.size(), 2); Attribute inspectedAttr1 = inspectedAttributes.get(0); revokedHandle = inspectedAttributes.get(1); assertEquals(inspectedAttr1.getAttributeValue(), NAME); } catch (Exception e) { e.printStackTrace(); } assertNotNull("Failed to inspect revocation handle!", revokedHandle); return revokedHandle; } private void inspectDifferentInspectors(PresentationToken pt, Injector inspectorInjector, Injector secondInspectorInjector){ CryptoEngineInspector engine = inspectorInjector.getInstance(CryptoEngineInspector.class); CryptoEngineInspector secondInspector = secondInspectorInjector.getInstance(CryptoEngineInspector.class); try{ MyAttributeValue lastname = MyAttributeEncodingFactory.parseValueFromEncoding(URI.create("urn:abc4trust:1.0:encoding:string:sha-256"), LASTNAME, null); List<Attribute> inspectedAttributes = engine.inspect(pt); assertEquals(inspectedAttributes.size(),1 ); Attribute inspectedFirstName = inspectedAttributes.get(0); assertEquals(inspectedFirstName.getAttributeValue(), NAME); inspectedAttributes = secondInspector.inspect(pt); assertEquals(1, inspectedAttributes.size()); Attribute inspectedLastName = inspectedAttributes.get(0); assertEquals(LASTNAME, inspectedLastName.getAttributeValue()); }catch(Exception e){ throw new RuntimeException(e); } } private void revokeCredential(Injector revocationInjector, IssuanceHelper issuanceHelper, URI revParamsUid, Attribute revocationHandleAttribute) throws CryptoEngineException { issuanceHelper.revokeCredential(revocationInjector, revParamsUid, revocationHandleAttribute); } private void revokedCredentialsShouldNotBeAllowed(Injector userInjector, Injector verifierInjector, IssuanceHelper issuanceHelper, RevocationInformation revocationInformation, URI chosenCredential) throws Exception { try { this.loginToSpecificAccount(userInjector, verifierInjector, issuanceHelper, REVOCATION_PARAMETERS_UID, revocationInformation, chosenCredential, PRESENTATION_POLICY_INSPECT_AND_REVOKABLE); fail("We should not be allowed to log in with a revoked credential"); } catch (TokenVerificationException ex) { assertTrue( "We expect the verification to fail due to a revoked credential", ex.getMessage() .startsWith( "The crypto evidence in the presentation token is not valid")); } catch (RuntimeException ex) { assertTrue( "We expect presentation token generation to fail", ex.getMessage().startsWith("Cannot generate presentationToken") || ex.getMessage().startsWith("Cannot choose credential, URI does not exist!")); } } private PresentationToken loginToSpecificAccount(Injector userInjector, Injector verifierInjector, IssuanceHelper issuanceHelper, URI revParamsUid, RevocationInformation revocationInformation, URI chosenCredential, String presentationPolicy) throws Exception { Pair<PresentationToken, PresentationPolicyAlternatives> p = issuanceHelper .createSpecificPresentationToken(USERNAME, userInjector, presentationPolicy, chosenCredential, revocationInformation, null); return issuanceHelper.verify(verifierInjector, p.second, p.first); } private Collection<Injector> createEntities(Entities entities) { entities.initInjectors(null); return entities.getInjectors(); } private Collection<Injector> createEntities(Entities entities, RevocationProxyAuthority revocationProxyAuthority) { entities.initInjectors(revocationProxyAuthority); return entities.getInjectors(); } private URI getIssuanceParametersUIDFromIssuancePolicy(String pathToIssuancePolicy) throws UnsupportedEncodingException, JAXBException, SAXException { // Load issuance policy IssuancePolicy issuancePolicy = (IssuancePolicy) XmlUtils.getObjectFromXML( this.getClass().getResourceAsStream(pathToIssuancePolicy), true); // Get issuer parameters UID from credential template return issuancePolicy.getCredentialTemplate().getIssuerParametersUID(); } private IssuerParameters setupIssuer(Injector issuerInjector, SystemParameters systemParameters, URI credentialTechnology, URI issuanceParametersUID, int maximalNumberOfAttributes) throws CryptoEngineException { return this.setupIssuer(issuerInjector, systemParameters, credentialTechnology, issuanceParametersUID, maximalNumberOfAttributes, null); } private IssuerParameters setupIssuer(Injector issuerInjector, SystemParameters systemParameters, URI credentialTechnology, URI issuanceParametersUID, int maximalNumberOfAttributes, URI revocationAuthority) throws CryptoEngineException { // Generate issuer parameters. IssuerAbcEngine issuerEngine = issuerInjector.getInstance(IssuerAbcEngine.class); IssuerParameters issuerParameters = issuerEngine.setupIssuerParameters(systemParameters, maximalNumberOfAttributes, credentialTechnology, issuanceParametersUID, revocationAuthority, new LinkedList<FriendlyDescription>()); return issuerParameters; } private InspectorPublicKey setupInspector(Injector inspectorInjector, URI uid, SystemParameters systemParameters, URI inspectorTechnology) throws CryptoEngineException, CredentialManagerException { // Generate issuer parameters. InspectorAbcEngine inspectorAbcEngine = inspectorInjector.getInstance(InspectorAbcEngine.class); return inspectorAbcEngine.setupInspectorPublicKey(systemParameters, inspectorTechnology, uid, new LinkedList<FriendlyDescription>()); } private void storeCredentialSpecificationToKeyManagers(Collection<Injector> injectors, String pathToCredentialSpecification) throws KeyManagerException, UnsupportedEncodingException, JAXBException, SAXException { // Load credential specifications. CredentialSpecification credSpec = (CredentialSpecification) XmlUtils.getObjectFromXML( this.getClass().getResourceAsStream(pathToCredentialSpecification), true); // Store credential specifications. URI specificationUID = credSpec.getSpecificationUID(); for (Injector injector : injectors) { KeyManager keyManager = injector.getInstance(KeyManager.class); keyManager.storeCredentialSpecification(specificationUID, credSpec); } } private void addRevocationKeyManagers(Entities entities, RevocationAuthorityParameters revAuthParams) throws KeyManagerException{ for(Injector injector: entities.getInjectors()){ KeyManager keyManager = injector.getInstance(KeyManager.class); keyManager.storeRevocationAuthorityParameters(revAuthParams.getParametersUID(), revAuthParams); } } }