Search in sources :

Example 91 with WonMessage

use of won.protocol.message.WonMessage in project webofneeds by researchstudio-sat.

the class SignatureCheckingWonMessageProcessor method process.

@Override
public WonMessage process(final WonMessage message) throws WonMessageProcessingException {
    StopWatch sw = new StopWatch();
    try {
        SignatureVerificationState result;
        /*
             * If the message is a successResponse to a delete Message then we can't check
             * the signature as it is stored in the deleted Atom, so we just accept the
             * message as valid and return it.
             */
        if (message.getRespondingToMessageType() == WonMessageType.DELETE && message.getMessageType() == WonMessageType.SUCCESS_RESPONSE) {
            return message;
        }
        for (WonMessage toCheck : message.getAllMessages()) {
            try {
                // obtain public keys
                sw.start("get public keys");
                Map<String, PublicKey> keys = WonKeysReaderWriter.readKeyFromMessage(toCheck);
                WonMessageType type = toCheck.getMessageType();
                switch(type) {
                    case CREATE_ATOM:
                        if (keys.isEmpty()) {
                            throw new WonMessageProcessingException("No key found in CREATE message");
                        }
                        break;
                    case REPLACE:
                        if (keys.isEmpty()) {
                            keys.putAll(getRequiredPublicKeys(toCheck.getCompleteDataset()));
                        }
                        break;
                    default:
                        if (!keys.isEmpty()) {
                            throw new WonMessageProcessingException(String.format("An Atom key may only be embedded in CREATE or REPLACE messages! Found one in %s message %s", type, message.getMessageURIRequired()));
                        }
                        keys.putAll(getRequiredPublicKeys(toCheck.getCompleteDataset()));
                }
                sw.stop();
                // verify with those public keys
                sw.start("verify");
                result = WonMessageSignerVerifier.verify(keys, toCheck);
                sw.stop();
                if (logger.isDebugEnabled()) {
                    logger.debug("VERIFIED=" + result.isVerificationPassed() + " with keys: " + keys.values() + " for\n" + RdfUtils.writeDatasetToString(Prefixer.setPrefixes(toCheck.getCompleteDataset()), Lang.TRIG));
                }
            } catch (LinkedDataFetchingException e) {
                /*
                     * If a delete message could not be validated because the atom was already
                     * deleted, we assume that this message is just mirrored back to the owner and
                     * is to be accepteed
                     */
                if (WonMessageType.DELETE.equals(toCheck.getMessageType())) {
                    if (e.getCause() instanceof HttpClientErrorException && HttpStatus.GONE.equals(((HttpClientErrorException) e.getCause()).getStatusCode())) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Failure during processing signature check of message" + toCheck.getMessageURI() + " (messageType was DELETE, but atom is already deleted, accept message anyway)");
                        }
                        return toCheck;
                    }
                }
                // TODO SignatureProcessingException?
                throw new WonMessageProcessingException("Could not verify message " + toCheck.getMessageURI(), e);
            } catch (Exception e) {
                // TODO SignatureProcessingException?
                throw new WonMessageProcessingException("Could not verify message " + toCheck.getMessageURI(), e);
            }
            // throw exception if the verification fails:
            if (!result.isVerificationPassed()) {
                String errormessage = "Message verification failed. Message:" + toCheck.toStringForDebug(false) + ", Problem:" + result.getMessage();
                if (logger.isDebugEnabled()) {
                    logger.debug(errormessage + ". Offending message:\n" + RdfUtils.toString(Prefixer.setPrefixes(toCheck.getCompleteDataset())));
                }
                // TODO SignatureProcessingException?
                throw new WonMessageProcessingException(new SignatureException(errormessage + ". To log the offending message, set Loglevel to DEBUG for logger '" + this.getClass().getName() + "'"));
            }
        }
        return message;
    } finally {
        logger.debug(LogMarkers.TIMING, "Signature check for message {} took {} millis, details:\n {}", new Object[] { message.getMessageURIRequired(), sw.getTotalTimeMillis(), sw.prettyPrint() });
    }
}
Also used : WonMessageProcessingException(won.protocol.exception.WonMessageProcessingException) HttpClientErrorException(org.springframework.web.client.HttpClientErrorException) PublicKey(java.security.PublicKey) WonMessage(won.protocol.message.WonMessage) LinkedDataFetchingException(won.protocol.rest.LinkedDataFetchingException) WonMessageType(won.protocol.message.WonMessageType) SignatureVerificationState(won.cryptography.rdfsign.SignatureVerificationState) SignatureException(java.security.SignatureException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) WonMessageProcessingException(won.protocol.exception.WonMessageProcessingException) SignatureException(java.security.SignatureException) LinkedDataFetchingException(won.protocol.rest.LinkedDataFetchingException) HttpClientErrorException(org.springframework.web.client.HttpClientErrorException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) NoSuchProviderException(java.security.NoSuchProviderException) StopWatch(org.springframework.util.StopWatch)

Example 92 with WonMessage

use of won.protocol.message.WonMessage in project webofneeds by researchstudio-sat.

the class VerifyAndSignExamples method nodeCreateAtomMsg.

@Test
public /*
     * Node receives create atom message, verifies it, if verification succeeds -
     * adds envelope that includes reference to verified signatures, and signs it.
     */
void nodeCreateAtomMsg() throws Exception {
    // create dataset that contains atom core data graph, envelope and its
    // signatures.
    // this is what nodes receives when the atom is created
    Dataset inputDataset = TestSigningUtils.prepareTestDatasetFromNamedGraphs(RESOURCE_FILE, new String[] { ATOM_CORE_DATA_URI, ATOM_CORE_DATA_SIG_URI, EVENT_ENV1_URI, EVENT_ENV1_SIG_URI });
    WonMessage inputMessage = WonMessage.of(inputDataset);
    // node verifies the signature:
    WonMessage verifiedMessage = null;
    try {
        verifiedMessage = checkingProcessor.process(inputMessage);
    } catch (WonMessageProcessingException e) {
        Assert.fail("Signature verification failed");
    }
    // write for debugging
    // TestSigningUtils.writeToTempFile(outputDataset);
    // everyone should be able to verify this message, inculding when it was read
    // from RDF:
    String datasetString = RdfUtils.writeDatasetToString(inputMessage.getCompleteDataset(), Lang.TRIG);
    WonMessage outputMessage = WonMessage.of(RdfUtils.readDatasetFromString(datasetString, Lang.TRIG));
    try {
        checkingProcessor.process(outputMessage);
    } catch (WonMessageProcessingException e) {
        Assert.fail("Signature verification failed");
    }
}
Also used : WonMessageProcessingException(won.protocol.exception.WonMessageProcessingException) Dataset(org.apache.jena.query.Dataset) WonMessage(won.protocol.message.WonMessage) Test(org.junit.Test)

Example 93 with WonMessage

use of won.protocol.message.WonMessage in project webofneeds by researchstudio-sat.

the class WonVerifierTest method testVerifyCreateAtomData.

@Test
public void testVerifyCreateAtomData() throws Exception {
    // create dataset that contains atom core data graph and its signature graph
    Dataset testDataset = TestSigningUtils.prepareTestDatasetFromNamedGraphs(RESOURCE_FILE, new String[] { ATOM_CORE_DATA_URI, ATOM_CORE_DATA_SIG_URI });
    WonMessage msg = WonMessage.of(testDataset);
    // verify
    WonVerifier verifier = new WonVerifier(msg);
    // TODO load public keys from certificate referenced from signatures
    boolean verified = verifier.verify(keys.getPublicKeys());
    SignatureVerificationState result = verifier.getVerificationResult();
    Assert.assertTrue(result.getMessage(), verified);
    Assert.assertEquals(1, result.getSignatureGraphNames().size());
    Assert.assertEquals(ATOM_CORE_DATA_URI, result.getSignedGraphNames(ATOM_CORE_DATA_SIG_URI));
    // modify a model and check that it does not verify..
    Model m = testDataset.getNamedModel(ATOM_CORE_DATA_URI);
    Statement stmt = m.listStatements().nextStatement();
    m.remove(stmt);
    verifier = new WonVerifier(WonMessage.of(testDataset));
    verified = verifier.verify(keys.getPublicKeys());
    result = verifier.getVerificationResult();
    Assert.assertFalse(verified);
    Assert.assertEquals(1, result.getSignatureGraphNames().size());
    Assert.assertEquals(ATOM_CORE_DATA_URI, result.getSignedGraphNames(ATOM_CORE_DATA_SIG_URI));
    // add the removed statement back
    m.add(stmt);
    verifier = new WonVerifier(WonMessage.of(testDataset));
    verified = verifier.verify(keys.getPublicKeys());
    // now it should verify again
    Assert.assertTrue(verified);
}
Also used : Dataset(org.apache.jena.query.Dataset) Statement(org.apache.jena.rdf.model.Statement) WonMessage(won.protocol.message.WonMessage) Model(org.apache.jena.rdf.model.Model) Test(org.junit.Test)

Example 94 with WonMessage

use of won.protocol.message.WonMessage in project webofneeds by researchstudio-sat.

the class WonMessageRoutesExternalRoutedTest method test_connect__try_force_racecondition.

@Test
// @Rollback would't work as camel still commits
@Commit
public void test_connect__try_force_racecondition() throws Exception {
    for (int i = 0; i < 10; i++) {
        logger.debug("Attempt #{} to force a race condition", i + 1);
        URI atomURI = newAtomURI();
        URI socketURI = URI.create(atomURI.toString() + "#socket1");
        URI atomURI2 = newAtomURI();
        URI socketURI2 = URI.create(atomURI2.toString() + "#socket1");
        prepareMockitoStubs(atomURI, socketURI, atomURI2, socketURI2);
        WonMessage createAtom1Msg = prepareFromOwner(makeCreateAtomMessage(atomURI, "/won/node/WonMessageRoutesTest/data/test-atom1.ttl"));
        WonMessage createAtom2Msg = prepareFromOwner(makeCreateAtomMessage(atomURI2, "/won/node/WonMessageRoutesTest/data/test-atom1.ttl"));
        // set minimal expectations just so we can expect something and subsequently
        // reset expectations
        toMatcherMockEndpoint.reset();
        toOwnerMockEndpoint.reset();
        toOwnerMockEndpoint.expectedMessageCount(2);
        toMatcherMockEndpoint.expectedMessageCount(2);
        sendFromOwner(createAtom1Msg, OWNERAPPLICATION_ID_OWNER1);
        sendFromOwner(createAtom2Msg, OWNERAPPLICATION_ID_OWNER2);
        WonMessage socketHintMessage = prepareFromMatcher(WonMessageBuilder.socketHint().recipientSocket(socketURI).hintTargetSocket(socketURI2).hintScore(0.5).build());
        assertMockEndpointsSatisfiedAndReset(toOwnerMockEndpoint, toMatcherMockEndpoint);
        // seems fair to wait for response to create before we send the hint
        toOwnerMockEndpoint.expectedMessageCount(1);
        sendFromMatcher(socketHintMessage);
        assertMockEndpointsSatisfiedAndReset(toOwnerMockEndpoint, toMatcherMockEndpoint);
        // start connecting
        WonMessage connectFromExternalMsg = prepareFromExternalOwner(WonMessageBuilder.connect().sockets().sender(socketURI2).recipient(socketURI).content().text("Unittest connect").build());
        assertMockEndpointsSatisfiedAndReset(toOwnerMockEndpoint, toMatcherMockEndpoint);
        WonMessage connectFromOwnerMsg = prepareFromOwner(WonMessageBuilder.connect().sockets().sender(socketURI).recipient(socketURI2).content().text("Unittest connect").build());
        toOwnerMockEndpoint.expectedMessageCount(6);
        toOwnerMockEndpoint.expectedMessagesMatches(or(maxOnce(isMessageAndResponse(connectFromExternalMsg)), maxOnce(isMessageAndResponseAndRemoteResponse(connectFromExternalMsg)), maxOnce(isSuccessResponseTo(connectFromExternalMsg)), maxOnce(isMessageAndResponse(connectFromOwnerMsg)), maxOnce(isMessageAndResponseAndRemoteResponse(connectFromOwnerMsg)), maxOnce(isSuccessResponseTo(connectFromOwnerMsg))));
        Thread t1 = new Thread(() -> helper.doInSeparateTransaction(() -> sendFromOwner(connectFromExternalMsg, OWNERAPPLICATION_ID_OWNER2)));
        Thread t2 = new Thread(() -> helper.doInSeparateTransaction(() -> sendFromOwner(connectFromOwnerMsg, OWNERAPPLICATION_ID_OWNER1)));
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        assertMockEndpointsSatisfiedAndReset(toOwnerMockEndpoint, toMatcherMockEndpoint);
        Optional<Connection> con = connectionRepository.findOneBySocketURIAndTargetSocketURI(socketURI, socketURI2);
        Connection expected = new Connection();
        expected.setState(ConnectionState.CONNECTED);
        expected.setAtomURI(atomURI);
        expected.setSocketURI(socketURI);
        expected.setTargetSocketURI(socketURI2);
        expected.setTargetAtomURI(atomURI2);
        assertConnectionAsExpected(expected, con);
        con = connectionRepository.findOneBySocketURIAndTargetSocketURI(socketURI2, socketURI);
        expected = new Connection();
        expected.setState(ConnectionState.CONNECTED);
        expected.setAtomURI(atomURI2);
        expected.setSocketURI(socketURI2);
        expected.setTargetSocketURI(socketURI);
        expected.setTargetAtomURI(atomURI);
        assertConnectionAsExpected(expected, con);
    }
}
Also used : WonMessage(won.protocol.message.WonMessage) URI(java.net.URI) Commit(org.springframework.test.annotation.Commit) Test(org.junit.Test)

Example 95 with WonMessage

use of won.protocol.message.WonMessage in project webofneeds by researchstudio-sat.

the class WonMessageRoutesExternalRoutedTest method test_conversation__proposal_rejected.

@Test
// @Rollback would't work as camel still commits
@Commit
public void test_conversation__proposal_rejected() throws Exception {
    URI atomURI = newAtomURI();
    URI socketURI = URI.create(atomURI.toString() + "#socket1");
    URI atomURI2 = newAtomURI();
    URI socketURI2 = URI.create(atomURI2.toString() + "#socket1");
    prepareMockitoStubs(atomURI, socketURI, atomURI2, socketURI2);
    MessageCollector collector = new MessageCollector();
    WonMessage createAtom1Msg = prepareFromOwner(makeCreateAtomMessage(atomURI, "/won/node/WonMessageRoutesTest/data/test-atom1.ttl"));
    WonMessage createAtom2Msg = prepareFromOwner(makeCreateAtomMessage(atomURI2, "/won/node/WonMessageRoutesTest/data/test-atom1.ttl"));
    // set minimal expectations just so we can expect something and subsequently
    // reset expectations
    toOwnerMockEndpoint.expectedMessageCount(2);
    toMatcherMockEndpoint.expectedMessageCount(2);
    sendFromOwner(createAtom1Msg, OWNERAPPLICATION_ID_OWNER1);
    sendFromOwner(createAtom2Msg, OWNERAPPLICATION_ID_OWNER2);
    WonMessage socketHintMessage = prepareFromMatcher(WonMessageBuilder.socketHint().recipientSocket(socketURI).hintTargetSocket(socketURI2).hintScore(0.5).build());
    assertMockEndpointsSatisfiedAndReset(collector, toOwnerMockEndpoint, toMatcherMockEndpoint);
    toOwnerMockEndpoint.expectedMessageCount(1);
    toMatcherMockEndpoint.expectedMessageCount(0);
    sendFromMatcher(socketHintMessage);
    // start connecting
    WonMessage connectFromExternalMsg = prepareFromExternalOwner(WonMessageBuilder.connect().sockets().sender(socketURI2).recipient(socketURI).content().text("Unittest connect").build());
    assertMockEndpointsSatisfiedAndReset(collector, toOwnerMockEndpoint, toMatcherMockEndpoint);
    toMatcherMockEndpoint.expectedMessageCount(0);
    toOwnerMockEndpoint.expectedMessageCount(3);
    sendFromOwner(connectFromExternalMsg, OWNERAPPLICATION_ID_OWNER2);
    assertMockEndpointsSatisfiedAndReset(collector, toOwnerMockEndpoint, toMatcherMockEndpoint);
    WonMessage connectFromOwnerMsg = prepareFromOwner(WonMessageBuilder.connect().sockets().sender(socketURI).recipient(socketURI2).content().text("Unittest connect (completing the handshake)").build());
    toOwnerMockEndpoint.expectedMessageCount(3);
    toMatcherMockEndpoint.expectedMessageCount(2);
    sendFromOwner(connectFromOwnerMsg, OWNERAPPLICATION_ID_OWNER1);
    assertMockEndpointsSatisfiedAndReset(collector, toOwnerMockEndpoint, toMatcherMockEndpoint);
    // // connect done
    Optional<Connection> con = connectionRepository.findOneBySocketURIAndTargetSocketURI(socketURI, socketURI2);
    // // send one message, which will be the content of the agreement
    WonMessage contentForProposal = prepareFromOwner(WonMessageBuilder.connectionMessage().sockets().sender(con.get().getSocketURI()).recipient(con.get().getTargetSocketURI()).content().text(// something important
    "We are best friends forever!").build());
    toOwnerMockEndpoint.expectedMessageCount(3);
    toMatcherMockEndpoint.expectedMessageCount(0);
    sendFromOwner(contentForProposal, OWNERAPPLICATION_ID_OWNER1);
    assertMockEndpointsSatisfiedAndReset(collector, toOwnerMockEndpoint, toMatcherMockEndpoint);
    // now propose the previous message formally
    WonMessage proposal = prepareFromOwner(WonMessageBuilder.connectionMessage().sockets().sender(con.get().getSocketURI()).recipient(con.get().getTargetSocketURI()).content().text("I am hereby proposing to be best friends forever").agreement().proposes(contentForProposal).build());
    toOwnerMockEndpoint.expectedMessageCount(3);
    toMatcherMockEndpoint.expectedMessageCount(0);
    sendFromOwner(proposal, OWNERAPPLICATION_ID_OWNER1);
    assertMockEndpointsSatisfiedAndReset(collector, toOwnerMockEndpoint, toMatcherMockEndpoint);
    // now accept the proposal from the other side
    WonMessage rejectMessage = prepareFromExternalOwner(WonMessageBuilder.connectionMessage().sockets().sender(con.get().getTargetSocketURI()).recipient(con.get().getSocketURI()).content().text("I am sorry, do I know you?").agreement().rejects(proposal.getMessageURI()).build());
    toOwnerMockEndpoint.expectedMessageCount(3);
    toMatcherMockEndpoint.expectedMessageCount(0);
    sendFromOwner(rejectMessage, OWNERAPPLICATION_ID_OWNER2);
    assertMockEndpointsSatisfiedAndReset(collector, toOwnerMockEndpoint, toMatcherMockEndpoint);
    printConversationIfDebugging(collector);
    assertCorrectAgreements("Wrong agreement content", collector.getCollected(), DatasetFactory.createGeneral());
}
Also used : WonMessage(won.protocol.message.WonMessage) URI(java.net.URI) Commit(org.springframework.test.annotation.Commit) Test(org.junit.Test)

Aggregations

WonMessage (won.protocol.message.WonMessage)237 URI (java.net.URI)157 Test (org.junit.Test)84 Dataset (org.apache.jena.query.Dataset)70 Commit (org.springframework.test.annotation.Commit)49 Connection (won.protocol.model.Connection)34 Event (won.bot.framework.eventbot.event.Event)31 Message (org.apache.camel.Message)30 EventListener (won.bot.framework.eventbot.listener.EventListener)30 Logger (org.slf4j.Logger)26 LoggerFactory (org.slf4j.LoggerFactory)26 MethodHandles (java.lang.invoke.MethodHandles)25 Optional (java.util.Optional)23 EventBus (won.bot.framework.eventbot.bus.EventBus)23 WonMessageBuilder (won.protocol.message.builder.WonMessageBuilder)23 EventBotActionUtils (won.bot.framework.eventbot.action.EventBotActionUtils)22 Set (java.util.Set)19 BaseEventBotAction (won.bot.framework.eventbot.action.BaseEventBotAction)19 EventListenerContext (won.bot.framework.eventbot.EventListenerContext)18 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)17