//* Licensed Materials - Property of * //* Alexandra Instituttet A/S * //* * //* eu.abc4trust.pabce.1.34 * //* * //* (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.services; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.security.SecureRandom; import java.util.ArrayList; 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.AbstractModule; import com.google.inject.Module; import com.google.inject.Singleton; import eu.abc4trust.abce.internal.user.policyCredentialMatcher.PolicyCredentialMatcherImpl; import eu.abc4trust.abce.utils.SecretWrapper; import eu.abc4trust.guice.ProductionModuleFactory.CryptoEngine; import eu.abc4trust.keyManager.KeyManager; import eu.abc4trust.keyManager.KeyManagerException; import eu.abc4trust.returnTypes.IssuanceReturn; import eu.abc4trust.returnTypes.UiIssuanceReturn; import eu.abc4trust.returnTypes.UiPresentationArguments; import eu.abc4trust.returnTypes.UiPresentationReturn; import eu.abc4trust.revocationProxy.InMemoryCommunicationStrategy; import eu.abc4trust.revocationProxy.RevocationProxyCommunicationStrategy; import eu.abc4trust.revocationProxy.revauth.RevocationProxyAuthority; import eu.abc4trust.ri.servicehelper.FileSystem; import eu.abc4trust.ri.servicehelper.issuer.IssuanceHelper; import eu.abc4trust.ri.servicehelper.user.UserHelper; import eu.abc4trust.ri.servicehelper.verifier.VerificationHelper; import eu.abc4trust.services.helpers.RevocationHelper; import eu.abc4trust.smartcard.BasicSmartcard; import eu.abc4trust.util.CryptoUriUtil; import eu.abc4trust.xml.Attribute; import eu.abc4trust.xml.CredentialSpecification; import eu.abc4trust.xml.FriendlyDescription; import eu.abc4trust.xml.InspectorPublicKey; import eu.abc4trust.xml.IssuanceMessage; import eu.abc4trust.xml.IssuanceMessageAndBoolean; import eu.abc4trust.xml.IssuancePolicy; import eu.abc4trust.xml.IssuancePolicyAndAttributes; import eu.abc4trust.xml.IssuerParameters; import eu.abc4trust.xml.IssuerParametersInput; import eu.abc4trust.xml.ObjectFactory; import eu.abc4trust.xml.PresentationPolicyAlternatives; import eu.abc4trust.xml.PresentationToken; import eu.abc4trust.xml.PresentationTokenDescription; import eu.abc4trust.xml.PseudonymMetadata; import eu.abc4trust.xml.Reference; import eu.abc4trust.xml.RevocationAuthorityParameters; import eu.abc4trust.xml.RevocationReferences; import eu.abc4trust.xml.SystemParameters; import eu.abc4trust.xml.util.XmlUtils; public class ITTicketTutorial extends ITAbstract { private static final CryptoEngine cryptoEngine = CryptoEngine.IDEMIX; private static final String USERNAME = "default_user"; private static final String revocation_fileStoragePrefix = "target/revocation_storage/"; private static final String issuerParamsPrefix = "target/issuer_resources/"; private static final String issuerFileStoragePrefix = "target/issuer_storage/"; private static final String userFileStoragePrefix = "target/user_storage/"; private static final String verifierFileStoragePrefix = "target/verifier_storage/"; private static final URI cryptographicMechanism = URI .create("urn:abc4trust:1.0:algorithm:idemix"); private static final int revocation_keyLength = 1024; private SystemParameters sysparams; static ObjectFactory of = new ObjectFactory(); final String baseUrl = "http://localhost:9500/abce-services/issuer"; private final Module inMemoryRevocationCommunicationStrategy = new AbstractModule() { @Override protected void configure() { this.bind(RevocationProxyCommunicationStrategy.class) .to(InMemoryCommunicationStrategy.class) .in(Singleton.class); } }; @Test public void completeFlow() throws Exception { PolicyCredentialMatcherImpl.GENERATE_SECRET_IF_NONE_EXIST = false; this.deleteStorageDirectory("revocation_storage"); this.deleteStorageDirectory("issuer_resources"); this.deleteStorageDirectory("issuer_storage"); this.deleteStorageDirectory("user_storage"); this.deleteStorageDirectory("verifier_storage"); // Setup revocation helper. final RevocationHelper revocationHelper = this.setupRevocationHelper(); Module revocationProxyAuthorityModule = new AbstractModule() { @Override protected void configure() { this.bind(RevocationProxyAuthority.class).toInstance( revocationHelper.revocationProxyAuthority); this.bind(RevocationProxyCommunicationStrategy.class) .to(InMemoryCommunicationStrategy.class) .in(Singleton.class); } }; // Setup issuance helper. IssuanceHelper issuanceHelper = this .setupIssuanceHelper(revocationProxyAuthorityModule); // Setup user helper. UserHelper userHelper = this .setupUserHelper(revocationProxyAuthorityModule); // Setup verification helper. VerificationHelper verificationHelper = this .setupVerificationHelper(revocationProxyAuthorityModule); // Setup System Parameters. SystemParameters systemParameters = this.setupSystemParameters(issuanceHelper); sysparams = systemParameters; // Store System parameters at Revocation Authority. this.storeSystemParametersAtRevocationAuthority(systemParameters); // Store System parameters at User. this.storeSystemParametersAtUser(userHelper, systemParameters); // Store System parameters at Verifier. this.storeSystemParametersAtVerifier(verificationHelper, systemParameters); CredentialSpecification credentialSpecification = this .getCredentialSpecification(); // Store credential specification at issuer. this.storeCredentialSpecificationAtIssuer(issuanceHelper, credentialSpecification); // Store credential specification at user. this.storeCredentialSpecificationAtUser(userHelper, credentialSpecification); // Store credential specification at Verifier. this.storeCredentialSpecificationAtVerifier(verificationHelper, credentialSpecification); // Setup Revocation Authority Parameters. RevocationAuthorityParameters revocationAuthorityParameters = this.setupRevocationAuthorityParameters(revocationHelper); // Store Revocation Authority Parameters at issuer. this.storeRevocationAuthorityParametersAtIssuer(issuanceHelper, revocationAuthorityParameters); // Store Revocation Authority Parameters at user. this.storeRevocationAuthorityParametersAtUser(userHelper, revocationAuthorityParameters); // Store Revocation Authority Parameters at verifier. this.storeRevocationAuthorityParametersAtVerifier(verificationHelper, revocationAuthorityParameters); // Setup issuer parameters. IssuerParameters issuerParameters = this .setupIssuerParameters(issuanceHelper); // Store Issuer Parameters at user. this.storeIssuerParametersAtUser(userHelper, issuerParameters); // Store Issuer Parameters at verifier. this.storeIssuerParametersAtVerifier(verificationHelper, issuerParameters); // Create smartcard at user. // this.createSmartcardAtUser(userHelper, // issuerParameters.getParametersUID()); // Init issuance protocol. IssuanceMessageAndBoolean issuanceMessageAndBoolean = this .initIssuanceProtocol(issuanceHelper); // Extract issuance message. IssuanceMessage issuanceMessage = issuanceMessageAndBoolean .getIssuanceMessage(); // First issuance protocol step (first step for the user. IssuanceReturn issuanceReturn = this.issuanceProtocolStep(userHelper, issuanceMessage); // First issuance protocol step - UI (first step for the user). UiIssuanceReturn uiIssuanceReturn = this.getUiIssuanceReturn(issuanceReturn); IssuanceMessage secondIssuanceMessage = this.issuanceProtocolStepUi( userHelper, uiIssuanceReturn); // Second issuance protocol step (second step for the issuer). IssuanceMessageAndBoolean secondIssuanceMessageAndBoolean = this .issuanceProtocolStep(issuanceHelper, secondIssuanceMessage); // Extract issuance message. IssuanceMessage thirdIssuanceMessage = secondIssuanceMessageAndBoolean .getIssuanceMessage(); // Third issuance protocol step (second step for the user). IssuanceReturn secondIssuanceReturn = this.issuanceProtocolStep( userHelper, thirdIssuanceMessage); assertNotNull(secondIssuanceReturn.cd); assertNull(secondIssuanceReturn.im); assertNull(secondIssuanceReturn.uia); // Create presentation policy alternatives. PresentationPolicyAlternatives modifiedPresentationPolicyAlternatives = this .createPresentationPolicyAlternatives(verificationHelper); // Create presentation UI return. UiPresentationArguments uiPresentationArguments = this .createPresentationToken(userHelper, modifiedPresentationPolicyAlternatives); UiPresentationReturn uiPresentationReturn = this .createUiPresentationReturn(uiPresentationArguments.uiContext); // Create presentation token. PresentationToken presentationToken = this .createPresentationTokenUi(userHelper, uiPresentationReturn); // Verify presentation token against presentation policy. PresentationTokenDescription presentationTokenDescription = this .verifyTokenAgainstPolicy(verificationHelper, presentationToken, modifiedPresentationPolicyAlternatives); assertNotNull(presentationTokenDescription); } private PresentationTokenDescription verifyTokenAgainstPolicy( VerificationHelper verificationHelper, PresentationToken presentationToken, PresentationPolicyAlternatives modifiedPresentationPolicyAlternatives) throws Exception { PresentationTokenDescription ptd = verificationHelper.engine .verifyTokenAgainstPolicy( modifiedPresentationPolicyAlternatives, presentationToken, false); return ptd; } private PresentationToken createPresentationTokenUi(UserHelper userHelper, UiPresentationReturn uiPresentationReturn) throws Exception { PresentationToken presentationToken = userHelper.getEngine() .createPresentationToken(USERNAME, uiPresentationReturn); return presentationToken; } private UiPresentationReturn createUiPresentationReturn(URI uiContext) { UiPresentationReturn uiPresentationReturn = new UiPresentationReturn(); uiPresentationReturn.chosenInspectors = new LinkedList<String>(); uiPresentationReturn.chosenPolicy = 0; uiPresentationReturn.chosenPresentationToken = 0; uiPresentationReturn.chosenPseudonymList = 0; uiPresentationReturn.metadataToChange = new HashMap<String, PseudonymMetadata>(); uiPresentationReturn.uiContext = uiContext; return uiPresentationReturn; } private UiPresentationArguments createPresentationToken( UserHelper userHelper, PresentationPolicyAlternatives modifiedPresentationPolicyAlternatives) throws Exception { UiPresentationArguments uiPresentationArguments = userHelper .getEngine().createPresentationToken(USERNAME, modifiedPresentationPolicyAlternatives); return uiPresentationArguments; } private PresentationPolicyAlternatives createPresentationPolicyAlternatives( VerificationHelper verificationHelper) throws Exception { // TODO(jdn): is this the cause of the bug? Map<URI, URI> revocationInformationUids = new HashMap<URI, URI>(); String applicationData = null; PresentationPolicyAlternatives presentationPolicy = this .getPresentationPolicyAlternatives(); //Was createPresentationPolicy, without nonce verificationHelper.modifyPresentationPolicy(presentationPolicy, verificationHelper.generateNonce(), applicationData, revocationInformationUids); return presentationPolicy; } private PresentationPolicyAlternatives getPresentationPolicyAlternatives() throws Exception { String filename = "presentationPolicyAlternatives.xml"; PresentationPolicyAlternatives o = (PresentationPolicyAlternatives) XmlUtils .getObjectFromXML( FileSystem.getInputStream("tutorial-resources/" + filename), true); return o; } private IssuanceMessageAndBoolean issuanceProtocolStep( IssuanceHelper issuanceHelper, IssuanceMessage secondIssuanceMessage) throws Exception { IssuanceMessageAndBoolean response = IssuanceHelper.getInstance() .issueStep(secondIssuanceMessage); return response; } private UiIssuanceReturn getUiIssuanceReturn(IssuanceReturn issuanceReturn) { UiIssuanceReturn uiIssuanceReturn = new UiIssuanceReturn(); uiIssuanceReturn.chosenInspectors = new LinkedList<String>(); uiIssuanceReturn.chosenIssuanceToken = 0; uiIssuanceReturn.chosenPseudonymList = 0; uiIssuanceReturn.metadataToChange = new HashMap<String, PseudonymMetadata>(); uiIssuanceReturn.uiContext = issuanceReturn.uia.uiContext; return uiIssuanceReturn; } private IssuanceMessage issuanceProtocolStepUi(UserHelper userHelper, UiIssuanceReturn uiIssuanceReturn) throws Exception { IssuanceMessage issuanceMessage = userHelper.getEngine() .issuanceProtocolStep(USERNAME, uiIssuanceReturn); return issuanceMessage; } private IssuanceReturn issuanceProtocolStep(UserHelper userHelper, IssuanceMessage issuanceMessage) throws Exception { IssuanceReturn issuanceReturn = userHelper.getEngine() .issuanceProtocolStep(USERNAME, issuanceMessage); return issuanceReturn; } private IssuanceMessageAndBoolean initIssuanceProtocol( IssuanceHelper issuanceHelper) throws Exception { IssuancePolicyAndAttributes issuancePolicyAndAttributes = this .getIssuancePolicyAndAttributes(); IssuancePolicy ip = issuancePolicyAndAttributes.getIssuancePolicy(); List<Attribute> attributes = issuancePolicyAndAttributes.getAttribute(); IssuanceMessageAndBoolean issuanceMessageAndBoolean = issuanceHelper .initIssuanceProtocol(ip, attributes); return issuanceMessageAndBoolean; } private IssuancePolicyAndAttributes getIssuancePolicyAndAttributes() throws Exception { String filename = "issuancePolicyAndAttributes.xml"; IssuancePolicyAndAttributes o = (IssuancePolicyAndAttributes) XmlUtils .getObjectFromXML( FileSystem.getInputStream("tutorial-resources/" + filename), true); return o; } /* NO LONGER IN USE? private void createSmartcardAtUser(UserHelper userHelper, URI issuerParametersUid) throws Exception { Parser xmlSerializer = Parser.getInstance(); Random random = new SecureRandom(); KeyManager keyManager = userHelper.keyManager; SystemParameters systemParameters = keyManager.getSystemParameters(); // Element gpAsElement = (Element) systemParameters.getAny().get(1); // // GroupParameters gp = (GroupParameters) // xmlSerializer.parse(gpAsElement); // // systemParameters.getAny().add(1, gp); SecretWrapper secretWrapper = new SecretWrapper(CryptoEngine.IDEMIX, random, systemParameters); IssuerParameters issuerParameters = keyManager .getIssuerParameters(issuerParametersUid); secretWrapper.addIssuerParameters(issuerParameters); BasicSmartcard softwareSmartcard = secretWrapper.getSoftwareSmartcard(); userHelper.cardStorage.addSmartcard(softwareSmartcard, 1234); } */ private void storeIssuerParametersAtVerifier( VerificationHelper verificationHelper, IssuerParameters issuerParameters) throws Exception { verificationHelper.keyManager.storeIssuerParameters( issuerParameters.getParametersUID(), issuerParameters); } private void storeIssuerParametersAtUser(UserHelper userHelper, IssuerParameters issuerParameters) throws Exception { userHelper.keyManager.storeIssuerParameters( issuerParameters.getParametersUID(), issuerParameters); } private void storeRevocationAuthorityParametersAtVerifier( VerificationHelper verificationHelper, RevocationAuthorityParameters revocationAuthorityParameters) throws Exception { verificationHelper.keyManager.storeRevocationAuthorityParameters( revocationAuthorityParameters.getParametersUID(), revocationAuthorityParameters); } private void storeRevocationAuthorityParametersAtUser( UserHelper userHelper, RevocationAuthorityParameters revocationAuthorityParameters) throws Exception { userHelper.keyManager.storeRevocationAuthorityParameters( revocationAuthorityParameters.getParametersUID(), revocationAuthorityParameters); } private void storeRevocationAuthorityParametersAtIssuer( IssuanceHelper issuanceHelper, RevocationAuthorityParameters revocationAuthorityParameters) throws Exception { issuanceHelper.keyManager.storeRevocationAuthorityParameters( revocationAuthorityParameters.getParametersUID(), revocationAuthorityParameters); } private RevocationAuthorityParameters setupRevocationAuthorityParameters( RevocationHelper revocationHelper) throws Exception { RevocationReferences references = this.getRevocationReferences(); Reference revocationInfoReference = references .getRevocationInfoReference(); Reference nonRevocationEvidenceReference = references .getNonRevocationEvidenceReference(); Reference nonRevocationUpdateReference = references .getNonRevocationEvidenceUpdateReference(); URI uid = URI.create("http://ticketcompany/revocation"); RevocationAuthorityParameters raParams = RevocationHelper .setupParameters(cryptographicMechanism, revocation_keyLength, uid, revocationInfoReference, nonRevocationEvidenceReference, nonRevocationUpdateReference, revocation_fileStoragePrefix); return raParams; } private RevocationReferences getRevocationReferences() throws Exception { String filename = "revocationReferences.xml"; RevocationReferences revocationReferences = (RevocationReferences) XmlUtils .getObjectFromXML( FileSystem.getInputStream("tutorial-resources/" + filename), true); return revocationReferences; } private void storeSystemParametersAtVerifier( VerificationHelper verificationHelper, SystemParameters systemParameters) throws Exception { verificationHelper.keyManager.storeSystemParameters(systemParameters); } private void storeSystemParametersAtUser(UserHelper userHelper, SystemParameters systemParameters) throws Exception { userHelper.keyManager.storeSystemParameters(systemParameters); } private void storeSystemParametersAtRevocationAuthority( SystemParameters systemParameters) throws Exception { KeyManager keyManager = UserStorageManager .getKeyManager(RevocationService.fileStoragePrefix); keyManager.storeSystemParameters(systemParameters); } private void storeCredentialSpecificationAtVerifier( VerificationHelper verificationHelper, CredentialSpecification credentialSpecification) throws Exception { verificationHelper.keyManager.storeCredentialSpecification( credentialSpecification.getSpecificationUID(), credentialSpecification); } private void storeCredentialSpecificationAtUser(UserHelper userHelper, CredentialSpecification credentialSpecification) throws Exception { userHelper.keyManager.storeCredentialSpecification( credentialSpecification.getSpecificationUID(), credentialSpecification); } private void storeCredentialSpecificationAtIssuer( IssuanceHelper issuanceHelper, CredentialSpecification credentialSpecification) throws Exception { issuanceHelper.keyManager.storeCredentialSpecification( credentialSpecification.getSpecificationUID(), credentialSpecification); } private CredentialSpecification getCredentialSpecification() throws Exception { String filename = "credentialSpecificationVIPSoccerTicket.xml"; CredentialSpecification credentialSpecification = (CredentialSpecification) XmlUtils .getObjectFromXML( FileSystem.getInputStream("tutorial-resources/" + filename), true); return credentialSpecification; } private IssuanceHelper setupIssuanceHelper( Module revocationProxyAuthorityModule) throws Exception { IssuanceHelper.initInstanceForService(ITTicketTutorial.issuerParamsPrefix, ITTicketTutorial.issuerFileStoragePrefix); IssuanceHelper issuanceHelper = IssuanceHelper.getInstance(); return issuanceHelper; } private VerificationHelper setupVerificationHelper( Module revocationProxyAuthorityModule) throws Exception { String[] credSpecResources = new String[0]; String[] revAuthResourceList = new String[0]; String[] inspectorResourceList = new String[0]; String[] issuerParamsResourceList = new String[0]; List<IssuerParameters> issuerParamsList = new ArrayList<IssuerParameters>(); List<CredentialSpecification> credSpecsList = new ArrayList<CredentialSpecification>(); List<InspectorPublicKey> inspectorKeyList = new ArrayList<InspectorPublicKey>(); List<RevocationAuthorityParameters> revAuthParamsList = new ArrayList<RevocationAuthorityParameters>(); VerificationHelper.initInstance(sysparams, issuerParamsList, credSpecsList, inspectorKeyList, revAuthParamsList, ITTicketTutorial.verifierFileStoragePrefix); VerificationHelper verificationHelper = VerificationHelper .getInstance(); return verificationHelper; } private RevocationHelper setupRevocationHelper() throws Exception { this.initRevocationHelper(); RevocationHelper revocationHelper = RevocationHelper.getInstance(); return revocationHelper; } private void initRevocationHelper() throws Exception { RevocationHelper.initInstance(RevocationService.fileStoragePrefix, this.inMemoryRevocationCommunicationStrategy); } private UserHelper setupUserHelper(Module revocationProxyAuthorityModule) throws Exception { UserHelper.initInstanceForService(cryptoEngine, ITTicketTutorial.userFileStoragePrefix); UserHelper instance = UserHelper.getInstance(); return instance; } private SystemParameters setupSystemParameters(IssuanceHelper issuanceHelper) throws IOException, KeyManagerException, Exception { int idemixKeylength = 1024; SystemParameters systemParameters = issuanceHelper.createNewSystemParametersKeylength(idemixKeylength); return systemParameters; } public IssuerParametersInput getIssuerParametersInput() throws IOException, JAXBException, UnsupportedEncodingException, SAXException { String filename = "/issuerParametersInput.xml"; IssuerParametersInput issuerParametersInput = (IssuerParametersInput) XmlUtils .getObjectFromXML(new FileInputStream("tutorial-resources/" + filename), true); return issuerParametersInput; } private IssuerParameters setupIssuerParameters(IssuanceHelper instance) throws Exception { URI hash = CryptoUriUtil.getHashSha256(); KeyManager keyManager = instance.keyManager; SystemParameters systemParameters = keyManager.getSystemParameters(); IssuerParametersInput issuerParametersInput = this .getIssuerParametersInput(); URI credentialSpecUid = issuerParametersInput.getCredentialSpecUID(); CredentialSpecification credspec = keyManager .getCredentialSpecification(credentialSpecUid); if (credspec == null) { throw new IllegalStateException( "Could not find credential specification \"" + credentialSpecUid + "\""); } URI issuerParametersUid = issuerParametersInput.getParametersUID(); URI revocationParametersUid = issuerParametersInput .getRevocationParametersUID(); List<FriendlyDescription> friendlyDescriptions = issuerParametersInput .getFriendlyIssuerDescription(); String systemAndIssuerParamsPrefix = Constants.ISSUER_RESOURCES_FOLDER + "/"; IssuerParameters issuerParameters = instance.setupIssuerParameters( cryptoEngine, credspec, systemParameters, issuerParametersUid, hash, revocationParametersUid, systemAndIssuerParamsPrefix, friendlyDescriptions); return issuerParameters; } }