Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
test_webauthn.cpp
Go to the documentation of this file.
1#define BOOST_TEST_MODULE webauthn_test_mod
2#include <boost/test/included/unit_test.hpp>
3#include <boost/algorithm/string.hpp>
4
8#include <fc/utility.hpp>
9
10using namespace fc::crypto;
11using namespace fc;
12using namespace std::literals;
13
14static fc::crypto::webauthn::signature make_webauthn_sig(const fc::crypto::r1::private_key& priv_key,
15 std::vector<uint8_t>& auth_data,
16 const std::string& json) {
17
18 //webauthn signature is sha256(auth_data || client_data_hash)
19 fc::sha256 client_data_hash = fc::sha256::hash(json);
21 e.write((char*)auth_data.data(), auth_data.size());
22 e.write(client_data_hash.data(), client_data_hash.data_size());
23
24 r1::compact_signature sig = priv_key.sign_compact(e.result());
25
26 char buff[8192];
27 datastream<char*> ds(buff, sizeof(buff));
28 fc::raw::pack(ds, sig);
29 fc::raw::pack(ds, auth_data);
31 ds.seekp(0);
32
35
36 return ret;
37}
38
39//used for many below
41static const r1::public_key pub = priv.get_public_key();
42static const fc::sha256 d = fc::sha256::hash("sup"s);
43static const fc::sha256 origin_hash = fc::sha256::hash("fctesting.invalid"s);
44
45BOOST_AUTO_TEST_SUITE(webauthn_suite)
46
47//Good signature
49 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
50 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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));
58
59//A valid signature but shouldn't match public key due to presence difference
60BOOST_AUTO_TEST_CASE(mismatch_presence) try {
61 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_PRESENT, "fctesting.invalid");
62 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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; //User presence verified
67
68 BOOST_CHECK_NE(wa_pub, make_webauthn_sig(priv, auth_data, json).recover(d, true));
70
71//A valid signature but shouldn't match public key due to origin difference
72BOOST_AUTO_TEST_CASE(mismatch_origin) try {
73 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_PRESENT, "fctesting.invalid");
74 std::string json = "{\"origin\":\"https://mallory.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
75
76 std::vector<uint8_t> auth_data(37);
77 fc::sha256 mallory_origin_hash = fc::sha256::hash("mallory.invalid"s);
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));
82
83//A valid signature but shouldn't recover because http was in use instead of https
84BOOST_AUTO_TEST_CASE(non_https) try {
85 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
86 std::string json = "{\"origin\":\"http://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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 });
95
96//A valid signature but shouldn't recover because there is no origin scheme
97BOOST_AUTO_TEST_CASE(lacking_scheme) try {
98 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
99 std::string json = "{\"origin\":\"fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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 });
108
109//A valid signature but shouldn't recover because empty origin
110BOOST_AUTO_TEST_CASE(empty_origin) try {
111 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
112 std::string json = "{\"origin\":\"\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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 });
121
122//Good signature with a port
123BOOST_AUTO_TEST_CASE(good_port) try {
124 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
125 std::string json = "{\"origin\":\"https://fctesting.invalid:123456\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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));
132
133//Good signature with an empty port
134BOOST_AUTO_TEST_CASE(empty_port) try {
135 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
136 std::string json = "{\"origin\":\"https://fctesting.invalid:\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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));
143
144//valid signature but with misc junk in challenge
145BOOST_AUTO_TEST_CASE(challenge_junk) try {
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
152 BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, json).recover(d, true), fc::exception, [](const fc::exception& e) {
153 return e.to_detail_string().find("sha256: size mismatch") != std::string::npos;
154 });
156
157//valid signature but with non base64 in challenge
158BOOST_AUTO_TEST_CASE(challenge_non_base64) try {
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
165 BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, json).recover(d, true), fc::exception, [](const fc::exception& e) {
166 return e.to_detail_string().find("encountered non-base64 character") != std::string::npos;
167 });
169
170//valid signature but with some other digest in the challenge that is not the one we are recovering from
171BOOST_AUTO_TEST_CASE(challenge_wrong) try {
172 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
173 fc::sha256 other_digest = fc::sha256::hash("yo"s);
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 });
183
184//valid signature but wrong webauthn type
185BOOST_AUTO_TEST_CASE(wrong_type) try {
186
187 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
188 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.meh\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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 });
197
198//signature if good but the auth_data rpid hash is not what is expected for origin
199BOOST_AUTO_TEST_CASE(auth_data_rpid_hash_bad) try {
200 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
201 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
202
203 std::vector<uint8_t> auth_data(37);
204 fc::sha256 origin_hash_corrupt = fc::sha256::hash("fctesting.invalid"s);
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 });
212
213//signature if good but auth_data too short to store what needs to be stored
214BOOST_AUTO_TEST_CASE(auth_data_too_short) try {
215 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
216 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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 });
224
225//Good signature but missing origin completely
226BOOST_AUTO_TEST_CASE(missing_origin) try {
227 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
228 std::string json = "{\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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 });
237
238//Good signature but missing type completely
239BOOST_AUTO_TEST_CASE(missing_type) try {
240 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
241 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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 });
250
251//Good signature but missing challenge completely
252BOOST_AUTO_TEST_CASE(missing_challenge) try {
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
259 BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, json).recover(d, true), fc::exception, [](const fc::exception& e) {
260 return e.to_detail_string().find("sha256: size mismatch") != std::string::npos;
261 });
263
264//Good signature with some extra stuff sprinkled in the json
265BOOST_AUTO_TEST_CASE(good_extrajunk) try {
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]},"
268 "\"type\":\"webauthn.get\",\"answer\": 42 ,\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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));
275
276//Good signature but it's not a JSON object!
277BOOST_AUTO_TEST_CASE(not_json_object) try {
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 });
288
289//damage the r/s portion of the signature
290BOOST_AUTO_TEST_CASE(damage_sig) try {
291 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
292 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
293
294 std::vector<uint8_t> auth_data(37);
295 memcpy(auth_data.data(), origin_hash.data(), sizeof(origin_hash));
296
297 webauthn::signature sig = make_webauthn_sig(priv, auth_data, json);
298 char buff[8192];
299 datastream<char*> ds(buff, sizeof(buff));
300 fc::raw::pack(ds, sig);
301 buff[4]++;
302 ds.seekp(0);
303 fc::raw::unpack(ds, sig);
304
305 bool failed_recovery = false;
306 bool failed_compare = false;
307 webauthn::public_key recovered_pub;
308
309 try {
310 recovered_pub = sig.recover(d, true);
311 failed_compare = !(wa_pub == recovered_pub);
312 }
313 catch(fc::exception& e) {
314 failed_recovery = e.to_detail_string().find("unable to reconstruct public key from signature") != std::string::npos;
315 }
316
317 //We can fail either by failing to recover any key, or recovering the wrong key. Check that at least one of these failed
318 BOOST_CHECK_EQUAL(failed_recovery || failed_compare, true);
320
321//damage the recovery index portion of the sig
322BOOST_AUTO_TEST_CASE(damage_sig_idx) try {
323 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
324 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
325
326 std::vector<uint8_t> auth_data(37);
327 memcpy(auth_data.data(), origin_hash.data(), sizeof(origin_hash));
328
329 webauthn::signature sig = make_webauthn_sig(priv, auth_data, json);
330 char buff[8192];
331 datastream<char*> ds(buff, sizeof(buff));
332 fc::raw::pack(ds, sig);
333 buff[0]++;
334 ds.seekp(0);
335 fc::raw::unpack(ds, sig);
336
337 bool failed_recovery = false;
338 bool failed_compare = false;
339 webauthn::public_key recovered_pub;
340
341 try {
342 recovered_pub = sig.recover(d, true);
343 failed_compare = !(wa_pub == recovered_pub);
344 }
345 catch(fc::exception& e) {
346 failed_recovery = e.to_detail_string().find("unable to reconstruct public key from signature") != std::string::npos;
347 }
348
349 //We can fail either by failing to recover any key, or recovering the wrong key. Check that at least one of these failed
350 BOOST_CHECK_EQUAL(failed_recovery || failed_compare, true);
352
353//Good signature but with a different private key than was expecting
354BOOST_AUTO_TEST_CASE(different_priv_key) try {
356
357 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
358 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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));
365
366//Good signature but has empty json
367BOOST_AUTO_TEST_CASE(empty_json) try {
368 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
369 std::string json;
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 });
378
379//empty rpid not allowed for pub key
380BOOST_AUTO_TEST_CASE(empty_rpid) try {
381 char data[67] = {};
382 datastream<char*> ds(data, sizeof(data));
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 });
389
390//good sig but remove the trailing =, should still be accepted
391BOOST_AUTO_TEST_CASE(good_no_trailing_equal) try {
392 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
393
394 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "\"}";
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));
402
403//Before the base64 decoder was adjusted to throw in error (pre-webauthn-merge), it would simply stop when encountering
404//a non-base64 char. This means it was possible for the following JSON & challenge to validate completely correctly. Now it
405//should not pass.
406BOOST_AUTO_TEST_CASE(base64_wonky) try {
407 webauthn::public_key wa_pub(pub.serialize(), webauthn::public_key::user_presence_t::USER_PRESENCE_NONE, "fctesting.invalid");
408
409 std::string json = "{\"origin\":\"https://fctesting.invalid\",\"type\":\"webauthn.get\",\"challenge\":\"" + fc::base64url_encode(d.data(), d.data_size()) + "!@#$\"}";
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
415 BOOST_CHECK_EXCEPTION(make_webauthn_sig(priv, auth_data, json).recover(d, true), fc::exception, [](const fc::exception& e) {
416 return e.to_detail_string().find("encountered non-base64 character") != std::string::npos;
417 });
419
420BOOST_AUTO_TEST_SUITE_END()
an elliptic curve private key.
compact_signature sign_compact(const fc::sha256 &digest) const
static private_key generate()
contains only the public point of an elliptic curve key.
public_key recover(const sha256 &digest, bool check_canonical) const
Used to generate a useful error report when an exception is thrown.
Definition exception.hpp:58
std::string to_detail_string(log_level ll=log_level::all) const
void write(const char *d, uint32_t dlen)
Definition sha256.cpp:59
static sha256 hash(const char *d, uint32_t dlen)
Definition sha256.cpp:44
const char * data() const
Definition sha256.cpp:31
size_t data_size() const
Definition sha256.hpp:23
void unpack(Stream &s, std::deque< T > &value)
Definition raw.hpp:540
void pack(Stream &s, const std::deque< T > &value)
Definition raw.hpp:531
namespace sysio::chain
Definition authority.cpp:3
std::string base64url_encode(unsigned char const *bytes_to_encode, unsigned int in_len)
Definition base64.cpp:101
BOOST_AUTO_TEST_CASE(good)
FC_LOG_AND_RETHROW()
CK_RV ret
char * s
CK_BYTE_PTR pubkey
memcpy((char *) pInfo->slotDescription, s, l)