#ifndef __CREDDY_HH__ #define __CREDDY_HH__ #include #include namespace Creddy { extern "C" { #include } class ID { public: ID() : m_id(NULL) { } // do not use: required by swig // load an ID from a file ID(char *filename) : m_id(NULL) { m_id = creddy_id_from_file(filename); if (m_id == NULL) throw std::invalid_argument("Could not load ID cert"); } // load an ID from a chunk ID(abac_chunk_t chunk) : m_id(NULL) { m_id = creddy_id_from_chunk(chunk); if (m_id == NULL) throw std::invalid_argument("Could not load ID cert"); } // generate an ID with a given CN and validity ID(char *cn, int validity) : m_id(NULL) { int ret = creddy_id_generate(&m_id, cn, validity); if (ret == CREDDY_GENERATE_INVALID_CN) throw std::invalid_argument("CN must be alphanumeric and start with a letter"); if (ret == CREDDY_GENERATE_INVALID_VALIDITY) throw std::invalid_argument("Validity must be > 0 days"); } ID(const ID &id) { m_id = creddy_id_dup(id.m_id); } ~ID() { creddy_id_free(m_id); } // load private key from a file void load_privkey(char *filename) { int ret = creddy_id_load_privkey(m_id, filename); if (!ret) throw std::invalid_argument("Could not load private key"); } char *keyid() { return creddy_id_keyid(m_id); } char *cert_filename() { return creddy_id_cert_filename(m_id); } void write_cert(std::FILE *out) { creddy_id_write_cert(m_id, out); } void write_cert(const std::string &name) { std::FILE *out = fopen(name.c_str(), "w"); if (out == NULL) throw std::invalid_argument("Could not open cert file for writing"); write_cert(out); fclose(out); } // Simplifies access from swig void write_cert(const char *n) { write_cert(std::string(n)); } char *privkey_filename() { return creddy_id_privkey_filename(m_id); } // write the private ket // throws a std::logic_error if no private key is loaded void write_privkey(std::FILE *out) { int ret = creddy_id_write_privkey(m_id, out); if (!ret) throw new std::logic_error("No private key loaded"); } void write_privkey(const std::string &name) { std::FILE *out = fopen(name.c_str(), "w"); if (out == NULL) throw std::invalid_argument("Could not open privkey file for writing"); write_privkey(out); fclose(out); } // Simplifies access from swig void write_privkey(const char *name) { write_privkey(std::string(name)); } abac_chunk_t cert_chunk() { return creddy_id_cert_chunk(m_id); } friend class Attribute; private: creddy_id_t *m_id; }; class Attribute { public: Attribute() : m_attr(NULL) { } // do not use: required by swig // create a cert Attribute(ID &issuer, char *role, int validity) : m_attr(NULL) { int ret = creddy_attribute_create(&m_attr, issuer.m_id, role, validity); if (ret == CREDDY_ATTRIBUTE_ISSUER_NOKEY) throw std::invalid_argument("Issuer has no private key"); if (ret == CREDDY_ATTRIBUTE_INVALID_ROLE) throw std::invalid_argument("Role name must be alphanumeric"); if (ret == CREDDY_ATTRIBUTE_INVALID_VALIDITY) throw std::invalid_argument("Validity must be > 0 days"); } ~Attribute() { creddy_attribute_free(m_attr); } // these return false if there's a bad keyid or role name // they'll throw a std::logic_error if the cert's been baked bool principal(char *keyid) { if (baked()) throw std::logic_error("Cert is already baked"); return creddy_attribute_principal(m_attr, keyid); } bool role(char *keyid, char *role) { if (baked()) throw std::logic_error("Cert is already baked"); return creddy_attribute_role(m_attr, keyid, role); } bool linking_role(char *keyid, char *role, char *linked) { if (baked()) throw std::logic_error("Cert is already baked"); return creddy_attribute_linking_role(m_attr, keyid, role, linked); } // returns false if there are no subjects or libstrongswan fails // throws a std::logic_error if the cert's already been baked bool bake() { if (baked()) throw std::logic_error("Cert is already baked"); return creddy_attribute_bake(m_attr); } // returns true iff the cert's been baked bool baked() { return creddy_attribute_baked(m_attr); } // throws a std::logic_error if the cert isn't baked void write(std::FILE *out) { int ret = creddy_attribute_write(m_attr, out); if (!ret) throw std::logic_error("Cert is not baked"); } void write(const std::string &name) { std::FILE *out = fopen(name.c_str(), "w"); if (out == NULL) throw std::invalid_argument("Could not open cert file for writing"); write(out); fclose(out); } // Simplifies access from swig void write(const char *name) { write(std::string(name)); } // throws a std::logic_error if the cert isn't baked abac_chunk_t cert_chunk() { abac_chunk_t ret; if (!baked()) throw new std::logic_error("Cert is not baked"); creddy_attribute_cert_chunk(m_attr, &ret); return ret; } private: creddy_attribute_t *m_attr; }; } #endif /* __CREDDY_HH__ */