diff options
author | Philip Kaufmann <phil.kaufmann@t-online.de> | 2015-01-09 14:25:43 +0100 |
---|---|---|
committer | Philip Kaufmann <phil.kaufmann@t-online.de> | 2015-02-04 13:47:32 +0100 |
commit | a6516686dcf0b93dd0bcae304e74f9ac69cb305c (patch) | |
tree | 44d9394cf2c1ac085f2815c8b55f1539f9c2d3c7 /src/qt/test | |
parent | 31dedb463b0ce77364e516239bf1b9c7eed5b3b0 (diff) |
[Qt] prevent amount overflow problem with payment requests
Bitcoin amounts are stored as uint64 in the protobuf messages (see
paymentrequest.proto), but CAmount is defined as int64_t. Because
of that we need to verify that single and accumulated amounts are
in a valid range and no variable overflow has happened.
- fixes #5624 (#5622)
Thanks @SergioDemianLerner for reporting that issue and also supplying us
with a possible solution.
- add static verifyAmount() function to PaymentServer and move the logging
on error into the function
- also add a unit test to paymentservertests.cpp
Diffstat (limited to 'src/qt/test')
-rw-r--r-- | src/qt/test/paymentrequestdata.h | 25 | ||||
-rw-r--r-- | src/qt/test/paymentservertests.cpp | 17 |
2 files changed, 42 insertions, 0 deletions
diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index 50636d7c67..c548ffe429 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -433,3 +433,28 @@ dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\ HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\ d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\ "; + +// +// Payment request with amount overflow (amount is set to 21000001 BTC) +// +const char* paymentrequest5_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+Ba0iTAoEdGVzdBIkCIDC9P+F\ +vt0DEhl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGLzcrKYFKhhUZXN0aW5nIGFt\ +b3VudCBvdmVyZmxvdyEqgAG8S7WEDUC6tCL6q2CTBjop/AitgEy31RL9IqYruytR\ +iEBFUrBDJZU+UEezGwr7/zoECjo5ZY3PmtZcM2sILNjyweJF6XVzGqTxUw6pN6sW\ +XR2T3Gy2LzRvhVA25QgGqpz0/juS2BtmNbsZPkN9gMMwKimgzc+PuCzmEKwPK9cQ\ +YQ==\ +"; diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index 04935192c8..e2ec439b2e 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -7,7 +7,10 @@ #include "optionsmodel.h" #include "paymentrequestdata.h" +#include "amount.h" #include "random.h" +#include "script/script.h" +#include "script/standard.h" #include "util.h" #include "utilstrencodings.h" @@ -184,6 +187,20 @@ void PaymentServerTests::paymentServerTests() tempFile.close(); QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); + // Payment request with amount overflow (amount is set to 21000001 BTC): + data = DecodeBase64(paymentrequest5_cert2_BASE64); + byteArray = QByteArray((const char*)&data[0], data.size()); + r.paymentRequest.parse(byteArray); + // Ensure the request is initialized + QVERIFY(r.paymentRequest.IsInitialized()); + // Extract address and amount from the request + QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo(); + foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { + CTxDestination dest; + if (ExtractDestination(sendingTo.first, dest)) + QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false); + } + delete server; } |