Index: libabac/abac_verifier.c
===================================================================
--- libabac/abac_verifier.c	(revision 15200beba77a0ea12f6dcaabfa529d03962d71fc)
+++ libabac/abac_verifier.c	(revision 0779c991d51ed7455ef21eeaaeae809db35ca630)
@@ -41,5 +41,5 @@
 // verify that cert was issued by issuer
 // cert and issuer can be the same, in which case the self-sig is validated
-static int _verify_cert(certificate_t *issuer, certificate_t *cert) {
+static int _verify_signature(certificate_t *issuer, certificate_t *cert) {
     // XXX make sure this checks signature
     if (cert->issued_by(cert, issuer))
@@ -91,5 +91,8 @@
     // get the cert's pub key
     public = cert->get_public_key(cert);
-    if (public == NULL) goto error;
+    if (public == NULL) {
+        ret = ABAC_CERT_INVALID;
+        goto error;
+    }
 
     // get the pubkey's fingerprint
@@ -98,9 +101,15 @@
         KEY_ID_PUBKEY_INFO_SHA1, &id
     );
-    if (!ret) goto error;
+    if (!ret) {
+        ret = ABAC_CERT_INVALID;
+        goto error;
+    }
 
     // validate sig
-    ret = _verify_cert(cert, cert);
-    if (!ret) goto error;
+    ret = _verify_signature(cert, cert);
+    if (!ret) {
+        ret = ABAC_CERT_BAD_SIG;
+        goto error;
+    }
 
     keyid = _chunk_to_string(id);
@@ -114,10 +123,10 @@
     public->destroy(public);
 
-    return 1;
+    return ABAC_CERT_SUCCESS;
 
 error:
     if (public != NULL) public->destroy(public);
 
-    return 0;
+    return ret;
 }
 
@@ -134,5 +143,5 @@
     );
     if (cert == NULL)
-        return 0;
+        return ABAC_CERT_INVALID;
     return _load_id(cert);
 }
@@ -150,5 +159,5 @@
     );
     if (cert == NULL)
-        return 0;
+        return ABAC_CERT_INVALID;
     return _load_id(cert);
 }
@@ -159,5 +168,5 @@
  * authority.
  */
-static abac_credential_t *_load_attribute_cert(certificate_t *cert) {
+static int _load_attribute_cert(certificate_t *cert, abac_credential_t **cred_ret) {
     ietf_attributes_t *attr_cert = NULL;
     abac_role_t *head_role = NULL;
@@ -169,31 +178,52 @@
     ac_t *ac = (ac_t *)cert;
     attr_cert = ac->get_groups(ac);
-    if (attr_cert == NULL) goto error;
+    if (attr_cert == NULL) {
+        ret = ABAC_CERT_INVALID;
+        goto error;
+    }
 
     char *attr_string = attr_cert->get_string(attr_cert);
-    if (attr_string == NULL) goto error;
+    if (attr_string == NULL) {
+        ret = ABAC_CERT_INVALID;
+        goto error;
+    }
 
     // split into head/tail parts
     char head[256], tail[256];
     ret = sscanf(attr_string, "%255s <- %255s", head, tail);
-    if (ret != 2) goto error;
+    if (ret != 2) {
+        ret = ABAC_CERT_INVALID;
+        goto error;
+    }
 
     // must be a role
     head_role = abac_role_from_string(head);
     if (head_role == NULL) goto error;
-    if (!abac_role_is_role(head_role)) goto error;
+    if (!abac_role_is_role(head_role)) {
+        ret = ABAC_CERT_INVALID;
+        goto error;
+    }
 
     // make sure the tail role is valid
     tail_role = abac_role_from_string(tail);
-    if (tail_role == NULL) goto error;
+    if (tail_role == NULL) {
+        ret = ABAC_CERT_INVALID;
+        goto error;
+    }
 
     // get the issuer based on keyid
     char *principal = abac_role_principal(head_role);
     HASH_FIND_STR(id_certs, principal, issuer);
-    if (issuer == NULL) goto error;
+    if (issuer == NULL) {
+        ret = ABAC_CERT_MISSING_ISSUER;
+        goto error;
+    }
 
     // make sure the issuer's signed it
-    ret = _verify_cert(issuer->cert, cert);
-    if (!ret) goto error;
+    ret = _verify_signature(issuer->cert, cert);
+    if (!ret) {
+        ret = ABAC_CERT_BAD_SIG;
+        goto error;
+    }
 
     // at this point we know we have a good attribute cert
@@ -203,9 +233,10 @@
     cred->cert = cert;
     cred->issuer = issuer->cert->get_ref(issuer->cert);
+    *cred_ret = cred;
 
     // free up some crap
     attr_cert->destroy(attr_cert);
 
-    return cred;
+    return ABAC_CERT_SUCCESS;
 
 error:
@@ -215,5 +246,5 @@
     if (tail_role != NULL) abac_role_free(tail_role);
 
-    return NULL;
+    return ret;
 }
 
@@ -221,5 +252,5 @@
  * Load an attribute cert from a file.
  */
-abac_credential_t *abac_verifier_load_attribute_cert_file(char *filename) {
+int abac_verifier_load_attribute_cert_file(char *filename, abac_credential_t **cred) {
     // load the cert
     certificate_t *cert = lib->creds->create(
@@ -229,6 +260,6 @@
     );
     if (cert == NULL)
-        return NULL;
-    return _load_attribute_cert(cert);
+        return ABAC_CERT_INVALID;
+    return _load_attribute_cert(cert, cred);
 }
 
@@ -236,5 +267,5 @@
  * Load an attribute cert from a chunk.
  */
-abac_credential_t *abac_verifier_load_attribute_cert_chunk(chunk_t chunk) {
+int abac_verifier_load_attribute_cert_chunk(chunk_t chunk, abac_credential_t **cred) {
     // load the cert
     certificate_t *cert = lib->creds->create(
@@ -244,6 +275,6 @@
     );
     if (cert == NULL)
-        return NULL;
-    return _load_attribute_cert(cert);
+        return ABAC_CERT_INVALID;
+    return _load_attribute_cert(cert, cred);
 }
 
