macaroons.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. /* Copyright (c) 2014-2016, Robert Escriva
  2. * All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * * Redistributions of source code must retain the above copyright notice,
  8. * this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of this project nor the names of its contributors may
  13. * be used to endorse or promote products derived from this software
  14. * without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  20. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  26. * POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. /* C */
  32. #include <assert.h>
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. /* macaroons */
  37. #include "macaroons.h"
  38. #include "constants.h"
  39. #include "macaroons.h"
  40. #include "macaroons-inner.h"
  41. #include "port.h"
  42. #include "slice.h"
  43. #include "v1.h"
  44. #include "v2.h"
  45. #if MACAROON_HASH_BYTES != MACAROON_SECRET_KEY_BYTES
  46. #error bad constants
  47. #endif
  48. #if MACAROON_HASH_BYTES != MACAROON_SUGGESTED_SECRET_LENGTH
  49. #error bad constants
  50. #endif
  51. #define XSTR(x) #x
  52. #define STR(x) XSTR(x)
  53. #define STRINGIFY(x) case (x): return XSTR(x);
  54. struct predicate
  55. {
  56. const unsigned char* data;
  57. size_t size;
  58. unsigned char* alloc;
  59. };
  60. struct verifier_callback
  61. {
  62. int (*func)(void* f, const unsigned char* pred, size_t pred_sz);
  63. void* ptr;
  64. };
  65. struct macaroon_verifier
  66. {
  67. struct predicate* predicates;
  68. size_t predicates_sz;
  69. size_t predicates_cap;
  70. struct verifier_callback* verifier_callbacks;
  71. size_t verifier_callbacks_sz;
  72. size_t verifier_callbacks_cap;
  73. };
  74. MACAROON_API const char*
  75. macaroon_error(enum macaroon_returncode err)
  76. {
  77. switch (err)
  78. {
  79. STRINGIFY(MACAROON_SUCCESS);
  80. STRINGIFY(MACAROON_OUT_OF_MEMORY);
  81. STRINGIFY(MACAROON_HASH_FAILED);
  82. STRINGIFY(MACAROON_INVALID);
  83. STRINGIFY(MACAROON_TOO_MANY_CAVEATS);
  84. STRINGIFY(MACAROON_CYCLE);
  85. STRINGIFY(MACAROON_BUF_TOO_SMALL);
  86. STRINGIFY(MACAROON_NOT_AUTHORIZED);
  87. STRINGIFY(MACAROON_NO_JSON_SUPPORT);
  88. STRINGIFY(MACAROON_UNSUPPORTED_FORMAT);
  89. default:
  90. return "unknown error";
  91. }
  92. }
  93. /* Allocate a new macaroon with space for "num_caveats" caveats and a body of
  94. * "body_data" bytes. Returns via _ptr a contiguous set of "body_data" bytes to
  95. * which the callee may write.
  96. */
  97. struct macaroon*
  98. macaroon_malloc(const size_t num_caveats,
  99. const size_t body_data,
  100. unsigned char** _ptr)
  101. {
  102. unsigned char* ptr = NULL;
  103. struct macaroon* M = NULL;
  104. const size_t additional_caveats = (num_caveats > 0) ? num_caveats - 1 : 0;
  105. const size_t sz = sizeof(struct macaroon) + body_data
  106. + additional_caveats * sizeof(struct caveat);
  107. M = malloc(sz);
  108. if (!M)
  109. {
  110. return NULL;
  111. }
  112. macaroon_memzero(M, sz);
  113. ptr = (unsigned char*) M;
  114. ptr += sizeof(struct macaroon);
  115. ptr += additional_caveats * sizeof(struct caveat);
  116. *_ptr = ptr;
  117. return M;
  118. }
  119. /* cumulative slice size, excluding the signature slice */
  120. size_t
  121. macaroon_body_size(const struct macaroon* M)
  122. {
  123. size_t i = 0;
  124. size_t sz = M->location.size
  125. + M->identifier.size;
  126. for (i = 0; i < M->num_caveats; ++i)
  127. {
  128. sz += M->caveats[i].cid.size;
  129. sz += M->caveats[i].vid.size;
  130. sz += M->caveats[i].cl.size;
  131. }
  132. return sz;
  133. }
  134. MACAROON_API struct macaroon*
  135. macaroon_create_raw(const unsigned char* location, size_t location_sz,
  136. const unsigned char* key, size_t key_sz,
  137. const unsigned char* id, size_t id_sz,
  138. enum macaroon_returncode* err)
  139. {
  140. unsigned char hash[MACAROON_HASH_BYTES];
  141. size_t sz;
  142. struct macaroon* M;
  143. unsigned char* ptr;
  144. assert(location_sz < MACAROON_MAX_STRLEN);
  145. assert(id_sz < MACAROON_MAX_STRLEN);
  146. assert(key_sz == MACAROON_SUGGESTED_SECRET_LENGTH);
  147. if (macaroon_hmac(key, key_sz, id, id_sz, hash) < 0)
  148. {
  149. *err = MACAROON_HASH_FAILED;
  150. return NULL;
  151. }
  152. sz = location_sz + id_sz + MACAROON_HASH_BYTES;
  153. M = macaroon_malloc(0, sz, &ptr);
  154. if (!M)
  155. {
  156. *err = MACAROON_OUT_OF_MEMORY;
  157. return NULL;
  158. }
  159. ptr = copy_to_slice(location, location_sz, &M->location, ptr);
  160. ptr = copy_to_slice(id, id_sz, &M->identifier, ptr);
  161. ptr = copy_to_slice(hash, MACAROON_HASH_BYTES, &M->signature, ptr);
  162. VALIDATE(M);
  163. return M;
  164. }
  165. #define MACAROON_KEY_GENERATOR "macaroons-key-generator"
  166. static int
  167. generate_derived_key(const unsigned char* variable_key,
  168. size_t variable_key_sz,
  169. unsigned char* derived_key)
  170. {
  171. unsigned char genkey[MACAROON_HASH_BYTES];
  172. macaroon_memzero(genkey, MACAROON_HASH_BYTES);
  173. assert(sizeof(MACAROON_KEY_GENERATOR) <= sizeof(genkey));
  174. memmove(genkey, MACAROON_KEY_GENERATOR, sizeof(MACAROON_KEY_GENERATOR));
  175. return macaroon_hmac(genkey, MACAROON_HASH_BYTES, variable_key, variable_key_sz, derived_key);
  176. }
  177. MACAROON_API struct macaroon*
  178. macaroon_create(const unsigned char* location, size_t location_sz,
  179. const unsigned char* key, size_t key_sz,
  180. const unsigned char* id, size_t id_sz,
  181. enum macaroon_returncode* err)
  182. {
  183. unsigned char derived_key[MACAROON_HASH_BYTES];
  184. if (generate_derived_key(key, key_sz, derived_key) < 0)
  185. {
  186. *err = MACAROON_HASH_FAILED;
  187. return NULL;
  188. }
  189. return macaroon_create_raw(location, location_sz, derived_key, MACAROON_HASH_BYTES, id, id_sz, err);
  190. }
  191. MACAROON_API void
  192. macaroon_destroy(struct macaroon* M)
  193. {
  194. if (M)
  195. {
  196. free(M);
  197. }
  198. }
  199. MACAROON_API int
  200. macaroon_validate(const struct macaroon* M)
  201. {
  202. /* XXX */
  203. (void) M;
  204. return 0;
  205. }
  206. static int
  207. macaroon_hash1(const unsigned char* key,
  208. const unsigned char* data1,
  209. size_t data1_sz,
  210. unsigned char* hash)
  211. {
  212. return macaroon_hmac(key, MACAROON_HASH_BYTES, data1, data1_sz, hash);
  213. }
  214. MACAROON_API struct macaroon*
  215. macaroon_add_first_party_caveat(const struct macaroon* N,
  216. const unsigned char* predicate, size_t predicate_sz,
  217. enum macaroon_returncode* err)
  218. {
  219. unsigned char hash[MACAROON_HASH_BYTES];
  220. size_t i;
  221. size_t sz;
  222. struct macaroon* M;
  223. unsigned char* ptr;
  224. assert(predicate_sz < MACAROON_MAX_STRLEN);
  225. if (N->num_caveats + 1 > MACAROON_MAX_CAVEATS)
  226. {
  227. *err = MACAROON_TOO_MANY_CAVEATS;
  228. return NULL;
  229. }
  230. if (!N->signature.data || N->signature.size != MACAROON_HASH_BYTES)
  231. {
  232. *err = MACAROON_INVALID;
  233. return NULL;
  234. }
  235. if (macaroon_hash1(N->signature.data, predicate, predicate_sz, hash) < 0)
  236. {
  237. *err = MACAROON_HASH_FAILED;
  238. return NULL;
  239. }
  240. sz = macaroon_body_size(N) + predicate_sz + MACAROON_HASH_BYTES;
  241. M = macaroon_malloc(N->num_caveats + 1, sz, &ptr);
  242. if (!M)
  243. {
  244. *err = MACAROON_OUT_OF_MEMORY;
  245. return NULL;
  246. }
  247. M->num_caveats = N->num_caveats + 1;
  248. ptr = copy_slice(&N->location, &M->location, ptr);
  249. ptr = copy_slice(&N->identifier, &M->identifier, ptr);
  250. for (i = 0; i < N->num_caveats; ++i)
  251. {
  252. ptr = copy_slice(&N->caveats[i].cid, &M->caveats[i].cid, ptr);
  253. ptr = copy_slice(&N->caveats[i].vid, &M->caveats[i].vid, ptr);
  254. ptr = copy_slice(&N->caveats[i].cl, &M->caveats[i].cl, ptr);
  255. }
  256. ptr = copy_to_slice(predicate, predicate_sz,
  257. &M->caveats[M->num_caveats - 1].cid, ptr);
  258. ptr = copy_to_slice(hash, MACAROON_HASH_BYTES, &M->signature, ptr);
  259. VALIDATE(M);
  260. return M;
  261. }
  262. static int
  263. macaroon_hash2(const unsigned char* key,
  264. const unsigned char* data1,
  265. size_t data1_sz,
  266. const unsigned char* data2,
  267. size_t data2_sz,
  268. unsigned char* hash)
  269. {
  270. int rc = 0;
  271. unsigned char tmp[2 * MACAROON_HASH_BYTES];
  272. rc |= macaroon_hmac(key, MACAROON_HASH_BYTES, data1, data1_sz, tmp);
  273. rc |= macaroon_hmac(key, MACAROON_HASH_BYTES, data2, data2_sz, tmp + MACAROON_HASH_BYTES);
  274. rc |= macaroon_hmac(key, MACAROON_HASH_BYTES, tmp, 2 * MACAROON_HASH_BYTES, hash);
  275. return rc;
  276. }
  277. #define SECRET_BOX_OVERHEAD \
  278. (MACAROON_SECRET_TEXT_ZERO_BYTES \
  279. - MACAROON_SECRET_BOX_ZERO_BYTES)
  280. #define VID_NONCE_KEY_SZ \
  281. (MACAROON_SECRET_NONCE_BYTES \
  282. + MACAROON_HASH_BYTES \
  283. + SECRET_BOX_OVERHEAD)
  284. #if MACAROON_SECRET_TEXT_ZERO_BYTES < MACAROON_SECRET_BOX_ZERO_BYTES
  285. #error bad constants
  286. #endif
  287. MACAROON_API struct macaroon*
  288. macaroon_add_third_party_caveat_raw(const struct macaroon* N,
  289. const unsigned char* location, size_t location_sz,
  290. const unsigned char* key, size_t key_sz,
  291. const unsigned char* id, size_t id_sz,
  292. enum macaroon_returncode* err)
  293. {
  294. unsigned char new_sig[MACAROON_HASH_BYTES];
  295. unsigned char enc_nonce[MACAROON_SECRET_NONCE_BYTES];
  296. unsigned char enc_plaintext[MACAROON_SECRET_TEXT_ZERO_BYTES + MACAROON_HASH_BYTES];
  297. unsigned char enc_ciphertext[MACAROON_SECRET_BOX_ZERO_BYTES + MACAROON_HASH_BYTES];
  298. unsigned char vid[VID_NONCE_KEY_SZ];
  299. size_t i;
  300. size_t sz;
  301. struct macaroon* M;
  302. unsigned char* ptr;
  303. assert(location_sz < MACAROON_MAX_STRLEN);
  304. assert(id_sz < MACAROON_MAX_STRLEN);
  305. assert(key_sz == MACAROON_SUGGESTED_SECRET_LENGTH);
  306. VALIDATE(N);
  307. if (N->num_caveats + 1 > MACAROON_MAX_CAVEATS)
  308. {
  309. *err = MACAROON_TOO_MANY_CAVEATS;
  310. return NULL;
  311. }
  312. /*
  313. * note that MACAROON_HASH_BYTES is necessarily the same as
  314. * MACAROON_SECRET_KEY_BYTES, so the signature is also good to use
  315. * as an encoding key
  316. */
  317. if (!N->signature.data || N->signature.size != MACAROON_HASH_BYTES)
  318. {
  319. *err = MACAROON_INVALID;
  320. return NULL;
  321. }
  322. macaroon_randombytes(enc_nonce, sizeof(enc_nonce));
  323. macaroon_memzero(enc_plaintext, sizeof(enc_plaintext));
  324. macaroon_memzero(enc_ciphertext, sizeof(enc_ciphertext));
  325. /* now encrypt the key to give us vid */
  326. memmove(enc_plaintext + MACAROON_SECRET_TEXT_ZERO_BYTES, key,
  327. key_sz < MACAROON_HASH_BYTES ? key_sz : MACAROON_HASH_BYTES);
  328. if (macaroon_secretbox(N->signature.data, enc_nonce, enc_plaintext,
  329. MACAROON_SECRET_TEXT_ZERO_BYTES + MACAROON_HASH_BYTES,
  330. enc_ciphertext) < 0)
  331. {
  332. *err = MACAROON_HASH_FAILED;
  333. return NULL;
  334. }
  335. /* copy the (nonce, vid) pair into vid */
  336. memmove(vid, enc_nonce, MACAROON_SECRET_NONCE_BYTES);
  337. memmove(vid + MACAROON_SECRET_NONCE_BYTES,
  338. enc_ciphertext + MACAROON_SECRET_BOX_ZERO_BYTES,
  339. VID_NONCE_KEY_SZ - MACAROON_SECRET_NONCE_BYTES);
  340. /* calculate the new signature */
  341. if (macaroon_hash2(N->signature.data, vid, VID_NONCE_KEY_SZ, id, id_sz, new_sig) < 0)
  342. {
  343. *err = MACAROON_HASH_FAILED;
  344. return NULL;
  345. }
  346. sz = macaroon_body_size(N)
  347. + id_sz
  348. + VID_NONCE_KEY_SZ
  349. + location_sz
  350. + MACAROON_HASH_BYTES;
  351. M = macaroon_malloc(N->num_caveats + 1, sz, &ptr);
  352. if (!M)
  353. {
  354. *err = MACAROON_OUT_OF_MEMORY;
  355. return NULL;
  356. }
  357. M->num_caveats = N->num_caveats + 1;
  358. ptr = copy_slice(&N->location, &M->location, ptr);
  359. ptr = copy_slice(&N->identifier, &M->identifier, ptr);
  360. for (i = 0; i < N->num_caveats; ++i)
  361. {
  362. ptr = copy_slice(&N->caveats[i].cid, &M->caveats[i].cid, ptr);
  363. ptr = copy_slice(&N->caveats[i].vid, &M->caveats[i].vid, ptr);
  364. ptr = copy_slice(&N->caveats[i].cl, &M->caveats[i].cl, ptr);
  365. }
  366. ptr = copy_to_slice(id, id_sz, &M->caveats[M->num_caveats - 1].cid, ptr);
  367. ptr = copy_to_slice(vid, VID_NONCE_KEY_SZ, &M->caveats[M->num_caveats - 1].vid, ptr);
  368. ptr = copy_to_slice(location, location_sz, &M->caveats[M->num_caveats - 1].cl, ptr);
  369. ptr = copy_to_slice(new_sig, MACAROON_HASH_BYTES, &M->signature, ptr);
  370. VALIDATE(M);
  371. return M;
  372. }
  373. MACAROON_API struct macaroon*
  374. macaroon_add_third_party_caveat(const struct macaroon* N,
  375. const unsigned char* location, size_t location_sz,
  376. const unsigned char* key, size_t key_sz,
  377. const unsigned char* id, size_t id_sz,
  378. enum macaroon_returncode* err)
  379. {
  380. unsigned char derived_key[MACAROON_HASH_BYTES];
  381. if (generate_derived_key(key, key_sz, derived_key) < 0)
  382. {
  383. *err = MACAROON_HASH_FAILED;
  384. return NULL;
  385. }
  386. return macaroon_add_third_party_caveat_raw(N, location, location_sz, derived_key, MACAROON_HASH_BYTES, id, id_sz, err);
  387. }
  388. static int
  389. macaroon_bind(const unsigned char* Msig,
  390. const unsigned char* MPsig,
  391. unsigned char* bound)
  392. {
  393. unsigned char key[MACAROON_HASH_BYTES];
  394. macaroon_memzero(key, MACAROON_HASH_BYTES);
  395. return macaroon_hash2(key, Msig, MACAROON_HASH_BYTES,
  396. MPsig, MACAROON_HASH_BYTES, bound);
  397. }
  398. MACAROON_API unsigned
  399. macaroon_num_third_party_caveats(const struct macaroon* M)
  400. {
  401. size_t idx = 0;
  402. unsigned count = 0;
  403. VALIDATE(M);
  404. for (idx = 0; idx < M->num_caveats; ++idx)
  405. {
  406. if (M->caveats[idx].vid.size > 0 && M->caveats[idx].cl.size > 0)
  407. {
  408. ++count;
  409. }
  410. }
  411. return count;
  412. }
  413. MACAROON_API int
  414. macaroon_third_party_caveat(const struct macaroon* M, unsigned which,
  415. const unsigned char** location, size_t* location_sz,
  416. const unsigned char** identifier, size_t* identifier_sz)
  417. {
  418. size_t idx = 0;
  419. unsigned count = 0;
  420. VALIDATE(M);
  421. for (idx = 0; idx < M->num_caveats; ++idx)
  422. {
  423. if (M->caveats[idx].vid.size > 0 && M->caveats[idx].cl.size > 0)
  424. {
  425. if (count == which)
  426. {
  427. unstruct_slice(&M->caveats[idx].cid, identifier, identifier_sz);
  428. unstruct_slice(&M->caveats[idx].cl, location, location_sz);
  429. return 0;
  430. }
  431. ++count;
  432. }
  433. }
  434. return -1;
  435. }
  436. #pragma GCC diagnostic push
  437. #pragma GCC diagnostic ignored "-Wcast-qual"
  438. MACAROON_API struct macaroon*
  439. macaroon_prepare_for_request(const struct macaroon* M,
  440. const struct macaroon* D,
  441. enum macaroon_returncode* err)
  442. {
  443. struct macaroon* B;
  444. unsigned char hash[MACAROON_HASH_BYTES];
  445. VALIDATE(M);
  446. VALIDATE(D);
  447. if (!M->signature.data || M->signature.size != MACAROON_HASH_BYTES ||
  448. !D->signature.data || D->signature.size != MACAROON_HASH_BYTES)
  449. {
  450. *err = MACAROON_INVALID;
  451. return NULL;
  452. }
  453. if (macaroon_bind(M->signature.data, D->signature.data, hash) < 0)
  454. {
  455. *err = MACAROON_HASH_FAILED;
  456. return NULL;
  457. }
  458. B = macaroon_copy(D, err);
  459. if (!B)
  460. {
  461. return NULL;
  462. }
  463. memmove((unsigned char*)B->signature.data, hash, MACAROON_HASH_BYTES);
  464. VALIDATE(B);
  465. return B;
  466. }
  467. #pragma GCC diagnostic pop
  468. MACAROON_API struct macaroon_verifier*
  469. macaroon_verifier_create()
  470. {
  471. struct macaroon_verifier* V;
  472. V = malloc(sizeof(struct macaroon_verifier));
  473. if (!V)
  474. {
  475. return NULL;
  476. }
  477. memset(V, 0, sizeof(struct macaroon_verifier));
  478. V->predicates = NULL;
  479. V->predicates_sz = 0;
  480. V->predicates_cap = 0;
  481. return V;
  482. }
  483. MACAROON_API void
  484. macaroon_verifier_destroy(struct macaroon_verifier* V)
  485. {
  486. size_t idx = 0;
  487. if (V)
  488. {
  489. for (idx = 0; idx < V->predicates_sz; ++idx)
  490. {
  491. if (V->predicates[idx].alloc)
  492. {
  493. free(V->predicates[idx].alloc);
  494. }
  495. }
  496. if (V->predicates)
  497. {
  498. free(V->predicates);
  499. }
  500. if (V->verifier_callbacks)
  501. {
  502. free(V->verifier_callbacks);
  503. }
  504. free(V);
  505. }
  506. }
  507. MACAROON_API int
  508. macaroon_verifier_satisfy_exact(struct macaroon_verifier* V,
  509. const unsigned char* predicate, size_t predicate_sz,
  510. enum macaroon_returncode* err)
  511. {
  512. struct predicate* tmp = NULL;
  513. if (V->predicates_sz == V->predicates_cap)
  514. {
  515. V->predicates_cap = V->predicates_cap < 8 ? 8 :
  516. V->predicates_cap + (V->predicates_cap >> 1);
  517. tmp = realloc(V->predicates, V->predicates_cap * sizeof(struct predicate));
  518. if (!tmp)
  519. {
  520. *err = MACAROON_OUT_OF_MEMORY;
  521. return -1;
  522. }
  523. V->predicates = tmp;
  524. }
  525. assert(V->predicates_sz < V->predicates_cap);
  526. tmp = &V->predicates[V->predicates_sz];
  527. tmp->data = tmp->alloc = malloc(sizeof(unsigned char) * predicate_sz);
  528. tmp->size = predicate_sz;
  529. if (!tmp->data)
  530. {
  531. *err = MACAROON_OUT_OF_MEMORY;
  532. return -1;
  533. }
  534. memmove(tmp->alloc, predicate, predicate_sz);
  535. ++V->predicates_sz;
  536. assert(V->predicates_sz <= V->predicates_cap);
  537. return 0;
  538. }
  539. MACAROON_API int
  540. macaroon_verifier_satisfy_general(struct macaroon_verifier* V,
  541. int (*general_check)(void* f, const unsigned char* pred, size_t pred_sz),
  542. void* f, enum macaroon_returncode* err)
  543. {
  544. struct verifier_callback* tmp = NULL;
  545. if (V->verifier_callbacks_sz == V->verifier_callbacks_cap)
  546. {
  547. V->verifier_callbacks_cap = V->verifier_callbacks_cap < 8 ? 8 :
  548. V->verifier_callbacks_cap +
  549. (V->verifier_callbacks_cap >> 1);
  550. tmp = realloc(V->verifier_callbacks,
  551. V->verifier_callbacks_cap * sizeof(struct verifier_callback));
  552. if (!tmp)
  553. {
  554. *err = MACAROON_OUT_OF_MEMORY;
  555. return -1;
  556. }
  557. V->verifier_callbacks = tmp;
  558. }
  559. assert(V->verifier_callbacks_sz < V->verifier_callbacks_cap);
  560. tmp = &V->verifier_callbacks[V->verifier_callbacks_sz];
  561. tmp->func = general_check;
  562. tmp->ptr = f;
  563. ++V->verifier_callbacks_sz;
  564. assert(V->verifier_callbacks_sz <= V->verifier_callbacks_cap);
  565. return 0;
  566. }
  567. static int
  568. macaroon_verify_inner(const struct macaroon_verifier* V,
  569. const struct macaroon* M,
  570. const struct macaroon* TM,
  571. const unsigned char* key, size_t key_sz,
  572. struct macaroon** MS, size_t MS_sz,
  573. enum macaroon_returncode* err,
  574. size_t* tree, size_t tree_idx);
  575. static int
  576. macaroon_verify_inner_1st(const struct macaroon_verifier* V,
  577. const struct caveat* C)
  578. {
  579. int fail = 0;
  580. int found = 0;
  581. size_t sz = 0;
  582. size_t idx = 0;
  583. struct predicate pred;
  584. struct predicate* poss;
  585. struct verifier_callback* vcb;
  586. pred.data = NULL;
  587. pred.size = 0;
  588. unstruct_slice(&C->cid, &pred.data, &pred.size);
  589. for (idx = 0; idx < V->predicates_sz; ++idx)
  590. {
  591. poss = &V->predicates[idx];
  592. sz = pred.size < poss->size ? pred.size : poss->size;
  593. found |= macaroon_memcmp(pred.data, poss->data, sz) == 0 &&
  594. pred.size == poss->size;
  595. }
  596. for (idx = 0; idx < V->verifier_callbacks_sz; ++idx)
  597. {
  598. vcb = &V->verifier_callbacks[idx];
  599. found |= vcb->func(vcb->ptr, pred.data, pred.size) == 0;
  600. }
  601. return (!fail && found) ? 0 : -1;
  602. }
  603. static int
  604. macaroon_verify_inner_3rd(const struct macaroon_verifier* V,
  605. const struct caveat* C,
  606. const unsigned char* sig,
  607. const struct macaroon* TM,
  608. struct macaroon** MS, size_t MS_sz,
  609. enum macaroon_returncode* err,
  610. size_t* tree, size_t tree_idx)
  611. {
  612. unsigned char enc_key[MACAROON_SECRET_KEY_BYTES];
  613. const unsigned char *enc_nonce;
  614. unsigned char enc_plaintext[MACAROON_SECRET_TEXT_ZERO_BYTES + MACAROON_HASH_BYTES];
  615. unsigned char enc_ciphertext[MACAROON_SECRET_BOX_ZERO_BYTES + MACAROON_HASH_BYTES + SECRET_BOX_OVERHEAD];
  616. unsigned char vid_data[VID_NONCE_KEY_SZ];
  617. int fail = 0;
  618. size_t midx = 0;
  619. size_t tidx = 0;
  620. struct predicate cav;
  621. struct predicate vid;
  622. struct predicate mac;
  623. size_t sz;
  624. cav.data = NULL;
  625. cav.size = 0;
  626. unstruct_slice(&C->cid, &cav.data, &cav.size);
  627. tree[tree_idx] = MS_sz;
  628. for (midx = 0; midx < MS_sz; ++midx)
  629. {
  630. mac.data = NULL;
  631. mac.size = 0;
  632. unstruct_slice(&MS[midx]->identifier, &mac.data, &mac.size);
  633. sz = cav.size < mac.size ? cav.size : mac.size;
  634. if (macaroon_memcmp(cav.data, mac.data, sz) == 0 && cav.size == mac.size)
  635. {
  636. tree[tree_idx] = midx;
  637. }
  638. for (tidx = 0; tidx < tree_idx; ++tidx)
  639. {
  640. fail |= tree[tidx] == tree[tree_idx];
  641. }
  642. }
  643. if (tree[tree_idx] < MS_sz)
  644. {
  645. /* zero everything */
  646. macaroon_memzero(enc_key, sizeof(enc_key));
  647. macaroon_memzero(enc_plaintext, sizeof(enc_plaintext));
  648. macaroon_memzero(enc_ciphertext, sizeof(enc_ciphertext));
  649. vid.data = vid_data;
  650. vid.size = sizeof(vid_data);
  651. unstruct_slice(&C->vid, &vid.data, &vid.size);
  652. assert(vid.size == VID_NONCE_KEY_SZ);
  653. /*
  654. * the nonce is in the first MACAROON_SECRET_NONCE_BYTES
  655. * of the vid; the ciphertext is in the rest of it.
  656. */
  657. enc_nonce = vid.data;
  658. /* fill in the ciphertext */
  659. memmove(enc_ciphertext + MACAROON_SECRET_BOX_ZERO_BYTES,
  660. vid.data + MACAROON_SECRET_NONCE_BYTES,
  661. vid.size - MACAROON_SECRET_NONCE_BYTES);
  662. /* now get the plaintext */
  663. fail |= macaroon_secretbox_open(sig, enc_nonce, enc_ciphertext,
  664. sizeof(enc_ciphertext),
  665. enc_plaintext);
  666. fail |= macaroon_verify_inner(V, MS[tree[tree_idx]], TM,
  667. enc_plaintext + MACAROON_SECRET_TEXT_ZERO_BYTES,
  668. MACAROON_HASH_BYTES,
  669. MS, MS_sz, err, tree, tree_idx + 1);
  670. }
  671. else
  672. {
  673. fail = -1;
  674. }
  675. return fail;
  676. }
  677. int
  678. macaroon_verify_inner(const struct macaroon_verifier* V,
  679. const struct macaroon* M,
  680. const struct macaroon* TM,
  681. const unsigned char* key, size_t key_sz,
  682. struct macaroon** MS, size_t MS_sz,
  683. enum macaroon_returncode* err,
  684. size_t* tree, size_t tree_idx)
  685. {
  686. size_t cidx = 0;
  687. int tree_fail = 0;
  688. const unsigned char* data = NULL;
  689. size_t data_sz = 0;
  690. const unsigned char* vdata = NULL;
  691. size_t vdata_sz = 0;
  692. unsigned char tmp[MACAROON_HASH_BYTES];
  693. unsigned char csig[MACAROON_HASH_BYTES];
  694. assert(M);
  695. assert(TM);
  696. if (macaroon_validate(M) < 0)
  697. {
  698. *err = MACAROON_INVALID;
  699. return -1;
  700. }
  701. if (tree_idx > MS_sz)
  702. {
  703. *err = MACAROON_CYCLE;
  704. return -1;
  705. }
  706. tree_fail = 0;
  707. tree_fail |= macaroon_hmac(key, key_sz, M->identifier.data, M->identifier.size, csig);
  708. for (cidx = 0; cidx < M->num_caveats; ++cidx)
  709. {
  710. if (M->caveats[cidx].vid.size == 0)
  711. {
  712. tree_fail |= macaroon_verify_inner_1st(V, M->caveats + cidx);
  713. /* move the signature and compute a new one */
  714. memmove(tmp, csig, MACAROON_HASH_BYTES);
  715. data = NULL;
  716. data_sz = 0;
  717. unstruct_slice(&M->caveats[cidx].cid, &data, &data_sz);
  718. tree_fail |= macaroon_hash1(tmp, data, data_sz, csig);
  719. }
  720. else
  721. {
  722. tree_fail |= macaroon_verify_inner_3rd(V, M->caveats + cidx, csig, TM, MS, MS_sz, err, tree, tree_idx);
  723. /* move the signature and compute a new one */
  724. memmove(tmp, csig, MACAROON_HASH_BYTES);
  725. data = NULL;
  726. data_sz = 0;
  727. unstruct_slice(&M->caveats[cidx].cid, &data, &data_sz);
  728. vdata = NULL;
  729. vdata_sz = 0;
  730. unstruct_slice(&M->caveats[cidx].vid, &vdata, &vdata_sz);
  731. tree_fail |= macaroon_hash2(tmp, vdata, vdata_sz, data, data_sz, csig);
  732. }
  733. }
  734. if (tree_idx > 0)
  735. {
  736. memmove(tmp, csig, MACAROON_HASH_BYTES);
  737. data = TM->signature.data;
  738. tree_fail |= TM->signature.size ^ MACAROON_HASH_BYTES;
  739. tree_fail |= macaroon_bind(data, tmp, csig);
  740. }
  741. data = M->signature.data;
  742. tree_fail |= M->signature.size ^ MACAROON_HASH_BYTES;
  743. tree_fail |= macaroon_memcmp(data, csig, MACAROON_HASH_BYTES);
  744. return tree_fail;
  745. }
  746. MACAROON_API int
  747. macaroon_verify_raw(const struct macaroon_verifier* V,
  748. const struct macaroon* M,
  749. const unsigned char* key, size_t key_sz,
  750. struct macaroon** MS, size_t MS_sz,
  751. enum macaroon_returncode* err)
  752. {
  753. int rc = 0;
  754. size_t i = 0;
  755. size_t* tree = malloc((MS_sz + 1) * sizeof(size_t));
  756. if (!tree)
  757. {
  758. *err = MACAROON_OUT_OF_MEMORY;
  759. return -1;
  760. }
  761. for (i = 0; i < MS_sz; ++i)
  762. {
  763. tree[i] = MS_sz;
  764. }
  765. tree[MS_sz] = MS_sz;
  766. assert(key_sz == MACAROON_SUGGESTED_SECRET_LENGTH);
  767. rc = macaroon_verify_inner(V, M, M, key, key_sz,
  768. MS, MS_sz, err, tree, 0);
  769. if (rc)
  770. {
  771. *err = MACAROON_NOT_AUTHORIZED;
  772. }
  773. free(tree);
  774. return rc;
  775. }
  776. MACAROON_API int
  777. macaroon_verify(const struct macaroon_verifier* V,
  778. const struct macaroon* M,
  779. const unsigned char* key, size_t key_sz,
  780. struct macaroon** MS, size_t MS_sz,
  781. enum macaroon_returncode* err)
  782. {
  783. unsigned char derived_key[MACAROON_HASH_BYTES];
  784. if (generate_derived_key(key, key_sz, derived_key) < 0)
  785. {
  786. *err = MACAROON_HASH_FAILED;
  787. return -1;
  788. }
  789. return macaroon_verify_raw(V, M, derived_key, MACAROON_HASH_BYTES, MS, MS_sz, err);
  790. }
  791. MACAROON_API void
  792. macaroon_location(const struct macaroon* M,
  793. const unsigned char** location, size_t* location_sz)
  794. {
  795. assert(M);
  796. VALIDATE(M);
  797. unstruct_slice(&M->location, location, location_sz);
  798. }
  799. MACAROON_API void
  800. macaroon_identifier(const struct macaroon* M,
  801. const unsigned char** identifier, size_t* identifier_sz)
  802. {
  803. assert(M);
  804. VALIDATE(M);
  805. unstruct_slice(&M->identifier, identifier, identifier_sz);
  806. }
  807. MACAROON_API void
  808. macaroon_signature(const struct macaroon* M,
  809. const unsigned char** signature, size_t* signature_sz)
  810. {
  811. assert(M);
  812. VALIDATE(M);
  813. unstruct_slice(&M->signature, signature, signature_sz);
  814. }
  815. MACAROON_API size_t
  816. macaroon_serialize_size_hint(const struct macaroon* M,
  817. enum macaroon_format f)
  818. {
  819. switch (f)
  820. {
  821. case MACAROON_V1:
  822. return macaroon_serialize_size_hint_v1(M);
  823. case MACAROON_V2:
  824. return macaroon_serialize_size_hint_v2(M);
  825. case MACAROON_V2J:
  826. #ifdef MACAROONS_JSON
  827. return macaroon_serialize_size_hint_v2j(M);
  828. #endif
  829. default:
  830. return 0;
  831. }
  832. }
  833. MACAROON_API size_t
  834. macaroon_serialize(const struct macaroon* M,
  835. enum macaroon_format f,
  836. unsigned char* buf, size_t buf_sz,
  837. enum macaroon_returncode* err)
  838. {
  839. switch (f)
  840. {
  841. case MACAROON_V1:
  842. if (macaroon_serialize_v1(M, (char*)buf, buf_sz, err) < 0) return 0;
  843. return strlen((char*)buf);
  844. case MACAROON_V2:
  845. return macaroon_serialize_v2(M, buf, buf_sz, err);
  846. case MACAROON_V2J:
  847. #ifdef MACAROONS_JSON
  848. return macaroon_serialize_v2j(M, buf, buf_sz, err);
  849. #else
  850. *err = MACAROON_NO_JSON_SUPPORT;
  851. return 0;
  852. #endif
  853. default:
  854. *err = MACAROON_INVALID;
  855. return 0;
  856. }
  857. }
  858. static const char v1_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/-_";
  859. MACAROON_API struct macaroon*
  860. macaroon_deserialize(const unsigned char* data, size_t data_sz,
  861. enum macaroon_returncode* err)
  862. {
  863. if (data_sz == 0)
  864. {
  865. *err = MACAROON_INVALID;
  866. return NULL;
  867. }
  868. if (strchr(v1_chars, data[0]))
  869. {
  870. return macaroon_deserialize_v1((const char*)data, data_sz, err);
  871. }
  872. if (data[0] == '{')
  873. {
  874. #ifdef MACAROONS_JSON
  875. return macaroon_deserialize_v2j(data, data_sz, err);
  876. #else
  877. *err = MACAROON_NO_JSON_SUPPORT;
  878. return 0;
  879. #endif
  880. }
  881. else if (data[0] == '\x02')
  882. {
  883. return macaroon_deserialize_v2(data, data_sz, err);
  884. }
  885. else
  886. {
  887. *err = MACAROON_INVALID;
  888. return NULL;
  889. }
  890. }
  891. MACAROON_API size_t
  892. macaroon_inspect_size_hint(const struct macaroon* M)
  893. {
  894. return macaroon_inspect_size_hint_v1(M);
  895. }
  896. MACAROON_API int
  897. macaroon_inspect(const struct macaroon* M,
  898. char* data, size_t data_sz,
  899. enum macaroon_returncode* err)
  900. {
  901. return macaroon_inspect_v1(M, data, data_sz, err);
  902. }
  903. MACAROON_API struct macaroon*
  904. macaroon_copy(const struct macaroon* N,
  905. enum macaroon_returncode* err)
  906. {
  907. size_t i;
  908. size_t sz;
  909. struct macaroon* M;
  910. unsigned char* ptr;
  911. assert(N);
  912. VALIDATE(N);
  913. sz = macaroon_body_size(N) + MACAROON_HASH_BYTES;
  914. M = macaroon_malloc(N->num_caveats, sz, &ptr);
  915. if (!M)
  916. {
  917. *err = MACAROON_OUT_OF_MEMORY;
  918. return NULL;
  919. }
  920. M->num_caveats = N->num_caveats;
  921. ptr = copy_slice(&N->location, &M->location, ptr);
  922. ptr = copy_slice(&N->identifier, &M->identifier, ptr);
  923. for (i = 0; i < N->num_caveats; ++i)
  924. {
  925. ptr = copy_slice(&N->caveats[i].cid, &M->caveats[i].cid, ptr);
  926. ptr = copy_slice(&N->caveats[i].vid, &M->caveats[i].vid, ptr);
  927. ptr = copy_slice(&N->caveats[i].cl, &M->caveats[i].cl, ptr);
  928. }
  929. ptr = copy_slice(&N->signature, &M->signature, ptr);
  930. VALIDATE(M);
  931. return M;
  932. }
  933. MACAROON_API int
  934. macaroon_cmp(const struct macaroon* M, const struct macaroon* N)
  935. {
  936. size_t i = 0;
  937. size_t num_caveats = 0;
  938. unsigned long long ret = 0;
  939. assert(M);
  940. assert(N);
  941. VALIDATE(M);
  942. VALIDATE(N);
  943. ret |= M->num_caveats ^ N->num_caveats;
  944. ret |= slice_cmp(&M->location, &N->location);
  945. ret |= slice_cmp(&M->identifier, &N->identifier);
  946. ret |= slice_cmp(&M->signature, &N->signature);
  947. num_caveats = M->num_caveats < N->num_caveats ?
  948. M->num_caveats : N->num_caveats;
  949. for (i = 0; i < num_caveats; ++i)
  950. {
  951. ret |= slice_cmp(&M->caveats[i].cid,
  952. &N->caveats[i].cid);
  953. ret |= slice_cmp(&M->caveats[i].vid,
  954. &N->caveats[i].vid);
  955. ret |= slice_cmp(&M->caveats[i].cl,
  956. &N->caveats[i].cl);
  957. }
  958. return ret;
  959. }