#include <boost/test/included/unit_test.hpp>
#include <boost/algorithm/string.hpp>
#include <fc/crypto/public_key.hpp>
#include <fc/crypto/private_key.hpp>
#include <fc/crypto/signature.hpp>
#include <fc/utility.hpp>
 
Go to the source code of this file.
◆ BOOST_TEST_MODULE
      
        
          | #define BOOST_TEST_MODULE   webauthn_test_mod | 
        
      
 
 
◆ BOOST_AUTO_TEST_CASE() [1/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          auth_data_rpid_hash_bad |            | ) | 
           | 
        
      
 
Definition at line 199 of file test_webauthn.cpp.
  199                                                  {
  200   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  202 
  203   std::vector<uint8_t> auth_data(37);
  205   memcpy(auth_data.data(), origin_hash_corrupt.
data(), 
sizeof(origin_hash_corrupt));
 
  206   auth_data[4]++;
  207 
  208   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  209      return e.to_detail_string().find("webauthn rpid hash doesn't match origin") != std::string::npos;
  210   });
static sha256 hash(const char *d, uint32_t dlen)
 
const char * data() const
 
std::string base64url_encode(unsigned char const *bytes_to_encode, unsigned int in_len)
 
memcpy((char *) pInfo->slotDescription, s, l)
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [2/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          auth_data_too_short |            | ) | 
           | 
        
      
 
Definition at line 214 of file test_webauthn.cpp.
  214                                              {
  215   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  217 
  218   std::vector<uint8_t> auth_data(1);
  219 
  220   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  221      return e.to_detail_string().find("auth_data not as large as required") != std::string::npos;
  222   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [3/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          base64_wonky |            | ) | 
           | 
        
      
 
Definition at line 406 of file test_webauthn.cpp.
  406                                       {
  407   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  408 
  410   boost::erase_all(
json, 
"=");
 
  411 
  412   std::vector<uint8_t> auth_data(37);
  413   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  414 
  416      return e.
to_detail_string().find(
"encountered non-base64 character") != std::string::npos;
 
  417   });
Used to generate a useful error report when an exception is thrown.
 
std::string to_detail_string(log_level ll=log_level::all) const
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [4/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          challenge_junk |            | ) | 
           | 
        
      
 
Definition at line 145 of file test_webauthn.cpp.
  145                                         {
  146   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  147   std::string 
json = 
"{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + 
"blahBLAH"s + 
"\"}";
 
  148 
  149   std::vector<uint8_t> auth_data(37);
  150   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  151 
  153      return e.
to_detail_string().find(
"sha256: size mismatch") != std::string::npos;
 
  154   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [5/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          challenge_non_base64 |            | ) | 
           | 
        
      
 
Definition at line 158 of file test_webauthn.cpp.
  158                                               {
  159   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  160   std::string 
json = 
"{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + 
"hello@world$"s + 
"\"}";
 
  161 
  162   std::vector<uint8_t> auth_data(37);
  163   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  164 
  166      return e.
to_detail_string().find(
"encountered non-base64 character") != std::string::npos;
 
  167   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [6/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          challenge_wrong |            | ) | 
           | 
        
      
 
Definition at line 171 of file test_webauthn.cpp.
  171                                          {
  172   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  174   std::string 
json = 
"{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + 
fc::base64url_encode(other_digest.
data(), other_digest.
data_size()) + 
"\"}";
 
  175 
  176   std::vector<uint8_t> auth_data(37);
  177   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  178 
  179   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  180      return e.to_detail_string().find("Wrong webauthn challenge") != std::string::npos;
  181   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [7/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          damage_sig |            | ) | 
           | 
        
      
 
Definition at line 290 of file test_webauthn.cpp.
  290                                     {
  291   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  293 
  294   std::vector<uint8_t> auth_data(37);
  295   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  296 
  298   char buff[8192];
  301   buff[4]++;
  304 
  305   bool failed_recovery = false;
  306   bool failed_compare = false;
  308 
  309   try {
  310      recovered_pub = sig.
recover(d, 
true);
 
  311      failed_compare = !(wa_pub == recovered_pub);
  312   }
  314      failed_recovery = e.
to_detail_string().find(
"unable to reconstruct public key from signature") != std::string::npos;
 
  315   }
  316 
  317   
  318   BOOST_CHECK_EQUAL(failed_recovery || failed_compare, true);
public_key recover(const sha256 &digest, bool check_canonical) const
 
static const Segment ds(Segment::ds)
 
void unpack(Stream &s, std::deque< T > &value)
 
void pack(Stream &s, const std::deque< T > &value)
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [8/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          damage_sig_idx |            | ) | 
           | 
        
      
 
Definition at line 322 of file test_webauthn.cpp.
  322                                         {
  323   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  325 
  326   std::vector<uint8_t> auth_data(37);
  327   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  328 
  330   char buff[8192];
  333   buff[0]++;
  336 
  337   bool failed_recovery = false;
  338   bool failed_compare = false;
  340 
  341   try {
  342      recovered_pub = sig.
recover(d, 
true);
 
  343      failed_compare = !(wa_pub == recovered_pub);
  344   }
  346      failed_recovery = e.
to_detail_string().find(
"unable to reconstruct public key from signature") != std::string::npos;
 
  347   }
  348 
  349   
  350   BOOST_CHECK_EQUAL(failed_recovery || failed_compare, true);
 
 
 
◆ BOOST_AUTO_TEST_CASE() [9/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          different_priv_key |            | ) | 
           | 
        
      
 
Definition at line 354 of file test_webauthn.cpp.
  354                                             {
  356 
  357   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  359 
  360   std::vector<uint8_t> auth_data(37);
  361   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  362 
  363   BOOST_CHECK_NE(wa_pub, make_webauthn_sig(other_priv, auth_data, 
json).recover(d, 
true));
 
static private_key generate()
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [10/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          empty_json |            | ) | 
           | 
        
      
 
Definition at line 367 of file test_webauthn.cpp.
  367                                     {
  368   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  370 
  371   std::vector<uint8_t> auth_data(37);
  372   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  373 
  374   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  375      return e.to_detail_string().find("Failed to parse client data JSON") != std::string::npos;
  376   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [11/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          empty_origin |            | ) | 
           | 
        
      
 
Definition at line 110 of file test_webauthn.cpp.
  110                                       {
  111   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  113 
  114   std::vector<uint8_t> auth_data(37);
  115   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  116 
  117   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  118      return e.to_detail_string().find("webauthn origin must begin with https://") != std::string::npos;
  119   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [12/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          empty_port |            | ) | 
           | 
        
      
 
Definition at line 134 of file test_webauthn.cpp.
  134                                     {
  135   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  137 
  138   std::vector<uint8_t> auth_data(37);
  139   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  140 
  141   BOOST_CHECK_EQUAL(wa_pub, make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true));
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [13/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          empty_rpid |            | ) | 
           | 
        
      
 
Definition at line 380 of file test_webauthn.cpp.
  380                                     {
  381   char data[67] = {};
  384 
  385   BOOST_CHECK_EXCEPTION(
fc::raw::unpack(ds, 
pubkey), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  386      return e.to_detail_string().find("webauthn pubkey must have non empty rpid") != std::string::npos;
  387   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [14/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          good |            | ) | 
           | 
        
      
 
Definition at line 48 of file test_webauthn.cpp.
   48                               {
   49   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
   51 
   52   std::vector<uint8_t> auth_data(37);
   53 
   54   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
   55 
   56   BOOST_CHECK_EQUAL(wa_pub, make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true));
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [15/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          good_extrajunk |            | ) | 
           | 
        
      
 
Definition at line 265 of file test_webauthn.cpp.
  265                                         {
  266   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  267   std::string 
json = 
"{\"origin\":\"https://fctesting.invalid\",\"cool\":\"beans\",\"obj\":{\"array\":[4, 5, 6]}," 
  269 
  270   std::vector<uint8_t> auth_data(37);
  271   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  272 
  273   BOOST_CHECK_EQUAL(wa_pub, make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true));
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [16/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          good_no_trailing_equal |            | ) | 
           | 
        
      
 
Definition at line 391 of file test_webauthn.cpp.
  391                                                 {
  392   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  393 
  395   boost::erase_all(
json, 
"=");
 
  396 
  397   std::vector<uint8_t> auth_data(37);
  398   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  399 
  400   BOOST_CHECK_EQUAL(wa_pub, make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true));
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [17/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          good_port |            | ) | 
           | 
        
      
 
Definition at line 123 of file test_webauthn.cpp.
  123                                    {
  124   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  126 
  127   std::vector<uint8_t> auth_data(37);
  128   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  129 
  130   BOOST_CHECK_EQUAL(wa_pub, make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true));
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [18/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          lacking_scheme |            | ) | 
           | 
        
      
 
Definition at line 97 of file test_webauthn.cpp.
   97                                         {
   98   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  100 
  101   std::vector<uint8_t> auth_data(37);
  102   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  103 
  104   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  105      return e.to_detail_string().find("webauthn origin must begin with https://") != std::string::npos;
  106   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [19/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          mismatch_origin |            | ) | 
           | 
        
      
 
Definition at line 72 of file test_webauthn.cpp.
   72                                          {
   73   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_PRESENT, 
"fctesting.invalid");
 
   75 
   76   std::vector<uint8_t> auth_data(37);
   78   memcpy(auth_data.data(), mallory_origin_hash.
data(), 
sizeof(mallory_origin_hash));
 
   79 
   80   BOOST_CHECK_NE(wa_pub, make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true));
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [20/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          mismatch_presence |            | ) | 
           | 
        
      
 
Definition at line 60 of file test_webauthn.cpp.
   60                                            {
   61   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_PRESENT, 
"fctesting.invalid");
 
   63 
   64   std::vector<uint8_t> auth_data(37);
   65   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
   66   auth_data[32] |= 0x04; 
   67 
   68   BOOST_CHECK_NE(wa_pub, make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true));
 
 
 
 
◆ BOOST_AUTO_TEST_CASE() [21/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          missing_challenge |            | ) | 
           | 
        
      
 
Definition at line 252 of file test_webauthn.cpp.
  252                                            {
  253   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  254   std::string 
json = 
"{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\"}";
 
  255 
  256   std::vector<uint8_t> auth_data(37);
  257   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  258 
  260      return e.
to_detail_string().find(
"sha256: size mismatch") != std::string::npos;
 
  261   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [22/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          missing_origin |            | ) | 
           | 
        
      
 
Definition at line 226 of file test_webauthn.cpp.
  226                                         {
  227   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  229 
  230   std::vector<uint8_t> auth_data(37);
  231   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  232 
  233   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  234      return e.to_detail_string().find("webauthn origin must begin with https://") != std::string::npos;
  235   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [23/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          missing_type |            | ) | 
           | 
        
      
 
Definition at line 239 of file test_webauthn.cpp.
  239                                       {
  240   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  242 
  243   std::vector<uint8_t> auth_data(37);
  244   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  245 
  246   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  247      return e.to_detail_string().find("webauthn signature type not an assertion") != std::string::npos;
  248   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [24/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          non_https |            | ) | 
           | 
        
      
 
Definition at line 84 of file test_webauthn.cpp.
   84                                    {
   85   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
   87 
   88   std::vector<uint8_t> auth_data(37);
   89   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
   90 
   91   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
   92      return e.to_detail_string().find("webauthn origin must begin with https://") != std::string::npos;
   93   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [25/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          not_json_object |            | ) | 
           | 
        
      
 
Definition at line 277 of file test_webauthn.cpp.
  277                                          {
  278   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  279   std::string 
json = 
"hey man"s;
 
  280 
  281   std::vector<uint8_t> auth_data(37);
  282   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  283 
  284   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  285      return e.to_detail_string().find("Failed to parse client data JSON") != std::string::npos;
  286   });
 
 
 
◆ BOOST_AUTO_TEST_CASE() [26/26]
      
        
          | BOOST_AUTO_TEST_CASE  | 
          ( | 
          wrong_type |            | ) | 
           | 
        
      
 
Definition at line 185 of file test_webauthn.cpp.
  185                                     {
  186 
  187   webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, 
"fctesting.invalid");
 
  189 
  190   std::vector<uint8_t> auth_data(37);
  191   memcpy(auth_data.data(), origin_hash.
data(), 
sizeof(origin_hash));
 
  192 
  193   BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, 
json).recover(d, 
true), fc::assert_exception, [](
const fc::assert_exception& e) {
 
  194      return e.to_detail_string().find("webauthn signature type not an assertion") != std::string::npos;
  195   });
 
 
 
◆ FC_LOG_AND_RETHROW()