package won.cryptography.rdfsign; import org.apache.jena.query.Dataset; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.StmtIterator; import won.protocol.message.WonMessage; import won.protocol.message.WonSignatureData; import won.protocol.util.RdfUtils; import won.protocol.util.WonRdfUtils; import won.protocol.vocabulary.RDFG; import won.protocol.vocabulary.WONMSG; import java.util.*; /** * A helper class to represent the won message information such * as which content and envelope graphs are unsigned, signatures * unreferenced, envelopes hierarchical order, etc., necessary * for the signing component to make decisions on what parts of * message should be signed and referenced. * * User: ypanchenko * Date: 09.04.2015 */ public class SigningStage { private Set<String> envUris = new HashSet<>(); private Set<String> contentUris = new HashSet<>(); private Map<String,String> contentUriToContainingItEnvUri = new HashMap<>(); private Map<String,String> envUriToContainedInItEnvUri = new HashMap<>(); private Map<String,String> graphUriToSigUri = new HashMap<>(); private Map<String,WonSignatureData> sigUriToSigReference = new HashMap<>(); private List<String> envOrderedByContainment = new ArrayList<>(); private String messageUri; private Map<String,String> graphUriToItsMessageUri = new HashMap<>(); private String outermostSignatureUri = null; public SigningStage(WonMessage message) { extractData(message); } public String getMessageUri() { return messageUri; } public String getMessageUri(String envelopeGraphUri) { return graphUriToItsMessageUri.get(envelopeGraphUri); } private void extractData(final WonMessage message) { messageUri = message.getMessageURI().toString(); Dataset dataset = message.getCompleteDataset(); for (String uri : RdfUtils.getModelNames(dataset)) { Model model = dataset.getNamedModel(uri); if (message.isEnvelopeGraph(uri, model)) { extractEnvelopeData(uri, model, message); } else if (WonRdfUtils.SignatureUtils.isSignature(model, uri)) { if (outermostSignatureUri != null){ throw new IllegalStateException("Found more than one signature graph"); } outermostSignatureUri = uri; extractSignatureData(uri, model); } else { // should be content extractContentData(uri); } } //created ordered env list orderEnvelopes(message); } private void orderEnvelopes(final WonMessage message) { String outer = message.getOuterEnvelopeGraphURI().toString(); envOrderedByContainment.add(outer); while (outer != null) { String inner = envUriToContainedInItEnvUri.get(outer); if (inner != null) { envOrderedByContainment.add(0, inner); } outer = inner; } } private void extractContentData(final String uri) { contentUris.add(uri); } private void extractSignatureData(final String uri, final Model model) { WonSignatureData wonSignatureData = WonRdfUtils.SignatureUtils.extractWonSignatureData(uri,model); if (wonSignatureData != null && wonSignatureData.getSignatureValue() != null) { graphUriToSigUri.put(wonSignatureData.getSignedGraphUri(), uri); sigUriToSigReference.put(uri, wonSignatureData); } } private void extractEnvelopeData(final String envelopeGraphUri, final Model envelopeGraph, final WonMessage message) { // add to envelope uris envUris.add(envelopeGraphUri); // find if it contains has_content //TODO this duplicates private findmessageuri method from wonmessage, refactor to avoid code repetition String envMessageUri = RdfUtils.findOnePropertyFromResource(envelopeGraph, envelopeGraph.getResource(envelopeGraphUri), RDFG.SUBGRAPH_OF).asResource().getURI(); graphUriToItsMessageUri.put(envelopeGraphUri, envMessageUri); Resource msgEventResource = envelopeGraph.getResource(envMessageUri); Resource msgEnvelopeResource = envelopeGraph.getResource(envelopeGraphUri); StmtIterator it = msgEventResource.listProperties(WONMSG.HAS_CONTENT_PROPERTY); while (it.hasNext()) { contentUriToContainingItEnvUri.put(it.nextStatement().getObject().asResource().getURI(), envelopeGraphUri); } // find if it contains another envelopes it = msgEnvelopeResource.listProperties(WONMSG.CONTAINS_ENVELOPE); // TODO make sure that > 1 envelope is not possible in the protocol if (it.hasNext()) { envUriToContainedInItEnvUri.put(envelopeGraphUri, it.nextStatement().getObject().asResource().getURI()); } // find if it contains a signature references it = msgEnvelopeResource.listProperties(WONMSG.CONTAINS_SIGNATURE_PROPERTY); while (it.hasNext()) { Resource refObj = it.next().getObject().asResource(); extractSignatureData(refObj.getURI(), refObj.getModel()); } } public List<String> getUnsignedEnvUrisOrderedByContainment() { List<String> ordered = new ArrayList<>(envOrderedByContainment.size()); for (String uri : envOrderedByContainment) { if (!graphUriToSigUri.containsKey(uri)) { ordered.add(uri); } } return ordered; } public Set<String> getUnsignedContentUris() { return getUnsignedUris(contentUris); } private Set<String> getUnsignedUris(final Set<String> fromUris) { Set<String> unsigned = new HashSet<>(fromUris.size()); for (String uri : fromUris) { if (!graphUriToSigUri.containsKey(uri)) { unsigned.add(uri); } } return unsigned; } public String getEnvelopeUriContainingContent(String contentUri) { return contentUriToContainingItEnvUri.get(contentUri); } public WonSignatureData getOutermostSignature() { return sigUriToSigReference.get(outermostSignatureUri); } }