source: libabac/abac_verifier.c @ 549656e

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

1) fix the missing check for 'This' rt2.y when called from creddy/prover

combo

2) patch up the stringify of abac_term that is of time type.
3) update the testing to reflect the changes to baseline output

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