Skip to content

Commit 4b96b60

Browse files
committed
start un-hardcoding certificates, etc
1 parent 7a75455 commit 4b96b60

File tree

4 files changed

+58
-29
lines changed

4 files changed

+58
-29
lines changed

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ CXXFLAGS = -g $(PLATFORM_CXXFLAGS)
1010
LDFLAGS = $(PLATFORM_LDFLAGS)
1111

1212
PBFILES = paymentrequest.pb.h paymentrequest.pb.cc
13-
TARGETS = paymentrequest-create paymentrequest-verify
13+
TARGETS = paymentrequest-create paymentrequest-dump
1414
LIBS = -lssl -lcrypto -lprotobuf
1515

1616
all: $(TARGETS) ca_in_a_box/certs/demomerchant.pem
@@ -25,9 +25,9 @@ CREATEOBJS = obj/util.o obj/paymentrequest-create.o obj/paymentrequest.pb.o
2525
paymentrequest-create: $(PBFILES) $(CREATEOBJS)
2626
$(CXX) $(CXXFLAGS) -o $@ $(CREATEOBJS) $(LDFLAGS) $(LIBS)
2727

28-
VERIFYOBJS = obj/util.o obj/paymentrequest-verify.o obj/paymentrequest.pb.o
29-
paymentrequest-verify: $(PBFILES) $(VERIFYOBJS)
30-
$(CXX) $(CXXFLAGS) -o $@ $(VERIFYOBJS) $(LDFLAGS) $(LIBS)
28+
DUMPOBJS = obj/util.o obj/paymentrequest-dump.o obj/paymentrequest.pb.o
29+
paymentrequest-dump: $(PBFILES) $(DUMPOBJS)
30+
$(CXX) $(CXXFLAGS) -o $@ $(DUMPOBJS) $(LDFLAGS) $(LIBS)
3131

3232
ca_in_a_box/certs/demomerchant.pem:
3333
pushd ca_in_a_box && ./create_ca.sh && popd

README.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ Code implementing a simple payment protocol for Bitcoin (PaymentRequest/etc).
33
See https://gist.github.com/4120476
44

55
Dependencies:
6-
OpenSSL
7-
Google Protocol Buffers
6+
OpenSSL (library and openssl command-line tool)
7+
Google Protocol Buffers (library and protoc command-line compiler)
8+
9+
Debian/Ubuntu:
10+
apt-get install openssl protobuf
11+
OSX MacPorts:
12+
port install openssl protobuf
813

914
To compile:
1015
make
@@ -15,3 +20,6 @@ compile command-line tools:
1520
paymentrequest-create # Prototype code: create a SignedPaymentRequest message
1621
paymentrequest-verify # Prototype code: verify a SignedPaymentRequest message
1722

23+
24+
Example usage:
25+
paymentrequest-create memo="Just Testing" amount=11.0 | paymentrequest-dump

paymentrequest-create.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,13 @@ int main(int argc, char **argv) {
150150
// We got here, so the signature is self-consistent.
151151
signedPaymentRequest.set_signature(signature, actual_signature_len);
152152

153-
std::fstream outfile("demo.bitcoin-paymentrequest", std::ios::out | std::ios::trunc | std::ios::binary);
154-
assert(signedPaymentRequest.SerializeToOstream(&outfile));
155-
printf("File written successfully, see demo.bitcoin-paymentrequest\n");
156-
printf("You can check it by running paymentrequest-verify\n");
153+
if (params.count("out")) {
154+
std::fstream outfile(params["out"].c_str(), std::ios::out | std::ios::trunc | std::ios::binary);
155+
assert(signedPaymentRequest.SerializeToOstream(&outfile));
156+
}
157+
else {
158+
assert(signedPaymentRequest.SerializeToOstream(&std::cout));
159+
}
157160

158161
delete[] signature;
159162

paymentrequest-verify.cpp renamed to paymentrequest-dump.cpp

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "util.h"
1818

1919
using std::string;
20+
using std::map;
2021

2122
// Take binary DER data and return an X509 object suitable for verification or use.
2223
X509 *parse_der_cert(string cert_data) {
@@ -27,6 +28,18 @@ X509 *parse_der_cert(string cert_data) {
2728
}
2829

2930
int main(int argc, char **argv) {
31+
std::list<string> expected = split("rootcertificates,in", ",");
32+
33+
map<string,string> params;
34+
if (!parse_command_line(argc, argv, expected, params)) {
35+
usage(expected);
36+
exit(1);
37+
}
38+
if (params["rootcertificates"].empty()) {
39+
// Use the certificate-authority-in-a-box root cert by default:
40+
params["rootcertificates"] = string("ca_in_a_box/certs/cacert.pem");
41+
}
42+
3043
SSL_library_init();
3144
ERR_load_BIO_strings();
3245
SSL_load_error_strings();
@@ -43,17 +56,13 @@ int main(int argc, char **argv) {
4356
// how to do it, it doesn't actually look anything up despite the name.
4457
X509_LOOKUP *lookup = X509_STORE_add_lookup(cert_store, X509_LOOKUP_file());
4558

46-
// Use the certificate-authority-in-a-box root cert:
47-
assert(X509_LOOKUP_load_file(lookup, "ca_in_a_box/certs/cacert.pem", X509_FILETYPE_PEM));
48-
49-
// Load all the root authority certificates. This file was retrieved from
50-
// http://www.startssl.com/certs/ca-bundle.pem on Nov 18th 2012.
51-
// assert(X509_LOOKUP_load_file(lookup, "ca-bundle-startcom.pem", X509_FILETYPE_PEM));
59+
assert(X509_LOOKUP_load_file(lookup, params["rootcertificates"].c_str(), X509_FILETYPE_PEM));
5260

53-
// Load the paymentrequest file.
54-
std::ifstream infile("demo.bitcoin-paymentrequest", std::ios::in | std::ios::binary);
61+
// Load the paymentrequest file from stdin
5562
SignedPaymentRequest signedPaymentRequest;
56-
assert(signedPaymentRequest.ParseFromIstream(&infile));
63+
if (!signedPaymentRequest.ParseFromIstream(&std::cin)) {
64+
exit(1);
65+
}
5766

5867
// Dump in raw text format, obviously this is mostly useless as bulk of
5968
// the data is binary.
@@ -105,19 +114,28 @@ int main(int argc, char **argv) {
105114
EVP_MD_CTX ctx;
106115
EVP_PKEY *pubkey = X509_get_pubkey(signing_cert);
107116
EVP_MD_CTX_init(&ctx);
108-
assert(EVP_VerifyInit_ex(&ctx, EVP_sha256(), NULL));
109-
assert(EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()));
110-
assert(EVP_VerifyFinal(&ctx, (const unsigned char*)signature.data(), signature.size(), pubkey));
117+
if (!EVP_VerifyInit_ex(&ctx, EVP_sha256(), NULL) ||
118+
!EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) ||
119+
!EVP_VerifyFinal(&ctx, (const unsigned char*)signature.data(), signature.size(), pubkey)) {
120+
121+
printf("Bad signature, invalid SignedPaymentRequest.\n");
122+
}
123+
else {
124+
// OpenSSL API for getting human printable strings from certs is baroque.
125+
int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0);
126+
char *website = new char[textlen + 1];
127+
if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) {
128+
printf("SignedPaymentRequest is valid! Signed by %s\n", website);
129+
}
130+
else {
131+
printf("Bad certificate, missing common name\n");
132+
}
133+
delete[] website;
134+
}
111135

112-
// OpenSSL API for getting human printable strings from certs is baroque.
113-
int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0);
114-
char *website = new char[textlen + 1];
115-
assert(X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen);
116-
printf("Paymentrequest is valid! Signed by %s\n", website);
117-
printf("Memo: %s\n", paymentRequest.memo().c_str());
136+
printf("PaymentRequest data:\n%s\n", paymentRequest.DebugString().c_str());
118137

119138
// Avoid reported memory leaks.
120-
delete website;
121139
X509_STORE_CTX_free(store_ctx);
122140
for (int i = 0; i < certs.size(); i++)
123141
X509_free(certs[i]);

0 commit comments

Comments
 (0)