Merge pull request #5467
6171e49
[Qt] Use identical strings for expired payment request message (Philip Kaufmann)06087bd
[Qt] minor comment updates in PaymentServer (Philip Kaufmann)35d1595
[Qt] constify first parameter of processPaymentRequest() (Philip Kaufmann)9b14aef
[Qt] take care of a missing typecast in PaymentRequestPlus::getMerchant() (Philip Kaufmann)d19ae3c
[Qt] remove unused PaymentRequestPlus::getPKIType function (Philip Kaufmann)6e17a74
[Qt] paymentserver: better logging of invalid certs (Philip Kaufmann)5a53d7c
[Qt] paymentserver: do not log NULL certificates (Philip Kaufmann)
This commit is contained in:
commit
bc8535b717
5 changed files with 28 additions and 26 deletions
|
@ -59,12 +59,6 @@ bool PaymentRequestPlus::IsInitialized() const
|
||||||
return paymentRequest.IsInitialized();
|
return paymentRequest.IsInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PaymentRequestPlus::getPKIType() const
|
|
||||||
{
|
|
||||||
if (!IsInitialized()) return QString("none");
|
|
||||||
return QString::fromStdString(paymentRequest.pki_type());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const
|
bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const
|
||||||
{
|
{
|
||||||
merchant.clear();
|
merchant.clear();
|
||||||
|
@ -124,7 +118,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
|
||||||
// The first cert is the signing cert, the rest are untrusted certs that chain
|
// The first cert is the signing cert, the rest are untrusted certs that chain
|
||||||
// to a valid root authority. OpenSSL needs them separately.
|
// to a valid root authority. OpenSSL needs them separately.
|
||||||
STACK_OF(X509) *chain = sk_X509_new_null();
|
STACK_OF(X509) *chain = sk_X509_new_null();
|
||||||
for (int i = certs.size()-1; i > 0; i--) {
|
for (int i = certs.size() - 1; i > 0; i--) {
|
||||||
sk_X509_push(chain, certs[i]);
|
sk_X509_push(chain, certs[i]);
|
||||||
}
|
}
|
||||||
X509 *signing_cert = certs[0];
|
X509 *signing_cert = certs[0];
|
||||||
|
@ -172,9 +166,8 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c
|
||||||
EVP_MD_CTX_init(&ctx);
|
EVP_MD_CTX_init(&ctx);
|
||||||
if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) ||
|
if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) ||
|
||||||
!EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) ||
|
!EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) ||
|
||||||
!EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) {
|
!EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) {
|
||||||
|
throw SSLVerifyError("Bad signature, invalid payment request.");
|
||||||
throw SSLVerifyError("Bad signature, invalid PaymentRequest.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenSSL API for getting human printable strings from certs is baroque.
|
// OpenSSL API for getting human printable strings from certs is baroque.
|
||||||
|
|
|
@ -29,7 +29,6 @@ public:
|
||||||
bool SerializeToString(std::string* output) const;
|
bool SerializeToString(std::string* output) const;
|
||||||
|
|
||||||
bool IsInitialized() const;
|
bool IsInitialized() const;
|
||||||
QString getPKIType() const;
|
|
||||||
// Returns true if merchant's identity is authenticated, and
|
// Returns true if merchant's identity is authenticated, and
|
||||||
// returns human-readable merchant identity in merchant
|
// returns human-readable merchant identity in merchant
|
||||||
bool getMerchant(X509_STORE* certStore, QString& merchant) const;
|
bool getMerchant(X509_STORE* certStore, QString& merchant) const;
|
||||||
|
|
|
@ -97,7 +97,11 @@ static QList<QString> savedPaymentRequests;
|
||||||
|
|
||||||
static void ReportInvalidCertificate(const QSslCertificate& cert)
|
static void ReportInvalidCertificate(const QSslCertificate& cert)
|
||||||
{
|
{
|
||||||
qDebug() << "ReportInvalidCertificate: Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
|
#if QT_VERSION < 0x050000
|
||||||
|
qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
|
||||||
|
#else
|
||||||
|
qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::DistinguishedNameQualifier) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -143,13 +147,20 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
|
||||||
|
|
||||||
int nRootCerts = 0;
|
int nRootCerts = 0;
|
||||||
const QDateTime currentTime = QDateTime::currentDateTime();
|
const QDateTime currentTime = QDateTime::currentDateTime();
|
||||||
foreach (const QSslCertificate& cert, certList)
|
|
||||||
{
|
foreach (const QSslCertificate& cert, certList) {
|
||||||
|
// Don't log NULL certificates
|
||||||
|
if (cert.isNull())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Not yet active/valid, or expired certificate
|
||||||
if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) {
|
if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) {
|
||||||
ReportInvalidCertificate(cert);
|
ReportInvalidCertificate(cert);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
|
// Blacklisted certificate
|
||||||
if (cert.isBlacklisted()) {
|
if (cert.isBlacklisted()) {
|
||||||
ReportInvalidCertificate(cert);
|
ReportInvalidCertificate(cert);
|
||||||
continue;
|
continue;
|
||||||
|
@ -301,7 +312,7 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) :
|
||||||
|
|
||||||
// Install global event filter to catch QFileOpenEvents
|
// Install global event filter to catch QFileOpenEvents
|
||||||
// on Mac: sent when you click bitcoin: links
|
// on Mac: sent when you click bitcoin: links
|
||||||
// other OSes: helpful when dealing with payment request files (in the future)
|
// other OSes: helpful when dealing with payment request files
|
||||||
if (parent)
|
if (parent)
|
||||||
parent->installEventFilter(this);
|
parent->installEventFilter(this);
|
||||||
|
|
||||||
|
@ -332,14 +343,13 @@ PaymentServer::~PaymentServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// OSX-specific way of handling bitcoin: URIs and
|
// OSX-specific way of handling bitcoin: URIs and PaymentRequest mime types.
|
||||||
// PaymentRequest mime types
|
// Also used by paymentservertests.cpp and when opening a payment request file
|
||||||
|
// via "Open URI..." menu entry.
|
||||||
//
|
//
|
||||||
bool PaymentServer::eventFilter(QObject *object, QEvent *event)
|
bool PaymentServer::eventFilter(QObject *object, QEvent *event)
|
||||||
{
|
{
|
||||||
// clicking on bitcoin: URIs creates FileOpen events on the Mac
|
if (event->type() == QEvent::FileOpen) {
|
||||||
if (event->type() == QEvent::FileOpen)
|
|
||||||
{
|
|
||||||
QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent*>(event);
|
QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent*>(event);
|
||||||
if (!fileEvent->file().isEmpty())
|
if (!fileEvent->file().isEmpty())
|
||||||
handleURIOrFile(fileEvent->file());
|
handleURIOrFile(fileEvent->file());
|
||||||
|
@ -515,7 +525,7 @@ bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentR
|
||||||
return request.parse(data);
|
return request.parse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient)
|
bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient)
|
||||||
{
|
{
|
||||||
if (!optionsModel)
|
if (!optionsModel)
|
||||||
return false;
|
return false;
|
||||||
|
@ -560,9 +570,9 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
||||||
addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString()));
|
addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString()));
|
||||||
}
|
}
|
||||||
else if (!recipient.authenticatedMerchant.isEmpty()) {
|
else if (!recipient.authenticatedMerchant.isEmpty()) {
|
||||||
// Insecure payments to custom bitcoin addresses are not supported
|
// Unauthenticated payment requests to custom bitcoin addresses are not supported
|
||||||
// (there is no good way to tell the user where they are paying in a way
|
// (there is no good way to tell the user where they are paying in a way they'd
|
||||||
// they'd have a chance of understanding).
|
// have a chance of understanding).
|
||||||
emit message(tr("Payment request rejected"),
|
emit message(tr("Payment request rejected"),
|
||||||
tr("Unverified payment requests to custom payment scripts are unsupported."),
|
tr("Unverified payment requests to custom payment scripts are unsupported."),
|
||||||
CClientUIInterface::MSG_ERROR);
|
CClientUIInterface::MSG_ERROR);
|
||||||
|
|
|
@ -131,7 +131,7 @@ protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event);
|
bool eventFilter(QObject *object, QEvent *event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient);
|
bool processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient);
|
||||||
void fetchRequest(const QUrl& url);
|
void fetchRequest(const QUrl& url);
|
||||||
|
|
||||||
// Setup networking
|
// Setup networking
|
||||||
|
|
|
@ -531,7 +531,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
|
||||||
msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
|
msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
|
||||||
break;
|
break;
|
||||||
case WalletModel::PaymentRequestExpired:
|
case WalletModel::PaymentRequestExpired:
|
||||||
msgParams.first = tr("Payment request expired!");
|
msgParams.first = tr("Payment request expired.");
|
||||||
msgParams.second = CClientUIInterface::MSG_ERROR;
|
msgParams.second = CClientUIInterface::MSG_ERROR;
|
||||||
break;
|
break;
|
||||||
// included to prevent a compiler warning.
|
// included to prevent a compiler warning.
|
||||||
|
|
Loading…
Reference in a new issue