Search in sources :

Example 16 with EncryptedTransaction

use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.

the class ResendManagerImplTest method storePayloadAsSenderWhenTxIsPresentAndPsv.

@Test
public void storePayloadAsSenderWhenTxIsPresentAndPsv() {
    final PublicKey senderKey = PublicKey.from("SENDER".getBytes());
    final PublicKey recipientKey1 = PublicKey.from("RECIPIENT-KEY1".getBytes());
    final RecipientBox recipientBox1 = RecipientBox.from("BOX1".getBytes());
    final PublicKey recipientKey2 = PublicKey.from("RECIPIENT-KEY2".getBytes());
    final RecipientBox recipientBox2 = RecipientBox.from("BOX2".getBytes());
    final EncodedPayload encodedPayload = mock(EncodedPayload.class);
    when(encodedPayload.getCipherText()).thenReturn("CIPHERTEXT".getBytes());
    when(encodedPayload.getSenderKey()).thenReturn(senderKey);
    when(encodedPayload.getRecipientKeys()).thenReturn(List.of(recipientKey2, senderKey));
    when(encodedPayload.getRecipientBoxes()).thenReturn(List.of(recipientBox2));
    when(encodedPayload.getPrivacyMode()).thenReturn(PrivacyMode.PRIVATE_STATE_VALIDATION);
    final EncodedPayload existingEncodedPayload = mock(EncodedPayload.class);
    when(existingEncodedPayload.getCipherText()).thenReturn("CIPHERTEXT".getBytes());
    when(existingEncodedPayload.getSenderKey()).thenReturn(senderKey);
    when(existingEncodedPayload.getRecipientKeys()).thenReturn(List.of(recipientKey1));
    when(existingEncodedPayload.getRecipientBoxes()).thenReturn(List.of(recipientBox1));
    final EncryptedTransaction et = new EncryptedTransaction(mock(MessageHash.class), existingEncodedPayload);
    when(enclave.getPublicKeys()).thenReturn(singleton(senderKey));
    when(encryptedTransactionDAO.retrieveByHash(any(MessageHash.class))).thenReturn(Optional.of(et));
    resendManager.acceptOwnMessage(encodedPayload);
    ArgumentCaptor<EncryptedTransaction> updatedTxCaptor = ArgumentCaptor.forClass(EncryptedTransaction.class);
    verify(encryptedTransactionDAO).update(updatedTxCaptor.capture());
    final EncodedPayload updated = updatedTxCaptor.getValue().getPayload();
    // Check recipients are being added
    assertThat(updated.getRecipientKeys()).containsExactlyInAnyOrder(recipientKey1, recipientKey2);
    // Check boxes are being added
    assertThat(updated.getRecipientBoxes()).hasSize(2);
    verify(encryptedTransactionDAO).retrieveByHash(any(MessageHash.class));
    verify(enclave).getPublicKeys();
    verify(enclave, times(2)).unencryptTransaction(any(EncodedPayload.class), eq(senderKey));
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) MessageHash(com.quorum.tessera.data.MessageHash) EncryptedTransaction(com.quorum.tessera.data.EncryptedTransaction) Test(org.junit.Test)

Example 17 with EncryptedTransaction

use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.

the class PrivacyHelperTest method findAffectedContractTransactionsFromPayload.

@Test
public void findAffectedContractTransactionsFromPayload() {
    final EncodedPayload payload = mock(EncodedPayload.class);
    Map<TxHash, SecurityHash> affected = new HashMap<>();
    affected.put(TxHash.from("Hash1".getBytes()), SecurityHash.from("secHash1".getBytes()));
    affected.put(TxHash.from("Hash2".getBytes()), SecurityHash.from("secHash2".getBytes()));
    EncryptedTransaction et1 = mock(EncryptedTransaction.class);
    when(et1.getEncodedPayload()).thenReturn("payload1".getBytes());
    when(et1.getHash()).thenReturn(new MessageHash("Hash1".getBytes()));
    when(et1.getPayload()).thenReturn(mock(EncodedPayload.class));
    when(payload.getAffectedContractTransactions()).thenReturn(affected);
    when(encryptedTransactionDAO.findByHashes(any())).thenReturn(singletonList(et1));
    List<AffectedTransaction> result = privacyHelper.findAffectedContractTransactionsFromPayload(payload);
    assertThat(result).hasSize(1);
    verify(encryptedTransactionDAO).findByHashes(any());
}
Also used : MessageHash(com.quorum.tessera.data.MessageHash) EncryptedTransaction(com.quorum.tessera.data.EncryptedTransaction) Test(org.junit.Test)

Example 18 with EncryptedTransaction

use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.

the class PrivacyHelperTest method findAffectedContractTransactionsFromSendRequestNotFound.

@Test
public void findAffectedContractTransactionsFromSendRequestNotFound() {
    final MessageHash hash1 = mock(MessageHash.class);
    final MessageHash hash2 = mock(MessageHash.class);
    EncryptedTransaction et1 = mock(EncryptedTransaction.class);
    when(et1.getEncodedPayload()).thenReturn("payload1".getBytes());
    when(et1.getHash()).thenReturn(new MessageHash("hash1".getBytes()));
    when(encryptedTransactionDAO.findByHashes(anyCollection())).thenReturn(List.of(et1));
    assertThatExceptionOfType(PrivacyViolationException.class).isThrownBy(() -> {
        privacyHelper.findAffectedContractTransactionsFromSendRequest(Set.of(hash1, hash2));
        failBecauseExceptionWasNotThrown(Exception.class);
    }).withMessageContaining("Unable to find affectedContractTransaction");
    verify(encryptedTransactionDAO).findByHashes(any());
}
Also used : MessageHash(com.quorum.tessera.data.MessageHash) EncryptedTransaction(com.quorum.tessera.data.EncryptedTransaction) PrivacyViolationException(com.quorum.tessera.transaction.exception.PrivacyViolationException) EnhancedPrivacyNotSupportedException(com.quorum.tessera.transaction.exception.EnhancedPrivacyNotSupportedException) Test(org.junit.Test)

Example 19 with EncryptedTransaction

use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.

the class ResendManagerImpl method acceptOwnMessage.

public synchronized void acceptOwnMessage(final EncodedPayload payload) {
    // check the payload can be decrypted to ensure it isn't rubbish being sent to us
    final byte[] newDecrypted;
    if (payload.getPrivacyMode() == PrivacyMode.PRIVATE_STATE_VALIDATION) {
        // if it is PSV, then the enclave would be expected our own box to be available,
        // but it isn't (since we are rebuilding)
        // since we only want to decrypt the tx and not worry about all the other pieces,
        // treat it just like a standard private tx, and remove the other recipients
        final EncodedPayload tempPayload = EncodedPayload.Builder.from(payload).withPrivacyMode(PrivacyMode.STANDARD_PRIVATE).withExecHash(new byte[0]).withNewRecipientKeys(List.of(payload.getRecipientKeys().get(0))).withRecipientBoxes(List.of(payload.getRecipientBoxes().get(0).getData())).build();
        newDecrypted = enclave.unencryptTransaction(tempPayload, payload.getSenderKey());
    } else {
        newDecrypted = enclave.unencryptTransaction(payload, payload.getSenderKey());
    }
    final MessageHash transactionHash = Optional.of(payload).map(EncodedPayload::getCipherText).map(payloadDigest::digest).map(MessageHash::new).get();
    final PublicKey sender = payload.getSenderKey();
    if (!enclave.getPublicKeys().contains(sender)) {
        throw new IllegalArgumentException("Message " + transactionHash.toString() + " does not have one the nodes own keys as a sender");
    }
    // this is a tx which we created
    final Optional<EncryptedTransaction> tx = this.encryptedTransactionDAO.retrieveByHash(transactionHash);
    if (tx.isPresent()) {
        // we just need to add the recipient
        final EncodedPayload existing = tx.get().getPayload();
        // this is the easiest way to tell if a recipient has already been included
        for (RecipientBox existingBox : existing.getRecipientBoxes()) {
            if (Objects.equals(existingBox, payload.getRecipientBoxes().get(0))) {
                // recipient must already exist, so just act as though things went normally
                return;
            }
        }
        final EncodedPayload.Builder payloadBuilder = EncodedPayload.Builder.from(existing);
        if (!existing.getRecipientKeys().contains(payload.getRecipientKeys().get(0))) {
            // lets compare it against another message received before
            final byte[] oldDecrypted = enclave.unencryptTransaction(existing, existing.getSenderKey());
            final boolean same = Arrays.equals(newDecrypted, oldDecrypted) && Arrays.equals(payload.getCipherText(), existing.getCipherText());
            if (!same) {
                throw new IllegalArgumentException("Invalid payload provided");
            }
            // check recipients
            if (!existing.getRecipientKeys().contains(payload.getRecipientKeys().get(0))) {
                payloadBuilder.withRecipientKey(payload.getRecipientKeys().get(0)).withRecipientBox(payload.getRecipientBoxes().get(0).getData());
            }
            EncryptedTransaction encryptedTransaction = tx.get();
            encryptedTransaction.setPayload(payloadBuilder.build());
            this.encryptedTransactionDAO.update(encryptedTransaction);
        }
    } else {
        final EncodedPayload.Builder payloadBuilder = EncodedPayload.Builder.from(payload);
        final List<PublicKey> recipientKeys = new ArrayList<>(payload.getRecipientKeys());
        // we need to recreate this
        if (!recipientKeys.contains(sender)) {
            recipientKeys.add(sender);
            payloadBuilder.withRecipientKey(sender);
        }
        // add recipient boxes for all recipients (applicable for PSV transactions)
        for (int i = payload.getRecipientBoxes().size(); i < recipientKeys.size(); i++) {
            PublicKey recipient = recipientKeys.get(i);
            byte[] newBox = enclave.createNewRecipientBox(payload, recipient);
            payloadBuilder.withRecipientBox(newBox);
        }
        final EncryptedTransaction txToSave = new EncryptedTransaction(transactionHash, payloadBuilder.build());
        this.encryptedTransactionDAO.save(txToSave);
    }
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) MessageHash(com.quorum.tessera.data.MessageHash) EncryptedTransaction(com.quorum.tessera.data.EncryptedTransaction)

Example 20 with EncryptedTransaction

use of com.quorum.tessera.data.EncryptedTransaction in project tessera by ConsenSys.

the class BatchWorkflowFactoryImplTest method createBatchWorkflowFactoryImplAndExecuteWorkflow.

@Test
public void createBatchWorkflowFactoryImplAndExecuteWorkflow() {
    BatchWorkflowFactoryImpl batchWorkflowFactory = new BatchWorkflowFactoryImpl(enclave, discovery, resendBatchPublisher);
    BatchWorkflow batchWorkflow = batchWorkflowFactory.create(1L);
    assertThat(batchWorkflow).isNotNull();
    BatchWorkflowContext batchWorkflowContext = new BatchWorkflowContext();
    PublicKey recipientKey = mock(PublicKey.class);
    batchWorkflowContext.setRecipientKey(recipientKey);
    PublicKey ownedKey = mock(PublicKey.class);
    EncodedPayload encodedPayload = mock(EncodedPayload.class);
    when(encodedPayload.getSenderKey()).thenReturn(ownedKey);
    when(encodedPayload.getRecipientKeys()).thenReturn(List.of(recipientKey));
    EncryptedTransaction encryptedTransaction = mock(EncryptedTransaction.class);
    when(encryptedTransaction.getPayload()).thenReturn(encodedPayload);
    batchWorkflowContext.setEncryptedTransaction(encryptedTransaction);
    batchWorkflowContext.setEncodedPayload(encodedPayload);
    batchWorkflowContext.setBatchSize(100);
    when(mockPayloadBuilder.build()).thenReturn(encodedPayload);
    when(enclave.status()).thenReturn(Service.Status.STARTED);
    when(enclave.getPublicKeys()).thenReturn(Set.of(ownedKey));
    NodeInfo nodeInfo = mock(NodeInfo.class);
    when(nodeInfo.getRecipients()).thenReturn(Set.of(Recipient.of(recipientKey, "url")));
    when(discovery.getCurrent()).thenReturn(nodeInfo);
    assertThat(batchWorkflow.execute(batchWorkflowContext)).isTrue();
    assertThat(batchWorkflow.getPublishedMessageCount()).isOne();
    verify(enclave).status();
    verify(enclave, times(2)).getPublicKeys();
    mockStaticPayloadBuilder.verify(() -> EncodedPayload.Builder.forRecipient(any(), any()));
    verify(mockPayloadBuilder).build();
    verify(discovery).getCurrent();
    verify(resendBatchPublisher).publishBatch(any(), any());
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) NodeInfo(com.quorum.tessera.partyinfo.node.NodeInfo) EncodedPayload(com.quorum.tessera.enclave.EncodedPayload) BatchWorkflow(com.quorum.tessera.recovery.workflow.BatchWorkflow) BatchWorkflowContext(com.quorum.tessera.recovery.workflow.BatchWorkflowContext) EncryptedTransaction(com.quorum.tessera.data.EncryptedTransaction) Test(org.junit.Test)

Aggregations

EncryptedTransaction (com.quorum.tessera.data.EncryptedTransaction)32 Test (org.junit.Test)24 PublicKey (com.quorum.tessera.encryption.PublicKey)21 MessageHash (com.quorum.tessera.data.MessageHash)19 EncodedPayload (com.quorum.tessera.enclave.EncodedPayload)13 Collectors (java.util.stream.Collectors)6 IntStream (java.util.stream.IntStream)6 ResendRequest (com.quorum.tessera.recovery.resend.ResendRequest)5 BatchWorkflow (com.quorum.tessera.recovery.workflow.BatchWorkflow)5 BatchWorkflowContext (com.quorum.tessera.recovery.workflow.BatchWorkflowContext)5 EncryptedTransactionDAO (com.quorum.tessera.data.EncryptedTransactionDAO)4 ResendResponse (com.quorum.tessera.recovery.resend.ResendResponse)4 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)4 After (org.junit.After)4 Before (org.junit.Before)4 Base64Codec (com.quorum.tessera.base64.Base64Codec)3 StagingEntityDAO (com.quorum.tessera.data.staging.StagingEntityDAO)3 StagingTransaction (com.quorum.tessera.data.staging.StagingTransaction)3 com.quorum.tessera.enclave (com.quorum.tessera.enclave)3 PrivacyMode (com.quorum.tessera.enclave.PrivacyMode)3