From 3f8b0ccb98af828e4364c58259f19ae6cb1a9c73 Mon Sep 17 00:00:00 2001
From: Will Hunter <william.hunter@trusted-logic.com>
Date: Tue, 6 Dec 2011 11:37:11 +0200
Subject: [PATCH 2/2] Allow the private key auth_id to be inside an
 AccessControlRule

---
 src/pkcs11/framework-pkcs15.c |   44 ++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c
index 5e55f5a..7396021 100644
--- a/src/pkcs11/framework-pkcs15.c
+++ b/src/pkcs11/framework-pkcs15.c
@@ -724,6 +724,42 @@ __pkcs15_prkey_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_prkey_
 }
 
 static void
+__pkcs15_prkey_check_auth_id(struct pkcs15_prkey_object *pk)
+{
+	struct sc_pkcs15_object *obj = pk->base.p15_object;
+	unsigned int i;
+
+	// No issues - auth ID is present or key is not private
+	if (!(obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) || (obj->auth_id.len != 0))
+		return;
+
+	sc_log(context, "Private key %s has no auth ID - checking AccessControlRules", 
+					sc_pkcs15_print_id(&pk->prv_info->id));
+
+	// Otherwise search in the access_rules for an appropriate auth ID
+	for (i = 0; i < SC_PKCS15_MAX_ACCESS_RULES; i++) {
+		// If access_mode is one of the private key usage modes
+		if (obj->access_rules[i].access_mode &&
+				(SC_PKCS15_ACCESS_RULE_MODE_EXECUTE |
+				 SC_PKCS15_ACCESS_RULE_MODE_PSO_CDS |
+				 SC_PKCS15_ACCESS_RULE_MODE_PSO_DECRYPT |
+				 SC_PKCS15_ACCESS_RULE_MODE_INT_AUTH)) {
+			if (obj->access_rules[i].auth_id.len != 0) {
+				// Found an auth ID to use for private key access
+				obj->auth_id = obj->access_rules[i].auth_id;
+				sc_log(context, "Auth ID found - %s",
+								sc_pkcs15_print_id(&obj->auth_id));
+				return;
+			}
+		}
+	}
+
+	// No auth ID found
+	sc_log(context, "Warning: No auth ID found");
+	return;
+}
+
+static void
 __pkcs15_cert_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_cert_object *cert)
 {
 	struct sc_pkcs15_cert *c1 = cert->cert_data;
@@ -785,6 +821,7 @@ pkcs15_bind_related_objects(struct pkcs15_fw_data *fw_data)
 
 		if (is_privkey(obj)) {
 			__pkcs15_prkey_bind_related(fw_data, (struct pkcs15_prkey_object *) obj);
+			__pkcs15_prkey_check_auth_id((struct pkcs15_prkey_object *)obj);
 		} else if (is_cert(obj)) {
 			__pkcs15_cert_bind_related(fw_data, (struct pkcs15_cert_object *) obj);
 		}
@@ -1054,7 +1091,8 @@ _get_auth_object_by_flags(struct sc_pkcs15_object **auths, size_t num, unsigned
 		int *out_idx)
 {
 	struct sc_pkcs15_object *out = NULL;
-	int i, idx = out_idx ? *out_idx : 0;
+	unsigned int i;
+	int idx = out_idx ? *out_idx : 0;
 
 	for (i = idx; i < num; i++)   {
 		struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *)(*(auths + i))->data;
@@ -1132,7 +1170,7 @@ _add_pin_related_objects(struct sc_pkcs11_slot *slot, struct sc_pkcs15_object *p
 		struct pkcs15_fw_data *fw_data, struct pkcs15_fw_data *move_to_fw)
 {
 	struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
-	int i;
+	unsigned int i;
 
 	sc_log(context, "PinID:%s", sc_pkcs15_print_id(&pin_info->auth_id));
 	for (i=0; i < fw_data->num_objects; i++) {
@@ -1185,7 +1223,7 @@ _add_pin_related_objects(struct sc_pkcs11_slot *slot, struct sc_pkcs15_object *p
 static void
 _add_public_objects(struct sc_pkcs11_slot *slot, struct pkcs15_fw_data *fw_data, struct pkcs15_fw_data *move_to_fw)
 {
-	int i;
+	unsigned int i;
 
 	sc_log(context, "%i public objects to process", fw_data->num_objects);
 	for (i=0; i < fw_data->num_objects; i++) {
-- 
1.7.7.1.msysgit.0

