source: libabac/abac_verifier.c @ ed3dc05

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

1) reorganized the test directory to include python tests
2) attribute via api and principal via api from python scripts is

working (although there is a annoying seg fault at the very end
that must be related to something not been dup()ed.. need to wait
for c example to debug it)

3) able to query via api
4) replicated access_rt2 example in python and the query result matches
5) expanded api to make it easier to generate rt2 structure

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