source: libabac/abac_verifier.c @ 669b481

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

1) finish test conversion from creddy-prover to python
2) update the abac.hh/API doc more, adding more intermediate calls

to make abac.hh more uniform

3) found out why a very long attribute rule can not survive in/out of

ietf_attribute_t call (m64 en/decoding - abac_verifier, alice_rt1)

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