Skip to content

Commit

Permalink
Fix use-after-free bug, and better error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinandresen committed Aug 3, 2013
1 parent 5b691ea commit 1068f4a
Show file tree
Hide file tree
Showing 8 changed files with 1,282 additions and 407 deletions.
25 changes: 8 additions & 17 deletions README.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
Code implementing a simple payment protocol for Bitcoin (PaymentRequest/etc).

See https://gist.github.com/4120476
See https://en.bitcoin.it/wiki/BIP_0070

Dependencies:
OpenSSL (library and openssl command-line tool)
Google Protocol Buffers (library and protoc command-line compiler)
Files here:

Debian/Ubuntu:
apt-get install openssl protobuf
OSX MacPorts:
port install openssl protobuf
paymentrequest.proto : Google protocol buffer definition of messages

To compile:
make
Subdirectories here:

The Makefile will create a "certificate authority in a box" in ca_in_a_box/ and
compile command-line tools:
c++ : command-line utilities for creating/validating PaymentRequests

paymentrequest-create # Prototype code: create a PaymentRequest message
paymentrequest-verify # Prototype code: verify a PaymentRequest message
php : php code and a demo website for creating/validating PaymentRequests


Example usage:
paymentrequest-create paytoaddress=1BTCorgHwCg6u2YSAWKgS17qUad6kHmtQW memo="Just Testing" amount=11.0 | paymentrequest-dump
ca_in_a_box : "certificate authority in a box", used to generate
certificates and certificate chains for testing.
76 changes: 0 additions & 76 deletions TODO.txt

This file was deleted.

21 changes: 21 additions & 0 deletions c++/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Dependencies:
OpenSSL (library and openssl command-line tool)
Google Protocol Buffers (library and protoc command-line compiler)

Debian/Ubuntu:
apt-get install openssl protobuf
OSX MacPorts:
port install openssl protobuf

To compile:
make

The Makefile will create a "certificate authority in a box" in ../ca_in_a_box/ and
compile command-line tools:

paymentrequest-create # Prototype code: create a PaymentRequest message
paymentrequest-verify # Prototype code: verify a PaymentRequest message


Example usage:
paymentrequest-create paytoaddress=1BTCorgHwCg6u2YSAWKgS17qUad6kHmtQW memo="Just Testing" amount=11.0 | paymentrequest-dump
34 changes: 20 additions & 14 deletions c++/paymentrequest-create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include <openssl/x509_vfy.h>
#include <openssl/evp.h>

#include "paymentrequest.pb.h";
#include "paymentrequest.pb.h"
#include <google/protobuf/io/tokenizer.h> // For string-to-uint64 conversion
#include "util.h"

Expand Down Expand Up @@ -352,25 +352,28 @@ int main(int argc, char **argv) {

// Certificate chain:
X509Certificates certChain;
X509 *first_cert = NULL;
X509 *last_cert = NULL;
EVP_PKEY *pubkey = NULL;
std::list<string> certFiles = split(params["certificates"], ",");
std::vector<X509*> certs;
for (std::list<string>::iterator it = certFiles.begin(); it != certFiles.end(); it++) {
X509 *cert = parse_pem_cert(load_file(*it));
certChain.add_certificate(x509_to_der(cert));
if (first_cert == NULL) {
first_cert = cert; // Don't free this yet, need pubkey to stay valid
pubkey = X509_get_pubkey(cert);
}
else {
X509_free(cert);
if (cert == NULL) {
fprintf(stderr, "Could not read %s\n", it->c_str());
continue;
}
last_cert = cert;
certs.push_back(cert);
certChain.add_certificate(x509_to_der(cert));
}

if (certs.empty()) {
fprintf(stderr, "Could not load any certificates\n");
exit(1);
}

// Public key is first certificate:
EVP_PKEY *pubkey = X509_get_pubkey(certs.front());

// Fetch any missing intermediate certificates, if we can:
fetchParentCerts(certChain, last_cert);
fetchParentCerts(certChain, certs.back());

string certChainBytes;
certChain.SerializeToString(&certChainBytes);
Expand Down Expand Up @@ -410,7 +413,10 @@ int main(int argc, char **argv) {
}
EVP_MD_CTX_destroy(ctx);
EVP_PKEY_free(pubkey);
X509_free(first_cert);
for (std::vector<X509*>::iterator it = certs.begin(); it != certs.end(); it++) {
X509_free(*it);
}
certs.clear();

// We got here, so the signature is self-consistent.
request.set_signature(signature, actual_signature_len);
Expand Down
2 changes: 1 addition & 1 deletion c++/paymentrequest-dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

#include "paymentrequest.pb.h";
#include "paymentrequest.pb.h"
#include "util.h"

using std::string;
Expand Down
7 changes: 6 additions & 1 deletion php/demo_website/createpaymentrequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function createPaymentRequest($params)
if (!empty($params[$field])) {
$output = new \payments\Output();
$r = address_to_script($params["address".$i]);
if ($r[0]) $testnet = true;
$testnet = $r[0];
$output->setScript($r[1]);
$output->setAmount($params["amount".$i]*1.0e8);
$totalAmount += $params["amount".$i];
Expand Down Expand Up @@ -183,6 +183,11 @@ function createPaymentRequest($params)
$validationData['amount3'] = array('type' => 'btcamount');

if (isset($request['submit'])) {
// For debugging Tor connections: replace $CLIENT_IP
// in memo/ACK_message with client's IP address:
$request['memo'] = str_replace('$CLIENT_IP', $_SERVER['REMOTE_ADDR'], $request['memo']);
$request['ACK_message'] = str_replace('$CLIENT_IP', $_SERVER['REMOTE_ADDR'], $request['ACK_message']);

$formErrors = validateForm($request, $validationData);

if (count($formErrors) == 0) {
Expand Down
1 change: 0 additions & 1 deletion php/demo_website/include/paymentrequest.php

This file was deleted.

Loading

0 comments on commit 1068f4a

Please sign in to comment.