Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ BITCOIN_CORE_H = \
core.h \
crypter.h \
db.h \
encryptionutils.h \
richlistdb.h \
servicelistdb.h \
serviceitemlistdb.h \
Expand Down Expand Up @@ -148,6 +149,7 @@ libbitcoin_wallet_a_SOURCES = \
wallet.cpp \
walletdb.cpp \
jeeq.cpp \
encryptionutils.cpp \
$(BITCOIN_CORE_H)

libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
Expand Down
62 changes: 62 additions & 0 deletions src/encryptionutils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "encryptionutils.h"
#include "wallet.h"
#include "key.h"
#include "util.h"
#include "base58.h"
#include "jeeq.h"

/*
Validate a public key.
*/
bool validatePublicKeyFromHexStr(std::string pubKeyHex) {
CPubKey pubKey(ParseHex(pubKeyHex));
return pubKey.IsFullyValid();
}

/*
Returns the Smileycoin address derived from a public key
*/
std::string addressFromPublicKey(std::string pubKeyHex) {
CPubKey pubKey(ParseHex(pubKeyHex));
CBitcoinAddress address(pubKey.GetID());
return CBitcoinAddress(pubKey.GetID()).ToString();
}

/*
Encrypts a string using a public key. Returns the data as
hex encoded string
*/
bool encryptString(std::string data, std::string pubKeyHex, std::string &resultHex) {
CPubKey pubKey(ParseHex(pubKeyHex));
if (!pubKey.IsFullyValid()) {
return false;
}

std::vector<uint8_t> encryptedData = Jeeq::EncryptMessage(pubKey, data);
if (encryptedData.size() == 0)
return false;

resultHex = HexStr(encryptedData);
return true;
}

bool decryptData(std::string txData, CBitcoinAddress address, const CWallet *wallet, std::string &decryptedData) {
CKeyID keyID;
if (!address.GetKeyID(keyID))
return false;

CKey vchSecret;
if (!wallet->GetKey(keyID, vchSecret))
return false;

if (!IsHex(txData))
return false;

std::string decryptedString = Jeeq::DecryptMessage(vchSecret, ParseHex(txData));

if (decryptedString.length() == 0)
return false;

decryptedData = HexStr(decryptedString);
return true;
}
19 changes: 19 additions & 0 deletions src/encryptionutils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Utility functions used for ElGamal encryption
of data.
*/

#ifndef BITCOIN_ENCRYPTIONUTILS_H
#define BITCOIN_ENCRYPTIONUTILS_H

#include <string>

class CWallet;
class CBitcoinAddress;

bool validatePublicKeyFromHexStr(std::string pubKeyHex);
std::string addressFromPublicKey(std::string pubKeyHex);
bool encryptString(std::string data, std::string pubKeyHex, std::string &resultHex);
bool decryptData(std::string txData, CBitcoinAddress address, const CWallet *wallet, std::string &decryptedData);

#endif
13 changes: 13 additions & 0 deletions src/qt/forms/sendcoinsentry.ui
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="addAsEncrypted">
<property name="toolTip">
<string>Data can be sent encrypted by receivers public key.</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
Expand Down Expand Up @@ -704,6 +711,9 @@
<item>
<widget class="QComboBox" name="addAsData2_is"/>
</item>
<item>
<widget class="QComboBox" name="addAsEncrypted_is"/>
</item>
</layout>
</item>
<item row="3" column="0">
Expand Down Expand Up @@ -1266,6 +1276,9 @@
<item>
<widget class="QComboBox" name="addAsData2_s"/>
</item>
<item>
<widget class="QComboBox" name="addAsEncrypted_s"/>
</item>
</layout>
</item>
<item row="3" column="0">
Expand Down
8 changes: 8 additions & 0 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
}

void setupSendAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
{
// Removes validator to allow public keys.
parent->setFocusProxy(widget);
widget->setFont(bitcoinAddressFont());
widget->setPlaceholderText(QObject::tr("Enter a Smileycoin address (e.g. AafeSfiXVkHpcPmb9nQJTDAE5sKybkJAzz)"));
}

void setupAmountWidget(QLineEdit *widget, QWidget *parent)
{
QDoubleValidator *amountValidator = new QDoubleValidator(parent);
Expand Down
1 change: 1 addition & 0 deletions src/qt/guiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace GUIUtil

// Set up widgets for address and amounts
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent);
void setupSendAddressWidget(QValidatedLineEdit *widget, QWidget *parent);
void setupAmountWidget(QLineEdit *widget, QWidget *parent);

// Parse "bitcoin:" URI into recipient object, return true on successful parsing
Expand Down
63 changes: 58 additions & 5 deletions src/qt/sendcoinsentry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "addressbookpage.h"
#include "addresstablemodel.h"
#include "guiutil.h"
#include "encryptionutils.h"
#include "optionsmodel.h"
#include "walletmodel.h"
#include "ui_interface.h"
Expand All @@ -33,11 +34,13 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
ui->addAsData->setPlaceholderText(tr("Enter a message to send with your transfer"));

// normal bitcoin address field
GUIUtil::setupAddressWidget(ui->payTo, this);
GUIUtil::setupSendAddressWidget(ui->payTo, this);
// just a label for displaying bitcoin address(es)
ui->payTo_is->setFont(GUIUtil::bitcoinAddressFont());
ui->addAsData2->addItem("HEX");
ui->addAsData2->addItem("ASCII");
ui->addAsEncrypted->addItem("Unencrypted");
ui->addAsEncrypted->addItem("Encrypted");
}

SendCoinsEntry::~SendCoinsEntry()
Expand Down Expand Up @@ -122,19 +125,41 @@ bool SendCoinsEntry::validate()
if (!model)
return false;

bool isPubKey = validatePublicKeyFromHexStr(ui->payTo->text().toStdString());
bool isAddress = model->validateAddress(ui->payTo->text());
// Check input validity
bool retval = true;

// Skip checks for payment request
if (recipient.paymentRequest.IsInitialized())
return retval;

if (!model->validateAddress(ui->payTo->text()))
if (!isPubKey && !isAddress)
{
ui->payTo->setValid(false);
retval = false;
}

if (ui->addAsEncrypted->currentText() == "Encrypted" && isAddress) {
QMessageBox::critical(0, tr("Public key was rejected!"), tr("Data encryption requires public key instead of address"));
retval = false;
}

if (ui->addAsEncrypted->currentText() == "Encrypted" && isPubKey) {
std::string encryptedString;
if (encryptString(
hexToAscii(ui->addAsData->text().toStdString()),
ui->payTo->text().toStdString(),
encryptedString)
) {
if (encryptedString.size() > 160 /* Max 80 bytes * 2 for the hex format */) {
QMessageBox::critical(0, tr("Data input was rejected!"),
tr("The data input is to long for encryption"));
retval = false;
}
}
}

if (!ui->payAmount->validate())
{
retval = false;
Expand Down Expand Up @@ -163,16 +188,44 @@ SendCoinsRecipient SendCoinsEntry::getValue()
return recipient;

// Normal payment
recipient.address = ui->payTo->text();
if (validatePublicKeyFromHexStr(ui->payTo->text().toStdString())) {
recipient.address = QString::fromStdString(addressFromPublicKey(ui->payTo->text().toStdString()));
} else {
recipient.address = ui->payTo->text();
}
recipient.label = ui->addAsLabel->text();
recipient.amount = ui->payAmount->value();
recipient.message = ui->messageTextLabel->text();

if(ui->addAsData2->currentText() == "ASCII") {
QString asciiData = ui->addAsData->text();
recipient.data = asciiData.toLatin1().toHex();

if (ui->addAsEncrypted->currentText() == "Encrypted") {
// Encrypt the data before setting it onto recipient object
std::string pubKeyHex = ui->payTo->text().toStdString();
std::string encryptedHexString;
if (encryptString(asciiData.toStdString(), pubKeyHex, encryptedHexString)){
recipient.data = QString::fromStdString(encryptedHexString);
}
} else {
// Send data unencrypted
recipient.data = asciiData.toLatin1().toHex();
}
} else {
recipient.data = ui->addAsData->text();
if (ui->addAsEncrypted->currentText() == "Encrypted") {
// Encrypt the data before setting it onto recipient object
QString asciiData = ui->addAsData->text();
std::string pubKeyHex = ui->payTo->text().toStdString();
std::string asciiHex = hexToAscii(asciiData.toStdString());
std::string encryptedHexString;
if (encryptString(asciiHex, pubKeyHex, encryptedHexString)){
recipient.data = QString::fromStdString(encryptedHexString);
}
} else {
// Send data unencrypted
recipient.data = ui->addAsData->text();
}

}

return recipient;
Expand Down
Loading