source: libabac/abac.hh @ d037f54

mei_rt2mei_rt2_fix_1
Last change on this file since d037f54 was d037f54, checked in by Mei <mei@…>, 12 years ago

1) able to programmatially build structure, bake attribute credential

write it out to a .der file and use prover to bring it back and
process just like other .der files.
-- tested with rt1 like policy without constraint.

2) changed abac_term structure alittle to ready it for 2 pass code

gen.

  • Property mode set to 100644
File size: 23.9 KB
Line 
1#ifndef __ABAC_HH__
2#define __ABAC_HH__
3
4#include <string>
5#include <vector>
6
7namespace ABAC {
8    extern "C" {
9        #include "abac.h"
10    }
11
12    static int debug=0;
13
14    class Role;
15    class Oset;
16
17    class Constraint {
18        public:
19            Constraint() : m_constraint(NULL) { } // do not use: here for swig
20            Constraint(abac_condition_t *constraint): 
21              m_constraint(abac_condition_dup(constraint))
22              { }
23            Constraint(const Constraint &constraint) { 
24                m_constraint =abac_condition_dup(constraint.m_constraint);
25              }
26            ~Constraint() { 
27                if(m_constraint) abac_condition_free(m_constraint);
28              }
29            /* range constraint */
30            Constraint(char *constraint) {
31                m_constraint=abac_condition_from_string(constraint); 
32              }
33            /* role constraint */
34            Constraint(Role *role);
35            /* oset constraint */
36            Constraint(Oset *oset);
37            char *string() const { 
38                return abac_condition_string(m_constraint);
39              }
40            char *typed_string() const { 
41                return abac_condition_typed_string(m_constraint);
42              }
43            abac_condition_t *constraint()
44              { return m_constraint; }
45        private:
46            abac_condition_t *m_constraint;
47    };
48
49    /* XXX need to track the principal [keyid:alice] so can generate
50       the id_type_clause within attribute clause */
51    class DataTerm {
52        public:
53            DataTerm() : m_term(NULL) { } // do not use: here for swig
54            DataTerm(abac_term_t *term) { 
55                m_term=abac_term_dup(term);
56                abac_condition_t *constraint=abac_term_constraint(m_term);
57                if(constraint) m_cond=new Constraint(constraint);
58                  else m_cond=NULL;
59              }
60            DataTerm(const DataTerm &term) { 
61                m_term =abac_term_dup(term.m_term);
62                abac_condition_t *constraint=abac_term_constraint(m_term);
63                if(constraint) m_cond=new Constraint(constraint);
64                  else m_cond=NULL;
65              }
66            ~DataTerm() { 
67                if(m_term) abac_term_free(m_term);
68                if(m_cond) free(m_cond);
69              }
70            /* this is for named principal data term */
71            DataTerm(char *sha) {
72                if(debug) printf("adding a Dataterm named principal(%s)\n",sha);
73                int isnamed=1;
74                int type=e_TERM_PRINCIPAL;
75                m_term=abac_term_named_create(type,sha);
76            }
77            /* can be an a variable data term or a specific value */
78            DataTerm(int type, char *name, Constraint *cond=NULL) {
79                if(debug) printf("adding a Dataterm (%s)\n",name);
80                if(cond) {
81                  m_cond=cond;
82                  m_term=abac_term_create(type,name,cond->constraint());
83                  } else {
84                      m_cond=NULL;
85                      m_term=abac_term_create(type,name,NULL);
86                }
87              }
88            char *string() const { 
89                return abac_term_string(m_term);
90              }
91            char *typed_string() const { 
92                return abac_term_typed_string(m_term);
93              }
94            bool is_time() const {
95                return abac_term_is_time_type(m_term);
96              }
97            bool is_string() const {
98                return abac_term_is_string_type(m_term);
99              }
100            bool is_urn() const {
101                return abac_term_is_urn_type(m_term);
102              }
103            bool is_integer() const {
104                return abac_term_is_integer_type(m_term);
105              }
106/* Add a constraint to this term. */
107            int add_constraint(Constraint& cond) {
108                m_cond=new Constraint(cond);
109                abac_term_add_constraint(m_term, m_cond->constraint());
110              }
111            int type() {
112                abac_term_type(m_term);
113              }
114            char *name() {
115                return abac_term_name(m_term);
116              }
117            char *value() {
118/* ??? value XXX */
119              }
120            Constraint *constraint() {
121                return m_cond;
122              }
123            abac_term_t *term() {
124                return m_term;
125              }
126
127        private:
128            abac_term_t *m_term;
129            Constraint *m_cond;
130    };
131
132
133    class Role {
134        public:
135            Role() : m_role(NULL) { } // do not use: here for swig
136            Role(abac_aspect_t *role): m_role(abac_aspect_dup(role))
137              { }
138            Role(char *principal_name) : 
139               m_role(abac_aspect_role_principal_create(principal_name)) 
140              { }
141            Role(char *principal_name, char *role_name) : 
142               m_role(abac_aspect_role_create(principal_name, role_name)) 
143              { }
144            Role(const Role &role) { 
145                m_role = abac_aspect_dup(role.m_role);
146              }
147            ~Role() { 
148                if (m_role) abac_aspect_free(m_role);
149              }
150            bool is_principal() const { 
151                return abac_aspect_is_principal(m_role); 
152              }
153            bool is_linking() const { 
154                return abac_aspect_is_linking(m_role); 
155              }
156            char *string() const { 
157                return abac_aspect_string(m_role);
158              }
159            char *typed_string() {
160                char* string=abac_aspect_typed_string(m_role);
161                return string;
162              }
163            char *linked_role() const { 
164                return abac_aspect_linked_role_name(m_role);
165              }
166            char *role_name() const { 
167                return abac_aspect_aspect_name(m_role);
168              }
169            char *principal() const { 
170                return abac_aspect_principal_name(m_role);
171              }
172/* Add a data term to this name. */
173            int add_data_term(DataTerm& d) {
174                abac_aspect_add_param(m_role, d.term());
175                return 1;
176              }
177/* Return the DataTerms bound to this name.  If the name is returned
178   in a proof, these will all have values. */
179            std::vector<DataTerm> get_data_terms(bool &success) {
180                abac_term_t **terms, **end;
181                int i;
182                terms = abac_param_list_vectorize(abac_aspect_aspect_params(m_role));
183                for (i = 0; terms[i] != NULL; ++i)
184                    ;
185                end = &terms[i];
186                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
187                abac_terms_free(terms);
188                success=1;
189                return dataterms;
190              }
191            int add_linking_data_term(DataTerm& d) {
192                abac_aspect_add_linked_param(m_role, d.term());
193                return 1;
194              }
195            std::vector<DataTerm> get_linked_data_terms(bool &success) {
196                abac_term_t **terms, **end;
197                int i;
198                terms = abac_param_list_vectorize(abac_aspect_linked_role_params(m_role));
199                for (i = 0; terms[i] != NULL; ++i)
200                    ;
201                end = &terms[i];
202                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
203                abac_terms_free(terms);
204                success=1;
205                return dataterms;
206              }
207            abac_aspect_t *role() {return m_role;}
208        private:
209            abac_aspect_t *m_role;
210    };
211
212    class Oset {
213        public:
214            Oset() : m_oset(NULL) { } // do not use: here for swig
215            Oset(abac_aspect_t *oset): m_oset(abac_aspect_dup(oset)) 
216              { }
217            Oset(char *oset_name) : m_oset(abac_aspect_role_principal_create(oset_name)) 
218              { }
219            Oset(char *principal_name, char *oset_name) : 
220               m_oset(abac_aspect_oset_create(principal_name, oset_name)) 
221              { }
222            Oset(const Oset &oset) { 
223                m_oset =abac_aspect_dup(oset.m_oset);
224              }
225            ~Oset() { 
226                if(m_oset) abac_aspect_free(m_oset);
227              }
228            bool is_object() const { 
229                return abac_aspect_is_object(m_oset); 
230              }
231            bool is_principal() const { 
232                return abac_aspect_is_principal(m_oset); 
233              }
234            bool is_linking() const { 
235                return abac_aspect_is_linking(m_oset); 
236              }
237            char *string() const { 
238                return abac_aspect_string(m_oset);
239              }
240            char *typed_string() {
241                char* string=abac_aspect_typed_string(m_oset);
242                return string;
243              }
244            char *linked_role() const { 
245                return abac_aspect_linked_role_name(m_oset);
246              }
247            char *oset_name() const { 
248                return abac_aspect_aspect_name(m_oset);
249              }
250            char *principal() const { 
251                return abac_aspect_principal_name(m_oset);
252              }
253            char *object() const { 
254                return abac_aspect_object_name(m_oset);
255              }
256/* Add a data term to this name. */
257            int add_data_term(DataTerm& d) {
258                abac_aspect_add_param(m_oset, d.term()); 
259                return 1;
260              }
261/* Return the DataTerms bound to this name.  If the name is returned
262   in a proof, these will all have values. */
263            std::vector<DataTerm> get_data_terms(bool &success) {
264                abac_term_t **terms, **end;
265                int i;
266                terms = abac_param_list_vectorize(abac_aspect_aspect_params(m_oset));
267                for (i = 0; terms[i] != NULL; ++i)
268                    ;
269                end = &terms[i];
270                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
271                abac_terms_free(terms);
272                success=1;
273                return dataterms;
274              }
275            int add_linking_data_term(DataTerm& d) {
276                abac_aspect_add_linked_param(m_oset, d.term());
277                return 1;
278              }
279            std::vector<DataTerm> get_linked_data_terms(bool &success) {
280                abac_term_t **terms, **end;
281                int i;
282                terms = abac_param_list_vectorize(abac_aspect_linked_role_params(m_oset));
283                for (i = 0; terms[i] != NULL; ++i)
284                    ;
285                end = &terms[i];
286                std::vector<DataTerm> dataterms = std::vector<DataTerm>(terms, end);
287                abac_terms_free(terms);
288                success=1;
289                return dataterms;
290              }
291            abac_aspect_t *oset() {return m_oset;}
292        private:
293            abac_aspect_t *m_oset;
294    };
295
296
297    class ID {
298        public:
299            ID() : m_id(NULL) { } // do not use: here for swig
300            ID(abac_id_t *id): m_id(abac_id_dup(id)) 
301              { }
302            ID(const ID &id) { m_id =abac_id_dup(id.m_id); }
303            ~ID() { if(m_id) abac_id_free(m_id); }
304
305/* load an ID cert from a file
306Will throw an exception if the cert cannot be loaded */
307            ID(char *filename) {
308                m_id=abac_id_from_file(filename); 
309                if(m_id==NULL)
310                  abac_errx(1, "Id creation from filename failed");
311              }
312/* generates a new ID with the supplied CN and validity period
313   - CN must be alphanumeric and begin with a letter
314   - validity must be at least one second
315   Will throw an exception if either of the above is violated */
316            ID(char *cn, int validity) {
317                int rt=abac_id_generate(&m_id, cn, validity);
318                if(rt != ABAC_ID_SUCCESS) 
319                  abac_errx(1, "Id creation failed");
320              }
321/* loads the private key associated with the cert
322   will throw an exception if the key cannot be loaded */
323            void load_privkey(char *filename) {
324                int rt=abac_id_load_privkey(m_id, filename);
325                if(rt != 1) 
326                  abac_errx(1, "Failed to load private key");
327              }
328            abac_id_t *id() { return m_id; }
329
330/* returns the SHA1 keyid of the cert */
331            char *keyid() { return abac_id_keyid(m_id); }
332/* returns the CN (the parameter passed to the constructor or the
333   CN of the cert). */
334            char *name() { return abac_id_cn(m_id); }
335/* returns true if the ID has an associated private key */
336            bool has_privkey() {
337                return abac_id_has_privkey(m_id);
338              }
339/* writes a PEM-encoded cert to the file handle */
340            void write_cert(FILE *out) {
341                abac_id_write_cert(m_id, out); 
342              }
343/* writes a PEM-encoded cert to a file named out */
344            void write_cert(char *filename) {
345                FILE *out = fopen(filename, "w");
346                write_cert(out);
347                fclose(out);
348              }
349/* writes a PEM-encoded private key to the file handle
350   throws an exception if no private key is loaded */
351            void write_privkey(FILE *out) {
352                if(!has_privkey())
353                    abac_errx(1, "No privkey to write");
354                abac_id_write_privkey(m_id, out);
355              }
356/* writes a PEM-encoded private key a file named out
357   throws an exception if no private key is loaded */
358            void write_privkey(char *filename) {
359                FILE *out = fopen(filename, "w");
360                write_privkey(out);
361                fclose(out);
362              }
363/* returns a DER-encoded binary representation of the X.509 ID cert
364   associated with this ID.
365   can be passed to libabac's Context::load_id_chunk() */
366            abac_chunk_t cert_chunk() {
367                return abac_id_cert_chunk(m_id);
368              }
369        public:
370            abac_id_t *m_id;
371    };
372
373
374/* N.B., The way you use this class is by instantiating the object, adding
375   subjects to it, and then baking it. Only once it's baked can you access the
376   X.509 cert. Once it's been baked you can no longer add subjects to it. */
377    class Attribute {
378        public:
379            Attribute() : m_attr(NULL) { } // do not use: here for swig
380            Attribute(abac_attribute_t *attr): m_attr(abac_attribute_dup(attr)) 
381              { }
382            Attribute(abac_credential_t *cred) {
383                m_attr=abac_attribute_dup(abac_credential_attribute(cred));
384              }
385            Attribute(const Attribute &id) { 
386                m_attr =abac_attribute_dup(id.m_attr);
387              }
388            ~Attribute() { 
389                if(m_attr) abac_attribute_free(m_attr);
390              }
391/* Create an object to be signed by the given issuer with the given role
392   and validity period
393   An exception will be thrown if:
394     - the issuer has no private key
395     - the Head is invalid
396     - the validity period is invalid (must be >= 1 second) */
397            Attribute(Role& head, int validity) {
398                int rt=abac_attribute_create(&m_attr, head.role(), NULL, validity);
399                if(rt!=ABAC_ATTRIBUTE_SUCCESS)
400                    abac_errx(1, "attribute(role), unable to make an attribute");
401              }
402            Attribute(Oset& head, int validity) {
403                int rt=abac_attribute_create(&m_attr, head.oset(), NULL, validity);
404                if(rt!=ABAC_ATTRIBUTE_SUCCESS)
405                    abac_errx(1, "attribute(oset), unable to make an attribute");
406              }
407            bool add_tail(Role& tail) {
408                if(abac_attribute_add_tail(m_attr, tail.role()))
409                    return 1;
410                    else return 0;
411              }
412            bool add_tail(Oset& tail) {
413                if(abac_attribute_add_tail(m_attr, tail.oset()))
414                    return 1;
415                    else return 0;
416              }
417            char *head_string() {
418                abac_aspect_t *head=abac_attribute_head(m_attr);
419                char *string=abac_aspect_string(head);
420                return string;
421              }
422            char *tail_string() {
423                abac_aspect_t *tail=abac_attribute_tail(m_attr);
424                char *string=abac_aspect_string(tail);
425                return string;
426              }
427            char *head_typed_string() {
428                abac_aspect_t *head=abac_attribute_head(m_attr);
429                char *string=abac_aspect_typed_string(head);
430                return string;
431              }
432            char *tail_typed_string() {
433                abac_aspect_t *tail=abac_attribute_tail(m_attr);
434                char *string=abac_aspect_typed_string(tail);
435                return string;
436              }
437            char *string() {
438                char *head=head_string();
439                char *tail=tail_string();
440                if(head==NULL || tail==NULL)
441                    abac_errx(1, "attribute string, head and tail can not be NULL");
442                char *tmp=NULL;
443                asprintf(&tmp,"%s<-%s",head,tail);
444                return tmp;
445              }
446            char *typed_string() {
447                char *head=head_typed_string();
448                char *tail=tail_typed_string();
449                if(head==NULL || tail==NULL)
450                    abac_errx(1, "attribute string, head and tail can not be NULL");
451                char *tmp=NULL;
452                asprintf(&tmp,"%s<-%s",head,tail);
453                return tmp;
454              }
455            const Role &role_head() {
456                abac_aspect_t *head=abac_attribute_head(m_attr);
457                static Role role=Role(head);
458                return role;
459              }
460            const Oset &oset_head() {
461                abac_aspect_t *head=abac_attribute_tail(m_attr);
462                static Oset oset=Oset(head);
463                return oset;
464              }
465            std::vector<Role> role_tails(bool &success) {
466                abac_aspect_t **tails, **end;
467                int i;
468                tails = abac_attribute_tail_vectorized(m_attr);
469                for (i = 0; tails[i] != NULL; ++i)
470                    ;
471                end = &tails[i];
472                std::vector<Role> roles = std::vector<Role>(tails, end);
473                abac_aspects_free(tails);
474                success=1;
475                return roles;
476              }
477            std::vector<Oset> oset_tails(bool &success) {
478                abac_aspect_t **tails, **end;
479                int i;
480                tails = abac_attribute_tail_vectorized(m_attr);
481                for (i = 0; tails[i] != NULL; ++i)
482                    ;
483                end = &tails[i];
484                std::vector<Oset> osets = std::vector<Oset>(tails, end);
485                success=1;
486                abac_aspects_free(tails);
487                return osets;
488              }
489            abac_attribute_t *attribute() { return m_attr; }
490
491/* Generate the cert. Call this after you've added subjects to your cert.
492   This returns false if there are no subjects
493   This will throw an exception if the cert's already been baked. */
494            bool bake() {
495                int rt=abac_attribute_bake(m_attr);
496                if(rt!=1)
497                    abac_errx(1, "bake, can not bake the cert");
498              }
499/* Returns true iff the cert has been baked. */
500            bool baked() {
501                return abac_attribute_baked(m_attr);
502              }
503/* Write the DER-encoded X.509 attribute cert to the open file handle
504   Throws an exception if the cert isn't baked */
505            void write_cert(FILE *out) {
506                int rt= abac_attribute_write(m_attr,out);
507                if(!rt)
508                    abac_errx(1, "write, cert is not baked");
509              }
510/* Write the DER-encoded X.509 attribute cert to a file named out
511   Throws an exception if the cert isn't baked */
512            void write_cert(char *filename) {
513                FILE *out = fopen(filename, "w");
514                printf("writing to %s\n", filename);
515                write_cert(out);
516                printf("done writing to %s\n", filename);
517                fclose(out);
518              }
519/* returns a DER-encoded binary representation of the X.509 attribute
520   cert associated with this cert
521   Throws an exception if the cert isn't baked
522   the chunk can be passed to libabac's Context::load_attribute_chunk() */
523            abac_chunk_t cert_chunk() {
524                return abac_attribute_cert_chunk(m_attr);
525              }
526      private:
527            abac_attribute_t *m_attr;
528     };
529
530
531    class Context {
532        public:
533            Context() { m_ctx = abac_context_new(); m_abac_version=strdup("1.0"); }
534            Context(const Context &context) { 
535                m_ctx = abac_context_dup(context.m_ctx);
536                m_abac_version=strdup(context.m_abac_version);
537              }
538            ~Context() { 
539                abac_context_free(m_ctx);
540                if(m_abac_version) free(m_abac_version);
541              }
542
543/* load an identity certificate, returns:
544      ABAC_CERT_SUCCESS   successfully loaded
545      ABAC_CERT_INVALID   invalid certificate (or file not found)
546      ABAC_CERT_BAD_SIG   invalid signature */
547            int load_id(ABAC::ID& id) {
548                return abac_context_load_id_id(m_ctx, id.id());
549              }
550            int load_id_file(char *filename, char *keyfilename) {
551                return abac_context_load_id_file(m_ctx, filename, keyfilename);
552              }
553            int load_id_chunk(abac_chunk_t cert) { 
554                return abac_context_load_id_chunk(m_ctx, cert);
555              }
556/* load an attribute certificate, returns the same values as above
557   * additionally can return ABAC_CERT_MISSING_ISSUER if the issuer
558   certificate has not been loaded */
559            int load_attribute(ABAC::Attribute& a) {
560                return abac_context_load_attribute_attribute(m_ctx, a.attribute());
561              }
562            int load_attribute_file(char *filename) { 
563                return abac_context_load_attribute_file(m_ctx, filename);
564              }
565            int load_attribute_chunk(abac_chunk_t cert) {
566                return abac_context_load_attribute_chunk(m_ctx, cert);
567              }
568/* load a directory full of certificates:
569   first: ${path}/*_ID.{der,pem} as identity certificates
570   then: ${path}/*_attr.der as attribute certificates */
571            void load_directory(char *path) {
572                abac_context_load_directory(m_ctx, path);
573              }
574/* run the query:
575       role <-?- principal
576   returns true/false in success
577   returns a proof upon success, partial proof on failure */
578            std::vector<Attribute> query(char *role, char *principal, bool &success) {
579                 abac_credential_t **creds, **end;
580                 int i, success_int;
581
582                 creds = abac_context_query(m_ctx, role, principal, &success_int);
583                 success = success_int;
584
585                 for (i = 0; creds[i] != NULL; ++i)
586                    ;
587
588                 end = &creds[i];
589                 std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
590                 if(debug) printf("rules, got (%d)\n", i);
591
592                 abac_context_credentials_free(creds);
593
594                 return attributes;
595              }
596
597/* returns a vector of all the credentials loaded in the context */
598            std::vector<Attribute> context_credentials(bool &success) {
599                abac_credential_t **creds, **end;
600                int i;
601                success = 1;
602
603                creds = abac_context_credentials(m_ctx);
604                for (i = 0; creds[i] != NULL; ++i)
605                    ;
606
607                end = &creds[i];
608                std::vector<Attribute> attributes = std::vector<Attribute>(creds, end);
609                if(debug) printf("credentials, got (%d)\n", i);
610
611                abac_context_credentials_free(creds);
612                return attributes;
613              }
614           
615            char *version() const { return m_abac_version; }
616
617        private:
618            abac_context_t *m_ctx;
619            char *m_abac_version;
620    };
621
622    Constraint::Constraint(Role *role)
623    { m_constraint=abac_condition_from_aspect(role->role()); }
624    Constraint::Constraint(Oset *oset)
625    { m_constraint=abac_condition_from_aspect(oset->oset()); }
626}
627
628#endif /* __ABAC_HH__ */
Note: See TracBrowser for help on using the repository browser.