//* Licensed Materials - Property of * //* IBM * //* * //* eu.abc4trust.pabce.1.34 * //* * //* (C) Copyright IBM Corp. 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.util; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import eu.abc4trust.abce.internal.user.policyCredentialMatcher.PresentationState; import eu.abc4trust.exceptions.IdentitySelectionException; import eu.abc4trust.keyManager.KeyManager; import eu.abc4trust.keyManager.KeyManagerException; import eu.abc4trust.returnTypes.SitdReturn; import eu.abc4trust.returnTypes.SptdReturn; import eu.abc4trust.returnTypes.UiIssuanceArguments; import eu.abc4trust.returnTypes.UiIssuanceReturn; import eu.abc4trust.returnTypes.UiPresentationArguments; import eu.abc4trust.returnTypes.UiPresentationReturn; import eu.abc4trust.returnTypes.ui.AddTokenCandidate; import eu.abc4trust.returnTypes.ui.CredentialInUi; import eu.abc4trust.returnTypes.ui.CredentialSpecInUi; import eu.abc4trust.returnTypes.ui.InspectableAttribute; import eu.abc4trust.returnTypes.ui.InspectorInUi; import eu.abc4trust.returnTypes.ui.IssuerInUi; import eu.abc4trust.returnTypes.ui.PseudonymInUi; import eu.abc4trust.returnTypes.ui.PseudonymListCandidate; import eu.abc4trust.returnTypes.ui.RevealedFactsAndAttributeValues; import eu.abc4trust.returnTypes.ui.TokenCandidate; import eu.abc4trust.returnTypes.ui.TokenCandidatePerPolicy; import eu.abc4trust.returnTypes.ui.UiCommonArguments; import eu.abc4trust.ui.idSelection.IdentitySelection; import eu.abc4trust.ui.idSelection.IdentitySelectionUi; import eu.abc4trust.xml.Attribute; import eu.abc4trust.xml.CredentialDescription; import eu.abc4trust.xml.CredentialInPolicy; import eu.abc4trust.xml.CredentialInPolicy.IssuerAlternatives.IssuerParametersUID; import eu.abc4trust.xml.CredentialSpecification; import eu.abc4trust.xml.CredentialTemplate; import eu.abc4trust.xml.FriendlyDescription; import eu.abc4trust.xml.InspectorDescription; import eu.abc4trust.xml.IssuancePolicy; import eu.abc4trust.xml.IssuanceTokenDescription; import eu.abc4trust.xml.IssuerParameters; import eu.abc4trust.xml.PolicyDescription; import eu.abc4trust.xml.PresentationPolicy; import eu.abc4trust.xml.PresentationTokenDescription; import eu.abc4trust.xml.PseudonymDescription; import eu.abc4trust.xml.PseudonymWithMetadata; public class MyCandidateToken { private final MyPresentationPolicy pp; private final PresentationTokenDescription ptd; private final IssuanceTokenDescription itd; private final List<MyCredentialDescription> creds; private final List<ArrayList<PseudonymWithMetadata>> pseudonyms; private final List<List<MyInspectableAttribute>> inspectors; public MyCandidateToken(MyPresentationPolicy pp, PresentationTokenDescription ptd, CredentialTemplate ct, List<MyCredentialDescription> creds, List<ArrayList<PseudonymWithMetadata>> pseudonyms, List<List<MyInspectableAttribute>> inspectors) { this.pp = pp; this.ptd = ptd; if (ct != null) { this.itd = generateIssuanceToken(ct); } else { this.itd = null; } this.creds = creds; this.pseudonyms = pseudonyms; this.inspectors = inspectors; } public IssuanceTokenDescription generateIssuanceToken(CredentialTemplate ct) { IssuanceTokenDescription issToken = new IssuanceTokenDescription(); issToken.setCredentialTemplate(ct); issToken.setPresentationTokenDescription(ptd); return issToken; } public void populateIssuance(Map<URI, PolicyDescription> mpo, Map<URI, CredentialDescription> mcd, Map<URI, PseudonymDescription> mps, Map<URI, InspectorDescription> mid, List<IssuanceTokenDescription> litd, List<List<URI>> credUri, List<Set<List<URI>>> pseudonyms, List<List<Set<URI>>> inspectors) { if (itd == null) { throw new RuntimeException("No issuance token description"); } populate(mpo, mcd, mps, mid, credUri, pseudonyms, inspectors); litd.add(itd); } public void populatePresentation(Map<URI, PolicyDescription> mpo, Map<URI, CredentialDescription> mcd, Map<URI, PseudonymDescription> mps, Map<URI, InspectorDescription> mid, List<PresentationTokenDescription> lptd, List<List<URI>> credUri, List<Set<List<URI>>> pseudonyms, List<List<Set<URI>>> inspectors) { populate(mpo, mcd, mps, mid, credUri, pseudonyms, inspectors); lptd.add(ptd); } private void populate(Map<URI, PolicyDescription> mpo, Map<URI, CredentialDescription> mcd, Map<URI, PseudonymDescription> mps, Map<URI, InspectorDescription> mid, List<List<URI>> credUri, List<Set<List<URI>>> lslp, List<List<Set<URI>>> llsi) { { PolicyDescription pd = new PolicyDescription(); pd.setPolicyUID(pp.getPolicyUri()); pd.setMessage(pp.getMessage()); mpo.put(pp.getPolicyUri(), pd); } for (MyCredentialDescription cd: creds) { mcd.put(cd.getUid(), cd.getCredentialDesc()); } for (List<PseudonymWithMetadata> lpwm: pseudonyms) { for(PseudonymWithMetadata pwm: lpwm) { URI psUri = pwm.getPseudonym().getPseudonymUID(); PseudonymDescription pd = new PseudonymDescription(); pd.setExclusive(pwm.getPseudonym().isExclusive()); pd.setPseudonymMetadata(pwm.getPseudonymMetadata()); pd.setPseudonymUID(psUri); pd.setScope(pwm.getPseudonym().getScope()); mps.put(psUri, pd); } } for (List<MyInspectableAttribute> sipk: inspectors) { for(MyInspectableAttribute ipk: sipk) { URI iUri = ipk.ipk.getPublicKeyUID(); InspectorDescription id = new InspectorDescription(); if (ipk.ipk.getFriendlyInspectorDescription().size() > 0) { if (ipk.ipk.getFriendlyInspectorDescription().size() > 0) { for (FriendlyDescription fid: ipk.ipk.getFriendlyInspectorDescription()){ id.getFriendlyInspectorDescription().add(fid); } } } id.setInspectorUID(ipk.ipk.getPublicKeyUID()); mid.put(iUri, id); } } { credUri.add(getCredentialUriList()); } { Set<List<URI>> psChoice = new HashSet<List<URI>>(); for (List<PseudonymWithMetadata> lpwm: pseudonyms) { List<URI> entry = new ArrayList<URI>(); for(PseudonymWithMetadata pwm: lpwm) { URI psUri = pwm.getPseudonym().getPseudonymUID(); entry.add(psUri); } psChoice.add(entry); } lslp.add(psChoice); } { List<Set<URI>> iChoice = new ArrayList<Set<URI>>(); for (List<MyInspectableAttribute> sipk: inspectors) { Set<URI> entry = new HashSet<URI>(); for(MyInspectableAttribute ipk: sipk) { URI psUri = ipk.ipk.getPublicKeyUID(); entry.add(psUri); } iChoice.add(entry); } llsi.add(iChoice); } } public static SitdReturn callIssuanceUi(IdentitySelection ui, List<MyCandidateToken> tokens) { Map<URI, PolicyDescription> mpo = new HashMap<URI, PolicyDescription>(); Map<URI, CredentialDescription> mcd = new HashMap<URI, CredentialDescription>(); Map<URI, PseudonymDescription> mps = new HashMap<URI, PseudonymDescription>(); Map<URI, InspectorDescription> mid = new HashMap<URI, InspectorDescription>(); List<IssuanceTokenDescription> litd = new ArrayList<IssuanceTokenDescription>(); List<List<URI>> credUri = new ArrayList<List<URI>>(); List<Set<List<URI>>> pseudonyms = new ArrayList<Set<List<URI>>>(); List<List<Set<URI>>> inspectors = new ArrayList<List<Set<URI>>>(); for(MyCandidateToken token: tokens) { token.populateIssuance(mpo, mcd, mps, mid, litd, credUri, pseudonyms, inspectors); } // TODO(enr): Remove empty list of attributes List<Attribute> atts = new ArrayList<Attribute>(); return ui.selectIssuanceTokenDescription(mpo, mcd, mps, mid, litd, credUri, atts, pseudonyms, inspectors); } public static SptdReturn callPresentationUi(IdentitySelection ui, List<MyCandidateToken> tokens) { Map<URI, PolicyDescription> mpo = new HashMap<URI, PolicyDescription>(); Map<URI, CredentialDescription> mcd = new HashMap<URI, CredentialDescription>(); Map<URI, PseudonymDescription> mps = new HashMap<URI, PseudonymDescription>(); Map<URI, InspectorDescription> mid = new HashMap<URI, InspectorDescription>(); List<PresentationTokenDescription> lptd = new ArrayList<PresentationTokenDescription>(); List<List<URI>> credUri = new ArrayList<List<URI>>(); List<Set<List<URI>>> pseudonyms = new ArrayList<Set<List<URI>>>(); List<List<Set<URI>>> inspectors = new ArrayList<List<Set<URI>>>(); for(MyCandidateToken token: tokens) { token.populatePresentation(mpo, mcd, mps, mid, lptd, credUri, pseudonyms, inspectors); } return ui.selectPresentationTokenDescription(mpo, mcd, mps, mid, lptd, credUri, pseudonyms, inspectors); } public List<URI> getCredentialUriList() { List<URI> credsInToken = new ArrayList<URI>(); for (MyCredentialDescription cd: creds) { credsInToken.add(cd.getUid()); } return credsInToken; } public PresentationTokenDescription getPresentationToken() { return ptd; } public void populatePseudonymsInMap(Map<URI, PseudonymWithMetadata> mpwm) { for (List<PseudonymWithMetadata> lpwm: pseudonyms) { for(PseudonymWithMetadata pwm: lpwm) { URI psUri = pwm.getPseudonym().getPseudonymUID(); mpwm.put(psUri, pwm); } } } public IssuanceTokenDescription getIssuanceToken() { return itd; } public void updateIssuerToRevocationInformationUidMap(Map<URI, URI> toUpdate) { pp.updateIssuerToRevocationInformationUidMap(toUpdate); } public static UiPresentationArguments prepareUiPresentationArguments( List<MyCandidateToken> candidateTokens, KeyManager km, ContextGenerator contextGenerator) { UiPresentationArguments arg = new UiPresentationArguments(); TokenCandidatePerPolicy tcpp = null; URI policyId = null; for(MyCandidateToken token: candidateTokens) { if(!token.ptd.getPolicyUID().equals(policyId)) { if(tcpp!=null) { arg.addTokenCandidate(tcpp); } tcpp = new TokenCandidatePerPolicy(); policyId = token.ptd.getPolicyUID(); tcpp.policy = token.pp.getPolicy(); populatePolicy(arg.data, tcpp.policy, km); } token.populate(arg.data, tcpp); } if(tcpp!=null) { arg.addTokenCandidate(tcpp); } arg.uiContext = contextGenerator.getUniqueContext(URI.create("ui-context-p/")); return arg; } private static void populatePolicy(UiCommonArguments data, PresentationPolicy policy, KeyManager km) { List<URI> neededIssuers = new ArrayList<URI>(); for(CredentialInPolicy cip: policy.getCredential()) { for(IssuerParametersUID ipu: cip.getIssuerAlternatives().getIssuerParametersUID()) { neededIssuers.add(ipu.getValue()); } } List<URI> neededCredSpecs = new ArrayList<URI>(); for(CredentialInPolicy cip: policy.getCredential()) { for(URI csid: cip.getCredentialSpecAlternatives().getCredentialSpecUID()) { neededCredSpecs.add(csid); } } for(URI u: neededIssuers) { try { if(u == null) { continue; } IssuerParameters ip = km.getIssuerParameters(u); if(ip == null) { continue; } data.addIssuer(new IssuerInUi(ip)); } catch(KeyManagerException kme) { //Ignore continue; } } for(URI credUri: neededCredSpecs) { try { if(credUri == null) { continue; } CredentialSpecification spec = km.getCredentialSpecification(credUri); if(spec == null) { continue; } data.addCredentialSpec(new CredentialSpecInUi(spec)); } catch(KeyManagerException kme) { //Ignore continue; } } } private static void populatePolicy(UiCommonArguments data, IssuancePolicy policy, KeyManager km) { populatePolicy(data, policy.getPresentationPolicy(), km); try { URI issuri = policy.getCredentialTemplate().getIssuerParametersUID(); if(issuri == null) { return; } IssuerParameters ip = km.getIssuerParameters(issuri); if(ip == null) { return; } data.addIssuer(new IssuerInUi(ip)); } catch(KeyManagerException kme) { // Ignore return; } try { URI credSpec = policy.getCredentialTemplate().getCredentialSpecUID(); if(credSpec == null) { return; } CredentialSpecification spec = km.getCredentialSpecification(credSpec); if(spec == null) { return; } data.addCredentialSpec(new CredentialSpecInUi(spec)); } catch(KeyManagerException kme) { // Ignore return; } } private void populate(UiCommonArguments data, AddTokenCandidate atc) { TokenCandidate tc = new TokenCandidate(); Map<URI,CredentialSpecification> uriCredspecs = new HashMap<URI, CredentialSpecification>(); // Token description tc.tokenDescription = ptd; // Credentials for (MyCredentialDescription cd: creds) { CredentialInUi ciu = new CredentialInUi(cd.getCredentialDescription(), cd.getIssuerParameters(), cd.getCredSpec(), cd.getRevocationAuthorityParameters()); //addFriendlyDescriptions(ciu); uriCredspecs.put(cd.getCredSpec().getSpecificationUID(), cd.getCredSpec()); data.addCredential(ciu); tc.credentials.add(ciu); } // Pseudonym candidates for (List<PseudonymWithMetadata> lpwm: pseudonyms) { PseudonymListCandidate plc = new PseudonymListCandidate(); for(PseudonymWithMetadata pwm: lpwm) { PseudonymInUi piu = new PseudonymInUi(pwm); data.addPseudonym(piu); plc.pseudonyms.add(piu); } tc.addPseudonymCandidate(plc); } // Get revealed facts and attribute values RevealedFactsAndAttributeValues rfats = RevealedAttrsAndFactsdDescrGenerator.generateFriendlyDesciptions(ptd, uriCredspecs); // Revealed facts tc.revealedAttributeValues = rfats.revealedAttributeValues; // Revealed attribute values tc.revealedFacts = rfats.revealedFacts; // Inspectable attributes for(List<MyInspectableAttribute> lmia: inspectors) { InspectableAttribute insa = new InspectableAttribute(); if(lmia.size() != 0) { insa.credential = tc.credentials.get(lmia.get(0).credential); insa.attributeType = lmia.get(0).attributeType; insa.inspectionGrounds = lmia.get(0).inspectionGrounds; insa.dataHandlingPolicy = lmia.get(0).dataHandlingPolicy; for(MyInspectableAttribute mia: lmia) { InspectorInUi iiu = new InspectorInUi(mia.ipk); insa.inspectorAlternatives.add(iiu); data.addInspector(iiu); } } else { throw new RuntimeException("Inspectable attributes empty"); } tc.inspectableAttributes.add(insa); } atc.addTokenCandidate(tc); } /* private void addFriendlyDescriptions(CredentialInUi ciu) { final String DEFAULT_LANG = "en"; Map<String, String> ownershipInfo = new HashMap<String, String>(); ownershipInfo.put("en", "You reveal that you own a credential of type '%s' issued by '%s'."); ownershipInfo.put("sv", "Du visar att du \u00e4ger en referens av typen '%s' som utf\u00e4rdas av '%s'."); ownershipInfo.put("el", "\u0398\u03b1 \u03b1\u03c0\u03bf\u03ba\u03b1\u03bb\u03cd\u03c8\u03b5\u03b9 \u03cc\u03c4\u03b9 \u03ad\u03c7\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b7\u03bd \u03ba\u03b1\u03c4\u03bf\u03c7\u03ae \u03c3\u03b1\u03c2 \u03bc\u03b9\u03b1 \u03c0\u03b9\u03c3\u03c4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03c4\u03cd\u03c0\u03bf\u03c5 '%s' \u03c0\u03bf\u03c5 \u03b5\u03ba\u03b4\u03af\u03b4\u03b5\u03c4\u03b1\u03b9 \u03b1\u03c0\u03cc \u03c4\u03b7\u03bd '%s'."); Map<String, String> validityInfo = new HashMap<String, String>(); validityInfo.put("en", "You reveal that your credential has not been revoked by '%s'."); validityInfo.put("sv", "Du visar att din referens inte har \u00e5terkallats av '%s'."); validityInfo.put("el", "\u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03b1\u03c0\u03bf\u03ba\u03b1\u03bb\u03cd\u03c0\u03c4\u03bf\u03c5\u03bd \u03cc\u03c4\u03b9 \u03c4\u03b1 \u03b4\u03b9\u03b1\u03c0\u03b9\u03c3\u03c4\u03b5\u03c5\u03c4\u03ae\u03c1\u03b9\u03ac \u03c3\u03b1\u03c2 \u03b4\u03b5\u03bd \u03ad\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03ba\u03bb\u03b7\u03b8\u03b5\u03af \u03b1\u03c0\u03cc \u03c4\u03bf '%s'."); Map<String, String> typeName = new HashMap<String, String>(); Map<String, String> issuerName = new HashMap<String, String>(); Map<String, String> raName = new HashMap<String, String>(); for(FriendlyDescription fd: ciu.issuer.description) { issuerName.put(fd.getLang(), fd.getValue()); } if(ciu.revocationAuthority != null) { for(FriendlyDescription fd: ciu.revocationAuthority.description) { raName.put(fd.getLang(), fd.getValue()); } } for(FriendlyDescription fd: ciu.spec.spec.getFriendlyCredentialName()) { typeName.put(fd.getLang(), fd.getValue()); } for(String lang: ownershipInfo.keySet()) { FriendlyDescription fd = new FriendlyDescription(); fd.setLang(lang); String type = typeName.get(lang); String issuer = issuerName.get(lang); if(type == null) { type = typeName.get(DEFAULT_LANG); if(type == null) { type = ciu.spec.uri; } } if(issuer == null) { issuer = typeName.get(DEFAULT_LANG); if(issuer == null) { type = ciu.issuer.uri; } } String formatString = ownershipInfo.get(lang); fd.setLang(lang); fd.setValue(String.format(formatString, type, issuer)); ciu.ownershipInfos.add(fd); } if(ciu.spec.spec.isRevocable()) { for(String lang: validityInfo.keySet()) { FriendlyDescription fd = new FriendlyDescription(); fd.setLang(lang); String ra = raName.get(lang); if(ra == null) { ra = raName.get(DEFAULT_LANG); if(ra == null) { if(ciu.revocationAuthority != null) { ra = ciu.revocationAuthority.uri; } else if (ciu.issuer.revocationAuthorityUri != null) { ra = ciu.issuer.revocationAuthorityUri.toString(); } else { ra = "(???)"; } } } String formatString = validityInfo.get(lang); fd.setLang(lang); fd.setValue(String.format(formatString, ra)); ciu.validityInfos.add(fd); } } } */ public static UiIssuanceArguments prepareUiIssuanceArguments(List<MyCandidateToken> candidateTokens, KeyManager km, ContextGenerator contextGenerator) { UiIssuanceArguments arg = new UiIssuanceArguments(); for(MyCandidateToken token: candidateTokens) { token.populate(arg.data, arg); } if (candidateTokens.size() != 0) { arg.policy.setCredentialTemplate(candidateTokens.get(0).itd.getCredentialTemplate()); arg.policy.setPresentationPolicy(candidateTokens.get(0).pp.getPolicy()); arg.policy.setVersion("1.0"); populatePolicy(arg.data, arg.policy, km); } else { throw new RuntimeException("Cannot satisfy policy (no candidate tokens)."); } arg.uiContext = contextGenerator.getUniqueContext(URI.create("ui-context-i/")); return arg; } }