Index: creddy/attr.c
===================================================================
--- creddy/attr.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ 	(revision )
@@ -1,239 +1,0 @@
-#include <assert.h>
-#include <ctype.h>
-#include <string.h>
-#include <time.h>
-
-#include "libcreddy_common.h"
-
-#define ROLE_SEPARATOR " <- "
-#define INTERSECTION_SEP " & "
-#define SHA1_LENGTH 40
-
-struct _creddy_attribute_t {
-    creddy_id_t *issuer;
-    char *role;
-    int validity;
-
-    char **subject;
-    int num_subjects;
-    int size_subjects;
-    int total_len; // total length of all subject strings
-
-    certificate_t *cert; // NULL until baked
-};
-
-static char *_validate_principal(char *keyid);
-static void _append(creddy_attribute_t *attr, char *subject);
-char *_get_role_encoding(creddy_attribute_t *attr);
-
-// validity is measured in seconds (as of 0.2.0)
-int creddy_attribute_create(creddy_attribute_t **ret, creddy_id_t *issuer, char *role, int validity) {
-    if (creddy_id_privkey(issuer) == NULL)
-        return CREDDY_ATTRIBUTE_ISSUER_NOKEY;
-    if (!creddy_clean_name(role))
-        return CREDDY_ATTRIBUTE_INVALID_ROLE;
-    if (validity < 0)
-        return CREDDY_ATTRIBUTE_INVALID_VALIDITY;
-
-    creddy_attribute_t *attr = creddy_xmalloc(sizeof(creddy_attribute_t));
-    attr->issuer = creddy_id_dup(issuer);
-    attr->role = creddy_xstrdup(role);
-    attr->validity = validity;
-
-    attr->num_subjects = 0;
-    attr->size_subjects = 4;
-    attr->subject = creddy_xmalloc(sizeof(char *) * attr->size_subjects);
-    attr->total_len = 0;
-
-    // NULL until baked
-    attr->cert = NULL;
-
-    *ret = attr;
-    return CREDDY_SUCCESS;
-}
-
-int creddy_attribute_principal(creddy_attribute_t *attr, char *keyid) {
-    char *copy = _validate_principal(keyid);
-    if (copy == NULL)
-        return 0;
-
-    _append(attr, copy);
-    return 1;
-}
-
-int creddy_attribute_role(creddy_attribute_t *attr, char *keyid, char *role) {
-    if (!creddy_clean_name(role))
-        return 0;
-
-    char *copy = _validate_principal(keyid);
-    if (copy == NULL)
-        return 0;
-
-    int len = strlen(copy) + strlen(role) + strlen(ROLE_SEPARATOR) + 1;
-    copy = creddy_xrealloc(copy, len);
-    strcat(copy, ".");
-    strcat(copy, role);
-
-    _append(attr, copy);
-    return 1;
-}
-
-int creddy_attribute_linking_role(creddy_attribute_t *attr, char *keyid, char *role, char *linked) {
-    if (!creddy_clean_name(role) || !creddy_clean_name(linked))
-        return 0;
-
-    char *copy = _validate_principal(keyid);
-    if (copy == NULL)
-        return 0;
-
-    int len = strlen(copy) + strlen(role) + strlen(linked) + strlen(ROLE_SEPARATOR) + 2;
-    copy = creddy_xrealloc(copy, len);
-    strcat(copy, ".");
-    strcat(copy, role);
-    strcat(copy, ".");
-    strcat(copy, linked);
-
-    _append(attr, copy);
-    return 1;
-}
-
-int creddy_attribute_bake(creddy_attribute_t *attr) {
-    if (attr->num_subjects == 0)
-        return 0;
-
-    libabac_init();
-
-    char *role_encoding = _get_role_encoding(attr);
-
-    // create attribute cert
-    time_t not_before = time(NULL);
-    time_t not_after = not_before + attr->validity;
-    chunk_t serial = creddy_generate_serial();
-
-    certificate_t *attr_cert = lib->creds->create(lib->creds,
-        CRED_CERTIFICATE, CERT_X509_AC,
-        BUILD_CERT, creddy_id_cert(attr->issuer),
-        BUILD_NOT_BEFORE_TIME, not_before,
-        BUILD_NOT_AFTER_TIME, not_after,
-        BUILD_SERIAL, serial,
-        BUILD_IETF_GROUP_ATTR, role_encoding,
-        BUILD_SIGNING_CERT, creddy_id_cert(attr->issuer),
-        BUILD_SIGNING_KEY, creddy_id_privkey(attr->issuer),
-        BUILD_END
-    );
-    if (attr_cert == NULL)
-        return 0;
-
-    attr->cert = attr_cert;
-
-    free(role_encoding);
-    free(serial.ptr);
-    return 1;
-}
-
-int creddy_attribute_cert_chunk(creddy_attribute_t *attr, abac_chunk_t *chunk) {
-    if (attr->cert == NULL)
-        return 0;
-
-    chunk_t encoding = attr->cert->get_encoding(attr->cert);
-    chunk->ptr = encoding.ptr; chunk->len = encoding.len;
-    return 1;
-}
-
-int creddy_attribute_baked(creddy_attribute_t *attr) {
-    return attr->cert != NULL;
-}
-
-// returns 0 if the cert hasn't been baked
-int creddy_attribute_write(creddy_attribute_t *attr, FILE *out) {
-    assert(attr != NULL);
-
-    if (attr->cert == NULL)
-        return 0;
-
-    // write to file
-    chunk_t encoding = attr->cert->get_encoding(attr->cert);
-    fwrite(encoding.ptr, encoding.len, 1, out);
-    free(encoding.ptr);
-
-    return 1;
-}
-
-void creddy_attribute_free(creddy_attribute_t *attr) {
-    int i;
-
-    if (attr == NULL)
-        return;
-
-    creddy_id_free(attr->issuer);
-    free(attr->role);
-    DESTROY_IF(attr->cert);
-
-    // free all the subjects
-    for (i = 0; i < attr->num_subjects; ++i)
-        free(attr->subject[i]);
-    free(attr->subject);
-
-    free(attr);
-}
-
-//
-// Helper functions below
-//
-
-// validate a princpal's name
-// makes sure it's a valid SHA1 identifier
-// return values:
-//  success: malloc'd copy with all hex digits lowercase
-//  fail: NULL
-static char *_validate_principal(char *keyid) {
-    int i;
-    char *copy = NULL;
-
-    if (strlen(keyid) != SHA1_LENGTH)
-        return NULL;
-
-    copy = creddy_xstrdup(keyid);
-    for (i = 0; i < SHA1_LENGTH; ++i) {
-        copy[i] = tolower(copy[i]);
-        if (!isxdigit(copy[i]))
-            goto error;
-    }
-
-    return copy;
-
-error:
-    free(copy);
-    return NULL;
-}
-
-static void _append(creddy_attribute_t *attr, char *subject) {
-    // expand the array if necessary
-    if (attr->num_subjects == attr->size_subjects) {
-        attr->size_subjects *= 2;
-        attr->subject = creddy_xrealloc(attr->subject, attr->size_subjects * sizeof(creddy_attribute_t));
-    }
-
-    attr->subject[attr->num_subjects++] = subject;
-    attr->total_len += strlen(subject);
-}
-
-char *_get_role_encoding(creddy_attribute_t *attr) {
-    int i, num_subjects;
-
-    num_subjects = attr->num_subjects;
-
-    int len = SHA1_LENGTH + 1 + strlen(attr->role) + strlen(ROLE_SEPARATOR);
-    len += attr->total_len + num_subjects * strlen(INTERSECTION_SEP);
-
-    char *encoding = creddy_xmalloc(len);
-    sprintf(encoding, "%s.%s" ROLE_SEPARATOR, creddy_id_keyid(attr->issuer), attr->role);
-
-    for (i = 0; i < num_subjects; ++i) {
-        strcat(encoding, attr->subject[i]);
-        if (i < num_subjects - 1)
-            strcat(encoding, INTERSECTION_SEP);
-    }
-
-    return encoding;
-}
Index: creddy/attribute.c
===================================================================
--- creddy/attribute.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/attribute.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -1,15 +1,16 @@
-#define GNU_SOURCE
+
+/* attribute.c */
+
+#define _GNU_SOURCE
+#include <stdio.h>
 
 #include <err.h>
 #include <termios.h>
 
-#include <credentials/keys/private_key.h>
-
-#include <creddy.h>
-
 #include "creddy_common.h"
+#include <abac.h>
 
 void attribute_main(options_t *opts) {
-    int i, ret, role_len = 1;
+    int i, ret= 1;
 
     if (
@@ -21,41 +22,44 @@
         usage(opts);
 
-
     // issuer
-    creddy_id_t *issuer = creddy_id_from_file(opts->issuer);
-    if (issuer == NULL)
+    abac_id_t *issuer_id = abac_id_from_file(opts->issuer);
+    if (issuer_id == NULL)
         errx(1, "Can't load cert from %s", opts->issuer);
 
     // private key
-    ret = creddy_id_load_privkey(issuer, opts->key);
-    if (!ret)
+    ret = abac_id_privkey_from_file(issuer_id, opts->key);
+    if (ret != ABAC_SUCCESS)
         errx(1, "Can't load private key from %s", opts->key);
 
-    creddy_attribute_t *attr = NULL;
-    ret = creddy_attribute_create(&attr, issuer, opts->role, opts->validity);
-    if (ret == CREDDY_ATTRIBUTE_ISSUER_NOKEY)
+    abac_attribute_t *attr = NULL;
+    ret = abac_attribute_create(&attr, issuer_id, opts->role, opts->validity);
+    if (ret == ABAC_ATTRIBUTE_ISSUER_NOKEY)
         abort(); // should never happen
-    if (ret == CREDDY_ATTRIBUTE_INVALID_ROLE)
+    if (ret == ABAC_ATTRIBUTE_INVALID_ROLE)
         errx(1, "Invalid role name: %s", opts->role);
-    if (ret == CREDDY_ATTRIBUTE_INVALID_VALIDITY)
+    if (ret == ABAC_ATTRIBUTE_INVALID_VALIDITY)
         errx(1, "Invalid validity: must be >= 1 second");
 
+    char *head_string=NULL;
+    char *subject_string=NULL;
+    asprintf(&head_string,"%s.%s",abac_id_keyid(issuer_id),opts->role);
+    abac_attribute_set_head(attr,head_string);
+
     for (i = 0; i < opts->num_subjects; ++i) {
+        char *string=NULL;
         subject_t *cur = &opts->subjects[i];
 
         // if we have a cert we need to get its ID
         if (cur->cert) {
-            creddy_id_t *subject = creddy_id_from_file(cur->cert);
+            abac_id_t *subject = abac_id_from_file(cur->cert);
             if (subject == NULL)
                 errx(1, "Can't load subject cert from %s", cur->cert);
-            cur->id = xstrdup(creddy_id_keyid(subject));
-            creddy_id_free(subject);
+            cur->id = xstrdup(abac_id_keyid(subject));
+            abac_id_free(subject);
         }
 
         // just a principal, add it
         if (!cur->role) {
-            ret = creddy_attribute_principal(attr, cur->id);
-            if (!ret)
-                errx(1, "Invalid principal: %s", cur->id);
+            asprintf(&string,"%s", cur->id);
         }
 
@@ -81,19 +85,23 @@
             // role
             if (name_parts == 1) {
-                ret = creddy_attribute_role(attr, cur->id, start[0]);
-                if (!ret)
-                    errx(1, "Invalid role: %s.%s", cur->id, start[0]);
+                asprintf(&string,"%s.%s", cur->id, start[0]);
             }
 
             // linking role
             else {
-                ret = creddy_attribute_linking_role(attr, cur->id, start[0], start[1]);
-                if (!ret)
-                    errx(1, "Invalid linking role: %s.%s.%s", cur->id, start[0], start[1]);
+                asprintf(&string,"%s.%s.%s", cur->id, start[0], start[1]);
             }
         }
+        /* collect up */
+        if(subject_string != NULL) {
+            char *tmp=subject_string;
+            subject_string=NULL;
+            asprintf(&subject_string,"%s & %s",tmp,string);
+        } else subject_string=string;
+
     }
 
-    ret = creddy_attribute_bake(attr);
+    abac_attribute_set_tail(attr,subject_string);
+    ret = abac_attribute_bake(attr);
     if (!ret)
         errx(1, "Couldn't bake attribute cert");
@@ -103,8 +111,8 @@
         err(1, "Couldn't open attr cert file %s for writing", opts->out);
 
-    creddy_attribute_write(attr, out);
+    abac_attribute_write(attr, out);
 
     fclose(out);
 
-    creddy_attribute_free(attr);
+    abac_attribute_free(attr);
 }
Index: creddy/attribute_rule.c
===================================================================
--- creddy/attribute_rule.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
+++ creddy/attribute_rule.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -0,0 +1,81 @@
+
+/* attribute_rule.c */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+
+#include <err.h>
+#include <termios.h>
+
+#include "creddy_common.h"
+#include <abac.h>
+#include "abac_util.h"
+
+void attribute_rule_main(options_t *opts) {
+    int ret;
+
+    if (
+        opts->issuer == NULL ||
+        opts->key == NULL ||
+        opts->attrrule == NULL ||
+        opts->out == NULL
+    )
+        usage(opts);
+
+    // issuer
+    abac_id_t *issuer_id = abac_id_from_file(opts->issuer);
+    if (issuer_id == NULL)
+        errx(1, "Can't load cert from %s", opts->issuer);
+
+    // private key
+    ret = abac_id_privkey_from_file(issuer_id, opts->key);
+    if (ret != ABAC_SUCCESS)
+        errx(1, "Can't load private key from %s", opts->key);
+
+
+    /* chop out the role, head_string, tail_string */
+    char *head_tail[2];
+    abac_split(opts->attrrule, "<-", head_tail, &ret);
+    if (ret != 2) errx(1, "Invalid access rule");
+    char *head_string = abac_xstrdup(head_tail[0]);
+    char *subject_string = abac_xstrdup(head_tail[1]);
+
+    char *head_role[2];
+    abac_split(head_tail[0], ".", head_role, &ret);
+    if (ret != 2) errx(1, "Invalid access rule");
+    char *keyid=abac_xstrdup(head_role[0]);
+    char *role =abac_xstrdup(head_role[1]);
+
+    /* make sure keyid match up with issuer */
+    char *issuer=abac_id_keyid(issuer_id);
+    if(strcmp(keyid,issuer)!=0) {
+        errx(1, "Mismatched issuer with the access rule");
+    }
+
+    abac_attribute_t *attr = NULL;
+    ret = abac_attribute_create(&attr, issuer_id, role, opts->validity);
+    if (ret == ABAC_ATTRIBUTE_ISSUER_NOKEY)
+        abort(); // should never happen
+    if (ret == ABAC_ATTRIBUTE_INVALID_ROLE)
+        errx(1, "Invalid role name: %s", role);
+    if (ret == ABAC_ATTRIBUTE_INVALID_VALIDITY)
+        errx(1, "Invalid validity: must be >= 1 second");
+
+    abac_attribute_set_head(attr,head_string);
+    abac_attribute_set_tail(attr,subject_string);
+
+    ret = abac_attribute_bake(attr);
+    if (!ret)
+        errx(1, "Couldn't bake attribute cert");
+
+    FILE *out = fopen(opts->out, "w");
+    if (out == NULL)
+        err(1, "Couldn't open attr cert file %s for writing", opts->out);
+
+    abac_attribute_write(attr, out);
+
+    fclose(out);
+
+    abac_attribute_free(attr);
+}
Index: creddy/compat/readpassphrase.c
===================================================================
--- creddy/compat/readpassphrase.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ 	(revision )
@@ -1,209 +1,0 @@
-/*	$OpenBSD: readpassphrase.c,v 1.23 2010/05/14 13:30:34 millert Exp $	*/
-
-/*
- * Copyright (c) 2000-2002, 2007, 2010
- *	Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F39502-99-1-0512.
- */
-
-/* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */
-
-/**
- * Tom Carroll <thomas.carroll@pnnl.gov>
- *
- * Properly handled tcsetattr and SIGTTOU
- */
-
-#ifndef HAVE_READPASSPHRASE
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#ifdef HAVE_PATHS_H
-# include <paths.h>
-#endif
-#include <signal.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-#include "compat/readpassphrase.h"
-
-#ifndef TCSASOFT
-# define TCSASOFT 0
-#endif
-
-#ifndef NSIG
-# ifdef _NSIG
-#  define NSIG _NSIG
-# else
-#  define NSIG 128
-# endif
-#endif
-
-static volatile sig_atomic_t signo[NSIG];
-
-static void handler(int);
-
-char *
-readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
-{
-	ssize_t nr;
-	int input, output, save_errno, i, need_restart;
-	char ch, *p, *end;
-	struct termios term, oterm;
-	struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
-	struct sigaction savetstp, savettin, savettou, savepipe;
-
-	/* I suppose we could alloc on demand in this case (XXX). */
-	if (bufsiz == 0) {
-		errno = EINVAL;
-		return(NULL);
-	}
-
-restart:
-	for (i = 0; i < NSIG; i++)
-		signo[i] = 0;
-	nr = -1;
-	save_errno = 0;
-	need_restart = 0;
-	/*
-	 * Read and write to /dev/tty if available.  If not, read from
-	 * stdin and write to stderr unless a tty is required.
-	 */
-	if ((flags & RPP_STDIN) ||
-	    (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
-		if (flags & RPP_REQUIRE_TTY) {
-			errno = ENOTTY;
-			return(NULL);
-		}
-		input = STDIN_FILENO;
-		output = STDERR_FILENO;
-	}
-
-	/*
-	 * Turn off echo if possible.
-	 * If we are using a tty but are not the foreground pgrp this will
-	 * generate SIGTTOU, so do it *before* installing the signal handlers.
-	 */
-	if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
-		memcpy(&term, &oterm, sizeof(term));
-		if (!(flags & RPP_ECHO_ON))
-			term.c_lflag &= ~(ECHO | ECHONL);
-#ifdef VSTATUS
-		if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
-			term.c_cc[VSTATUS] = _POSIX_VDISABLE;
-#endif
-		(void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
-	} else {
-		memset(&term, 0, sizeof(term));
-		term.c_lflag |= ECHO;
-		memset(&oterm, 0, sizeof(oterm));
-		oterm.c_lflag |= ECHO;
-	}
-
-	/*
-	 * Catch signals that would otherwise cause the user to end
-	 * up with echo turned off in the shell.  Don't worry about
-	 * things like SIGXCPU and SIGVTALRM for now.
-	 */
-	sigemptyset(&sa.sa_mask);
-	sa.sa_flags = 0;		/* don't restart system calls */
-	sa.sa_handler = handler;
-	(void)sigaction(SIGALRM, &sa, &savealrm);
-	(void)sigaction(SIGHUP, &sa, &savehup);
-	(void)sigaction(SIGINT, &sa, &saveint);
-	(void)sigaction(SIGPIPE, &sa, &savepipe);
-	(void)sigaction(SIGQUIT, &sa, &savequit);
-	(void)sigaction(SIGTERM, &sa, &saveterm);
-	(void)sigaction(SIGTSTP, &sa, &savetstp);
-	(void)sigaction(SIGTTIN, &sa, &savettin);
-	(void)sigaction(SIGTTOU, &sa, &savettou);
-
-	if (!(flags & RPP_STDIN))
-		(void)write(output, prompt, strlen(prompt));
-	end = buf + bufsiz - 1;
-	p = buf;
-	while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
-		if (p < end) {
-			if ((flags & RPP_SEVENBIT))
-				ch &= 0x7f;
-			if (isalpha(ch)) {
-				if ((flags & RPP_FORCELOWER))
-					ch = (char)tolower(ch);
-				if ((flags & RPP_FORCEUPPER))
-					ch = (char)toupper(ch);
-			}
-			*p++ = ch;
-		}
-	}
-	*p = '\0';
-	save_errno = errno;
-	if (!(term.c_lflag & ECHO))
-		(void)write(output, "\n", 1);
-
-	/* Restore old terminal settings and signals. */
-	if (memcmp(&term, &oterm, sizeof(term)) != 0) {
-		sigset_t ttou_sigset, old_sigset;
-		sigemptyset(&ttou_sigset);
-		sigaddset(&ttou_sigset, SIGTTOU);
-		sigprocmask(SIG_BLOCK, &ttou_sigset, &old_sigset);
-		while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
-		    errno == EINTR)
-			continue;
-		sigprocmask(SIG_SETMASK, &old_sigset, NULL);
-	}
-	(void)sigaction(SIGALRM, &savealrm, NULL);
-	(void)sigaction(SIGHUP, &savehup, NULL);
-	(void)sigaction(SIGINT, &saveint, NULL);
-	(void)sigaction(SIGQUIT, &savequit, NULL);
-	(void)sigaction(SIGPIPE, &savepipe, NULL);
-	(void)sigaction(SIGTERM, &saveterm, NULL);
-	(void)sigaction(SIGTSTP, &savetstp, NULL);
-	(void)sigaction(SIGTTIN, &savettin, NULL);
-	(void)sigaction(SIGTTOU, &savettou, NULL);
-	if (input != STDIN_FILENO)
-		(void)close(input);
-
-	/*
-	 * If we were interrupted by a signal, resend it to ourselves
-	 * now that we have restored the signal handlers.
-	 */
-	for (i = 0; i < NSIG; i++) {
-		if (signo[i]) {
-			kill(getpid(), i);
-			switch (i) {
-			case SIGTSTP:
-			case SIGTTIN:
-			case SIGTTOU:
-				need_restart = 1;
-			}
-		}
-	}
-	if (need_restart)
-		goto restart;
-
-	return(nr == -1 ? errno = save_errno, NULL : buf);
-}
-
-static void handler(int s)
-{
-
-	signo[s] = 1;
-}
-
-#endif /* ! HAVE_READPASSPHRASE */
Index: creddy/compat/readpassphrase.h
===================================================================
--- creddy/compat/readpassphrase.h	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ 	(revision )
@@ -1,42 +1,0 @@
-/*	$OpenBSD: readpassphrase.h,v 1.5 2003/06/17 21:56:23 millert Exp $	*/
-
-/*
- * Copyright (c) 2000, 2002 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F39502-99-1-0512.
- */
-
-#ifndef _READPASSPHRASE_H_
-#define _READPASSPHRASE_H_
-
-#ifndef HAVE_READPASSPHRASE
-
-#define RPP_ECHO_OFF    0x00		/* Turn off echo (default). */
-#define RPP_ECHO_ON     0x01		/* Leave echo on. */
-#define RPP_REQUIRE_TTY 0x02		/* Fail if there is no tty. */
-#define RPP_FORCELOWER  0x04		/* Force input to lower case. */
-#define RPP_FORCEUPPER  0x08		/* Force input to upper case. */
-#define RPP_SEVENBIT    0x10		/* Strip the high bit from input. */
-#define RPP_STDIN       0x20		/* Read from stdin, not /dev/tty */
-
-#include <stddef.h>
-
-char * readpassphrase(const char *, char *, size_t, int);
-
-#endif /* ! HAVE_READPASSPHRASE */
-
-#endif /* !_READPASSPHRASE_H_ */
Index: creddy/creddy.c
===================================================================
--- creddy/creddy.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/creddy.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -1,2 +1,5 @@
+
+/* creddy.c */
+
 #include <assert.h>
 #include <errno.h>
@@ -5,4 +8,6 @@
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
+#include <err.h>
 
 #include "creddy_common.h"
@@ -20,4 +25,5 @@
 #define OPT_SUBJECT_ID      11
 #define OPT_SHOW            12
+#define OPT_ATTRRULE        13
 
 subject_t *subjects = NULL;
@@ -57,7 +63,8 @@
 
 int main(int argc, char **argv) {
-    int ret;
     options_t options = { 0, };
     char *validity_str = NULL;
+
+    libabac_init();
 
     subjects = xmalloc(sizeof(subject_t) * 2);
@@ -92,4 +99,7 @@
         { "out",          1, 0, OPT_OUT },
 
+        // attribute_rule option
+        { "attrrule",   1, 0, OPT_ATTRRULE },
+
         // verify option
         { "attrcert",   1, 0, OPT_ATTRCERT },
@@ -144,4 +154,9 @@
             case OPT_OUT:
                 options.out = xstrdup(optarg);
+                break;
+
+            // attribute rule options
+            case OPT_ATTRRULE:
+                options.attrrule = xstrdup(optarg);
                 break;
 
@@ -225,5 +240,5 @@
     }
 
-    if (options.mode == MODE_ATTRIBUTE) {
+    if (options.mode == MODE_ATTRIBUTE && options.attrrule == NULL) {
         int i;
 
@@ -262,5 +277,7 @@
         case MODE_ATTRIBUTE:
             if (options.validity == 0) options.validity = 365 * 86400;
-            attribute_main(&options);
+            if(options.attrrule)
+                attribute_rule_main(&options);
+                else attribute_main(&options);
             break;
 
@@ -380,14 +397,2 @@
 }
 
-certificate_t *attr_cert_from_file(char *filename) {
-    libabac_init();
-    certificate_t *cert = lib->creds->create(lib->creds,
-        CRED_CERTIFICATE, CERT_X509_AC,
-        BUILD_FROM_FILE, filename,
-        BUILD_END
-    );
-    if (cert == NULL)
-        errx(1, "Couldn't load attribute cert %s", filename);
-
-    return cert;
-}
Index: creddy/creddy.h
===================================================================
--- creddy/creddy.h	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ 	(revision )
@@ -1,122 +1,0 @@
-#ifndef __LIBCREDDY_H__
-#define __LIBCREDDY_H__
-
-#include <stdio.h>
-#include <time.h> // for time_t
-
-#include <abac_common.h>
-
-#define CREDDY_SUCCESS                      0
-#define CREDDY_GENERATE_INVALID_CN          -1
-#define CREDDY_GENERATE_INVALID_VALIDITY    -2
-#define CREDDY_ATTRIBUTE_ISSUER_NOKEY       -3
-#define CREDDY_ATTRIBUTE_INVALID_ROLE       -4
-#define CREDDY_ATTRIBUTE_INVALID_VALIDITY   -5
-
-/**
- * Creddy identifiers.
- */
-
-typedef struct _creddy_id_t creddy_id_t;
-
-// create an ID from an X.509 certificate
-creddy_id_t *creddy_id_from_file(char *filename);
-
-// create an ID from a DER-encoded X.509 certificate chunk
-creddy_id_t *creddy_id_from_chunk(abac_chunk_t chunk);
-
-// load an X.509 private key for an from a file
-// handles keys with a password
-int creddy_id_load_privkey(creddy_id_t *id, char *filename);
-
-// generate an ID
-// returns one of CREDDY_SUCCESS or CREDDY_GENERATE_* (see top)
-int creddy_id_generate(creddy_id_t **ret, char *cn, int validity);
-
-// get the SHA1 keyid, pointer is valid for the lifetime of the object
-char *creddy_id_keyid(creddy_id_t *id);
-
-// get the name of the issuer
-// caller must free the returned string
-char *creddy_id_issuer(creddy_id_t *id);
-
-// get the DN of the subject
-// caller must free the returned string
-char *creddy_id_subject(creddy_id_t *id);
-
-// get the validity period of the cert
-void creddy_id_validity(creddy_id_t *id, time_t *not_before, time_t *not_after);
-
-// default filename for the cert: ${CN}_ID.pem
-// caller must free the returned string
-char *creddy_id_cert_filename(creddy_id_t *id);
-
-// write the cert fo an open file pointer
-void creddy_id_write_cert(creddy_id_t *id, FILE *out);
-
-// default filename for the private key: ${CN}_key.pem
-// caller must free the return value
-char *creddy_id_privkey_filename(creddy_id_t *id);
-
-// write the private key to a file
-// it is recommended that you open this file mode 0600
-// returns false if there's no private key loaded
-int creddy_id_write_privkey(creddy_id_t *id, FILE *out);
-
-// get a chunk representing the cert
-// you must free the ptr of the chunk when done
-abac_chunk_t creddy_id_cert_chunk(creddy_id_t *id);
-
-// dup an ID (increases its refcount)
-creddy_id_t *creddy_id_dup(creddy_id_t *id);
-
-// destroy the id
-// decreases refcount and destroys when it hits 0
-void creddy_id_free(creddy_id_t *id);
-
-/**
- * Attribute cert
- */
-typedef struct _creddy_attribute_t creddy_attribute_t;
-
-//
-// Here's the skinny:
-//  Attribute cert objects don't contain an actual cert until they're baked.
-//  First you construct the object using creddy_attribute_create, then you add
-//  subjects to it using creddy_attribute_{principal,role,linking_role}.
-//  Finally you bake it. Once you've done that, you can access the DER encoding
-//  or write it to a file.
-//
-
-// create an attribute cert
-// validity is in days
-// returns one of CREDDY_SUCCESS or CREDDY_ATTRIBUTE_* (see top)
-int creddy_attribute_create(creddy_attribute_t **attr, creddy_id_t *issuer, char *role, int validity);
-
-// add a principal subject to the cert
-int creddy_attribute_principal(creddy_attribute_t *attr, char *keyid);
-
-// add a role subject
-int creddy_attribute_role(creddy_attribute_t *attr, char *keyid, char *role);
-
-// add a linking role subject
-int creddy_attribute_linking_role(creddy_attribute_t *attr, char *keyid, char *role, char *linked);
-
-// create the attribute cert once all the subjects have been added
-// can return 0 if there are no subjects or there's a problem building the cert
-int creddy_attribute_bake(creddy_attribute_t *attr);
-
-// returns true iff the cert's been baked
-int creddy_attribute_baked(creddy_attribute_t *attr);
-
-// write the cert to a file. returns 0 if the cert hasn't been baked
-int creddy_attribute_write(creddy_attribute_t *attr, FILE *out);
-
-// get the DER-encoded cert
-// returns 0 if the cert isn't baked
-int creddy_attribute_cert_chunk(creddy_attribute_t *attr, abac_chunk_t *chunk);
-
-// destroy the cert
-void creddy_attribute_free(creddy_attribute_t *attr);
-
-#endif /* __LIBCREDDY_H__ */
Index: creddy/creddy.hh
===================================================================
--- creddy/creddy.hh	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/creddy.hh	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -7,159 +7,6 @@
 namespace Creddy {
     extern "C" {
-        #include <creddy.h>
+        #include <abac.h>
     }
-
-    class ID {
-        public:
-            ID() : m_id(NULL) { } // do not use: required by swig
-
-            // load an ID from a file
-            ID(char *filename) : m_id(NULL) {
-                m_id = creddy_id_from_file(filename);
-                if (m_id == NULL)
-                    throw std::invalid_argument("Could not load ID cert");
-            }
-
-            // load an ID from a chunk
-            ID(abac_chunk_t chunk) : m_id(NULL) {
-                m_id = creddy_id_from_chunk(chunk);
-                if (m_id == NULL)
-                    throw std::invalid_argument("Could not load ID cert");
-            }
-
-            // generate an ID with a given CN and validity
-            ID(char *cn, int validity) : m_id(NULL) {
-                int ret = creddy_id_generate(&m_id, cn, validity);
-                if (ret == CREDDY_GENERATE_INVALID_CN)
-                    throw std::invalid_argument("CN must be alphanumeric and start with a letter");
-                if (ret == CREDDY_GENERATE_INVALID_VALIDITY)
-                    throw std::invalid_argument("Validity must be > 0 days");
-            }
-
-            ID(const ID &id) { m_id = creddy_id_dup(id.m_id); }
-
-            ~ID() { creddy_id_free(m_id); }
-
-            // load private key from a file
-            void load_privkey(char *filename) {
-                int ret = creddy_id_load_privkey(m_id, filename);
-                if (!ret)
-                    throw std::invalid_argument("Could not load private key");
-            }
-
-            char *keyid() { return creddy_id_keyid(m_id); }
-            char *cert_filename() { return creddy_id_cert_filename(m_id); }
-            void write_cert(std::FILE *out) { creddy_id_write_cert(m_id, out); }
-            void write_cert(const std::string &name) {
-                std::FILE *out = fopen(name.c_str(), "w");
-                if (out == NULL)
-                    throw std::invalid_argument("Could not open cert file for writing");
-                write_cert(out);
-                fclose(out);
-            }
-            // Simplifies access from swig
-            void write_cert(const char *n) {
-                write_cert(std::string(n));
-            }
-            char *privkey_filename() { return creddy_id_privkey_filename(m_id); }
-
-            // write the private ket
-            // throws a std::logic_error if no private key is loaded
-            void write_privkey(std::FILE *out) {
-                int ret = creddy_id_write_privkey(m_id, out);
-                if (!ret) throw std::logic_error("No private key loaded");
-            }
-            void write_privkey(const std::string &name) {
-                std::FILE *out = fopen(name.c_str(), "w");
-                if (out == NULL)
-                    throw std::invalid_argument("Could not open privkey file for writing");
-                write_privkey(out);
-                fclose(out);
-            }
-            // Simplifies access from swig
-            void write_privkey(const char *name) {
-                write_privkey(std::string(name));
-            }
-
-            abac_chunk_t cert_chunk() { return creddy_id_cert_chunk(m_id); }
-
-            friend class Attribute;
-
-        private:
-            creddy_id_t *m_id;
-    };
-
-    class Attribute {
-        public:
-            Attribute() : m_attr(NULL) { } // do not use: required by swig
-
-            // create a cert
-            Attribute(ID &issuer, char *role, int validity) : m_attr(NULL) {
-                int ret = creddy_attribute_create(&m_attr, issuer.m_id, role, validity);
-                if (ret == CREDDY_ATTRIBUTE_ISSUER_NOKEY)
-                    throw std::invalid_argument("Issuer has no private key");
-                if (ret == CREDDY_ATTRIBUTE_INVALID_ROLE)
-                    throw std::invalid_argument("Role name must be alphanumeric");
-                if (ret == CREDDY_ATTRIBUTE_INVALID_VALIDITY)
-                    throw std::invalid_argument("Validity must be > 0 days");
-            }
-
-            ~Attribute() { creddy_attribute_free(m_attr); }
-
-            // these return false if there's a bad keyid or role name
-            // they'll throw a std::logic_error if the cert's been baked
-            bool principal(char *keyid) {
-                if (baked()) throw std::logic_error("Cert is already baked");
-                return creddy_attribute_principal(m_attr, keyid);
-            }
-            bool role(char *keyid, char *role) {
-                if (baked()) throw std::logic_error("Cert is already baked");
-                return creddy_attribute_role(m_attr, keyid, role);
-            }
-            bool linking_role(char *keyid, char *role, char *linked) {
-                if (baked()) throw std::logic_error("Cert is already baked");
-                return creddy_attribute_linking_role(m_attr, keyid, role, linked);
-            }
-
-            // returns false if there are no subjects or libstrongswan fails
-            // throws a std::logic_error if the cert's already been baked
-            bool bake() {
-                if (baked()) throw std::logic_error("Cert is already baked");
-                return creddy_attribute_bake(m_attr);
-            }
-
-            // returns true iff the cert's been baked
-            bool baked() { return creddy_attribute_baked(m_attr); }
-
-            // throws a std::logic_error if the cert isn't baked
-            void write(std::FILE *out) {
-                int ret = creddy_attribute_write(m_attr, out);
-                if (!ret) throw std::logic_error("Cert is not baked");
-            }
-
-            void write(const std::string &name) {
-                std::FILE *out = fopen(name.c_str(), "w");
-                if (out == NULL)
-                    throw std::invalid_argument("Could not open cert file for writing");
-                write(out);
-                fclose(out);
-            }
-
-            // Simplifies access from swig
-            void write(const char *name) {
-                write(std::string(name));
-            }
-
-            // throws a std::logic_error if the cert isn't baked
-            abac_chunk_t cert_chunk() {
-                abac_chunk_t ret;
-                if (!baked()) throw std::logic_error("Cert is not baked");
-                creddy_attribute_cert_chunk(m_attr, &ret);
-                return ret;
-            }
-
-        private:
-            creddy_attribute_t *m_attr;
-    };
 }
 
Index: creddy/creddy_common.h
===================================================================
--- creddy/creddy_common.h	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/creddy_common.h	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -1,8 +1,9 @@
-#ifndef __CREDDY_H__
-#define __CREDDY_H__
+#ifndef __CREDDY_COMMON_H__
+#define __CREDDY_COMMON_H__
 
-#include <library.h>
-#include <credentials/certificates/certificate.h>
-#include <credentials/certificates/x509.h>
+/* used locally by creddy */
+
+#include <stdlib.h>
+
 
 typedef struct _subject_t {
@@ -33,4 +34,7 @@
     char *attrcert;
 
+    // attribute_rule options
+    char *attrrule;
+
     // display options
     char *show;
@@ -45,13 +49,4 @@
 #define MODE_DISPLAY    7
 
-// returns true if a name starts with a letter and is otherwise alphanumeric
-int clean_name(char *string);
-
-// load an attr cert from file (aborts on fail)
-certificate_t *attr_cert_from_file(char *filename);
-
-// generate a random serial
-chunk_t creddy_generate_serial();
-
 void usage(options_t *opts);
 void *xmalloc(size_t len);
@@ -63,7 +58,8 @@
 void keyid_main(options_t *opts);
 void attribute_main(options_t *opts);
+void attribute_rule_main(options_t *opts);
 void roles_main(options_t *opts);
 void verify_main(options_t *opts);
 void display_main(options_t *opts);
 
-#endif /* __CREDDY_H__ */
+#endif /* __CREDDY_COMMON_H__ */
Index: creddy/display.c
===================================================================
--- creddy/display.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/display.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -1,10 +1,18 @@
-#include <creddy.h>
 
+/* display.c */
+
+#include <time.h>
+#include <string.h>
+#include <err.h>
+
+#include <abac.h>
 #include "creddy_common.h"
 
-#include <credentials/certificates/ac.h>
+extern char *abac_attribute_role_string(abac_attribute_t *attr);
+extern abac_chunk_t abac_attribute_cert(abac_attribute_t *ptr);
 
 // helper
-static void _print_validity(time_t not_before, time_t not_after);
+void _print_validity(struct tm not_before, struct tm not_after);
+void _print_info(abac_attribute_t *attr, int show_issuer, int show_subject, int show_validity, int show_roles, char*);
 
 void display_main(options_t *opts) {
@@ -44,8 +52,8 @@
 
     // first try ID cert
-    creddy_id_t *id = creddy_id_from_file(opts->cert);
+    abac_id_t *id = abac_id_from_file(opts->cert);
     if (id != NULL) {
         if (show_issuer) {
-            char *issuer = creddy_id_issuer(id);
+            char *issuer = abac_id_issuer(id);
             printf("Issuer: %s\n", issuer);
             free(issuer);
@@ -53,5 +61,5 @@
 
         if (show_subject) {
-            char *subject = creddy_id_subject(id);
+            char *subject = abac_id_subject(id);
             printf("Subject: %s\n", subject);
             free(subject);
@@ -59,62 +67,65 @@
 
         if (show_validity) {
-            time_t not_before, not_after;
-            creddy_id_validity(id, &not_before, &not_after);
+            struct tm not_before, not_after;
+            abac_id_validity(id, &not_before, &not_after);
             _print_validity(not_before, not_after);
         }
 
-        creddy_id_free(id);
+        abac_id_free(id);
         return;
     }
 
     // then try attribute cert
-    certificate_t *ac = lib->creds->create(lib->creds,
-        CRED_CERTIFICATE, CERT_X509_AC,
-        BUILD_FROM_FILE, opts->cert,
-        BUILD_END
+    abac_attribute_t *attr;
+    abac_list_t *attr_list = abac_attribute_certs_from_file(opts->cert);
+    int sz=abac_list_size(attr_list);
+    abac_list_foreach(attr_list, attr,
+        _print_info(attr,show_issuer,show_subject,show_validity,show_roles, opts->cert);
+        abac_attribute_free(attr);
     );
-    if (ac != NULL) {
-        if (show_issuer)
-            printf("Issuer: %Y\n", ac->get_issuer(ac));
+    abac_list_free(attr_list);
 
-        if (show_subject)
-            printf("Subject: %Y\n", ac->get_subject(ac));
+    // give up if neither works
+    if(sz==0)
+        errx(1, "Couldn't load %s as an ID or attribute, ", opts->cert);
+}
 
+void _print_info(abac_attribute_t *attr, int show_issuer, int show_subject, int show_validity, int show_roles, char *fname)
+{
+    if (attr != NULL) {
+        abac_id_t *issuer_id=abac_attribute_issuer_id(attr);
+        if (show_issuer && issuer_id) {
+            char *issuer = abac_id_issuer(issuer_id);
+            printf("Issuer: %s\n", issuer);
+            free(issuer);
+        }
+        if (show_subject && issuer_id) {
+            char *subject = abac_id_subject(issuer_id);
+            printf("Subject: %s\n", subject);
+            free(subject);
+        }
         if (show_validity) {
-            time_t not_before, not_after;
-            ac->get_validity(ac, NULL, &not_before, &not_after);
+            struct tm not_before, not_after;
+            abac_attribute_validity(attr, &not_before, &not_after);
             _print_validity(not_before, not_after);
         }
-
         if (show_roles) {
-            ac_t *attr_cert = (ac_t *)ac;
-            ietf_attributes_t *attr = attr_cert->get_groups(attr_cert);
-            if (attr == NULL)
-                errx(1, "Couldn't get attributes from cert");
-
-            printf("Roles: %s\n", attr->get_string(attr));
-
-            DESTROY_IF(attr);
+            char *role_string = abac_attribute_role_string(attr);
+            if (role_string == NULL) errx(1, "Couldn't get attributes from %s", fname );
+            printf("Roles: %s\n", role_string);
+            free(role_string);
         }
-
-        DESTROY_IF(ac);
-        return;
     }
-
-    // give up if neither works
-    errx(1, "Couldn't load %s as an ID or attribute cert", opts->cert);
 }
 
 // display the validity period of a cert
-static void _print_validity(time_t not_before, time_t not_after) {
+void _print_validity(struct tm not_before, struct tm not_after) {
     char buf[256];
-    struct tm time_tm;
-
     printf("Validity:\n");
 
-    strftime(buf, sizeof(buf), "%F %T %Z", localtime_r(&not_before, &time_tm));
-    printf("    Not before: %s [%lld]\n", buf, (long long)not_before);
+    strftime(buf, sizeof(buf), "%F %T %Z", &not_before);
+    printf("    Not before: %s [%lld]\n", buf, (long long) mktime(&not_before));
 
-    strftime(buf, sizeof(buf), "%F %T %Z", localtime_r(&not_after, &time_tm));
-    printf("    Not after:  %s [%lld]\n", buf, (long long)not_after);
+    strftime(buf, sizeof(buf), "%F %T %Z", &not_after);
+    printf("    Not after:  %s [%lld]\n", buf, (long long) mktime(&not_after));
 }
Index: creddy/generate.c
===================================================================
--- creddy/generate.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/generate.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -1,13 +1,15 @@
+
+/* generate.c */
+
+#include <unistd.h>
 #include <fcntl.h>
+#include <err.h>
 
-#include <credentials/keys/private_key.h>
-
-#include <creddy.h>
-
+#include <abac.h>
 #include "creddy_common.h"
 
 void generate_main(options_t *opts) {
     int ret, fd;
-    creddy_id_t *id;
+    abac_id_t *id;
     char *filename;
     FILE *out;
@@ -28,11 +30,12 @@
     printf("    - generate disk activity (run find)\n");
 
-    ret = creddy_id_generate(&id, opts->cn, opts->validity);
 
-    if (ret == CREDDY_GENERATE_INVALID_CN) {
+    ret = abac_id_generate(&id, opts->cn, opts->validity);
+
+    if (ret == ABAC_GENERATE_INVALID_CN) {
         printf("Invalid CN: must start with a letter and be alphanumeric\n");
         usage(opts);
     }
-    if (ret == CREDDY_GENERATE_INVALID_VALIDITY) {
+    if (ret == ABAC_GENERATE_INVALID_VALIDITY) {
         printf("Validity must be >= 1 day\n");
         usage(opts);
@@ -45,21 +48,21 @@
 
     // write the cert
-    filename = creddy_id_cert_filename(id);
+    filename = abac_id_cert_filename(id);
     out = fopen(filename, "w");
     if (out == NULL)
         err(1, "Can't open cert file %s", filename);
-    creddy_id_write_cert(id, out);
+    abac_id_write_cert(id, out);
     fclose(out);
     free(filename);
 
     // write the key
-    filename = creddy_id_privkey_filename(id);
+    filename = abac_id_privkey_filename(id);
     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); // mode 600
     if (fd < 0)
         err(1, "Can't open private key file %s", filename);
     out = fdopen(fd, "w");
-    creddy_id_write_privkey(id, out);
+    abac_id_write_privkey(id, out);
     fclose(out);
 
-    creddy_id_free(id);
+    abac_id_free(id);
 }
Index: creddy/id.c
===================================================================
--- creddy/id.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ 	(revision )
@@ -1,470 +1,0 @@
-#include <assert.h>
-#include <err.h>
-#include <time.h>
-
-// include the GNU extension of asprintf
-#define _GNU_SOURCE
-#include <stdio.h>
-
-#include "libcreddy_common.h"
-
-#define KEY_SUFFIX  "_private.pem"
-#define CERT_SUFFIX "_ID.pem"
-/* Size of password memory allocation */
-#define PWLEN 128
-
-#ifdef HAVE_READPASSPHRASE
-# include <readpassphrase.h>
-#else
-# include "compat/readpassphrase.h"
-#endif
-
-//
-// ID object
-//
-struct _creddy_id_t {
-    char *keyid;
-    char *cn;
-    certificate_t *cert;
-    private_key_t *key;
-
-    int refcount;
-};
-
-/* Callback configuration */
-struct cb_opts {
-    bool use_prompt;    /* Print a prompt to stderr */
-    bool use_echo;      /* If true, turn off input echo on stdin */
-    unsigned int tries; /* Number of attempts allowed */
-    char prompt[20];    /* The prompt to display if use_echo is true */
-};
-
-static char *_get_keyid(certificate_t *cert);
-static chunk_t _passphrase_callback(void *user, int try);
-static private_key_t *_generate_key(void);
-static certificate_t *_generate_cert(private_key_t *private, char *cn, int validity);
-static void _encode_base64(FILE *out, chunk_t encoding);
-
-/**
- * Helper function for building a creddy ID from a cert. Used by
- * creddy_id_from_*
- */
-creddy_id_t *_creddy_id_from_cert(certificate_t *cert) {
-    creddy_id_t *id = creddy_xmalloc(sizeof(creddy_id_t));
-    id->keyid = NULL;
-    id->cn = NULL;
-    id->cert = cert;
-    id->key = NULL;
-
-    id->keyid = _get_keyid(id->cert);
-
-    // get the CN from the cert
-    id_part_t type;
-    chunk_t data;
-
-    identification_t *cert_id = id->cert->get_subject(id->cert);
-    enumerator_t *id_enum = cert_id->create_part_enumerator(cert_id);
-    while (id_enum->enumerate(id_enum, &type, &data))
-        if (type == ID_PART_RDN_CN) {
-            id->cn = creddy_xmalloc(data.len + 1);
-            memcpy(id->cn, data.ptr, data.len);
-            id->cn[data.len] = 0;
-        }
-    id_enum->destroy(id_enum);
-
-    id->refcount = 1;
-
-    return id;
-}
-
-/**
- * Load an ID cert from a file.
- */
-creddy_id_t *creddy_id_from_file(char *filename) {
-    libabac_init();
-
-    certificate_t *cert = lib->creds->create(lib->creds,
-        CRED_CERTIFICATE, CERT_X509,
-        BUILD_FROM_FILE, filename,
-        BUILD_X509_FLAG, X509_AA,
-        BUILD_END
-    );
-
-    if (cert == NULL)
-        return NULL;
-
-    return _creddy_id_from_cert(cert);
-}
-
-/**
- * Load an ID cert from a chunk.
- */
-creddy_id_t *creddy_id_from_chunk(abac_chunk_t achunk) {
-    chunk_t chunk = { .ptr = achunk.ptr, .len = achunk.len };
-
-    libabac_init();
-
-    certificate_t *cert = lib->creds->create(lib->creds,
-        CRED_CERTIFICATE, CERT_X509,
-        BUILD_BLOB_ASN1_DER, chunk,
-        BUILD_X509_FLAG, X509_AA,
-        BUILD_END
-    );
-
-    if (cert == NULL)
-        return NULL;
-
-    return _creddy_id_from_cert(cert);
-}
-
-/**
- * Load private key for a cert.
- */
-int creddy_id_load_privkey(creddy_id_t *id, char *filename) {
-    struct cb_opts c_opts = { 1, 0, 3, "Key password:" };
-
-    assert(id != NULL);
-
-    libabac_init();
-
-    // load signer key
-    private_key_t *key = lib->creds->create(lib->creds,
-        CRED_PRIVATE_KEY, KEY_RSA,
-        BUILD_FROM_FILE, filename,
-        /* Ask for password if the key's encrypted */
-        BUILD_PASSPHRASE_CALLBACK, _passphrase_callback, &c_opts,
-        BUILD_END
-    );
-    if (key == NULL)
-        return 0;
-
-    id->key = key;
-    return 1;
-}
-
-/**
- * Generate an ID with the specified CN and validity.
- *
- * validity is measured in seconds (as of 0.2.0)
- */
-int creddy_id_generate(creddy_id_t **ret, char *cn, int validity) {
-    if (cn == NULL || !creddy_clean_name(cn))
-        return CREDDY_GENERATE_INVALID_CN;
-
-    if (validity < 0)
-        return CREDDY_GENERATE_INVALID_VALIDITY;
-
-    creddy_id_t *id = creddy_xmalloc(sizeof(creddy_id_t));
-
-    id->cn = creddy_xstrdup(cn);
-    id->key = _generate_key();
-    id->cert = _generate_cert(id->key, cn, validity);
-    id->keyid = _get_keyid(id->cert);
-
-    id->refcount = 1;
-
-    *ret = id;
-    return CREDDY_SUCCESS;
-}
-
-char *creddy_id_keyid(creddy_id_t *id) {
-    assert(id != NULL);
-
-    return id->keyid;
-}
-
-/**
- * Get the issuer of an ID cert.
- * Returns a malloc'd string that must be free'd.
- */
-char *creddy_id_issuer(creddy_id_t *id) {
-    char *ret;
-    int rv = asprintf(&ret, "%Y", id->cert->get_issuer(id->cert));
-
-    if (rv < 0)
-        err(1, "couldn't malloc string for issuer\n");
-
-    return ret;
-}
-
-/**
- * Gets the subject DN of an ID cert.
- * Returns a malloc'd string that must be free'd.
- */
-char *creddy_id_subject(creddy_id_t *id) {
-    char *ret;
-    int rv = asprintf(&ret, "%Y", id->cert->get_subject(id->cert));
-
-    if (rv < 0)
-        err(1, "couldn't malloc string for subject\n");
-
-    return ret;
-}
-
-/**
- * Get the validity period.
- */
-void creddy_id_validity(creddy_id_t *id, time_t *not_before, time_t *not_after) {
-    id->cert->get_validity(id->cert, NULL, not_before, not_after);
-}
-
-certificate_t *creddy_id_cert(creddy_id_t *id) {
-    assert(id != NULL);
-
-    return id->cert;
-}
-
-private_key_t *creddy_id_privkey(creddy_id_t *id) {
-    assert(id != NULL);
-
-    return id->key;
-}
-
-/**
- * Get the default filename for the cert. Value must be freed by caller.
- */
-char *creddy_id_cert_filename(creddy_id_t *id) {
-    assert(id != NULL);
-    assert(id->cn != NULL);
-
-    // malloc the filename
-    int len = strlen(id->cn) + strlen(CERT_SUFFIX) + 1;
-    char *filename = creddy_xmalloc(len);
-    sprintf(filename, "%s" CERT_SUFFIX, id->cn);
-
-    return filename;
-}
-
-/**
- * Write the ID cert to an open file pointer.
- */
-void creddy_id_write_cert(creddy_id_t *id, FILE *out) {
-    assert(id != NULL);
-
-    chunk_t encoding = id->cert->get_encoding(id->cert);
-    _encode_base64(out, encoding);
-    free(encoding.ptr);
-}
-
-/**
- * Default private key filename. Value must be freed by caller.
- */
-char *creddy_id_privkey_filename(creddy_id_t *id) {
-    assert(id != NULL);
-    assert(id->cn != NULL);
-
-    // malloc the filename
-    int len = strlen(id->cn) + strlen(KEY_SUFFIX) + 1;
-    char *filename = creddy_xmalloc(len);
-    sprintf(filename, "%s" KEY_SUFFIX, id->cn);
-
-    return filename;
-}
-
-/**
- * Write the private key to a file.
- * Returns false if there's no private key loaded
- */
-int creddy_id_write_privkey(creddy_id_t *id, FILE *out) {
-    int ret;
-    chunk_t encoding;
-
-    assert(id != NULL);
-
-    if (id->key == NULL)
-        return 0;
-
-    ret = id->key->get_encoding(id->key, KEY_PRIV_PEM, &encoding);
-    if (!ret)
-        errx(1, "Couldn't encode private key");
-
-    fwrite(encoding.ptr, encoding.len, 1, out);
-
-    free(encoding.ptr);
-    return 1;
-}
-
-/**
- * Get a DER-encoded chunk representing the cert.
- */
-abac_chunk_t creddy_id_cert_chunk(creddy_id_t *id) {
-    chunk_t encoding = id->cert->get_encoding(id->cert);
-    abac_chunk_t ret = { encoding.ptr, encoding.len };
-    return ret;
-}
-
-/**
- * Copy a creddy ID. Actually just increases its reference count.
- */
-creddy_id_t *creddy_id_dup(creddy_id_t *id) {
-    ++id->refcount;
-    return id;
-}
-
-void creddy_id_free(creddy_id_t *id) {
-    if (id == NULL)
-        return;
-
-    --id->refcount;
-    if (id->refcount > 0)
-        return;
-
-    // free once the reference count reaches 0
-    DESTROY_IF(id->cert);
-    DESTROY_IF(id->key);
-
-    free(id->keyid);
-    free(id);
-}
-
-//
-// Helper functions below
-//
-
-static char *_get_keyid(certificate_t *cert) {
-    // get the keyid
-    x509_t *x509 = (x509_t *)cert;
-    chunk_t keyid = x509->get_subjectKeyIdentifier(x509);
-    chunk_t string = chunk_to_hex(keyid, NULL, 0);
-    return (char *)string.ptr;
-}
-
-static chunk_t _passphrase_callback(void *user, int try) {
-    /* Get a password from stdin and return it as a chunk_t.  If too many tries
-     * have occurred or there is any other problem, return an empty chunk_t,
-     * which libstrongswan takes as giving up.  The chunk is alloated here
-     * (inside getline), and presumably freed by libstrongswan. User points to
-     * a cb_opts struct, which affects this routine in the obvious ways.
-     */
-
-    /* Configuration options */
-    struct cb_opts *opts = (struct cb_opts *) user;
-
-    if (try -1 < opts->tries ) {
-        char *secret = malloc(PWLEN);
-	if(!secret) {
-	    perror("malloc(PWLEN)");
-	    return chunk_empty;
-	}
-	if (readpassphrase(opts->use_prompt ? opts->prompt : NULL, secret, PWLEN, 
-                     opts->use_echo ? RPP_ECHO_ON : RPP_ECHO_OFF) == NULL) {
-          perror("readpassphrase()");
-	  memset(secret, '\0', PWLEN);
-	  free(secret);
-          return chunk_empty;
-	} 
-	return chunk_create(secret, strlen(secret));
-    } else {
-        fprintf(stderr, "Too many tries (%d)", try-1);
-        return chunk_empty;
-    }
-}
-
-/**
- * Generate a private key.
- */
-static private_key_t *_generate_key(void) {
-    private_key_t *key;
-    libabac_init();
-
-    // generate the key
-    key = lib->creds->create(
-        lib->creds,
-        CRED_PRIVATE_KEY, KEY_RSA,
-        BUILD_KEY_SIZE, 2048,
-        BUILD_END
-    );
-    if (key == NULL)
-        errx(1, "Key generation failed");
-
-    return key;
-}
-
-static char *_create_dn(char *cn) {
-
-#define DN "cn="
-
-    char *dn = creddy_xmalloc(sizeof(DN) + strlen(cn));
-    memcpy(dn, DN, sizeof(DN));
-    strcat(dn, cn);
-
-    return dn;
-}
-
-/**
- * Generate certificate.
- *
- * validity is measured in seconds (as of 0.2.0)
- */
-static certificate_t *_generate_cert(private_key_t *private, char *cn, int validity) {
-    // build the DN
-    char *dn_string = _create_dn(cn);
-    libabac_init();
-
-    identification_t *id = identification_create_from_string(dn_string);
-    if (id == NULL)
-        errx(1, "couldn't create ID from DN %s", dn_string);
-    free(dn_string);
-
-    // get the public key
-    public_key_t *public = private->get_public_key(private);
-    if (public == NULL)
-        errx(1, "couldn't get public key from private key");
-
-    // create a serial (stolen from strongswan pki)
-    rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-    if (!rng)
-        errx(1, "no random number generator");
-
-    // random serial
-    chunk_t serial = creddy_generate_serial();
-
-    // validity period
-    time_t not_before = time(NULL);
-    time_t not_after = not_before + validity;
-
-    // create!
-    certificate_t *cert = lib->creds->create(lib->creds,
-        CRED_CERTIFICATE, CERT_X509,
-        BUILD_SIGNING_KEY, private,
-        BUILD_PUBLIC_KEY, public,
-        BUILD_SUBJECT, id,
-        BUILD_NOT_BEFORE_TIME, not_before,
-        BUILD_NOT_AFTER_TIME, not_after,
-        BUILD_SERIAL, serial,
-        BUILD_DIGEST_ALG, HASH_SHA1,
-        BUILD_X509_FLAG, X509_CA,
-        BUILD_PATHLEN, X509_NO_PATH_LEN_CONSTRAINT,
-        BUILD_END
-    );
-    if (cert == NULL)
-        errx(1, "couldn't build cert :(");
-
-    DESTROY_IF(id);
-    DESTROY_IF(public);
-    free(serial.ptr);
-
-    return cert;
-}
-
-#define BYTES_PER_LINE 64
-
-// thx libstrongswan
-static void _encode_base64(FILE *out, chunk_t encoding) {
-    int start;
-
-    chunk_t b64 = chunk_to_base64(encoding, NULL);
-
-    fprintf(out, "-----BEGIN CERTIFICATE-----\n");
-
-    for (start = 0; start < b64.len; start += BYTES_PER_LINE) {
-        int left = b64.len - start;
-        int len = left < BYTES_PER_LINE ? left : BYTES_PER_LINE;
-        fwrite(b64.ptr + start, len, 1, out);
-        fprintf(out, "\n");
-    }
-
-    fprintf(out, "-----END CERTIFICATE-----\n");
-
-    free(b64.ptr);
-}
Index: creddy/keyid.c
===================================================================
--- creddy/keyid.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/keyid.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -1,4 +1,7 @@
-#include <creddy.h>
 
+/* keyid.c */
+#include <err.h>
+
+#include <abac.h>
 #include "creddy_common.h"
 
@@ -7,10 +10,10 @@
         usage(opts);
 
-    creddy_id_t *id = creddy_id_from_file(opts->cert);
+    abac_id_t *id = abac_id_from_file(opts->cert);
     if (id == NULL)
         errx(1, "Couldn't load ID cert from %s", opts->cert);
 
-    puts(creddy_id_keyid(id));
+    puts(abac_id_keyid(id));
 
-    creddy_id_free(id);
+    abac_id_free(id);
 }
Index: creddy/libcreddy.c
===================================================================
--- creddy/libcreddy.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ 	(revision )
@@ -1,60 +1,0 @@
-#include <assert.h>
-#include <ctype.h>
-#include <err.h>
-
-#include "libcreddy_common.h"
-
-void *creddy_xmalloc(size_t len) {
-    void *ret = malloc(len);
-    if (ret == NULL)
-        err(1, "couldn't malloc %d bytes\n", len);
-    return ret;
-}
-
-void *creddy_xrealloc(void *ptr, size_t size) {
-    void *ret = realloc(ptr, size);
-    if (ret == NULL)
-        err(1, "couldn't realloc %d bytes\n", size);
-    return ret;
-}
-
-char *creddy_xstrdup(char *string) {
-    char *dup = strdup(string);
-    if (dup == NULL)
-        err(1, "Can't dup %s", string);
-    return dup;
-}
-
-int creddy_clean_name(char *string) {
-    int i;
-
-    assert(string != NULL);
-
-    // must start with a letter/number
-    if (!isalnum(string[0])) return 0;
-
-    // Name must be alphanumeric or - or _ or :
-    for (i = 1; string[i] != '\0'; ++i)
-        if (!isalnum(string[i]) && string[i] != '-' && string[i] != '_' &&
-		string[i] != ':')
-            return 0;
-
-    return 1;
-}
-
-chunk_t creddy_generate_serial() {
-    chunk_t serial = chunk_empty;
-
-    // create a serial (stolen from strongswan pki)
-    rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-    if (!rng)
-        errx(1, "no random number generator");
-
-    rng->allocate_bytes(rng, 8, &serial);
-    while (serial.ptr[0] == 0)
-        // don't get leading 0's
-        rng->get_bytes(rng, 1, serial.ptr);
-    rng->destroy(rng);
-
-    return serial;
-}
Index: creddy/libcreddy_common.h
===================================================================
--- creddy/libcreddy_common.h	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ 	(revision )
@@ -1,30 +1,0 @@
-#ifndef __LIBCREDDY_COMMON_H__
-#define __LIBCREDDY_COMMON_H__
-
-#include <credentials/certificates/certificate.h>
-#include <credentials/certificates/x509.h>
-#include <credentials/keys/private_key.h>
-
-#include <creddy.h>
-
-void *creddy_xmalloc(size_t len);
-void *creddy_xrealloc(void *ptr, size_t size);
-char *creddy_xstrdup(char *string);
-int creddy_clean_name(char *string);
-chunk_t creddy_generate_serial();
-
-// from libabac
-void libabac_init();
-
-//
-// Private API
-//
-
-// get the cert from the ID
-certificate_t *creddy_id_cert(creddy_id_t *id);
-
-// get the private key from the ID
-// will return NULL if no key has been loaded
-private_key_t *creddy_id_privkey(creddy_id_t *id);
-
-#endif /* __ID_H__ */
Index: creddy/roles.c
===================================================================
--- creddy/roles.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/roles.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -1,5 +1,11 @@
-#include "creddy_common.h"
 
-#include <credentials/certificates/ac.h>
+/* roles.c */
+
+#include <err.h>
+
+#include "abac.h"
+#include <creddy_common.h>
+
+extern char *abac_attribute_role_string(abac_attribute_t *attr);
 
 void roles_main(options_t *opts) {
@@ -7,14 +13,17 @@
         usage(opts);
 
-    certificate_t *cert = attr_cert_from_file(opts->cert);
+    abac_list_t *attr_list = abac_attribute_certs_from_file(opts->cert);
+    if (abac_list_size(attr_list) == 0)
+        errx(1, "Couldn't get cert from %s", opts->cert);
 
-    ac_t *ac = (ac_t *)cert;
-    ietf_attributes_t *attr = ac->get_groups(ac);
-    if (attr == NULL)
-        errx(1, "Couldn't get attributes from cert");
-
-    puts(attr->get_string(attr));
-
-    DESTROY_IF(attr);
-    DESTROY_IF(cert);
+    abac_attribute_t *cert=NULL;
+    abac_list_foreach(attr_list, cert,
+            char *role_string=abac_attribute_role_string(cert);
+            if (role_string != NULL) {
+                puts(role_string);
+                free(role_string);
+            } else errx(1, "Couldn't get attributes from %s", opts->cert);
+            abac_attribute_free(cert);
+    );
+    abac_list_free(attr_list);
 }
Index: creddy/verify.c
===================================================================
--- creddy/verify.c	(revision 2579c1a1b48df617683bedd12fb71e2a687ec741)
+++ creddy/verify.c	(revision 461541aae6382bb58dfb3c4a1679d2d48e8f9e64)
@@ -1,44 +1,55 @@
-#include <creddy.h>
 
+/* verify.c */
+
+#include <err.h>
+#include <string.h>
+
+#include <abac.h>
 #include "creddy_common.h"
 
-// ugh, this needs to go away
-// do so by replacing this with a call into libabac
-#include "libcreddy_common.h"
+int debug=0;
+
+// verify can only valiate that the issuer and the attribute credential
+// are still valid currently and the issuer's keyid is the same as that
+// of the signing issuer id of the attribute credential
+static void _validate(abac_attribute_t *subjec_cert, abac_id_t *cert);
 
 void verify_main(options_t *opts) {
-    certificate_t *subject_cert = NULL;
-
     if (opts->cert == NULL)
         usage(opts);
 
-    creddy_id_t *issuer = creddy_id_from_file(opts->cert);
-    if (issuer == NULL)
+    abac_id_t *issuer_id = abac_id_from_file(opts->cert);
+    if (issuer_id == NULL)
         errx(1, "Can't load issuer cert from %s", opts->cert);
-    certificate_t *cert = creddy_id_cert(issuer); // replace this with a call into libabac
+    if (opts->attrcert != NULL) {
+        abac_list_t *attr_list = abac_attribute_certs_from_file(opts->attrcert);
+        abac_attribute_t *subject_attr=NULL;
+        abac_list_foreach(attr_list, subject_attr,
+            _validate(subject_attr, issuer_id);
+            abac_attribute_free(subject_attr);
+        );
+        abac_list_free(attr_list);
+    } 
 
-    if (opts->attrcert != NULL)
-        subject_cert = attr_cert_from_file(opts->attrcert);
-    else
-        subject_cert = cert;
+    abac_id_free(issuer_id);
 
-    int good = 0;
-    if (subject_cert->issued_by(subject_cert, cert))
-        if (subject_cert->get_validity(subject_cert, NULL, NULL, NULL))
-            if (cert->get_validity(cert, NULL, NULL, NULL)) {
-                puts("signature good, certificates valid");
-                good = 1;
-            }
-            else
-                puts("signature good, issuer cert not valid now");
-        else
-            puts("certificate not valid now");
-    else
-        puts("signature invalid");
+}
 
-    if (subject_cert != cert)
-        DESTROY_IF(subject_cert);
-    creddy_id_free(issuer);
+static void _validate(abac_attribute_t *attr, abac_id_t *issuer)
+{
+    // checking for matching principal keyid
+    char *prin=abac_attribute_get_principal(attr);
+    char *keyid=abac_id_keyid(issuer);
+    if(strcmp(prin,keyid) != 0)
+        puts("issuer and attribute cert have mismatched principals\n");
+        else puts("issuer and attribute cert have matching principals\n");
+    free(prin);
 
-    exit(good ? 0 : 1);
+    if(!abac_id_still_valid(issuer))
+        puts("issuer cert not valid now");
+        else puts("issuer cert still valid");
+
+    if(!abac_attribute_still_valid(attr))
+        puts("attribute cert not valid now");
+        else puts("attribute cert still valid");
 }
