Skip to content

Commit

Permalink
Ensure lookup signatures are produced in a consistent way
Browse files Browse the repository at this point in the history
  • Loading branch information
maxidorius committed Apr 28, 2019
1 parent 85d9f9e commit 44a8046
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 10 deletions.
33 changes: 33 additions & 0 deletions src/main/java/io/kamax/mxisd/crypto/SignatureManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,45 @@

package io.kamax.mxisd.crypto;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.kamax.matrix.event.EventKey;
import io.kamax.matrix.json.MatrixJson;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

public interface SignatureManager {

/**
* Sign the message and add the signature to the <code>signatures</code> key.
* <p>
* If the key does not exist yet, it is created. If the key exist, the produced signature will be merged with any
* existing ones.
*
* @param domain The domain under which the signature should be added
* @param message The message to sign and add the produced signature to
* @return The provided message with the new signature
* @throws IllegalArgumentException If the <code>signatures</code> value is not a JSON object
*/
default JsonObject signMessageGson(String domain, JsonObject message) throws IllegalArgumentException {
JsonElement signEl = message.remove(EventKey.Signatures.get());
JsonObject oldSigns = new JsonObject();
if (!Objects.isNull(signEl)) {
if (!signEl.isJsonObject()) {
throw new IllegalArgumentException("Message contains a signatures key that is not a JSON object value");
}

oldSigns = signEl.getAsJsonObject();
}

JsonObject newSigns = signMessageGson(domain, MatrixJson.encodeCanonical(message));
oldSigns.entrySet().forEach(entry -> newSigns.add(entry.getKey(), entry.getValue()));
message.add(EventKey.Signatures.get(), newSigns);

return message;
}

/**
* Sign the message and produce a <code>signatures</code> object that can directly be added to the object being signed.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
package io.kamax.mxisd.http.undertow.handler.identity.v1;

import com.google.gson.JsonObject;
import io.kamax.matrix.event.EventKey;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.matrix.json.MatrixJson;
import io.kamax.mxisd.config.MxisdConfig;
import io.kamax.mxisd.config.ServerConfig;
import io.kamax.mxisd.crypto.SignatureManager;
Expand Down Expand Up @@ -73,11 +71,8 @@ public void handleRequest(HttpServerExchange exchange) {
respondJson(exchange, "{}");
} else {
SingleLookupReply lookup = lookupOpt.get();

// FIXME signing should be done in the business model, not in the controller
JsonObject obj = GsonUtil.makeObj(new SingeLookupReplyJson(lookup));
obj.add(EventKey.Signatures.get(), signMgr.signMessageGson(cfg.getName(), MatrixJson.encodeCanonical(obj)));

signMgr.signMessageGson(cfg.getName(), obj);
respondJson(exchange, obj);
}
}
Expand Down
20 changes: 16 additions & 4 deletions src/test/java/io/kamax/mxisd/test/crypto/SignatureManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package io.kamax.mxisd.test.crypto;

import com.google.gson.JsonObject;
import io.kamax.matrix.event.EventKey;
import io.kamax.matrix.json.GsonUtil;
import io.kamax.matrix.json.MatrixJson;
import io.kamax.mxisd.crypto.Signature;
Expand All @@ -36,10 +37,14 @@

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

public class SignatureManagerTest {

private static final String lookupData = "{\n" + " \"not_before\": 0,\n" + " \"address\": \"[email protected]\",\n"
+ " \"medium\": \"email\",\n" + " \"mxid\": \"@mxisd-lookup-test:kamax.io\",\n"
+ " \"not_after\": 253402300799000,\n" + " \"ts\": 1523482030147\n" + "}";
private static SignatureManager signMgr;

private static SignatureManager build(String keySeed) {
Expand Down Expand Up @@ -98,12 +103,19 @@ public void onFederationHeader() {

@Test
public void onIdentityLookup() {
String value = MatrixJson.encodeCanonical("{\n" + " \"address\": \"[email protected]\",\n"
+ " \"medium\": \"email\",\n" + " \"mxid\": \"@mxisd-lookup-test:kamax.io\",\n"
+ " \"not_after\": 253402300799000,\n" + " \"not_before\": 0,\n" + " \"ts\": 1523482030147\n" + "}");

String value = MatrixJson.encodeCanonical(lookupData);
String sign = "ObKA4PNQh2g6c7Yo2QcTcuDgIwhknG7ZfqmNYzbhrbLBOqZomU22xX9raufN2Y3ke1FXsDqsGs7WBDodmzZJCg";
testSign(value, sign);
}

@Test
public void onIdentityLookupFull() {
JsonObject data = GsonUtil.parseObj(lookupData);
signMgr.signMessageGson("localhost", data);
JsonObject signatures = EventKey.Signatures.getObj(data);
JsonObject domainSign = GsonUtil.getObj(signatures, "localhost");
String sign = GsonUtil.getStringOrThrow(domainSign, "ed25519:0");
assertEquals(sign, "ObKA4PNQh2g6c7Yo2QcTcuDgIwhknG7ZfqmNYzbhrbLBOqZomU22xX9raufN2Y3ke1FXsDqsGs7WBDodmzZJCg");
}

}

0 comments on commit 44a8046

Please sign in to comment.