16 #include <openssl/x509_vfy.h>    20 #include <QSslCertificate>    30     bool parseOK = 
paymentRequest.ParseFromArray(data.data(), data.size());
    32         qWarning() << 
"PaymentRequestPlus::parse: Error parsing payment request";
    36         qWarning() << 
"PaymentRequestPlus::parse: Received up-version payment details, version=" << 
paymentRequest.payment_details_version();
    43         qWarning() << 
"PaymentRequestPlus::parse: Error parsing payment details";
    69     const EVP_MD* digestAlgorithm = 
nullptr;
    71         digestAlgorithm = EVP_sha256();
    74         digestAlgorithm = EVP_sha1();
    77         qWarning() << 
"PaymentRequestPlus::getMerchant: Payment request: pki_type == none";
    81         qWarning() << 
"PaymentRequestPlus::getMerchant: Payment request: unknown pki_type " << QString::fromStdString(
paymentRequest.pki_type());
    85     payments::X509Certificates certChain;
    87         qWarning() << 
"PaymentRequestPlus::getMerchant: Payment request: error parsing pki_data";
    91     std::vector<X509*> certs;
    92     const QDateTime currentTime = QDateTime::currentDateTime();
    93     for (
int i = 0; i < certChain.certificate_size(); i++) {
    94         QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size());
    95         QSslCertificate qCert(certData, QSsl::Der);
    96         if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) {
    97             qWarning() << 
"PaymentRequestPlus::getMerchant: Payment request: certificate expired or not yet active: " << qCert;
   100         if (qCert.isBlacklisted()) {
   101             qWarning() << 
"PaymentRequestPlus::getMerchant: Payment request: certificate blacklisted: " << qCert;
   104         const unsigned char *data = (
const unsigned char *)certChain.certificate(i).data();
   105         X509 *cert = d2i_X509(
nullptr, &data, certChain.certificate(i).size());
   107             certs.push_back(cert);
   110         qWarning() << 
"PaymentRequestPlus::getMerchant: Payment request: empty certificate chain";
   116     STACK_OF(X509) *chain = sk_X509_new_null();
   117     for (
int i = certs.size() - 1; i > 0; i--) {
   118         sk_X509_push(chain, certs[i]);
   120     X509 *signing_cert = certs[0];
   124     X509_STORE_CTX *store_ctx = X509_STORE_CTX_new();
   126         qWarning() << 
"PaymentRequestPlus::getMerchant: Payment request: error creating X509_STORE_CTX";
   130     char *website = 
nullptr;
   134         if (!X509_STORE_CTX_init(store_ctx, certStore, signing_cert, chain))
   136             int error = X509_STORE_CTX_get_error(store_ctx);
   141         int result = X509_verify_cert(store_ctx);
   143             int error = X509_STORE_CTX_get_error(store_ctx);
   145             if (!(
error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && 
gArgs.
GetBoolArg(
"-allowselfsignedrootcertificates", DEFAULT_SELFSIGNED_ROOTCERTS))) {
   148                qDebug() << 
"PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true.";
   151         X509_NAME *certname = X509_get_subject_name(signing_cert);
   155         rcopy.set_signature(std::string(
""));
   156         std::string data_to_verify;                     
   157         rcopy.SerializeToString(&data_to_verify);
   159 #if HAVE_DECL_EVP_MD_CTX_NEW   160         EVP_MD_CTX *ctx = EVP_MD_CTX_new();
   161         if (!ctx) 
throw SSLVerifyError(
"Error allocating OpenSSL context.");
   167         EVP_PKEY *pubkey = X509_get_pubkey(signing_cert);
   168         EVP_MD_CTX_init(ctx);
   169         if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, 
nullptr) ||
   170             !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) ||
   171             !EVP_VerifyFinal(ctx, (
const unsigned char*)
paymentRequest.signature().data(), (
unsigned int)
paymentRequest.signature().size(), pubkey)) {
   174 #if HAVE_DECL_EVP_MD_CTX_NEW   175         EVP_MD_CTX_free(ctx);
   179         int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, 
nullptr, 0);
   180         website = 
new char[textlen + 1];
   181         if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) {
   191         qWarning() << 
"PaymentRequestPlus::getMerchant: SSL error: " << err.what();
   195     X509_STORE_CTX_free(store_ctx);
   196     for (
unsigned int i = 0; i < certs.size(); i++)
   204     QList<std::pair<CScript,CAmount> > result;
   205     for (
int i = 0; i < 
details.outputs_size(); i++)
   207         const unsigned char* scriptStr = (
const unsigned char*)
details.outputs(i).script().data();
   208         CScript s(scriptStr, scriptStr+
details.outputs(i).script().size());
   210         result.append(std::make_pair(s, 
details.outputs(i).amount()));
 SSLVerifyError(std::string err)
 
bool SerializeToString(std::string *output) const
 
bool IsInitialized() const
 
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value. 
 
bool getMerchant(X509_STORE *certStore, QString &merchant) const
 
QList< std::pair< CScript, CAmount > > getPayTo() const
 
bool parse(const QByteArray &data)
 
payments::PaymentDetails details
 
payments::PaymentRequest paymentRequest
 
Serialized script, used inside transaction inputs and outputs. 
 
bool error(const char *fmt, const Args &... args)