use of com.quorum.tessera.api.PayloadEncryptResponse in project tessera by ConsenSys.
the class EncodedPayloadResource method createEncodedPayload.
// hide this operation from swagger generation; the /encodedpayload/create operation is overloaded
// and must be documented in a single place
@Hidden
@POST
@Path("create")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response createEncodedPayload(@NotNull @Valid final SendRequest sendRequest) {
LOGGER.info("Received request for custom payload encryption");
final PublicKey sender = Optional.ofNullable(sendRequest.getFrom()).map(base64Decoder::decode).map(PublicKey::from).orElseGet(transactionManager::defaultPublicKey);
final List<PublicKey> recipientList = Stream.of(sendRequest).filter(sr -> Objects.nonNull(sr.getTo())).flatMap(s -> Stream.of(s.getTo())).map(base64Decoder::decode).map(PublicKey::from).collect(Collectors.toList());
final Set<MessageHash> affectedTransactions = Stream.ofNullable(sendRequest.getAffectedContractTransactions()).flatMap(Arrays::stream).map(Base64.getDecoder()::decode).map(MessageHash::new).collect(Collectors.toSet());
final byte[] execHash = Optional.ofNullable(sendRequest.getExecHash()).map(String::getBytes).orElse(new byte[0]);
final com.quorum.tessera.transaction.SendRequest request = com.quorum.tessera.transaction.SendRequest.Builder.create().withRecipients(recipientList).withSender(sender).withPayload(sendRequest.getPayload()).withExecHash(execHash).withPrivacyMode(PrivacyMode.fromFlag(sendRequest.getPrivacyFlag())).withAffectedContractTransactions(affectedTransactions).build();
final EncodedPayload encodedPayload = encodedPayloadManager.create(request);
final Map<String, String> affectedContractTransactionMap = encodedPayload.getAffectedContractTransactions().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().encodeToBase64(), e -> Base64.getEncoder().encodeToString(e.getValue().getData())));
final PayloadEncryptResponse response = new PayloadEncryptResponse();
response.setSenderKey(encodedPayload.getSenderKey().getKeyBytes());
response.setCipherText(encodedPayload.getCipherText());
response.setCipherTextNonce(encodedPayload.getCipherTextNonce().getNonceBytes());
response.setRecipientBoxes(encodedPayload.getRecipientBoxes().stream().map(RecipientBox::getData).collect(Collectors.toList()));
response.setRecipientNonce(encodedPayload.getRecipientNonce().getNonceBytes());
response.setRecipientKeys(encodedPayload.getRecipientKeys().stream().map(PublicKey::getKeyBytes).collect(Collectors.toList()));
response.setPrivacyMode(encodedPayload.getPrivacyMode().getPrivacyFlag());
response.setAffectedContractTransactions(affectedContractTransactionMap);
response.setExecHash(encodedPayload.getExecHash());
return Response.ok(response).type(APPLICATION_JSON).build();
}
use of com.quorum.tessera.api.PayloadEncryptResponse in project tessera by ConsenSys.
the class EncodedPayloadResource method createEncodedPayload21.
// path /encodedpayload/create is overloaded (application/json and
// application/vnd.tessera-2.1+json); swagger annotations cannot handle situations like this so
// this operation documents both
@POST
@Path("create")
@Operation(summary = "/encodedpayload/create", operationId = "encrypt", description = "encrypt a payload and return the result; does not store to the database or push to peers", requestBody = @RequestBody(content = { @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = SendRequest.class)), @Content(mediaType = MIME_TYPE_JSON_2_1, schema = @Schema(implementation = SendRequest.class)) }))
@ApiResponse(responseCode = "200", description = "encrypted payload", content = { @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = PayloadEncryptResponse.class)), @Content(mediaType = MIME_TYPE_JSON_2_1, schema = @Schema(implementation = PayloadEncryptResponse.class)) })
@Consumes(MIME_TYPE_JSON_2_1)
@Produces(MIME_TYPE_JSON_2_1)
public Response createEncodedPayload21(@NotNull @Valid final SendRequest sendRequest) {
LOGGER.info("Received request for custom payload encryption");
final PublicKey sender = Optional.ofNullable(sendRequest.getFrom()).map(base64Decoder::decode).map(PublicKey::from).orElseGet(transactionManager::defaultPublicKey);
final List<PublicKey> recipientList = Stream.of(sendRequest).filter(sr -> Objects.nonNull(sr.getTo())).flatMap(s -> Stream.of(s.getTo())).map(base64Decoder::decode).map(PublicKey::from).collect(Collectors.toList());
final Set<MessageHash> affectedTransactions = Stream.ofNullable(sendRequest.getAffectedContractTransactions()).flatMap(Arrays::stream).map(Base64.getDecoder()::decode).map(MessageHash::new).collect(Collectors.toSet());
final byte[] execHash = Optional.ofNullable(sendRequest.getExecHash()).map(String::getBytes).orElse(new byte[0]);
final com.quorum.tessera.transaction.SendRequest request = com.quorum.tessera.transaction.SendRequest.Builder.create().withRecipients(recipientList).withSender(sender).withPayload(sendRequest.getPayload()).withExecHash(execHash).withPrivacyMode(PrivacyMode.fromFlag(sendRequest.getPrivacyFlag())).withAffectedContractTransactions(affectedTransactions).build();
final EncodedPayload encodedPayload = encodedPayloadManager.create(request);
final Map<String, String> affectedContractTransactionMap = encodedPayload.getAffectedContractTransactions().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().encodeToBase64(), e -> Base64.getEncoder().encodeToString(e.getValue().getData())));
final PayloadEncryptResponse response = new PayloadEncryptResponse();
response.setSenderKey(encodedPayload.getSenderKey().getKeyBytes());
response.setCipherText(encodedPayload.getCipherText());
response.setCipherTextNonce(encodedPayload.getCipherTextNonce().getNonceBytes());
response.setRecipientBoxes(encodedPayload.getRecipientBoxes().stream().map(RecipientBox::getData).collect(Collectors.toList()));
response.setRecipientNonce(encodedPayload.getRecipientNonce().getNonceBytes());
response.setRecipientKeys(encodedPayload.getRecipientKeys().stream().map(PublicKey::getKeyBytes).collect(Collectors.toList()));
response.setPrivacyMode(encodedPayload.getPrivacyMode().getPrivacyFlag());
response.setAffectedContractTransactions(affectedContractTransactionMap);
response.setExecHash(encodedPayload.getExecHash());
return Response.ok(response).type(MIME_TYPE_JSON_2_1).build();
}
use of com.quorum.tessera.api.PayloadEncryptResponse in project tessera by ConsenSys.
the class EncodedPayloadResourceTest method decryptPayloadVersion21.
@Test
public void decryptPayloadVersion21() {
final Base64.Decoder decoder = Base64.getDecoder();
final PayloadDecryptRequest request = new PayloadDecryptRequest();
request.setSenderKey(decoder.decode("BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo="));
request.setCipherText(decoder.decode("h7av/vhPlaPFECB1K30hNWugv/Bu"));
request.setCipherTextNonce(decoder.decode("8MVXAESCQuRHWxrQ6b5MXuYApjia+2h0"));
request.setRecipientBoxes(List.of(decoder.decode("FNirZRc2ayMaYopCBaWQ/1I7VWFiCM0lNw533Hckzxb+qpvngdWVVzJlsE05dbxl")));
request.setRecipientNonce(decoder.decode("p9gYDJlEoBvLdUQ+ZoONl2Jl9AirV1en"));
request.setRecipientKeys(List.of(decoder.decode("BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=")));
request.setPrivacyMode(3);
request.setAffectedContractTransactions(Map.of("dHgx", "dHgxdmFs", "dHgy", "dHgydmFs"));
request.setExecHash("execHash".getBytes());
final ReceiveResponse response = ReceiveResponse.Builder.create().withUnencryptedTransactionData("decryptedData".getBytes()).withPrivacyMode(PrivacyMode.PRIVATE_STATE_VALIDATION).withAffectedTransactions(Set.of(new MessageHash("tx1val".getBytes()), new MessageHash("tx2val".getBytes()))).withExecHash("execHash".getBytes()).withSender(PublicKey.from(request.getSenderKey())).build();
when(encodedPayloadManager.decrypt(any(), eq(null))).thenReturn(response);
final Response result = encodedPayloadResource.receive21(request);
assertThat(result.getStatus()).isEqualTo(200);
final com.quorum.tessera.api.ReceiveResponse payloadEncryptResponse = Optional.of(result).map(Response::getEntity).map(com.quorum.tessera.api.ReceiveResponse.class::cast).get();
assertThat(payloadEncryptResponse.getPayload()).isEqualTo("decryptedData".getBytes());
assertThat(payloadEncryptResponse.getPrivacyFlag()).isEqualTo(3);
assertThat(payloadEncryptResponse.getAffectedContractTransactions()).containsExactlyInAnyOrder("dHgxdmFs", "dHgydmFs");
assertThat(payloadEncryptResponse.getExecHash()).isEqualTo("execHash");
final ArgumentCaptor<EncodedPayload> argumentCaptor = ArgumentCaptor.forClass(EncodedPayload.class);
verify(encodedPayloadManager).decrypt(argumentCaptor.capture(), eq(null));
final EncodedPayload payloadBeforeDecryption = argumentCaptor.getValue();
assertThat(payloadBeforeDecryption.getSenderKey().encodeToBase64()).isEqualTo("BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=");
assertThat(payloadBeforeDecryption.getCipherText()).isEqualTo(decoder.decode("h7av/vhPlaPFECB1K30hNWugv/Bu"));
assertThat(payloadBeforeDecryption.getCipherTextNonce().getNonceBytes()).isEqualTo(decoder.decode("8MVXAESCQuRHWxrQ6b5MXuYApjia+2h0"));
assertThat(payloadBeforeDecryption.getRecipientBoxes()).containsExactly(RecipientBox.from(decoder.decode("FNirZRc2ayMaYopCBaWQ/1I7VWFiCM0lNw533Hckzxb+qpvngdWVVzJlsE05dbxl")));
assertThat(payloadBeforeDecryption.getRecipientNonce().getNonceBytes()).isEqualTo(decoder.decode("p9gYDJlEoBvLdUQ+ZoONl2Jl9AirV1en"));
assertThat(payloadBeforeDecryption.getRecipientKeys()).containsExactly(PublicKey.from(decoder.decode("BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=")));
assertThat(payloadBeforeDecryption.getPrivacyMode()).isEqualTo(PrivacyMode.PRIVATE_STATE_VALIDATION);
assertThat(payloadBeforeDecryption.getAffectedContractTransactions()).contains(entry(TxHash.from("tx1".getBytes()), SecurityHash.from("tx1val".getBytes())), entry(TxHash.from("tx2".getBytes()), SecurityHash.from("tx2val".getBytes())));
assertThat(payloadBeforeDecryption.getExecHash()).isEqualTo("execHash".getBytes());
}
use of com.quorum.tessera.api.PayloadEncryptResponse in project tessera by ConsenSys.
the class CustomPayloadEncryptionIT method payloadDecryptionFailsOnBadMessage.
@Test
public void payloadDecryptionFailsOnBadMessage() {
final Party sender = partyHelper.findByAlias(NodeAlias.A);
final SendRequest sendRequest = new SendRequest();
sendRequest.setPayload(Base64.getEncoder().encode("Test Payload".getBytes()));
Response result = sender.getRestClientWebTarget().path("/encodedpayload/create").request().post(Entity.entity(sendRequest, mediaType));
assertThat(result.getStatus()).isEqualTo(200);
final PayloadEncryptResponse payloadEncryptResponse = result.readEntity(PayloadEncryptResponse.class);
// edit the cipher text to something rubbish, so it can't be decrypted
payloadEncryptResponse.setCipherText("Unexpected data".getBytes());
// attempt to decrypt it
final Response decryptResultForSender = sender.getRestClientWebTarget().path("/encodedpayload/decrypt").request().post(Entity.entity(payloadEncryptResponse, mediaType));
assertThat(decryptResultForSender.getStatus()).isEqualTo(500);
}
use of com.quorum.tessera.api.PayloadEncryptResponse in project tessera by ConsenSys.
the class CustomPayloadEncryptionIT method createAndDecryptPayload.
@Test
public void createAndDecryptPayload() {
final Party sender = partyHelper.findByAlias(NodeAlias.A);
final Party recipient = partyHelper.findByAlias(NodeAlias.B);
final SendRequest sendRequest = new SendRequest();
sendRequest.setPayload(Base64.getEncoder().encode("Test Payload".getBytes()));
sendRequest.setTo(recipient.getPublicKey());
final Response encryptResult = sender.getRestClientWebTarget().path("/encodedpayload/create").request().post(Entity.entity(sendRequest, mediaType));
assertThat(encryptResult.getStatus()).isEqualTo(200);
final PayloadEncryptResponse payloadEncryptResponse = encryptResult.readEntity(PayloadEncryptResponse.class);
// decrypt it again with the sender
final Response decryptResultForSender = sender.getRestClientWebTarget().path("/encodedpayload/decrypt").request().post(Entity.entity(payloadEncryptResponse, mediaType));
final ReceiveResponse decryptedPayload = decryptResultForSender.readEntity(ReceiveResponse.class);
assertThat(Base64.getDecoder().decode(decryptedPayload.getPayload())).isEqualTo("Test Payload".getBytes());
// decrypt it using the recipient
final String firstRecipientInList = Base64.getEncoder().encodeToString(payloadEncryptResponse.getRecipientKeys().get(0));
if (Objects.equals(firstRecipientInList, sender.getPublicKey())) {
payloadEncryptResponse.getRecipientBoxes().remove(0);
} else {
payloadEncryptResponse.getRecipientBoxes().remove(1);
}
payloadEncryptResponse.setRecipientKeys(Collections.emptyList());
final Response decryptResultForRecipient = recipient.getRestClientWebTarget().path("/encodedpayload/decrypt").request().post(Entity.entity(payloadEncryptResponse, mediaType));
final ReceiveResponse decryptedPayloadForRecipient = decryptResultForRecipient.readEntity(ReceiveResponse.class);
assertThat(Base64.getDecoder().decode(decryptedPayloadForRecipient.getPayload())).isEqualTo("Test Payload".getBytes());
}
Aggregations