Search in sources :

Example 76 with PublicKey

use of com.quorum.tessera.encryption.PublicKey in project tessera by ConsenSys.

the class EncodedPayloadManagerImpl method create.

@Override
public EncodedPayload create(final SendRequest request) {
    final PublicKey senderPublicKey = request.getSender();
    LOGGER.debug("Sender for payload: {}", request.getSender().encodeToBase64());
    final Set<PublicKey> recipientSet = new HashSet<>();
    recipientSet.add(senderPublicKey);
    recipientSet.addAll(request.getRecipients());
    recipientSet.addAll(enclave.getForwardingKeys());
    final List<PublicKey> recipientListNoDuplicate = new ArrayList<>(recipientSet);
    LOGGER.debug("Recipients for payload: {}", recipientListNoDuplicate);
    final PrivacyMode privacyMode = request.getPrivacyMode();
    LOGGER.debug("Privacy mode for payload: {}", request.getPrivacyMode());
    LOGGER.debug("ExecHash for payload: {}", new String(request.getExecHash()));
    final Set<PublicKey> mandatoryRecipients = request.getMandatoryRecipients();
    LOGGER.debug("Mandatory recipients for payload: {}", mandatoryRecipients);
    final List<AffectedTransaction> affectedContractTransactions = privacyHelper.findAffectedContractTransactionsFromSendRequest(request.getAffectedContractTransactions());
    LOGGER.debug("Validating request against affected contracts");
    privacyHelper.validateSendRequest(privacyMode, recipientListNoDuplicate, affectedContractTransactions, mandatoryRecipients);
    LOGGER.debug("Successful validation against affected contracts");
    final PrivacyMetadata.Builder metaDataBuilder = PrivacyMetadata.Builder.create().withPrivacyMode(privacyMode).withAffectedTransactions(affectedContractTransactions).withExecHash(request.getExecHash());
    request.getPrivacyGroupId().ifPresent(metaDataBuilder::withPrivacyGroupId);
    return enclave.encryptPayload(request.getPayload(), senderPublicKey, recipientListNoDuplicate, metaDataBuilder.build());
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey)

Example 77 with PublicKey

use of com.quorum.tessera.encryption.PublicKey in project tessera by ConsenSys.

the class EncodedPayloadManagerImpl method decrypt.

@Override
public ReceiveResponse decrypt(final EncodedPayload payload, final PublicKey maybeDefaultRecipient) {
    final MessageHash customPayloadHash = new MessageHash(payloadDigest.digest(payload.getCipherText()));
    LOGGER.debug("Decrypt request for custom message with hash {}", customPayloadHash);
    final PublicKey recipientKey = Optional.ofNullable(maybeDefaultRecipient).orElseGet(() -> searchForRecipientKey(payload).orElseThrow(() -> new RecipientKeyNotFoundException("No suitable recipient keys found to decrypt payload for " + customPayloadHash)));
    LOGGER.debug("Decryption key found: {}", recipientKey.encodeToBase64());
    final byte[] decryptedTransactionData = enclave.unencryptTransaction(payload, recipientKey);
    final Set<MessageHash> affectedTransaction = payload.getAffectedContractTransactions().keySet().stream().map(TxHash::getBytes).map(MessageHash::new).collect(Collectors.toSet());
    ReceiveResponse.Builder builder = ReceiveResponse.Builder.create().withUnencryptedTransactionData(decryptedTransactionData).withPrivacyMode(payload.getPrivacyMode()).withAffectedTransactions(affectedTransaction).withExecHash(payload.getExecHash()).withSender(payload.getSenderKey());
    payload.getPrivacyGroupId().ifPresent(builder::withPrivacyGroupId);
    return builder.build();
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) ReceiveResponse(com.quorum.tessera.transaction.ReceiveResponse) MessageHash(com.quorum.tessera.data.MessageHash) RecipientKeyNotFoundException(com.quorum.tessera.transaction.exception.RecipientKeyNotFoundException)

Example 78 with PublicKey

use of com.quorum.tessera.encryption.PublicKey in project tessera by ConsenSys.

the class EncodedPayloadManagerImpl method searchForRecipientKey.

private Optional<PublicKey> searchForRecipientKey(final EncodedPayload payload) {
    final MessageHash customPayloadHash = new MessageHash(payloadDigest.digest(payload.getCipherText()));
    for (final PublicKey potentialMatchingKey : enclave.getPublicKeys()) {
        try {
            LOGGER.debug("Attempting to decrypt {} using key {}", customPayloadHash, potentialMatchingKey.encodeToBase64());
            enclave.unencryptTransaction(payload, potentialMatchingKey);
            LOGGER.debug("Succeeded decrypting {} using key {}", customPayloadHash, potentialMatchingKey.encodeToBase64());
            return Optional.of(potentialMatchingKey);
        } catch (EnclaveException | IndexOutOfBoundsException | EncryptorException ex) {
            LOGGER.debug("Attempted payload decryption using wrong key, discarding.");
        }
    }
    return Optional.empty();
}
Also used : EncryptorException(com.quorum.tessera.encryption.EncryptorException) PublicKey(com.quorum.tessera.encryption.PublicKey) MessageHash(com.quorum.tessera.data.MessageHash)

Example 79 with PublicKey

use of com.quorum.tessera.encryption.PublicKey in project tessera by ConsenSys.

the class TransactionManagerImpl method send.

@Override
public SendResponse send(SendRequest sendRequest) {
    final PublicKey senderPublicKey = sendRequest.getSender();
    final List<PublicKey> recipientList = new ArrayList<>(sendRequest.getRecipients());
    recipientList.add(senderPublicKey);
    recipientList.addAll(enclave.getForwardingKeys());
    final List<PublicKey> recipientListNoDuplicate = recipientList.stream().distinct().collect(Collectors.toList());
    final byte[] raw = sendRequest.getPayload();
    final PrivacyMode privacyMode = sendRequest.getPrivacyMode();
    final byte[] execHash = sendRequest.getExecHash();
    final List<AffectedTransaction> affectedContractTransactions = privacyHelper.findAffectedContractTransactionsFromSendRequest(sendRequest.getAffectedContractTransactions());
    privacyHelper.validateSendRequest(privacyMode, recipientList, affectedContractTransactions, sendRequest.getMandatoryRecipients());
    final PrivacyMetadata.Builder metadataBuilder = PrivacyMetadata.Builder.create().withPrivacyMode(privacyMode).withAffectedTransactions(affectedContractTransactions).withExecHash(execHash).withMandatoryRecipients(sendRequest.getMandatoryRecipients());
    sendRequest.getPrivacyGroupId().ifPresent(metadataBuilder::withPrivacyGroupId);
    final EncodedPayload payload = enclave.encryptPayload(raw, senderPublicKey, recipientListNoDuplicate, metadataBuilder.build());
    final MessageHash transactionHash = Optional.of(payload).map(EncodedPayload::getCipherText).map(payloadDigest::digest).map(MessageHash::new).get();
    final EncryptedTransaction newTransaction = new EncryptedTransaction(transactionHash, payload);
    final Set<PublicKey> managedPublicKeys = enclave.getPublicKeys();
    final Set<PublicKey> managedParties = Stream.concat(Stream.of(senderPublicKey), recipientListNoDuplicate.stream()).filter(managedPublicKeys::contains).collect(Collectors.toSet());
    final List<PublicKey> recipientListRemotesOnly = recipientListNoDuplicate.stream().filter(not(managedPublicKeys::contains)).collect(Collectors.toList());
    this.encryptedTransactionDAO.save(newTransaction, () -> {
        batchPayloadPublisher.publishPayload(payload, recipientListRemotesOnly);
        return null;
    });
    return SendResponse.Builder.create().withMessageHash(transactionHash).withManagedParties(managedParties).withSender(payload.getSenderKey()).build();
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey)

Example 80 with PublicKey

use of com.quorum.tessera.encryption.PublicKey in project tessera by ConsenSys.

the class TransactionManagerImpl method receive.

@Override
public ReceiveResponse receive(ReceiveRequest request) {
    final MessageHash hash = request.getTransactionHash();
    LOGGER.info("Lookup transaction {}", hash);
    if (request.isRaw()) {
        final EncryptedRawTransaction encryptedRawTransaction = encryptedRawTransactionDAO.retrieveByHash(hash).orElseThrow(() -> new TransactionNotFoundException("Raw Message with hash " + hash + " was not found"));
        final PublicKey senderKey = PublicKey.from(encryptedRawTransaction.getSender());
        final RawTransaction rawTransaction = new RawTransaction(encryptedRawTransaction.getEncryptedPayload(), encryptedRawTransaction.getEncryptedKey(), new Nonce(encryptedRawTransaction.getNonce()), senderKey);
        final byte[] response = enclave.unencryptRawPayload(rawTransaction);
        return ReceiveResponse.Builder.create().withPrivacyMode(PrivacyMode.STANDARD_PRIVATE).withUnencryptedTransactionData(response).withManagedParties(Set.of(senderKey)).withSender(senderKey).build();
    }
    final EncryptedTransaction encryptedTransaction = encryptedTransactionDAO.retrieveByHash(hash).orElseThrow(() -> new TransactionNotFoundException("Message with hash " + hash + " was not found"));
    final EncodedPayload payload = Optional.of(encryptedTransaction).map(EncryptedTransaction::getPayload).orElseThrow(() -> new IllegalStateException("Unable to decode previously encoded payload"));
    PublicKey recipientKey = request.getRecipient().orElse(searchForRecipientKey(payload).orElseThrow(() -> new RecipientKeyNotFoundException("No suitable recipient keys found to decrypt payload for : " + hash)));
    byte[] unencryptedTransactionData = enclave.unencryptTransaction(payload, recipientKey);
    Set<MessageHash> affectedTransactions = payload.getAffectedContractTransactions().keySet().stream().map(TxHash::getBytes).map(MessageHash::new).collect(Collectors.toSet());
    Set<PublicKey> managedParties = new HashSet<>();
    if (payload.getRecipientKeys().isEmpty()) {
        // legacy tx
        for (RecipientBox box : payload.getRecipientBoxes()) {
            EncodedPayload singleBoxPayload = EncodedPayload.Builder.from(payload).withRecipientBoxes(List.of(box.getData())).build();
            Optional<PublicKey> possibleRecipient = searchForRecipientKey(singleBoxPayload);
            possibleRecipient.ifPresent(managedParties::add);
        }
    } else {
        managedParties = enclave.getPublicKeys().stream().filter(payload.getRecipientKeys()::contains).collect(Collectors.toSet());
    }
    final ReceiveResponse.Builder responseBuilder = ReceiveResponse.Builder.create();
    payload.getPrivacyGroupId().ifPresent(responseBuilder::withPrivacyGroupId);
    return responseBuilder.withUnencryptedTransactionData(unencryptedTransactionData).withPrivacyMode(payload.getPrivacyMode()).withAffectedTransactions(affectedTransactions).withExecHash(payload.getExecHash()).withManagedParties(managedParties).withSender(payload.getSenderKey()).build();
}
Also used : PublicKey(com.quorum.tessera.encryption.PublicKey) TransactionNotFoundException(com.quorum.tessera.transaction.exception.TransactionNotFoundException) Nonce(com.quorum.tessera.encryption.Nonce) RecipientKeyNotFoundException(com.quorum.tessera.transaction.exception.RecipientKeyNotFoundException)

Aggregations

PublicKey (com.quorum.tessera.encryption.PublicKey)281 Test (org.junit.Test)213 Response (jakarta.ws.rs.core.Response)59 MessageHash (com.quorum.tessera.data.MessageHash)57 EncodedPayload (com.quorum.tessera.enclave.EncodedPayload)48 Collectors (java.util.stream.Collectors)32 PrivacyGroup (com.quorum.tessera.enclave.PrivacyGroup)28 NodeInfo (com.quorum.tessera.partyinfo.node.NodeInfo)25 java.util (java.util)23 SendResponse (com.quorum.tessera.api.SendResponse)21 Nonce (com.quorum.tessera.encryption.Nonce)20 Recipient (com.quorum.tessera.partyinfo.node.Recipient)20 Operation (io.swagger.v3.oas.annotations.Operation)20 ApiResponse (io.swagger.v3.oas.annotations.responses.ApiResponse)20 Stream (java.util.stream.Stream)19 ReceiveResponse (com.quorum.tessera.transaction.ReceiveResponse)18 EncryptedTransaction (com.quorum.tessera.data.EncryptedTransaction)17 PrivacyMode (com.quorum.tessera.enclave.PrivacyMode)17 URI (java.net.URI)17 SendRequest (com.quorum.tessera.api.SendRequest)15