source: libabac/abac.hh @ 06c86d7

mei-rt0-n
Last change on this file since 06c86d7 was 06c86d7, checked in by Mei <mei@…>, 11 years ago

i1) trying to get in sync with master

  • Property mode set to 100644
File size: 20.6 KB
Line 
1#ifndef __ABAC_HH__
2#define __ABAC_HH__
3
4#include <cstdio>
5#include <stdexcept>
6#include <string>
7#include <vector>
8
9namespace ABAC {
10    extern "C" {
11        #include "abac.h"
12    }
13
14    class Attribute;
15    class ID;
16
17/***
18ABAC::Role
19   A Role, most calls are rarely used outside the library
20***/
21    class Role {
22        public:
23/***
24f  Role()
25     default constructor, do not use, for swig only
26f  Role(abac_role_t*)
27     copy constructor, used for cloning an Role
28     (C:abac_role_dup)
29f  Role(char *)
30     instantiate a role from a string
31     (C:abac_role_from_string)
32f  Role(const Role &)
33     copy constructor, used for cloning an Role
34     (C:abac_role_dup)
35f  ~Role()
36     default destructor
37     (C:abac_role_free)
38***/
39            Role() : m_role(NULL) { } // do not use: here for swig
40            Role(abac_role_t *role) { m_role = abac_role_dup(role); }
41            Role(char *role_name) { m_role = abac_role_from_string(role_name); }
42            Role(const Role &role) { m_role = abac_role_dup(role.m_role); }
43            ~Role() { abac_role_free(m_role); }
44/***
45f  bool is_principal()
46     (C:abac_role_is_principal)
47f  bool is_role()
48     (C:abac_role_is_role)
49f  bool is_linking()
50     (C:abac_role_is_linking)
51     indicates the type of role encoded
52***/
53            bool is_principal() const { return abac_role_is_principal(m_role); }
54            bool is_role() const { return abac_role_is_role(m_role); }
55            bool is_linking() const { return abac_role_is_linking(m_role); }
56
57/***
58f  char* string()
59     string representation of the role
60     (C:abac_role_string)
61***/
62            char *string() const { return abac_role_string(m_role); }
63/***
64f  char* linked_role()
65     the linked role of a linking role
66     i.e., A.r1.r2, linked_role() returns A.r1
67     (C:abac_role_linked_role)
68f  char* role_name()
69     the role name of any role (the part after the last dot)
70     (C:abac_role_role_name)
71f  char* principal()
72     the principal part of any role
73     (C:abac_role_principal)
74***/
75            char *linked_role() const { return abac_role_linked_role(m_role); }
76            char *role_name() const { return abac_role_role_name(m_role); }
77            char *principal() const { return abac_role_principal(m_role); }
78
79        private:
80            abac_role_t *m_role;
81    };
82
83/***
84ABAC::Credential
85   This is never instantiated directly. These will only ever be
86   returned as a result of calls to Context::query or
87   Context::credentials.
88***/
89    class Credential {
90        public:
91/***
92f  Credential()
93     default constructor, do not use, for swig only
94f  Credential(abac_credential_t*)
95     copy constructor, used for cloning a credential
96     (C:abac_credential_head)
97     (C:abac_credential_tail)
98     (C:abac_credential_dup)
99f  Credential(const Credential&)
100     copy constructor, used for cloning a credential
101     (C:abac_credential_head)
102     (C:abac_credential_tail)
103     (C:abac_credential_dup)
104f  ~Credential()
105     default destructor
106     (C:abac_credential_free)
107***/
108            Credential() : m_cred(NULL) { } // do not use: here for swig
109            Credential(abac_credential_t *cred) :
110                m_head(abac_credential_head(cred)),
111                m_tail(abac_credential_tail(cred)),
112                m_cred(abac_credential_dup(cred))
113                    { }
114            Credential(const Credential &cred) :
115                m_head(cred.m_head),
116                m_tail(cred.m_tail),
117                m_cred(abac_credential_dup(cred.m_cred))
118                    { }
119            ~Credential() { abac_credential_free(m_cred); }
120/***
121f  Role &head()
122     returns the head of the credential
123f  Role &tail()
124     returns the tail of the credential
125***/
126            const Role &head() { return m_head; }
127            const Role &tail() { return m_tail; }
128/***
129f  abac_chunk_t attribute_cert()
130     returns the attribute certificate in chunk, suitable for
131     transmission over the network or storage in a file
132     (C:abac_credential_attribute_cert)
133f  abac_chunk_t issuer_cert()
134     returns the issuer certificate in chunk, again suitable for
135     network transmission or file storage
136     (C:abac_credential_issuer_cert)
137***/
138            abac_chunk_t attribute_cert() { return abac_credential_attribute_cert(m_cred); }
139            abac_chunk_t issuer_cert() { return abac_credential_issuer_cert(m_cred); }
140       
141        private:
142            abac_credential_t *m_cred;
143            Role m_head, m_tail;
144    };
145
146/***
147ABAC::Context
148    An ABAC Context
149***/
150    class Context {
151        public:
152/***
153f  Context()
154     default constructor
155     (C:abac_context_new)
156f  Context(const Context &)
157     copy constructor, used for cloning the context
158     (C:abac_context_dup)
159f  ~Context()
160     default destructor
161     (C:abac_context_free)
162***/
163            Context() { m_ctx = abac_context_new(); }
164            Context(const Context &context) { m_ctx = abac_context_dup(context.m_ctx); }
165            ~Context() { abac_context_free(m_ctx); }
166
167/***
168f  int load_id_file(char *)
169     load identity certificate from an id file
170     (C:abac_context_load_id_file)
171f  int load_id_chunk(abac_chunk_t)
172     load id certificate from an chunk
173     (C:abac_context_load_id_chunk)
174f  int load_attribute_file(char *)
175     load attribute certificate from an id file.
176     (C:abac_context_load_attribute_file)
177f  int load_attribute_chunk(abac_chunk_t)
178     load attribute certificate from an chunk
179     (C:abac_context_load_attribute_chunk)
180f  returns :
181        ABAC_CERT_SUCCESS   successfully loaded
182        ABAC_CERT_INVALID   invalid certificate (or file not found)
183        ABAC_CERT_BAD_SIG   invalid signature
184***/
185            int load_id_file(char *filename) { return abac_context_load_id_file(m_ctx, filename); }
186            int load_id_chunk(abac_chunk_t cert) { return abac_context_load_id_chunk(m_ctx, cert); }
187            int load_attribute_file(char *filename) { return abac_context_load_attribute_file(m_ctx, filename); }
188            int load_attribute_chunk(abac_chunk_t cert) { return abac_context_load_attribute_chunk(m_ctx, cert); }
189
190/***
191f  void load_directory(char *)
192     load a directory full of certificates:
193f       first: ${path}/*_ID.{der,pem} as identity certificates
194               implicitly looking for ${path}/*_private.{der,pem} as
195               the private key file
196        last: ${path}/*_attr.xml as attribute certificates
197      (C:abac_context_load_directory)
198***/
199            void load_directory(char *path) { abac_context_load_directory(m_ctx, path); }
200
201/***
202f  std::vector<Credential> query(char *, char *, bool &)
203     run the query:
204        role <-?- principal
205     returns true/false in success
206     returns a proof upon success, partial proof on failure
207     (C:abac_context_query)
208     (C::abac_free_credentials_free)
209***/
210
211            /* abac query, returns a vector of credentials on success, NULL on fail */
212            std::vector<Credential> query(char *role, char *principal, bool &success) {
213                abac_credential_t **creds, **end;
214                int i, success_int;
215                creds = abac_context_query(m_ctx, role, principal, &success_int);
216                success = success_int;
217
218                for (i = 0; creds[i] != NULL; ++i)
219                    ;
220
221                end = &creds[i];
222                std::vector<Credential> credentials = std::vector<Credential>(creds, end);
223                abac_context_credentials_free(creds);
224                return credentials;
225            }
226/***
227f  std::vector<Credential> credentials(bool &)
228     returns a vector of all the credentials loaded in the context
229     (C:abac_context_credentials)
230     (C::abac_context_credentials_free)
231***/
232            std::vector<Credential> credentials() {
233                abac_credential_t **creds, **end;
234                int i;
235
236                creds = abac_context_credentials(m_ctx);
237                for (i = 0; creds[i] != NULL; ++i)
238                    ;
239
240                end = &creds[i];
241                std::vector<Credential> credentials = std::vector<Credential>(creds, end);
242
243                abac_context_credentials_free(creds);
244                return credentials;
245            }
246
247        private:
248            abac_context_t *m_ctx;
249    };
250
251/***
252ABAC::ID
253   An ID holds a principal credential. It maybe imported from an existing
254   ID credential via external files, constructed from a streaming chunk,
255   or instantiated on the fly
256***/
257    class ID {
258        public:
259/***
260f  ID()
261     default constructor, do not use, for swig only
262f  ID(const ID &)
263     copy constructor, used for cloning an ID
264     (C:abac_id_dup)
265f  ~ID()
266     default destructor
267     (C:abac_id_free)
268***/
269            ID() : m_id(NULL) { } // do not use: required by swig
270            ID(const ID &id) { m_id = abac_id_dup(id.m_id); }
271            ~ID() { abac_id_free(m_id); }
272
273/***
274f  ID(char *)
275     load an ID certificate from a file, will throw an exception
276     if the certificate cannot be loaded
277     (C:abac_id_from_file)
278***/
279            ID(char *filename) : m_id(NULL) {
280                m_id = abac_id_from_file(filename);
281                if (m_id == NULL)
282                    throw std::invalid_argument("Could not load ID cert");
283            }
284
285/***
286f  ID_chunk(abac_chunk_t chunk)
287     create an ID certificate from an certificate chunk, will
288     throw an exception if the certificate cannot be loaded
289     (C:abac_id_from_chunk)
290***/
291            ID(abac_chunk_t chunk) : m_id(NULL) {
292                m_id = abac_id_from_chunk(chunk);
293                if (m_id == NULL)
294                    throw std::invalid_argument("Could not load ID certificate with a chunk");
295            }
296/***
297f  ID(char *,int)
298     generates a new ID(cert&key) with the supplied CN and validity period
299     - CN must be alphanumeric and begin with a letter
300     - validity must be at least one second
301     will throw an exception if either of the above is violated
302     (C:abac_id_generate)
303***/
304            ID(char *cn, int validity) : m_id(NULL) {
305                int ret = abac_id_generate(&m_id, cn, validity);
306                if (ret == ABAC_GENERATE_INVALID_CN)
307                    throw std::invalid_argument("CN must be alphanumeric and start with a letter");
308                if (ret == ABAC_GENERATE_INVALID_VALIDITY)
309                    throw std::invalid_argument("Validity must be > 0 days");
310            }
311/***
312f  void load_privkey(char *)
313     loads the private key associated with the ID credential,
314     will throw an exception if the key cannot be loaded
315     (C:abac_id_privkey_from_file)
316f  void load_privkey_chunk(abac_chunk_t)
317     loads the private key associated with the ID credential,
318     will throw an exception if the key cannot be loaded
319     (C:abac_id_privkey_from_chunk)
320f  int has_privkey()
321     check to see if there is a privkey in this ID
322     (C:abac_id_has_privkey)
323***/
324            void load_privkey(char *filename) {
325                int ret = abac_id_privkey_from_file(m_id, filename);
326                if (ret != ABAC_SUCCESS)
327                    throw std::invalid_argument("Could not load private key");
328            }
329            void load_privkey_chunk(abac_chunk_t chunk) {
330                int ret = abac_id_privkey_from_chunk(m_id, chunk);
331                if (ret != ABAC_SUCCESS)
332                    throw std::invalid_argument("Could not load private key with a chunk");
333            }
334            int has_privkey() {
335                int ret= abac_id_has_privkey(m_id);
336                return ret;
337            }
338/***
339f  char *keyid()
340     returns the SHA1 keyid of the id cert
341     (C:abac_id_keyid)
342f  char *cert_filename()
343     returns the default libabac filename for the cert.
344     value must be freed by caller.
345     (C:abac_id_cert_filename)
346***/
347            char *keyid() { return abac_id_keyid(m_id); }
348            char *cert_filename() { return abac_id_cert_filename(m_id); }
349/***
350f  void write_cert(FILE *)
351     writes a PEM-encoded certificate to a file handle
352     (C:abac_id_write_cert)
353f  void write_cert(string &)
354     writes a PEM-encoded certificate to a file named in string
355f  void write_cert_file(const char *)
356     writes a PEM-encoded certificate to a file
357f  void write_cert_name(const char *)
358     writes a PEM-encoded certificate to a file
359     (added to support original libcreddy users)
360***/
361            void write_cert(FILE *out) { abac_id_write_cert(m_id, out); }
362            void write_cert(const std::string &name) {
363                FILE *out = fopen(name.c_str(), "a+");
364                if (out == NULL)
365                    throw std::invalid_argument("Could not open certificate file for writing");
366                write_cert(out);
367                fclose(out);
368            }
369            // Simplifies access from swig
370            void write_cert_file(const char *n) {
371                write_cert(std::string(n));
372            }
373            void write_cert_name(const char *n) {
374                write_cert(std::string(n));
375                fprintf(stderr,"ABAC::ID::write_cert_name is deprecated, please use ABAC::ID::write_cert_name\n");
376            }
377/***
378f  char *privkey_filename()
379     returns the default libabac filename for the private key.
380     value must be freed by caller.
381     (C:abac_id_privkey_filename)
382***/
383            char *privkey_filename() { return abac_id_privkey_filename(m_id); }
384/***
385f  void write_privkey(FILE *)
386     write the private key to a file handle
387     throws a std::logic_error if no private key is loaded
388     (C:abac_id_write_privkey)
389f  void write_privkey(string &)
390     writes a private key to file named in string
391f  void write_privkey_file(const char *)
392     writes a private key to a file
393f  void write_privkey_name(const char *)
394     writes a private key to a file
395     (added to support original libcreddy users)
396***/
397            void write_privkey(FILE *out) {
398                int ret = abac_id_write_privkey(m_id, out);
399                if (ret!=ABAC_SUCCESS) throw std::logic_error("No private key loaded");
400            }
401            void write_privkey(const std::string &name) {
402                FILE *out = fopen(name.c_str(), "a+");
403                if (out == NULL)
404                    throw std::invalid_argument("Could not open privkey file for writing");
405                write_privkey(out);
406                fclose(out);
407            }
408            // Simplifies access from swig
409            void write_privkey_file(const char *name) {
410                write_privkey(std::string(name));
411            }
412            void write_privkey_name(const char *name) {
413                write_privkey(std::string(name));
414                fprintf(stderr,"ABAC::ID::write_privkey_name is deprecated, please use ABAC::ID::write_privkey_file\n");
415            }
416/***
417f  abac_chunk_t cert_chunk()
418     returns a DER-encoded binary representation of the X.509 ID cert
419     associated with this ID.
420     can be passed to libabac's Context::load_id_chunk()
421     (C:abac_id_cert_chunk)
422f  abac_chunk_t privkey_chunk()
423     returns a PEM-encoded binary representation of the private key
424     associated with this ID.
425     (C:abac_id_privkey_chunk)
426***/
427            abac_chunk_t cert_chunk() { return abac_id_cert_chunk(m_id); }
428            abac_chunk_t privkey_chunk() { return abac_id_privkey_chunk(m_id); }
429
430            friend class Attribute;
431
432        private:
433            abac_id_t *m_id;
434    };
435
436/***
437ABAC::Attribute
438   This is the attribute representation for the access policy rule
439       LHS <- RHS
440   The sequence of generation is to
441       first, instantiate the object, ie, LHS (head)
442       second, adding subject(s) to it, ie, RHS (tail)
443       and then baking it.
444   Only once it's baked can you access the X.509 cert.
445   Once it's been baked you can no longer add subjects to it
446***/
447    class Attribute {
448        public:
449/***
450f  Attribute()
451     default constructor, do not use, for swig only
452f  ~Attribute()
453     default destructor
454     (C:abac_attribute_free)
455***/
456            Attribute() : m_attr(NULL) { } // do not use: required by swig
457            ~Attribute() { abac_attribute_free(m_attr); }
458
459/***
460f  Attribute(ID&, char*,int)
461     constructor that creates an attribute policy to be signed by the issuer
462     with the given role with a specified validity period
463     An exception will be thrown if:
464       - the issuer has no private key
465       - the Head role is invalid
466       - the validity period is invalid (must be >= 0 second)
467       - The issuer is invalid
468     (C:abac_attribute_create)
469***/
470            Attribute(ID &issuer, char *role, int validity) : m_attr(NULL) {
471                int ret = abac_attribute_create(&m_attr, issuer.m_id, role, validity);
472                if (ret == ABAC_ATTRIBUTE_ISSUER_NOKEY)
473                    throw std::invalid_argument("Issuer has no private key");
474                if (ret == ABAC_ATTRIBUTE_INVALID_ROLE)
475                    throw std::invalid_argument("Role name must be alphanumeric");
476                if (ret == ABAC_ATTRIBUTE_INVALID_VALIDITY)
477                    throw std::invalid_argument("Validity must be > 0 days");
478                if (ret == ABAC_ATTRIBUTE_INVALID_ISSUER)
479                    throw std::invalid_argument("Issuer's validity expired");
480            }
481
482
483/***
484f  bool principal(char *)
485     validate the principal and insert into the attribute
486     throw a std::logic_error if the cert's been baked and keyid bad
487     (C:abac_attribute_principal)
488f bool role(char *, char *)
489     validate the principal and role and insert into the attribute
490     throw a std::logic_error if the cert's been baked and keyid bad
491     (C:abac_attribute_role)
492f bool linkig_role(char *, char *)
493     validate the role and linking role and insert into the attribute
494     throw a std::logic_error if the cert's been baked and keyid bad
495     (C:abac_attribute_linking_role)
496***/
497            bool principal(char *keyid) {
498                if (baked()) throw std::logic_error("Cert is already baked");
499                return abac_attribute_principal(m_attr, keyid);
500            }
501            bool role(char *keyid, char *role) {
502                if (baked()) throw std::logic_error("Cert is already baked");
503                return abac_attribute_role(m_attr, keyid, role);
504            }
505            bool linking_role(char *keyid, char *role, char *linked) {
506                if (baked()) throw std::logic_error("Cert is already baked");
507                return abac_attribute_linking_role(m_attr, keyid, role, linked);
508            }
509/***
510f  bool bake()
511     Generate the cert. Call this after you've added subjects to your cert.
512     This returns false if there are no subjects
513     This will throw an exception if the cert's already been baked.
514     (C:abac_attribute_bake)
515***/
516            bool bake() {
517                if (baked()) throw std::logic_error("Cert is already baked");
518                return abac_attribute_bake(m_attr);
519            }
520
521/***
522f  bool baked()
523     returns true iff the certificate has been baked.
524     (C:abac_attribute_baked)
525***/
526            bool baked() { return abac_attribute_baked(m_attr); }
527
528/***
529f  void write(FILE *)
530     write an attribute certificate in XML to an open file handle
531     Throws an exception if the certificate isn't baked
532     (C:abac_attribute_write)
533f  void write(const string&)
534     write an attribute certificate in XML to file named in string
535f  void write_file(const char *)
536     write an attribute certificate in XML to file
537f  void write_name(const char *)
538     write an attribute certificate in XML to file
539     (added to support original libcreddy users)
540***/
541            void write(FILE *out) {
542                int ret = abac_attribute_write(m_attr, out);
543                if (ret!=ABAC_SUCCESS) throw std::logic_error("Cert is not baked");
544            }
545            void write(const std::string &name) {
546                FILE *out = fopen(name.c_str(), "w");
547                if (out == NULL)
548                    throw std::invalid_argument("Could not open certificate file for writing");
549                write(out);
550                fclose(out);
551            }
552            void write_file(const char *name) {
553                int ret = abac_attribute_write_file(m_attr, name);
554                if (ret!=ABAC_SUCCESS) throw std::logic_error("Cert is not baked");
555            }
556            void write_name(const char *name) {
557                write_file(name);
558                fprintf(stderr,"ABAC::Attribute::write_name is deprecated, please use ABAC::Attribute::write_name\n");
559            }
560/***
561f  abac_chunk_t cert_chunk()
562     returns a XML structure of the attribute certificate in a abac_chunk_t
563     Throws an exception if the certificate isn't baked
564     the chunk can be passed to libabac's Context::load_attribute_chunk()
565     (C:abac_attribute_cert_chunk)
566***/
567            abac_chunk_t cert_chunk() {
568                abac_chunk_t ret=abac_attribute_cert_chunk(m_attr);
569                if(ret.len == 0)
570                    throw std::logic_error("Cert is not baked");
571                return ret;
572            }
573
574        private:
575            abac_attribute_t *m_attr;
576    };
577}
578
579#endif /* __ABAC_HH__ */
Note: See TracBrowser for help on using the repository browser.