Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
canonical_tests.cpp
Go to the documentation of this file.
1 //
2 // Unit tests for canonical signatures
3 
5 #include <boost/test/unit_test.hpp>
6 #include <openssl/ecdsa.h>
7 
8 #include "key.h"
9 #include "script.h"
10 #include "util.h"
11 
12 using namespace std;
13 using namespace json_spirit;
14 
15 
16 // In script_tests.cpp
17 extern Array read_json(const std::string& filename);
18 
19 BOOST_AUTO_TEST_SUITE(canonical_tests)
20 
21 // OpenSSL-based test for canonical signature (without test for hashtype byte)
22 bool static IsCanonicalSignature_OpenSSL_inner(const std::vector<unsigned char>& vchSig)
23 {
24  if (vchSig.size() == 0)
25  return false;
26  const unsigned char *input = &vchSig[0];
27  ECDSA_SIG *psig = NULL;
28  d2i_ECDSA_SIG(&psig, &input, vchSig.size());
29  if (psig == NULL)
30  return false;
31  unsigned char buf[256];
32  unsigned char *pbuf = buf;
33  unsigned int nLen = i2d_ECDSA_SIG(psig, NULL);
34  if (nLen != vchSig.size()) {
35  ECDSA_SIG_free(psig);
36  return false;
37  }
38  nLen = i2d_ECDSA_SIG(psig, &pbuf);
39  ECDSA_SIG_free(psig);
40  return (memcmp(&vchSig[0], &buf[0], nLen) == 0);
41 }
42 
43 // OpenSSL-based test for canonical signature
44 bool static IsCanonicalSignature_OpenSSL(const std::vector<unsigned char> &vchSignature) {
45  if (vchSignature.size() < 1)
46  return false;
47  if (vchSignature.size() > 127)
48  return false;
49  if (vchSignature[vchSignature.size() - 1] & 0x7C)
50  return false;
51 
52  std::vector<unsigned char> vchSig(vchSignature);
53  vchSig.pop_back();
54  if (!IsCanonicalSignature_OpenSSL_inner(vchSig))
55  return false;
56  return true;
57 }
58 
59 BOOST_AUTO_TEST_CASE(script_canon)
60 {
61  Array tests = read_json("sig_canonical.json");
62 
63  BOOST_FOREACH(Value &tv, tests) {
64  string test = tv.get_str();
65  if (IsHex(test)) {
66  std::vector<unsigned char> sig = ParseHex(test);
67  BOOST_CHECK_MESSAGE(IsCanonicalSignature(sig), test);
68  BOOST_CHECK_MESSAGE(IsCanonicalSignature_OpenSSL(sig), test);
69  }
70  }
71 }
72 
73 BOOST_AUTO_TEST_CASE(script_noncanon)
74 {
75  Array tests = read_json("sig_noncanonical.json");
76 
77  BOOST_FOREACH(Value &tv, tests) {
78  string test = tv.get_str();
79  if (IsHex(test)) {
80  std::vector<unsigned char> sig = ParseHex(test);
81  BOOST_CHECK_MESSAGE(!IsCanonicalSignature(sig), test);
82  BOOST_CHECK_MESSAGE(!IsCanonicalSignature_OpenSSL(sig), test);
83  }
84  }
85 }
86 
87 BOOST_AUTO_TEST_SUITE_END()
Array read_json(const std::string &filename)
bool IsHex(const string &str)
Definition: util.cpp:490
Config::Array_type Array
const String_type & get_str() const
DBTest * test
Definition: db_test.cc:1701
BOOST_AUTO_TEST_CASE(script_canon)
vector< unsigned char > ParseHex(const char *psz)
Definition: util.cpp:500
bool IsCanonicalSignature(const valtype &vchSig)
Definition: script.cpp:245