source: libabac/abac.hh @ 92d6cca

abac0-leakabac0-mei
Last change on this file since 92d6cca was 4f79997, checked in by Mei <mei@…>, 11 years ago

1) add a new scaling test -haystack/ralphs
2) tweak some libabac code here and there

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