source: libabac/abac_verifier.c @ 7211a95

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

1) modify abac.hh and added abac_c.c to unify the c and c++ api

interface (almost)

2) add new API
3) tweak the tests
4) filling missing code for abac_verifier_load_attribute_cert_attribute

  • Property mode set to 100644
File size: 26.4 KB
Line 
1/**
2**  abac_verifier.c
3**/
4
5// include the GNU extension of asprintf
6#define _GNU_SOURCE
7
8#include <stdio.h>
9#include <regex.h>
10#include <sys/mman.h>
11#include <fcntl.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <unistd.h>
15
16
17#include <assert.h>
18#include <stdio.h>
19
20#include <library.h>
21
22#include "abac_internal.h"
23#include "abac_verifier.h"
24
25#include "abac_util.h"
26#include "abac_rt.h"
27
28static int debug=0;
29 
30/* from abac_attribute.c */
31extern char *get_cred_encoding(abac_attribute_t *ptr);
32
33extern abac_aspect_t *abac_yy_get_rule_head_aspect();
34extern abac_aspect_t *abac_yy_get_rule_tail_aspect();
35extern abac_list_t *abac_yy_get_rule_clauses();
36extern char* abac_decode_string(char *);
37extern void abac_yy_free_rule_clauses();
38extern char *generate_pl_type_clause(char *, int);
39extern abac_list_t *generate_pl_clauses(abac_aspect_t *, abac_aspect_t *);
40
41extern void abac_print_aspect_string_with_condition(abac_aspect_t *role, FILE*);
42
43struct _abac_id_credential_t {
44    char *hashkeyid; 
45    abac_id_t *id;
46    char *pl_clause;
47
48    UT_hash_handle hh;
49};
50/* hash table base on sha with a p */
51abac_id_credential_t *id_creds = NULL;
52/* linked list of all the ids's hashkeyid */
53abac_list_t *id_hashkeyid_list = NULL;
54
55/* can store either role or oset */
56struct _abac_credential_t {
57    char *hashkeyid;
58    abac_attribute_t *attr;
59    abac_list_t *pl_clauses;
60
61    UT_hash_handle hh;
62};
63/* hash table base on encoded attr rule */
64abac_credential_t *attr_creds = NULL;
65/* linked list of all the attr's hashkeyid */
66abac_list_t *attr_hashkeyid_list = NULL;
67
68/*****************************************************************************/
69void abac_print_cred_info(abac_credential_t *cred, FILE *fp)
70{
71    if(fp == NULL)
72        fp=stdout;
73
74    abac_attribute_t *ptr=cred->attr;
75    abac_aspect_t *head=abac_attribute_head(ptr);
76    abac_aspect_t *tail=abac_attribute_tail(ptr);
77
78    if(debug) {
79        fprintf(fp,"---> printing out credential info cred(%d)..\n", (int) cred);
80        if(head) {
81            abac_print_aspect_string_with_condition(head,fp);
82        }
83        if(tail) {
84            abac_print_aspect_string_with_condition(tail,fp);
85        }
86
87        abac_list_t *clauses=cred->pl_clauses;
88        if (clauses != NULL) {
89            char *cur=NULL;
90            abac_list_foreach(clauses, cur,
91                fprintf(fp,"\n  a clause(%d):\n",(int)cur);
92                if(cur)
93                    fprintf(fp,"strlen(%d)loc(%d)(%s)\n", strlen(cur),(int)cur, cur);
94            );
95        }
96        } else {
97            fprintf(fp," ");
98            abac_print_aspect_string_with_condition(head,fp);
99            fprintf(fp," <- ");
100            abac_print_aspect_string_with_condition(tail,fp);
101            fprintf(fp,"\n");
102   }
103}
104
105void abac_print_prin_info(abac_id_credential_t *prin, FILE *fp)
106{
107    if(fp == NULL)
108        return;
109
110    abac_id_t *ptr=abac_id_credential_id(prin);
111
112    if(debug) fprintf(fp,"---> printing out principal info ..\n");
113    if(abac_id_has_privkey(ptr))
114        fprintf(fp," (%s,%s,y)\n",abac_id_name(ptr),abac_id_idtype_string(ptr));
115        else
116            fprintf(fp," (%s,%s,n)\n",abac_id_name(ptr),abac_id_idtype_string(ptr));
117}
118
119//
120int abac_verify_idtype_type(char *type) {
121    int i;
122
123    if (type == NULL)
124        return 0;
125
126    for (i = 1; i <= _idtypename_cnt ; i++)
127        if(strcmp(type,_idtypename[i])==0)
128            return i;
129    return 0;
130}
131
132char *abac_idtype_string(int i)
133{
134    if(i > _idtypename_cnt) {
135        printf("bad idtypename idx %d\n", i);
136        panic("abac_idtype_string: went out of range on idtypename");
137    }
138    return (char*) _idtypename[i];
139}
140
141// convert a chunk to a lowercase binary string
142// malloc's the string
143static char *_chunk_to_string(chunk_t chunk) {
144    int i;
145
146    char *ret = abac_xmalloc(chunk.len * 2 + 1);
147
148    for (i = 0; i < chunk.len; ++i)
149        sprintf(ret + 2 * i, "%02x", chunk.ptr[i]);
150
151    return ret;
152}
153
154// verify that cert was issued by issuer
155// cert and issuer can be the same, in which case the self-sig is validated
156static int _verify_signature(certificate_t *issuer_cert, certificate_t *cert) {
157    if (cert->issued_by(cert, issuer_cert))
158        if (cert->get_validity(cert, NULL, NULL, NULL))
159            return 1;
160    return 0;
161}
162
163/**
164 * Init the verifier subsystem.
165 */
166void abac_verifier_init(void) {
167    // silence all debugging
168
169    if (!library_init(NULL))
170        exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
171
172    if (!lib->plugins->load(lib->plugins, NULL,
173            lib->settings->get_str(lib->settings, "pki.load", PLUGINS)))
174        exit(SS_RC_INITIALIZATION_FAILED);
175
176    attr_hashkeyid_list = abac_list_new();
177    id_hashkeyid_list = abac_list_new();
178}
179
180/**
181 * Uninitialize the system, free up any allocated memory.
182 */
183void abac_verifier_deinit(void) {
184    abac_id_credential_t *ptr;
185    while ((ptr = id_creds) != NULL) {
186        if(debug) printf("abac_verifier_deinit: deleting id (%s)\n",abac_id_name(ptr->id));
187        HASH_DEL(id_creds, ptr);
188
189        free(ptr->hashkeyid);
190        free(ptr->pl_clause);
191        abac_id_free(ptr->id);
192        free(ptr);
193    }
194
195    abac_credential_t *ptr2;
196    while ((ptr2 = attr_creds) != NULL) {
197        HASH_DEL(attr_creds, ptr2);
198        if(debug) {
199           printf("abac_verifier_deinit: deleting attr hashkey(%s)\n",ptr2->hashkeyid); 
200        }
201        free(ptr2->hashkeyid);
202        abac_attribute_free(ptr2->attr);
203        char *cur=NULL;
204        abac_list_foreach(ptr2->pl_clauses, cur,
205              free(cur);
206        );
207        free(ptr2->pl_clauses);
208        free(ptr2);
209    }
210
211    if(attr_hashkeyid_list) { 
212        char *cur;
213        if(attr_hashkeyid_list) {
214            abac_list_foreach(attr_hashkeyid_list, cur,
215                if(cur) free(cur);
216            );
217        }
218        abac_list_free(attr_hashkeyid_list);
219    }
220    if(id_hashkeyid_list) { 
221        char *cur;
222        if(id_hashkeyid_list) {
223            abac_list_foreach(id_hashkeyid_list, cur,
224                if(cur) free(cur);
225            );
226        }
227        abac_list_free(id_hashkeyid_list);
228    }
229
230    library_deinit();
231}
232
233abac_id_credential_t *abac_verifier_add_id_credential(abac_id_t *a_id)
234{ 
235    abac_id_credential_t *id_cred;
236    char *cn=abac_id_cn(a_id);
237    char *keyid=abac_id_keyid(a_id);
238
239    if(debug) {
240         printf("abac_verifier_add_id_credential, cn(%s),keyid(%s)\n",
241                cn, keyid);
242    }
243
244    // add the abac_id to the map of id credentials
245    id_cred = abac_xmalloc(sizeof(abac_id_credential_t));
246    id_cred->hashkeyid = abac_xstrdup(keyid);
247    id_cred->id=abac_id_dup(a_id);
248
249    /* special handling here */
250    if(USE("ABAC_CN")) {
251        id_cred->pl_clause = generate_pl_type_clause(cn, abac_id_idtype(a_id));
252        } else {
253           id_cred->pl_clause=generate_pl_type_clause(prologIt(keyid), abac_id_idtype(a_id));
254    }
255    HASH_ADD_KEYPTR(hh, id_creds, id_cred->hashkeyid, strlen(id_cred->hashkeyid), id_cred);
256    if(debug)
257        printf("-->adding into id_creds, (%s)..cnt(%d)\n",
258                                   id_cred->hashkeyid, HASH_COUNT(id_creds));
259
260    assert(id_hashkeyid_list);
261    abac_list_add(id_hashkeyid_list, abac_xstrdup(id_cred->hashkeyid));
262    return id_cred;
263}
264
265/**
266 * Load an ID
267 */
268static int _load_id(abac_id_t **a_id,certificate_t *cert, abac_id_credential_t **id_cred_ret) {
269    abac_id_credential_t *id_cred = NULL;
270    char *keyid = NULL;
271    chunk_t id;
272    int ret;
273    x509_t *x509 = (x509_t *)cert;
274
275    assert(cert != NULL);
276
277    // get the key ID, add p to keyid SHA here */
278    id = x509->get_subjectKeyIdentifier(x509);
279    keyid = _chunk_to_string(id);
280
281    /* Mike said this is the way it is */
282    char *str;
283    int rv = asprintf(&str, "%Y", cert->get_issuer(cert));
284
285    /* add p to cn name here */
286    char *cn=(char *)abac_xmalloc(strlen(str)+2);
287    cn[0]='p';
288    int n=sscanf(str,"CN=%s", &(cn[1]));
289    if ( n!=1 ) { 
290        ret = ABAC_CERT_BAD_CN;
291        goto error;
292    }
293
294    if(debug) {
295        printf ("DEBUG:keyid %s \n", keyid);
296        printf( "DEBUG:issuer '%s' \n", str);
297        printf ("DEBUG:cn %s \n", cn);
298    }
299    free(str);
300
301    // if we already have this cert 'error' with success
302    HASH_FIND_STR(id_creds, keyid, id_cred);
303    if (id_cred != NULL) {
304        if(debug) printf("existing cert \n");
305        ret = ABAC_CERT_EXISTS;
306        goto error;
307    }
308
309    // validate sig
310    ret = _verify_signature(cert, cert);
311    if (!ret) {
312        ret = ABAC_CERT_BAD_SIG;
313        goto error;
314    }
315
316    // success, add a new abac_id
317    if(*a_id==NULL) {
318        *a_id=abac_id_keyid_new(keyid,cn,cert);
319    }
320
321    abac_id_credential_t *n_id_cred=abac_verifier_add_id_credential(*a_id);
322    *id_cred_ret=n_id_cred;
323
324    return ABAC_CERT_SUCCESS;
325
326error:
327    if (keyid != NULL) free(keyid);
328    if (cn != NULL) free(cn);
329
330    return ret;
331}
332
333/* collect all the creds stored so far */
334abac_stack_t *abac_verifier_dump_creds()
335{
336    abac_stack_t *cred_list = abac_stack_new();
337
338    int cnt=0;
339    if(attr_hashkeyid_list) {
340        char *keyid;
341        abac_credential_t *cred;
342        abac_list_foreach(attr_hashkeyid_list, keyid,
343            cred=abac_credential_lookup(keyid);
344            abac_stack_push(cred_list, cred);
345            cnt++;
346        );
347    }
348    if(debug) printf("abac_verifier_dump_cred: %d\n",cnt);
349    return cred_list;
350}
351
352/* collect all the id stored so far */
353abac_stack_t *abac_verifier_dump_principals()
354{
355    abac_stack_t *id_list = abac_stack_new();
356
357    int cnt=0;
358    if(id_hashkeyid_list) {
359        char *keyid;
360        abac_id_credential_t *id;
361        abac_list_foreach(id_hashkeyid_list, keyid,
362            id=abac_id_credential_lookup(keyid);
363            abac_stack_push(id_list, id);
364            cnt++;
365        );
366    }
367    if(debug) printf("abac_verifier_dump_principals: %d\n",cnt);
368    return id_list;
369}
370
371
372static void check_id_cred(abac_id_credential_t *id_cred)
373{
374    if(id_cred) {
375        printf("checking on this id_cred location %d\n", (int)id_cred);
376        printf("  --> sha is (%s)\n", abac_id_keyid(id_cred->id));
377        printf("  --> cn is (%s)\n", abac_id_cn(id_cred->id));
378    }
379}
380
381/**
382 * Load an attribute cert as string.
383 * have minimum syntax & validity check
384 */
385static int _load_attribute_string(char* attr_string) {
386    printf("NOT implemented yet!!!");
387    return ABAC_CERT_INVALID;
388}
389
390int _exist(char *filename)
391{
392   struct stat stbuf;
393   if(stat(filename,&stbuf) == -1)
394       return 0;
395   return 1;
396}
397
398/**
399 * Load an ID cert from a file.
400 */
401int abac_verifier_load_id_file_key_file(char *filename, char *keyfilename, abac_id_credential_t **id_cred_ret) {
402    abac_id_t *id=NULL;
403    if (lib == NULL)
404        errx(1, "looks like you didn't call libabac_init() (lib is NULL)");
405
406    if(debug) printf("loading id file... %s\n", filename);
407
408    // load the cert, with pubic key
409    certificate_t *cert = lib->creds->create(
410        lib->creds, CRED_CERTIFICATE, CERT_X509,
411        BUILD_FROM_FILE, filename,
412        BUILD_X509_FLAG, X509_AA, // attribute authority, dumb
413        BUILD_END
414    );
415
416    if (cert == NULL)
417        return ABAC_CERT_INVALID;
418
419    int rc=_load_id(&id,cert,id_cred_ret);
420    if(rc==ABAC_CERT_EXISTS) {
421        if(debug) printf("abac_verifier_load_id_files: id already exists\n");
422        return ABAC_CERT_SUCCESS;
423    } 
424
425    /* try to load the private key if it is there */
426    if((rc==ABAC_CERT_SUCCESS) && keyfilename!=NULL && _exist(keyfilename)) {
427        if(debug) printf("loading... %s\n", keyfilename);
428        int keyrc=abac_id_load_privkey_file(id, keyfilename);
429        if(debug) {
430           if(keyrc == 1) printf("..load_id_file: load(%s) with a private key\n",filename);
431               else printf("..load_id_file: load(%s) without a private key\n",filename);
432        }
433    }
434    return rc;
435}
436
437/**
438 * Load an ID cert from a abac_id_t
439 */
440int abac_verifier_load_id_id(abac_id_t *id, abac_id_credential_t **id_cred_ret) {
441    certificate_t *cert = abac_id_cert(id);
442    return _load_id(&id,cert,id_cred_ret);
443}
444
445/**
446 * Load an ID cert from a chunk.
447 */
448int abac_verifier_load_id_pem_chunk(chunk_t chunk, abac_id_credential_t **id_cred_ret) {
449    abac_id_t *id=NULL;
450    // load the cert
451    certificate_t *cert = lib->creds->create(
452        lib->creds, CRED_CERTIFICATE, CERT_X509,
453        BUILD_BLOB_PEM, chunk,
454        BUILD_X509_FLAG, X509_AA, // attribute authority, dumb
455        BUILD_END
456    );
457    if (cert == NULL)
458        return ABAC_CERT_INVALID;
459    return _load_id(&id, cert,id_cred_ret);
460}
461/**
462 * Load an ID cert from a chunk.
463 */
464int abac_verifier_load_id_chunk(chunk_t chunk, abac_id_credential_t **id_cred_ret) {
465    abac_id_t *id=NULL;
466    // load the cert
467    certificate_t *cert = lib->creds->create(
468        lib->creds, CRED_CERTIFICATE, CERT_X509,
469        BUILD_BLOB_ASN1_DER, chunk,
470        BUILD_X509_FLAG, X509_AA, // attribute authority, dumb
471        BUILD_END
472    );
473    if (cert == NULL)
474        return ABAC_CERT_INVALID;
475    return _load_id(&id, cert,id_cred_ret);
476}
477
478
479static int matchex(const char *subject, const char *pattern, int *so, int *eo)
480{
481int rc; // Returned code
482regmatch_t pmatch;
483
484regex_t re; // Compiled regexp pattern
485
486if (regcomp(&re, pattern, 0) != 0) return 0;
487
488rc = regexec(&re, subject, 1 , &pmatch, 0);
489regfree(&re); 
490
491if (rc == REG_NOMATCH ) return 0; 
492
493*so=pmatch.rm_so;
494*eo=pmatch.rm_eo;
495
496return 1;
497}
498
499
500
501static chunk_t _extract_chunk(char *data, char* startline, char* endline)
502{
503    int found=0;
504    int startos=0;
505    int endos=0;
506    regex_t re;
507    regmatch_t pm;
508    int rc;
509
510    int st;
511    int et;
512
513    rc=matchex(data, startline, &st, &et);
514    if(rc==0) return chunk_empty;
515    startos=st;
516
517    rc=matchex(data, endline, &st, &et);
518    if(rc==0) return chunk_empty;
519    endos=et;
520   
521    int len=endos - startos; 
522
523    if(debug) printf("making a chunk of size (%d) from %d and %d\n",len, startos,endos);
524    char *ptr=strndup(data+startos,len);
525
526    chunk_t ret = { ptr, len };
527    return ret;
528}
529
530   
531int abac_verifier_load_idkey_file(char *filename, abac_id_credential_t **id_cred_ret)
532{
533    struct stat sb;
534    int fd;
535    int rc;
536
537    fd = open(filename, O_RDONLY);
538    if (fd == -1) { return 1; }
539    if(stat(filename, &sb) == -1) {
540        close(fd);
541        return 1;
542    }
543    char* data = (char *)mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
544    if(data == MAP_FAILED) {
545        close(fd);
546        return 1;
547    }
548    close(fd);
549
550    chunk_t key_pem_chunk=_extract_chunk(data,
551               "-----BEGIN RSA PRIVATE KEY-----","-----END RSA PRIVATE KEY-----");
552    chunk_t cert_pem_chunk=_extract_chunk(data,
553                   "-----BEGIN CERTIFICATE-----","-----END CERTIFICATE-----");
554
555    /* key=0, cert=0 */
556    if(key_pem_chunk.len==0 && cert_pem_chunk.len==0) {
557        if(debug) printf("abac_verifier_load_idkey_file: no key or id in idkey_file\n");
558        goto error;
559    }
560
561    /* key=0, cert=1 */
562    if(key_pem_chunk.len==0) {
563        if(debug) printf("abac_verifier_load_idkey_file: no key in idkey_file\n");
564        munmap(data, sb.st_size);
565        chunk_free(&key_pem_chunk);
566        return abac_verifier_load_id_file_key_file(filename,NULL,id_cred_ret);
567    }
568
569    /* key=1, cert=1 */
570    if(cert_pem_chunk.len!=0) {
571        if(debug) {
572            printf("loading cert pem chunk %d\n", cert_pem_chunk.len);
573            printf("(%s)\n",cert_pem_chunk.ptr);
574        }
575        rc=abac_verifier_load_id_pem_chunk(cert_pem_chunk, id_cred_ret);
576        if(rc != 0) {
577            if(debug) printf("abac_verifier_load_idkey_file: fail to load the id\n");
578            goto error;
579        }
580    /* key=1, cert=0 */
581        } else {
582            if(debug) printf("abac_verifier_load_idkey_file: there is no id info in there\n");
583            goto error;
584    }
585   
586    /* handle the key_pem_chunk */
587    if(debug)  {
588        printf("loading key pem chunk %d\n", key_pem_chunk.len);
589        printf("(%s)\n",key_pem_chunk.ptr);
590    }
591    abac_id_t *id=abac_id_credential_id(*id_cred_ret);
592    rc=abac_id_load_privkey_chunk(id, key_pem_chunk);
593    if(rc==0) {
594        printf("abac_verifier_load_idkey_file:failed to load priv key!!!\n");
595        goto error;
596    }
597
598    munmap(data, sb.st_size);
599    return 0;
600
601error:
602    munmap(data, sb.st_size);
603    return 1;
604}
605
606
607
608void abac_print_clauses(abac_list_t *clauses, FILE *fp)
609{
610    if (clauses != NULL) {
611        char *cur;
612        printf("total-- %d clauses\n", abac_list_size(clauses));
613        abac_list_foreach(clauses, cur,
614            if(cur) {
615                if(fp)
616                    fprintf (fp,"a clause, %d(%s)\n", (int)cur,cur);
617                    else printf ("a clause, %d(%s)\n", (int)cur,cur);
618            }
619        );
620    }
621}
622
623abac_id_credential_t *abac_id_credential_dup(abac_id_credential_t *ptr) {
624    assert(ptr != NULL);
625    abac_id_dup(ptr->id);
626    return ptr;
627}
628
629abac_id_t *abac_id_credential_id(abac_id_credential_t *ptr)
630{
631    assert(ptr);
632    return ptr->id;
633}
634
635
636abac_id_credential_t *abac_id_credential_lookup(char *pname)
637{
638    abac_id_credential_t *id_cred=NULL;
639    HASH_FIND_STR(id_creds, pname, id_cred);
640    if(id_cred != NULL)
641        return abac_id_credential_dup(id_cred);
642    else return NULL;
643}
644
645void abac_id_credential_free(abac_id_credential_t *ptr)
646{
647    if (ptr == NULL)
648        return;
649
650    if(debug)
651        printf("abac_id_credential_free:freeing (%s)\n", abac_id_name(ptr->id));
652
653    // this is very hacky...
654    int last=abac_id_lastone(ptr->id);
655    if(!last) {
656        if(debug) printf("abac_id_credential_free:not last one\n");
657        abac_id_free(ptr->id);
658        } else {
659            if(debug) printf("abac_id_credential_free: deleting id (%s)\n",abac_id_name(ptr->id));
660            free(ptr->hashkeyid);
661            if(ptr->pl_clause)
662                free(ptr->pl_clause);
663            abac_id_free(ptr->id);
664            HASH_DEL(id_creds, ptr);
665            free(ptr);
666    }
667}
668
669/****************************************************************************/
670
671static int _verify_valid_credential_string(certificate_t *cert,
672abac_credential_t **cred_ret, char *encoded_attr_string)
673{
674    abac_aspect_t *head_aspect = NULL;
675    abac_aspect_t *tail_aspect = NULL;
676    abac_list_t *clauses=NULL;
677    abac_id_credential_t *id_cred;
678    abac_id_t *issuer_id;
679    int ret, i;
680
681    // get the attr
682    head_aspect = abac_yy_get_rule_head_aspect();
683    tail_aspect = abac_yy_get_rule_tail_aspect();
684    clauses = abac_yy_get_rule_clauses();
685
686    // get the issuer based on keyid
687    char *principalname = abac_aspect_principal_principalname(head_aspect);
688    if(debug) printf("LOOKING for %s\n", principalname);
689
690    HASH_FIND_STR(id_creds, principalname, id_cred);
691    if(id_cred == NULL) {
692        ret = ABAC_CERT_MISSING_ISSUER;
693        if(debug)
694             printf("can not find %s in id_creds\n", principalname);
695        goto error;
696    }
697    issuer_id=id_cred->id;
698    if (issuer_id == NULL) {
699        ret = ABAC_CERT_MISSING_ISSUER;
700        if(debug)
701             printf("can not find %s in id_creds\n", principalname);
702        goto error;
703    }
704
705
706    // make sure the issuer's signed it
707    ret = _verify_signature(abac_id_cert(issuer_id), cert);
708    if (!ret) {
709        abac_yy_set_error_code(ABAC_RT_CERT_BAD_SIG);
710        ret=ABAC_CERT_BAD_SIG;
711        goto error;
712    }
713
714    // at this point we know we have a good attribute cert baked it in
715    abac_attribute_t *attr=abac_attribute_new(issuer_id, cert, cert->get_ref(cert));
716    abac_attribute_set_head(attr, head_aspect);
717    abac_attribute_add_tail(attr, tail_aspect);
718
719    abac_credential_t *cred = abac_xmalloc(sizeof(abac_credential_t));
720    cred->hashkeyid=abac_xstrdup(encoded_attr_string);
721    cred->attr=attr;
722    cred->pl_clauses = clauses;
723    *cred_ret = cred;
724
725    // success, add the key to the map of certificates
726    HASH_ADD_KEYPTR(hh, attr_creds, cred->hashkeyid, strlen(cred->hashkeyid), cred);
727
728    assert(attr_hashkeyid_list);
729    abac_list_add(attr_hashkeyid_list, abac_xstrdup(cred->hashkeyid));
730    return ABAC_CERT_SUCCESS;
731
732error:
733    if (head_aspect) abac_aspect_free(head_aspect);
734    if (tail_aspect) abac_aspect_free(tail_aspect);
735    abac_yy_free_rule_clauses();
736
737    return ret;
738}
739
740/**
741 * Load an attribute cert.
742 * Returns true only if the certificate is valid and is issued by the proper
743 * authority.
744 * attribute string is parsed via yyparse call
745 */
746static int _load_attribute_cert(certificate_t *cert, abac_credential_t **cred_ret) {
747    ietf_attributes_t *attr_cert = NULL;
748    abac_id_credential_t *issuer;
749    int ret, i;
750
751    // get the attr
752    ac_t *ac = (ac_t *)cert;
753    attr_cert = ac->get_groups(ac);
754    if (attr_cert == NULL) {
755        ret = ABAC_CERT_INVALID;
756        goto error;
757    }
758
759    char *encoded_attr_string=attr_cert->get_string(attr_cert);
760    char *attr_string = abac_decode_string(encoded_attr_string);
761    if(debug)
762         printf("string to be yyparse..(%s)\n",attr_string);
763
764    if (attr_string == NULL) {
765        ret = ABAC_CERT_INVALID;
766        goto error;
767    }
768
769    /* call into yacc parser */
770    abac_reset_yyfptr(attr_string);
771    abac_yy_init();
772    int rc=yyparse();
773    if (rc) {
774        ret = ABAC_CERT_INVALID;
775        goto error;
776    }
777
778    ret=_verify_valid_credential_string(cert,cred_ret,encoded_attr_string);
779
780    if(ret != ABAC_CERT_SUCCESS) {
781        panic("_load_attribute_cert: fail to process (%s)",encoded_attr_string);
782    }
783
784    // free up some crap
785    attr_cert->destroy(attr_cert);
786
787    return ret;
788
789error:
790    if (cert) cert->destroy(cert);
791    if (attr_cert) attr_cert->destroy(attr_cert);
792    return ret;
793}
794
795/**
796 * Load an attribute cert from a abac_attribute_t.
797 * attr should be all checked out before arriving here
798 */
799int abac_verifier_load_attribute_cert_attribute(abac_attribute_t *ptr, abac_credential_t **cred_ret) {
800    // get the attr
801    abac_aspect_t *head=abac_attribute_head(ptr);
802    abac_aspect_t *tail=abac_attribute_tail(ptr);
803
804    // preprocess for constraint part
805    preprocess_pl_head(head);
806    preprocess_pl_tail(tail);
807
808/* XXX collect up type clauses, constraint clauses and
809   generate rule clauses */
810    abac_list_t *clauses=generate_pl_clauses(head,tail);
811    char *encoded_attr_string=get_cred_encoding(ptr);
812
813    abac_credential_t *cred = abac_xmalloc(sizeof(abac_credential_t));
814    cred->hashkeyid=abac_xstrdup(encoded_attr_string);
815    cred->attr=abac_attribute_dup(ptr);
816    cred->pl_clauses = clauses;
817    *cred_ret = cred;
818
819    // success, add the key to the map of certificates
820    HASH_ADD_KEYPTR(hh, attr_creds, cred->hashkeyid, strlen(cred->hashkeyid), cred);
821
822    assert(attr_hashkeyid_list);
823    abac_list_add(attr_hashkeyid_list, abac_xstrdup(cred->hashkeyid));
824    return ABAC_CERT_SUCCESS;
825}
826
827/**
828 * Load an attribute cert from a file.
829 */
830int abac_verifier_load_attribute_cert_file(char *filename, abac_credential_t **cred) {
831    // load the cert
832    if(debug) printf("..loading attr file %s\n", filename);
833    certificate_t *cert = lib->creds->create(
834        lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
835        BUILD_FROM_FILE, filename,
836        BUILD_END
837    );
838    if (cert == NULL)
839        return ABAC_CERT_INVALID;
840    return _load_attribute_cert(cert, cred);
841}
842
843/**
844 * Load an attribute cert from a chunk.
845 */
846int abac_verifier_load_attribute_cert_chunk(chunk_t chunk, abac_credential_t **cred) {
847    // load the cert
848    certificate_t *cert = lib->creds->create(
849        lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
850        BUILD_BLOB_ASN1_DER, chunk,
851        BUILD_END
852    );
853    if (cert == NULL)
854        return ABAC_CERT_INVALID;
855    return _load_attribute_cert(cert, cred);
856}
857
858/**
859 * Return the encoding of the attribute cert.
860 */
861abac_chunk_t abac_credential_attribute_cert(abac_credential_t *cred) {
862    abac_attribute_t *ptr=cred->attr;
863    certificate_t *cert=abac_attribute_cert(ptr);
864    chunk_t encoding = cert->get_encoding(cert);
865    abac_chunk_t ret = { encoding.ptr, encoding.len };
866    return ret;
867}
868
869/**
870 * Return the encoding of the issuer cert.
871 */
872abac_chunk_t abac_credential_issuer_cert(abac_credential_t *cred) {
873    certificate_t *issuer_cert=abac_attribute_issuer_cert(cred->attr);
874    assert(issuer_cert);
875    chunk_t encoding = issuer_cert->get_encoding(issuer_cert);
876    abac_chunk_t ret = { encoding.ptr, encoding.len };
877    return ret;
878}
879
880/**
881 * Return the clause of the cert
882 */
883abac_list_t *abac_credential_clauses(abac_credential_t *cred) {
884    return cred->pl_clauses;
885}
886
887abac_attribute_t *abac_credential_attribute(abac_credential_t *cred) {
888    assert(cred);
889    return cred->attr;
890}
891
892/**
893 * Increase the ref count of a credential.
894 */
895abac_credential_t *abac_credential_dup(abac_credential_t *cred) {
896    assert(cred != NULL);
897
898    abac_attribute_dup(cred->attr);
899    return cred;
900}
901
902/**
903 *  lookup for a credential.
904 */
905abac_credential_t *abac_credential_lookup(char* cred_string)
906{
907    if(debug)
908        printf("abac_credential_lookup: looking for (%s)\n", cred_string);
909    abac_credential_t *attr_cred;
910    HASH_FIND_STR(attr_creds, cred_string, attr_cred);
911    if (attr_cred == NULL) {
912        if(debug) printf("DEBUG:NOT FOUND..\n");
913        return NULL;
914    }
915    abac_credential_t *rt=abac_credential_dup(attr_cred);
916    if(debug) printf("DEBUG:FOUND.. (%d) returning, (%d)\n", (int)attr_cred, (int) rt);
917    return rt;
918}
919
920/**
921 * Decrease the reference count of a credential, freeing it when it reaches 0.
922 */
923void abac_credential_free(abac_credential_t *cred)
924{
925    if(debug)
926        printf("abac_credential_free:freeing cred(%d)clause(%d)\n", (int)cred, (int)cred->pl_clauses);
927
928    if (cred == NULL)
929        return;
930
931    // this is very hacky...
932    int last=abac_attribute_lastone(cred->attr);
933    if(!last) {
934        abac_attribute_free(cred->attr);
935        } else {
936            free(cred->hashkeyid);
937            char *cur=NULL;
938            abac_list_foreach(cred->pl_clauses, cur,
939                free(cur);
940            );
941            abac_attribute_free(cred->attr);
942            HASH_DEL(attr_creds, cred);
943            free(cred);
944    }
945}
946
947char *abac_id_clause(abac_id_credential_t *id_cred)
948{
949    if(id_cred)
950        return id_cred->pl_clause;
951    return NULL;
952}
953
954/* retrieve the cn that is associated with this sha_string */
955char *abac_cn_with_sha(char *sha_string)
956{
957    // get the issuer based on keyid
958    abac_id_credential_t *id_cred;
959    HASH_FIND_STR(id_creds, sha_string, id_cred);
960    if (id_cred == NULL) {
961        return NULL;
962    }
963    if(debug)
964        check_id_cred(id_cred);
965    return abac_id_cn(id_cred->id);
966}
967
968char *abac_idtype_with_sha(char* sha_string)
969{ 
970    // get the issuer based on keyid
971    abac_id_credential_t *id_cred;
972    HASH_FIND_STR(id_creds, sha_string, id_cred);
973    if (id_cred == NULL) {
974        return NULL;
975    }
976    int idtype=abac_id_idtype(id_cred->id);
977   
978    return abac_idtype_string(idtype);
979}
980
981abac_aspect_t *abac_credential_head(abac_credential_t *cred) {
982    return abac_attribute_head(cred->attr); 
983}
984
985abac_aspect_t *abac_credential_tail(abac_credential_t *cred) {
986    return abac_attribute_tail(cred->attr); 
987}
988
989
Note: See TracBrowser for help on using the repository browser.