source: libabac/abac_verifier.c @ 5730a10

mei_rt2mei_rt2_fix_1 libabac-0.2.1
Last change on this file since 5730a10 was 9b43fc3, checked in by Mei <mei@…>, 12 years ago

1) add code to load id into context with both cert chunk and privkey
chunk
2) test out the sample scripts in swig/perl and swig/python

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