source: creddy/creddy.hh @ 09b066a

rt2
Last change on this file since 09b066a was f7f458a, checked in by Ted Faber <faber@…>, 12 years ago

Must throw exception objects not pointers to them

  • Property mode set to 100644
File size: 7.8 KB
Line 
1#ifndef __CREDDY_HH__
2#define __CREDDY_HH__
3
4#include <cstdio>
5#include <stdexcept>
6
7namespace Creddy {
8    extern "C" {
9        #include <creddy.h>
10    }
11
12    class ID {
13        public:
14            ID() : m_id(NULL) { } // do not use: required by swig
15
16            // load an ID from a file
17            ID(char *filename) : m_id(NULL) {
18                m_id = creddy_id_from_file(filename);
19                if (m_id == NULL)
20                    throw std::invalid_argument("Could not load ID cert");
21            }
22
23            // load an ID from a chunk
24            ID(abac_chunk_t chunk) : m_id(NULL) {
25                m_id = creddy_id_from_chunk(chunk);
26                if (m_id == NULL)
27                    throw std::invalid_argument("Could not load ID cert");
28            }
29
30            // generate an ID with a given CN and validity
31            ID(char *cn, int validity) : m_id(NULL) {
32                int ret = creddy_id_generate(&m_id, cn, validity);
33                if (ret == CREDDY_GENERATE_INVALID_CN)
34                    throw std::invalid_argument("CN must be alphanumeric and start with a letter");
35                if (ret == CREDDY_GENERATE_INVALID_VALIDITY)
36                    throw std::invalid_argument("Validity must be > 0 days");
37            }
38
39            ID(const ID &id) { m_id = creddy_id_dup(id.m_id); }
40
41            ~ID() { creddy_id_free(m_id); }
42
43            // load private key from a file
44            void load_privkey(char *filename) {
45                int ret = creddy_id_load_privkey(m_id, filename);
46                if (!ret)
47                    throw std::invalid_argument("Could not load private key");
48            }
49
50            char *keyid() { return creddy_id_keyid(m_id); }
51            char *cert_filename() { return creddy_id_cert_filename(m_id); }
52            void write_cert(std::FILE *out) { creddy_id_write_cert(m_id, out); }
53            void write_cert(const std::string &name) {
54                std::FILE *out = fopen(name.c_str(), "w");
55                if (out == NULL)
56                    throw std::invalid_argument("Could not open cert file for writing");
57                write_cert(out);
58                fclose(out);
59            }
60            // Simplifies access from swig
61            void write_cert(const char *n) {
62                write_cert(std::string(n));
63            }
64            char *privkey_filename() { return creddy_id_privkey_filename(m_id); }
65
66            // write the private ket
67            // throws a std::logic_error if no private key is loaded
68            void write_privkey(std::FILE *out) {
69                int ret = creddy_id_write_privkey(m_id, out);
70                if (!ret) throw std::logic_error("No private key loaded");
71            }
72            void write_privkey(const std::string &name) {
73                std::FILE *out = fopen(name.c_str(), "w");
74                if (out == NULL)
75                    throw std::invalid_argument("Could not open privkey file for writing");
76                write_privkey(out);
77                fclose(out);
78            }
79            // Simplifies access from swig
80            void write_privkey(const char *name) {
81                write_privkey(std::string(name));
82            }
83
84            abac_chunk_t cert_chunk() { return creddy_id_cert_chunk(m_id); }
85
86            friend class Attribute;
87
88        private:
89            creddy_id_t *m_id;
90    };
91
92    class Attribute {
93        public:
94            Attribute() : m_attr(NULL) { } // do not use: required by swig
95
96            // create a cert
97            Attribute(ID &issuer, char *role, int validity) : m_attr(NULL) {
98                int ret = creddy_attribute_role_create(&m_attr, issuer.m_id, role, validity);
99                if (ret == CREDDY_ATTRIBUTE_ISSUER_NOKEY)
100                    throw std::invalid_argument("Issuer has no private key");
101                if (ret == CREDDY_ATTRIBUTE_INVALID_ROLE)
102                    throw std::invalid_argument("Role name must be alphanumeric");
103                if (ret == CREDDY_ATTRIBUTE_INVALID_VALIDITY)
104                    throw std::invalid_argument("Validity must be > 0 days");
105            }
106            // create a cert
107            Attribute(ID &issuer, char *oset, int validity, bool make_oset) :
108                m_attr(NULL) {
109                int ret = creddy_attribute_oset_create(&m_attr, issuer.m_id, oset, validity);
110                if (ret == CREDDY_ATTRIBUTE_ISSUER_NOKEY)
111                    throw std::invalid_argument("Issuer has no private key");
112                if (ret == CREDDY_ATTRIBUTE_INVALID_OSET)
113                    throw std::invalid_argument("Error parsing oset");
114                if (ret == CREDDY_ATTRIBUTE_INVALID_VALIDITY)
115                    throw std::invalid_argument("Validity must be > 0 days");
116            }
117
118            ~Attribute() { creddy_attribute_free(m_attr); }
119
120            // these return false if there's a bad keyid or role name
121            // they'll throw a std::logic_error if the cert's been baked
122            bool principal(char *keyid) {
123                if (baked()) throw std::logic_error("Cert is already baked");
124                return creddy_attribute_principal(m_attr, keyid);
125            }
126            bool role(char *keyid, char *role) {
127                if (baked()) throw std::logic_error("Cert is already baked");
128                return creddy_attribute_role(m_attr, keyid, role);
129            }
130            bool linking_role(char *keyid, char *role, char *linked) {
131                if (baked()) throw std::logic_error("Cert is already baked");
132                return creddy_attribute_linking_role(m_attr, keyid, role, linked);
133            }
134
135            // these return false if there's a bad keyid or role name
136            // they'll throw a std::logic_error if the cert's been baked
137            bool object(char *keyid) {
138                if (baked()) throw std::logic_error("Cert is already baked");
139                return creddy_attribute_principal_object(m_attr, keyid);
140            }
141            bool oset(char *keyid, char *role) {
142                if (baked()) throw std::logic_error("Cert is already baked");
143                return creddy_attribute_oset(m_attr, keyid, role);
144            }
145            bool linking_oset(char *keyid, char *role, char *linked) {
146                if (baked()) throw std::logic_error("Cert is already baked");
147                return creddy_attribute_linking_oset(m_attr, keyid, role, linked);
148            }
149
150            // returns false if there are no subjects or libstrongswan fails
151            // throws a std::logic_error if the cert's already been baked
152            bool bake() {
153                if (baked()) throw std::logic_error("Cert is already baked");
154                return creddy_attribute_bake(m_attr);
155            }
156
157            // returns true iff the cert's been baked
158            bool baked() { return creddy_attribute_baked(m_attr); }
159
160            // throws a std::logic_error if the cert isn't baked
161            void write(std::FILE *out) {
162                int ret = creddy_attribute_write(m_attr, out);
163                if (!ret) throw std::logic_error("Cert is not baked");
164            }
165
166            void write(const std::string &name) {
167                std::FILE *out = fopen(name.c_str(), "w");
168                if (out == NULL)
169                    throw std::invalid_argument("Could not open cert file for writing");
170                write(out);
171                fclose(out);
172            }
173
174            // Simplifies access from swig
175            void write(const char *name) {
176                write(std::string(name));
177            }
178
179            // throws a std::logic_error if the cert isn't baked
180            abac_chunk_t cert_chunk() {
181                abac_chunk_t ret;
182                if (!baked()) throw std::logic_error("Cert is not baked");
183                creddy_attribute_cert_chunk(m_attr, &ret);
184                return ret;
185            }
186
187        private:
188            creddy_attribute_t *m_attr;
189    };
190}
191
192#endif /* __CREDDY_HH__ */
Note: See TracBrowser for help on using the repository browser.