Browse Source

[Qt] add payment request unit test for non matching networks

- verify that payment request network matches client network
- add static verifyNetwork() function to PaymentServer to be able to use
  the same validation code in GUI and unit-testing code
0.13
Philip Kaufmann 10 years ago
parent
commit
17005bc0fc
  1. 15
      src/qt/paymentserver.cpp
  2. 3
      src/qt/paymentserver.h
  3. 24
      src/qt/test/paymentrequestdata.h
  4. 28
      src/qt/test/paymentservertests.cpp

15
src/qt/paymentserver.cpp

@ -521,8 +521,7 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
const payments::PaymentDetails& details = request.getDetails(); const payments::PaymentDetails& details = request.getDetails();
// Payment request network matches client network? // Payment request network matches client network?
if (details.network() != Params().NetworkIDString()) if (!verifyNetwork(request.getDetails())) {
{
emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."),
CClientUIInterface::MSG_ERROR); CClientUIInterface::MSG_ERROR);
@ -745,3 +744,15 @@ void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
// currently we don't futher process or store the paymentACK message // currently we don't futher process or store the paymentACK message
emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL);
} }
bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails)
{
bool fVerified = requestDetails.network() == Params().NetworkIDString();
if (!fVerified) {
qWarning() << QString("PaymentServer::%1: Payment request network \"%2\" doesn't match client network \"%3\".")
.arg(__func__)
.arg(QString::fromStdString(requestDetails.network()))
.arg(QString::fromStdString(Params().NetworkIDString()));
}
return fVerified;
}

3
src/qt/paymentserver.h

@ -91,6 +91,9 @@ public:
// This is now public, because we use it in paymentservertests.cpp // This is now public, because we use it in paymentservertests.cpp
static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
// Verify that the payment request network matches the client network
static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
signals: signals:
// Fired when a valid payment request is received // Fired when a valid payment request is received
void receivedPaymentRequest(SendCoinsRecipient); void receivedPaymentRequest(SendCoinsRecipient);

24
src/qt/test/paymentrequestdata.h

@ -337,3 +337,27 @@ ssymvca1S/1KeM3n8Ydi2fi1JUzAAr59xPvNJRUeqCLP9upHn5z7br3P12Oz9A20\
5/4wL4ClPRPVnOHgij0bEg+y0tGESqmF1rfOfXDszlo2U92wCxS07kq79YAZJ1Zo\ 5/4wL4ClPRPVnOHgij0bEg+y0tGESqmF1rfOfXDszlo2U92wCxS07kq79YAZJ1Zo\
XYh860/Q4wvc7lfiTe+dXBzPKAKhMy91yETY\ XYh860/Q4wvc7lfiTe+dXBzPKAKhMy91yETY\
"; ";
//
// Contains a testnet paytoaddress, so payment request network doesn't match client network
//
const char* paymentrequest1_cert2_BASE64 =
"\
Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
+S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iPQoEdGVzdBIhCIDWwowE\
Ehl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGNeMy6UFKgxKdXN0IFRlc3Rpbmcq\
gAFwThsozZxkZxzCn4R8WxNiLFV6m0ye9fEtSbolfaW+EjBMpO03lr/dwNnrclhg\
ew+A05xfZztrAt16XKEY7qKJ/eY2nLd0fVAIu/nIt+7/VYVXT83zLrWc150aRS7W\
AdJbL3JOJLs6Eyp5zrPbfI8faRttFAdONKDrJgIpuW1E3g==\
";

28
src/qt/test/paymentservertests.cpp

@ -115,6 +115,34 @@ void PaymentServerTests::paymentServerTests()
r.paymentRequest.getMerchant(caStore, merchant); r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString("")); QCOMPARE(merchant, QString(""));
// Load second root certificate
caStore = X509_STORE_new();
X509_STORE_add_cert(caStore, parse_b64der_cert(caCert2_BASE64));
PaymentServer::LoadRootCAs(caStore);
QByteArray byteArray;
// For the tests below we just need the payment request data from
// paymentrequestdata.h parsed + stored in r.paymentRequest.
//
// These tests require us to bypass the following normal client execution flow
// shown below to be able to explicitly just trigger a certain condition!
//
// handleRequest()
// -> PaymentServer::eventFilter()
// -> PaymentServer::handleURIOrFile()
// -> PaymentServer::readPaymentRequestFromFile()
// -> PaymentServer::processPaymentRequest()
// Contains a testnet paytoaddress, so payment request network doesn't match client network:
data = DecodeBase64(paymentrequest1_cert2_BASE64);
byteArray = QByteArray((const char*)&data[0], data.size());
r.paymentRequest.parse(byteArray);
// Ensure the request is initialized, because network "main" is default, even for
// uninizialized payment requests and that will fail our test here.
QVERIFY(r.paymentRequest.IsInitialized());
QCOMPARE(PaymentServer::verifyNetwork(r.paymentRequest.getDetails()), false);
// Just get some random data big enough to trigger BIP70 DoS protection // Just get some random data big enough to trigger BIP70 DoS protection
unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1]; unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
GetRandBytes(randData, sizeof(randData)); GetRandBytes(randData, sizeof(randData));

Loading…
Cancel
Save