/****************************************************************************** * Copyright © 2013-2016 The Nxt Core Developers. * * * * See the AUTHORS.txt, DEVELOPER-AGREEMENT.txt and LICENSE.txt files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * Nxt software, including this file, may be copied, modified, propagated, * * or distributed except according to the terms contained in the LICENSE.txt * * file. * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ package nxt.http; import nxt.Account; import nxt.Appendix; import nxt.Nxt; import nxt.Transaction; import nxt.crypto.Crypto; import nxt.crypto.EncryptedData; import nxt.util.Convert; import nxt.util.Logger; import org.json.simple.JSONObject; import org.json.simple.JSONStreamAware; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import static nxt.http.JSONResponses.INCORRECT_TRANSACTION; import static nxt.http.JSONResponses.MISSING_TRANSACTION; import static nxt.http.JSONResponses.NO_MESSAGE; import static nxt.http.JSONResponses.UNKNOWN_TRANSACTION; public final class ReadMessage extends APIServlet.APIRequestHandler { static final ReadMessage instance = new ReadMessage(); private ReadMessage() { super(new APITag[] {APITag.MESSAGES}, "transaction", "secretPhrase"); } @Override JSONStreamAware processRequest(HttpServletRequest req) throws ParameterException { String transactionIdString = Convert.emptyToNull(req.getParameter("transaction")); if (transactionIdString == null) { return MISSING_TRANSACTION; } Transaction transaction; try { transaction = Nxt.getBlockchain().getTransaction(Convert.parseUnsignedLong(transactionIdString)); if (transaction == null) { return UNKNOWN_TRANSACTION; } } catch (RuntimeException e) { return INCORRECT_TRANSACTION; } JSONObject response = new JSONObject(); Appendix.Message message = transaction.getMessage(); Appendix.EncryptedMessage encryptedMessage = transaction.getEncryptedMessage(); Appendix.EncryptToSelfMessage encryptToSelfMessage = transaction.getEncryptToSelfMessage(); Appendix.PrunablePlainMessage prunableMessage = transaction.getPrunablePlainMessage(); Appendix.PrunableEncryptedMessage prunableEncryptedMessage = transaction.getPrunableEncryptedMessage(); if (message == null && encryptedMessage == null && encryptToSelfMessage == null && prunableMessage == null && prunableEncryptedMessage == null) { return NO_MESSAGE; } if (message != null) { response.put("message", Convert.toString(message.getMessage(), message.isText())); response.put("messageIsPrunable", false); } else if (prunableMessage != null) { response.put("message", Convert.toString(prunableMessage.getMessage(), prunableMessage.isText())); response.put("messageIsPrunable", true); } String secretPhrase = Convert.emptyToNull(req.getParameter("secretPhrase")); if (secretPhrase != null) { EncryptedData encryptedData = null; boolean isText = false; boolean uncompress = true; if (encryptedMessage != null) { encryptedData = encryptedMessage.getEncryptedData(); isText = encryptedMessage.isText(); uncompress = encryptedMessage.isCompressed(); response.put("encryptedMessageIsPrunable", false); } else if (prunableEncryptedMessage != null) { encryptedData = prunableEncryptedMessage.getEncryptedData(); isText = prunableEncryptedMessage.isText(); uncompress = prunableEncryptedMessage.isCompressed(); response.put("encryptedMessageIsPrunable", true); } if (encryptedData != null) { byte[] readerPublicKey = Crypto.getPublicKey(secretPhrase); byte[] senderPublicKey = Account.getPublicKey(transaction.getSenderId()); byte[] recipientPublicKey = Account.getPublicKey(transaction.getRecipientId()); byte[] publicKey = Arrays.equals(senderPublicKey, readerPublicKey) ? recipientPublicKey : senderPublicKey; if (publicKey != null) { try { byte[] decrypted = Account.decryptFrom(publicKey, encryptedData, secretPhrase, uncompress); response.put("decryptedMessage", Convert.toString(decrypted, isText)); } catch (RuntimeException e) { Logger.logDebugMessage("Decryption of message to recipient failed: " + e.toString()); JSONData.putException(response, e, "Wrong secretPhrase"); } } } if (encryptToSelfMessage != null) { byte[] publicKey = Crypto.getPublicKey(secretPhrase); try { byte[] decrypted = Account.decryptFrom(publicKey, encryptToSelfMessage.getEncryptedData(), secretPhrase, encryptToSelfMessage.isCompressed()); response.put("decryptedMessageToSelf", Convert.toString(decrypted, encryptToSelfMessage.isText())); } catch (RuntimeException e) { Logger.logDebugMessage("Decryption of message to self failed: " + e.toString()); } } } return response; } }