123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- /*
- * macaroon.cpp
- *
- * Created on: Mar 19, 2017
- * Author: hp
- */
- #include "macaroon.h"
- #include <iostream>
- #include <string.h>
- #include <sodium/randombytes.h>
- #include <sodium/crypto_box.h>
- namespace c_macaroons {
- #include "macaroons.h"
- }
- namespace macaroons {
- macaroon::macaroon() {
- m = nullptr;
- }
- macaroon::macaroon(const macaroon& rhs) {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- m = c_macaroons::macaroon_copy(rhs.m, &err);
- //TODO error handling
- }
- macaroon::macaroon(std::string location, std::string key, std::string id) {
- create(reinterpret_cast<const unsigned char*>(location.c_str()),
- location.size(),
- reinterpret_cast<const unsigned char*>(key.c_str()), key.size(),
- reinterpret_cast<const unsigned char*>(id.c_str()), id.size());
- }
- macaroon::macaroon(const char* location, size_t location_sz, const char* key,
- size_t key_sz, const char* id, size_t id_sz) {
- create(reinterpret_cast<const unsigned char*>(location), location_sz,
- reinterpret_cast<const unsigned char*>(key), key_sz,
- reinterpret_cast<const unsigned char*>(id), id_sz);
- }
- macaroon::macaroon(const unsigned char* location, size_t location_sz,
- const unsigned char* key, size_t key_sz, const unsigned char* id,
- size_t id_sz) {
- create(location, location_sz, key, key_sz, id, id_sz);
- }
- macaroon::macaroon(std::string data) {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- m = c_macaroons::macaroon_deserialize((const unsigned char*) data.data(),
- data.size(), &err);
- if (err != c_macaroons::MACAROON_SUCCESS) {
- std::cerr << macaroon_error(err) << std::endl;
- }
- // TODO error handling
- }
- void macaroon::add_first_party_caveat(std::string predicate) {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- c_macaroons::macaroon *n;
- n = c_macaroons::macaroon_add_first_party_caveat(m,
- reinterpret_cast<const unsigned char*>(predicate.c_str()),
- predicate.size(), &err);
- if (err != c_macaroons::MACAROON_SUCCESS) {
- std::cerr << macaroon_error(err) << std::endl;
- }
- c_macaroons::macaroon_destroy(m);
- m = n;
- // TODO error handling
- }
- void macaroon::add_first_party_caveat(const char* predicate,
- size_t predicate_sz) {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- c_macaroons::macaroon *n;
- n = c_macaroons::macaroon_add_first_party_caveat(m,
- reinterpret_cast<const unsigned char*>(predicate), predicate_sz,
- &err);
- if (err != c_macaroons::MACAROON_SUCCESS) {
- std::cerr << macaroon_error(err) << std::endl;
- }
- c_macaroons::macaroon_destroy(m);
- m = n;
- // TODO error handling
- }
- void macaroon::add_third_party_caveat(std::string location, std::string key,
- std::string id) {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- c_macaroons::macaroon *n;
- n = c_macaroons::macaroon_add_third_party_caveat(m,
- reinterpret_cast<const unsigned char*>(location.c_str()),
- location.size(),
- reinterpret_cast<const unsigned char*>(key.c_str()), key.size(),
- reinterpret_cast<const unsigned char*>(id.c_str()), id.size(),
- &err);
- if (err != c_macaroons::MACAROON_SUCCESS) {
- std::cerr << macaroon_error(err) << std::endl;
- }
- c_macaroons::macaroon_destroy(m);
- m = n;
- // TODO error handling
- }
- void macaroon::add_third_party_caveat(const char* location, size_t location_sz,
- const char *key, size_t key_sz, const char* id, size_t id_sz) {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- c_macaroons::macaroon *n;
- n = c_macaroons::macaroon_add_third_party_caveat(m,
- reinterpret_cast<const unsigned char*>(location), location_sz,
- reinterpret_cast<const unsigned char*>(key), key_sz,
- reinterpret_cast<const unsigned char*>(id), id_sz, &err);
- if (err != c_macaroons::MACAROON_SUCCESS) {
- std::cerr << macaroon_error(err) << std::endl;
- }
- c_macaroons::macaroon_destroy(m);
- m = n;
- // TODO error handling
- }
- void macaroon::add_third_party_caveat(const char* location, size_t location_sz,
- const unsigned char *key, size_t key_sz, const unsigned char* id,
- size_t id_sz) {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- c_macaroons::macaroon *n;
- n = c_macaroons::macaroon_add_third_party_caveat(m,
- reinterpret_cast<const unsigned char*>(location), location_sz, key,
- key_sz, id, id_sz, &err);
- if (err != c_macaroons::MACAROON_SUCCESS) {
- std::cerr << macaroon_error(err) << std::endl;
- }
- c_macaroons::macaroon_destroy(m);
- m = n;
- // TODO error handling
- }
- void macaroon::add_third_party_caveat_with_keypair(std::string location,
- unsigned char pk[crypto_box_PUBLICKEYBYTES],
- unsigned char sk[crypto_box_SECRETKEYBYTES]) {
- // secret for the remote
- unsigned char key[MACAROON_SUGGESTED_SECRET_LENGTH];
- randombytes(key, sizeof(key));
- unsigned char nonce[crypto_box_NONCEBYTES];
- randombytes(nonce, crypto_box_NONCEBYTES);
- unsigned char id[crypto_box_MACBYTES + sizeof(key) + sizeof(nonce)];
- crypto_box_easy(id, key, sizeof(key), nonce, pk, sk);
- memcpy(id + (crypto_box_MACBYTES + sizeof(key)), nonce, sizeof(nonce));
- add_third_party_caveat(location.c_str(), location.size(), key, sizeof(key),
- id, sizeof(id));
- }
- third_party_caveat_list macaroon::third_party_caveats() const {
- third_party_caveat_list ret;
- unsigned int num = c_macaroons::macaroon_num_third_party_caveats(m);
- for (unsigned int i = 0; i < num; ++i) {
- const unsigned char* location;
- size_t location_sz;
- const unsigned char* identifier;
- size_t identifier_sz;
- c_macaroons::macaroon_third_party_caveat(m, i, &location, &location_sz,
- &identifier, &identifier_sz);
- ret.push_back(
- { std::string(reinterpret_cast<const char*>(location),
- location_sz), std::string(
- reinterpret_cast<const char*>(identifier),
- identifier_sz) });
- }
- return ret;
- }
- macaroon macaroon::prepare_for_request(const macaroon& d) const {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- macaroon ret;
- ret.m = c_macaroons::macaroon_prepare_for_request(m, d.m, &err);
- return ret;
- }
- std::string macaroon::inspect() const {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- size_t sz = c_macaroons::macaroon_inspect_size_hint(m);
- char* data = new char[sz];
- c_macaroons::macaroon_inspect(m, data, sz, &err);
- std::string ret(data);
- delete[] data;
- return ret;
- // TODO error handling
- }
- std::string macaroon::serialize() const {
- c_macaroons::macaroon_returncode err = c_macaroons::MACAROON_SUCCESS;
- size_t sz = c_macaroons::macaroon_serialize_size_hint(m,
- c_macaroons::MACAROON_V1);
- unsigned char *data = new unsigned char[sz];
- c_macaroons::macaroon_serialize(m, c_macaroons::MACAROON_V1, data, sz,
- &err);
- std::string ret((const char*) data);
- delete[] data;
- return ret;
- // TODO error handling
- }
- bool macaroon::validate() const {
- if (c_macaroons::macaroon_validate(m) == 0)
- return true;
- return false;
- }
- std::string macaroon::location() const {
- const unsigned char* location = NULL;
- size_t location_sz = 0;
- c_macaroons::macaroon_location(m, &location, &location_sz);
- return std::string((const char*) location, location_sz);
- }
- std::string macaroon::identifier() const {
- const unsigned char* identifier = NULL;
- size_t identifier_sz = 0;
- c_macaroons::macaroon_identifier(m, &identifier, &identifier_sz);
- return std::string((const char*) identifier, identifier_sz);
- }
- macaroon macaroon::operator=(const macaroon& rhs) {
- c_macaroons::macaroon_returncode err;
- m = c_macaroons::macaroon_copy(rhs.m, &err);
- return *this;
- }
- bool macaroon::operator==(const macaroon& rhs) const {
- if (c_macaroons::macaroon_cmp(m, rhs.m) == 0)
- return true;
- return false;
- }
- void macaroon::create(const unsigned char* location, size_t location_sz,
- const unsigned char* key, size_t key_sz, const unsigned char* id,
- size_t id_sz) {
- c_macaroons::macaroon_returncode err;
- m = c_macaroons::macaroon_create(location, location_sz, key, key_sz, id,
- id_sz, &err);
- // TODO error handler
- }
- bool macaroon::has_third_party_caveats() const {
- if (macaroon_num_third_party_caveats(m) > 0)
- return true;
- return false;
- }
- macaroon::~macaroon() {
- c_macaroons::macaroon_destroy(m);
- }
- macaroon macaroon_discharge(std::string location, std::string secret,
- unsigned char pk[crypto_box_PUBLICKEYBYTES],
- unsigned char sk[crypto_box_SECRETKEYBYTES]) {
- unsigned char key[MACAROON_SUGGESTED_SECRET_LENGTH];
- const unsigned char *key_s =
- reinterpret_cast<const unsigned char*>(secret.data());
- const unsigned char *nonce =
- reinterpret_cast<const unsigned char*>(secret.data())
- + crypto_box_MACBYTES + sizeof(key);
- if (secret.size()
- != (sizeof(key) + crypto_box_MACBYTES + crypto_box_NONCEBYTES)) {
- throw authentication_exception("Macaroon secret size mismatch");
- }
- int rc = crypto_box_open_easy(key, key_s, crypto_box_MACBYTES + sizeof(key),
- nonce, pk, sk);
- return macaroon(reinterpret_cast<const unsigned char*>(location.c_str()),
- location.size(), key, sizeof(key),
- reinterpret_cast<const unsigned char*>(secret.c_str()),
- secret.size());
- }
- } // namespace macaroons
|