HomePhabricator

[paymentservertests] fix certificates and payment requests

Description

[paymentservertests] fix certificates and payment requests

Summary:
Procedure:

git clone git@github.com:gavinandresen/paymentrequest.git
cd paymentrequest
ca_in_a_box/create_ca.sh
ca_in_a_box/create_intermediate_cas.sh

# get caCert1_BASE64 (root authority)
openssl x509 -in ca_in_a_box/certs/cacert.pem -inform PEM -outform DER | openssl enc -base64

cd c++
# ... fix outdated openssl code and then compile
make

mv ../ca_in_a_box .

# get paymentrequest1_cert1_BASE64 by running the program with default certs and privatekey
./paymentrequest-create paytoaddress=1Nf4eZ76SFZdhrHVNLQkLAiS1oPPGaZxSv  amount=42 expires=1986627327 | ./paymentrequest-dump
./paymentrequest-create paytoaddress=1Nf4eZ76SFZdhrHVNLQkLAiS1oPPGaZxSv  amount=42 expires=1986627327 | base64

# get paymentrequest3_cert1_BASE64 by chaining the certificates
./paymentrequest-create paytoaddress=1Nf4eZ76SFZdhrHVNLQkLAiS1oPPGaZxSv  amount=42 expires=4826525372 payment_url=testmerchant8.org certificates=./ca_in_a_box/intermediate_8/certs/demomerchant.pem,./ca_in_a_box/intermediate_8/certs/cacert.pem,./ca_in_a_box/intermediate_7/certs/cacert.pem,./ca_in_a_box/intermediate_6/certs/cacert.pem,./ca_in_a_box/intermediate_5/certs/cacert.pem,./ca_in_a_box/intermediate_4/certs/cacert.pem,./ca_in_a_box/intermediate_3/certs/cacert.pem,./ca_in_a_box/intermediate_2/certs/cacert.pem,./ca_in_a_box/intermediate_1/certs/cacert.pem,./ca_in_a_box/certs/cacert.pem privatekey=./ca_in_a_box/intermediate_8/private/demomerchantkey.pem |  base64

The patch to fix the outdated OpenSSL code is:

diff --git a/c++/paymentrequest-create.cpp b/c++/paymentrequest-create.cpp
index 5fdbc8c..69d5b8d 100644
--- a/c++/paymentrequest-create.cpp
+++ b/c++/paymentrequest-create.cpp
@@ -178,16 +178,17 @@ bool decode_base58(const string& btcaddress, unsigned char& version, string& has
     unsigned char decoded[25];

     size_t nBytes = 0;
-    BIGNUM bn58, bn, bnChar;
+    BIGNUM *bn58, *bn, *bnChar;
     BN_CTX *ctx;

     ctx = BN_CTX_new();
-    BN_init(&bn58);
-    BN_init(&bn);
-    BN_init(&bnChar);

-    BN_set_word(&bn58, 58);
-    BN_set_word(&bn, 0);
+    bn58 = BN_new();
+    bn = BN_new();
+    bnChar = BN_new();
+
+    BN_set_word(bn58, 58);
+    BN_set_word(bn, 0);

     for (unsigned int i = 0; i < btcaddress.length(); i++) {
         const char *p1 = strchr(base58_chars, btcaddress[i]);
@@ -195,23 +196,23 @@ bool decode_base58(const string& btcaddress, unsigned char& version, string& has
             goto out;
         }

-        BN_set_word(&bnChar, p1 - base58_chars);
+        BN_set_word(bnChar, p1 - base58_chars);

-        assert(BN_mul(&bn, &bn, &bn58, ctx));
-        assert(BN_add(&bn, &bn, &bnChar));
+        assert(BN_mul(bn, bn, bn58, ctx));
+        assert(BN_add(bn, bn, bnChar));
     }

-    nBytes = BN_num_bytes(&bn);
+    nBytes = BN_num_bytes(bn);
     if (nBytes == 0 || nBytes > 25)
         return false;

     std::fill(decoded, decoded+25, (unsigned char)0);
-    BN_bn2bin(&bn, &decoded[25-nBytes]);
+    BN_bn2bin(bn, &decoded[25-nBytes]);

 out:
-    BN_clear_free(&bn58);
-    BN_clear_free(&bn);
-    BN_clear_free(&bnChar);
+    BN_clear_free(bn58);
+    BN_clear_free(bn);
+    BN_clear_free(bnChar);
     BN_CTX_free(ctx);

     version = decoded[0];
diff --git a/c++/paymentrequest-dump.cpp b/c++/paymentrequest-dump.cpp
index d20e400..d28d1dd 100644
--- a/c++/paymentrequest-dump.cpp
+++ b/c++/paymentrequest-dump.cpp
@@ -133,12 +133,14 @@ int main(int argc, char **argv) {
     request.SerializeToString(&data_to_verify);
     request.set_signature(signature);

-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx;
+    ctx = EVP_MD_CTX_new();
+
     EVP_PKEY *pubkey = X509_get_pubkey(signing_cert);
-    EVP_MD_CTX_init(&ctx);
-    if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) ||
-        !EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) ||
-        !EVP_VerifyFinal(&ctx, (const unsigned char*)signature.data(), signature.size(), pubkey)) {
+    EVP_MD_CTX_init(ctx);
+    if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, NULL) ||
+        !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) ||
+        !EVP_VerifyFinal(ctx, (const unsigned char*)signature.data(), signature.size(), pubkey)) {

         printf("Bad signature, invalid PaymentRequest.\n");
     }

Notes:

  • the merchant certificate is the first in the chain, then all the intermediate certificate authorities in reverse order, and finally the root certificate authority. The private key is the one for the merchant.
  • do not run the create_ca.sh and create_intermediate_cas.sh more than once, or delete the previous results in between two runs. This is because re-running it causes some or all keys to be overwritten, but it fails to recreate the new corresponding certs.

Test Plan: ninja check-bitcoin-qt

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D12887

Details

Provenance
PiRKAuthored on Dec 12 2022, 14:36
PiRKPushed on Dec 14 2022, 14:58
Reviewer
Restricted Project
Differential Revision
D12887: [paymentservertests] fix certificates and payment requests
Parents
rABCbf4a9cfa2e30: [avalanche] Actually finalize block in voting functional test
Branches
Unknown
Tags
Unknown