[gnome-keyring/dbus-api] [gck] Pass session to get/set attribute functions.



commit a077d102f2e5d2af1063d2388a1ebdeb0e6101a3
Author: Stef Walter <stef memberwebs com>
Date:   Sun Jul 19 19:24:27 2009 +0000

    [gck] Pass session to get/set attribute functions.
    
    This allows attributes to be different depending on which session or
    application they're accessed from. Implement CKA_ALWAYS_AUTHENTICATE
    as a session dependent attribute.

 pkcs11/gck/gck-authenticator.c             |    4 +-
 pkcs11/gck/gck-certificate-key.c           |    6 +-
 pkcs11/gck/gck-certificate-trust.c         |   14 ++++---
 pkcs11/gck/gck-certificate.c               |    6 +-
 pkcs11/gck/gck-key.c                       |    4 +-
 pkcs11/gck/gck-manager.c                   |   12 +++---
 pkcs11/gck/gck-object.c                    |   64 +++++++++++++---------------
 pkcs11/gck/gck-object.h                    |   19 ++++++--
 pkcs11/gck/gck-private-key.c               |   21 +++++++---
 pkcs11/gck/gck-private-key.h               |    3 +-
 pkcs11/gck/gck-public-key.c                |    4 +-
 pkcs11/gck/gck-session.c                   |   20 ++++----
 pkcs11/gck/tests/mock-locked-object.c      |    4 +-
 pkcs11/roots-store/gck-roots-certificate.c |    4 +-
 pkcs11/ssh-store/gck-ssh-private-key.c     |    6 +-
 pkcs11/ssh-store/gck-ssh-public-key.c      |    4 +-
 pkcs11/user-store/gck-user-private-key.c   |    4 +-
 pkcs11/user-store/gck-user-storage.c       |    6 +-
 18 files changed, 110 insertions(+), 95 deletions(-)
---
diff --git a/pkcs11/gck/gck-authenticator.c b/pkcs11/gck/gck-authenticator.c
index 2f71c2a..5c0d7f5 100644
--- a/pkcs11/gck/gck-authenticator.c
+++ b/pkcs11/gck/gck-authenticator.c
@@ -130,7 +130,7 @@ object_went_away (gpointer data, GObject *old_object)
  */
 
 static CK_RV 
-gck_authenticator_real_get_attribute (GckObject *base, CK_ATTRIBUTE *attr)
+gck_authenticator_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE *attr)
 {
 	GckAuthenticator *self = GCK_AUTHENTICATOR (base);
 
@@ -156,7 +156,7 @@ gck_authenticator_real_get_attribute (GckObject *base, CK_ATTRIBUTE *attr)
 		return CKR_ATTRIBUTE_SENSITIVE;
 	};
 
-	return GCK_OBJECT_CLASS (gck_authenticator_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_authenticator_parent_class)->get_attribute (base, session, attr);
 }
 
 static GObject* 
diff --git a/pkcs11/gck/gck-certificate-key.c b/pkcs11/gck/gck-certificate-key.c
index f50d3ca..d0e05a3 100644
--- a/pkcs11/gck/gck-certificate-key.c
+++ b/pkcs11/gck/gck-certificate-key.c
@@ -46,18 +46,18 @@ G_DEFINE_TYPE (GckCertificateKey, gck_certificate_key, GCK_TYPE_PUBLIC_KEY);
  */
 
 static CK_RV
-gck_certificate_key_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
+gck_certificate_key_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE_PTR attr)
 {
 	GckCertificateKey *self = GCK_CERTIFICATE_KEY (base);
 	
 	switch (attr->type) {
 	case CKA_LABEL:
 		if (self->pv->certificate)
-			return gck_object_get_attribute (GCK_OBJECT (self->pv->certificate), attr);
+			return gck_object_get_attribute (GCK_OBJECT (self->pv->certificate), session, attr);
 		return gck_attribute_set_string (attr, "");
 	}
 	
-	return GCK_OBJECT_CLASS (gck_certificate_key_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_certificate_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static void
diff --git a/pkcs11/gck/gck-certificate-trust.c b/pkcs11/gck/gck-certificate-trust.c
index 40b2355..bda4a9e 100644
--- a/pkcs11/gck/gck-certificate-trust.c
+++ b/pkcs11/gck/gck-certificate-trust.c
@@ -132,7 +132,8 @@ has_enhanced_usage (GckCertificateTrust *self, CK_ATTRIBUTE_TYPE type, CK_ULONG
 	g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
 
 	/* Check if we have the purpose setup */
-	if (!gck_object_get_attribute_boolean (GCK_OBJECT (self->pv->certificate), type, &bval))
+	if (!gck_object_get_attribute_boolean (GCK_OBJECT (self->pv->certificate), 
+	                                       NULL, type, &bval))
 		bval = FALSE;
 	
 	/* Don't have the purpose */
@@ -142,7 +143,8 @@ has_enhanced_usage (GckCertificateTrust *self, CK_ATTRIBUTE_TYPE type, CK_ULONG
 	}
 	
 	/* Ascertain the trust in this certificate */
-	if (!gck_object_get_attribute_boolean (GCK_OBJECT (self->pv->certificate), CKA_TRUSTED, &bval))
+	if (!gck_object_get_attribute_boolean (GCK_OBJECT (self->pv->certificate), 
+	                                       NULL, CKA_TRUSTED, &bval))
 		bval = FALSE;
 	
 	if (bval != TRUE) {
@@ -152,7 +154,7 @@ has_enhanced_usage (GckCertificateTrust *self, CK_ATTRIBUTE_TYPE type, CK_ULONG
 	
 	/* See if we can delegate the purpase (ie: CA) */
 	if (!gck_object_get_attribute_ulong (GCK_OBJECT (self->pv->certificate),
-	                                     CKA_CERTIFICATE_CATEGORY, &nval))
+	                                     NULL, CKA_CERTIFICATE_CATEGORY, &nval))
 		nval = 0;
 
 	/* 2 is a certificate authority in PKCS#11 */
@@ -200,7 +202,7 @@ hash_certificate (GckCertificateTrust *self, int algo, CK_ATTRIBUTE_PTR result)
  */
 
 static CK_RV
-gck_certificate_trust_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
+gck_certificate_trust_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE_PTR attr)
 {
 	GckCertificateTrust *self = GCK_CERTIFICATE_TRUST (base);
 	
@@ -267,7 +269,7 @@ gck_certificate_trust_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
 	case CKA_SERIAL_NUMBER:
 	case CKA_ISSUER:
 		g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
-		return gck_object_get_attribute (GCK_OBJECT (self->pv->certificate), attr);
+		return gck_object_get_attribute (GCK_OBJECT (self->pv->certificate), session, attr);
 
 	case CKA_CERT_MD5_HASH:
 		return hash_certificate (self, GCRY_MD_MD5, attr);
@@ -278,7 +280,7 @@ gck_certificate_trust_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
 		break;
 	};
 	
-	return GCK_OBJECT_CLASS (gck_certificate_trust_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_certificate_trust_parent_class)->get_attribute (base, session, attr);
 }
 
 static void
diff --git a/pkcs11/gck/gck-certificate.c b/pkcs11/gck/gck-certificate.c
index a024a91..a3b4c41 100644
--- a/pkcs11/gck/gck-certificate.c
+++ b/pkcs11/gck/gck-certificate.c
@@ -281,7 +281,7 @@ factory_create_certificate (GckSession *session, GckTransaction *transaction,
  */
 
 static CK_RV 
-gck_certificate_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
+gck_certificate_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
 {
 	GckCertificate *self = GCK_CERTIFICATE (base);
 	CK_ULONG category;
@@ -343,7 +343,7 @@ gck_certificate_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
 
 	case CKA_ID:
 		g_return_val_if_fail (self->pv->key, CKR_GENERAL_ERROR);
-		return gck_object_get_attribute (GCK_OBJECT (self->pv->key), attr);
+		return gck_object_get_attribute (GCK_OBJECT (self->pv->key), session, attr);
 
 	case CKA_ISSUER:
 		g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
@@ -408,7 +408,7 @@ gck_certificate_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
 		return read_certificate_purpose (self, OID_USAGE_TIME_STAMPING, attr);
 	};
 
-	return GCK_OBJECT_CLASS (gck_certificate_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_certificate_parent_class)->get_attribute (base, session, attr);
 }
 
 static GObject* 
diff --git a/pkcs11/gck/gck-key.c b/pkcs11/gck/gck-key.c
index bc27704..134fc7e 100644
--- a/pkcs11/gck/gck-key.c
+++ b/pkcs11/gck/gck-key.c
@@ -49,7 +49,7 @@ G_DEFINE_TYPE (GckKey, gck_key, GCK_TYPE_OBJECT);
  */
 
 static CK_RV 
-gck_key_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
+gck_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
 {
 	GckKey *self = GCK_KEY (base);
 	
@@ -108,7 +108,7 @@ gck_key_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
 		return gck_attribute_set_data (attr, "", 0);
 	};
 
-	return GCK_OBJECT_CLASS (gck_key_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static GObject* 
diff --git a/pkcs11/gck/gck-manager.c b/pkcs11/gck/gck-manager.c
index 1638b3e..7829889 100644
--- a/pkcs11/gck/gck-manager.c
+++ b/pkcs11/gck/gck-manager.c
@@ -119,7 +119,7 @@ read_attribute(GckObject *object, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE_PTR *resu
 	attr.ulValueLen = 0;
 		
 	/* Figure out memory length */
-	rv = gck_object_get_attribute (object, &attr);
+	rv = gck_object_get_attribute (object, NULL, &attr);
 	
 	/* Not an error, just not present */
 	if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
@@ -135,7 +135,7 @@ read_attribute(GckObject *object, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE_PTR *resu
 	/* Allocate memory length */
 	if (attr.ulValueLen) {
 		attr.pValue = g_malloc0 (attr.ulValueLen);
-		rv = gck_object_get_attribute (object, &attr);
+		rv = gck_object_get_attribute (object, NULL, &attr);
 		if (rv != CKR_OK) {
 			g_warning ("accessing indexed attribute failed");
 			g_free (attr.pValue);
@@ -465,7 +465,7 @@ find_each_object (gpointer unused, gpointer object, gpointer user_data)
 			if (!index_contains (index, object, attr))
 				return;
 		} else {
-			if (!gck_object_match (object, attr))
+			if (!gck_object_match (object, NULL, attr))
 				return;
 		}
 	}
@@ -505,7 +505,7 @@ find_for_attributes (Finder *finder)
 	if (!index) {
 		
 		for (l = finder->manager->pv->objects; l; l = g_list_next (l)) {
-			if (gck_object_match (l->data, first))
+			if (gck_object_match (l->data, NULL, first))
 				find_each_object (NULL, l->data, finder);
 		}
 		
@@ -549,7 +549,7 @@ static void
 accumulate_public_handles (Finder *finder, GckObject *object)
 {
 	gboolean is_private;
-	if (gck_object_get_attribute_boolean (object, CKA_PRIVATE, &is_private) && is_private)
+	if (gck_object_get_attribute_boolean (object, NULL, CKA_PRIVATE, &is_private) && is_private)
 		return;
 	accumulate_handles (finder, object);
 }
@@ -889,7 +889,7 @@ gck_manager_find_related (GckManager *self, CK_OBJECT_CLASS klass, GckObject *re
 	g_return_val_if_fail (GCK_IS_MANAGER (self), NULL);
 	g_return_val_if_fail (GCK_IS_OBJECT (related_to), NULL);
 	
-	id = gck_object_get_attribute_data (related_to, CKA_ID, &n_id);
+	id = gck_object_get_attribute_data (related_to, NULL, CKA_ID, &n_id);
 	if (id == NULL)
 		return NULL;
 	
diff --git a/pkcs11/gck/gck-object.c b/pkcs11/gck/gck-object.c
index e1188a9..f7bd7f7 100644
--- a/pkcs11/gck/gck-object.c
+++ b/pkcs11/gck/gck-object.c
@@ -139,7 +139,7 @@ complete_destroy (GckTransaction *transaction, GObject *unused, gpointer user_da
  */
 
 static CK_RV 
-gck_object_real_get_attribute (GckObject *self, CK_ATTRIBUTE* attr)
+gck_object_real_get_attribute (GckObject *self, GckSession *session, CK_ATTRIBUTE* attr)
 {
 	CK_RV rv;
 	
@@ -184,7 +184,8 @@ gck_object_real_get_attribute (GckObject *self, CK_ATTRIBUTE* attr)
 }
 
 static void 
-gck_object_real_set_attribute (GckObject *self, GckTransaction* transaction, CK_ATTRIBUTE* attr)
+gck_object_real_set_attribute (GckObject *self, GckSession *session,
+                               GckTransaction* transaction, CK_ATTRIBUTE* attr)
 {
 	switch (attr->type) {
 	case CKA_TOKEN:
@@ -217,8 +218,8 @@ gck_object_real_set_attribute (GckObject *self, GckTransaction* transaction, CK_
 }
 
 static void
-gck_object_real_create_attributes (GckObject *self, GckTransaction *transaction, 
-                                   GckSession *session, CK_ATTRIBUTE *attrs, CK_ULONG n_attrs)
+gck_object_real_create_attributes (GckObject *self, GckSession *session,
+                                   GckTransaction *transaction, CK_ATTRIBUTE *attrs, CK_ULONG n_attrs)
 {
 	CK_ATTRIBUTE_PTR transient_attr;
 	CK_ATTRIBUTE_PTR lifetime_attr;
@@ -270,17 +271,8 @@ gck_object_real_create_attributes (GckObject *self, GckTransaction *transaction,
 static CK_RV
 gck_object_real_unlock (GckObject *self, GckAuthenticator *auth)
 {
-	gboolean always_auth;
-	
-	if (!gck_object_get_attribute_boolean (self, CKA_ALWAYS_AUTHENTICATE, &always_auth))
-		always_auth = FALSE;
-	
-	/* A strange error code, but according to spec */
-	if (!always_auth)
-		return CKR_OPERATION_NOT_INITIALIZED;
-
 	/* A derived class should have overridden this */
-	g_return_val_if_reached (CKR_GENERAL_ERROR);
+	return CKR_FUNCTION_FAILED;
 }
 
 static GObject* 
@@ -479,17 +471,17 @@ gck_object_class_init (GckObjectClass *klass)
  */
 
 CK_RV
-gck_object_get_attribute (GckObject *self, CK_ATTRIBUTE_PTR attr)
+gck_object_get_attribute (GckObject *self, GckSession *session, CK_ATTRIBUTE_PTR attr)
 {
 	g_return_val_if_fail (GCK_IS_OBJECT (self), CKR_GENERAL_ERROR);
 	g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
 	g_assert (GCK_OBJECT_GET_CLASS (self)->get_attribute);
-	return GCK_OBJECT_GET_CLASS (self)->get_attribute (self, attr);
+	return GCK_OBJECT_GET_CLASS (self)->get_attribute (self, session, attr);
 }
 
 void
-gck_object_set_attribute (GckObject *self, GckTransaction *transaction,
-                          CK_ATTRIBUTE_PTR attr)
+gck_object_set_attribute (GckObject *self, GckSession *session,
+                          GckTransaction *transaction, CK_ATTRIBUTE_PTR attr)
 {
 	CK_ATTRIBUTE check;
 	CK_RV rv;
@@ -505,19 +497,19 @@ gck_object_set_attribute (GckObject *self, GckTransaction *transaction,
 	check.type = attr->type;
 	check.pValue = 0;
 	check.ulValueLen = 0;
-	rv = gck_object_get_attribute (self, &check);
+	rv = gck_object_get_attribute (self, session, &check);
 	if (rv != CKR_OK && rv != CKR_ATTRIBUTE_SENSITIVE) {
 		gck_transaction_fail (transaction, rv);
 		return;
 	}
 	
 	/* Check that the value will actually change */
-	if (rv == CKR_ATTRIBUTE_SENSITIVE || !gck_object_match (self, attr))
-		GCK_OBJECT_GET_CLASS (self)->set_attribute (self, transaction, attr);
+	if (rv == CKR_ATTRIBUTE_SENSITIVE || !gck_object_match (self, session, attr))
+		GCK_OBJECT_GET_CLASS (self)->set_attribute (self, session, transaction, attr);
 }
 
 void
-gck_object_create_attributes (GckObject *self, GckTransaction *transaction, GckSession *session,
+gck_object_create_attributes (GckObject *self, GckSession *session, GckTransaction *transaction,
                               CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 {
 	g_return_if_fail (GCK_IS_OBJECT (self));
@@ -529,7 +521,7 @@ gck_object_create_attributes (GckObject *self, GckTransaction *transaction, GckS
 	g_assert (GCK_OBJECT_GET_CLASS (self)->create_attributes);
 
 	/* Check that the value will actually change */
-	GCK_OBJECT_GET_CLASS (self)->create_attributes (self, transaction, session, attrs, n_attrs);
+	GCK_OBJECT_GET_CLASS (self)->create_attributes (self, session, transaction, attrs, n_attrs);
 }
 
 void
@@ -540,7 +532,7 @@ gck_object_notify_attribute  (GckObject *self, CK_ATTRIBUTE_TYPE attr_type)
 }
 
 gboolean
-gck_object_match (GckObject *self, CK_ATTRIBUTE_PTR match)
+gck_object_match (GckObject *self, GckSession *session, CK_ATTRIBUTE_PTR match)
 {
 	CK_ATTRIBUTE attr;
 	gboolean matched = FALSE;
@@ -557,7 +549,7 @@ gck_object_match (GckObject *self, CK_ATTRIBUTE_PTR match)
 	
 	matched = FALSE;
 	
-	rv = gck_object_get_attribute (self, &attr);
+	rv = gck_object_get_attribute (self, session, &attr);
 	matched = (rv == CKR_OK) && 
 	          (match->ulValueLen == attr.ulValueLen) &&
 	          (memcmp (match->pValue, attr.pValue, attr.ulValueLen) == 0);
@@ -567,14 +559,15 @@ gck_object_match (GckObject *self, CK_ATTRIBUTE_PTR match)
 }
 
 gboolean
-gck_object_match_all (GckObject *self, CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
+gck_object_match_all (GckObject *self, GckSession *session,
+                      CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
 {
 	CK_ULONG i;
 	
 	g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
 	
 	for (i = 0; i < n_attrs; ++i) {
-		if (!gck_object_match (self, &attrs[i]))
+		if (!gck_object_match (self, session, &attrs[i]))
 			return FALSE;
 	}
 	
@@ -639,7 +632,8 @@ gck_object_unlock (GckObject *self, GckAuthenticator *auth)
 
 
 gboolean
-gck_object_get_attribute_boolean (GckObject *self, CK_ATTRIBUTE_TYPE type, gboolean *value)
+gck_object_get_attribute_boolean (GckObject *self, GckSession *session,
+                                  CK_ATTRIBUTE_TYPE type, gboolean *value)
 {
 	CK_ATTRIBUTE attr;
 	CK_BBOOL bvalue;
@@ -651,7 +645,7 @@ gck_object_get_attribute_boolean (GckObject *self, CK_ATTRIBUTE_TYPE type, gbool
 	attr.ulValueLen = sizeof (CK_BBOOL);
 	attr.pValue = &bvalue;
 	
-	if (gck_object_get_attribute (self, &attr) != CKR_OK)
+	if (gck_object_get_attribute (self, session, &attr) != CKR_OK)
 		return FALSE;
 	
 	*value = (bvalue == CK_TRUE) ? TRUE : FALSE;
@@ -659,7 +653,8 @@ gck_object_get_attribute_boolean (GckObject *self, CK_ATTRIBUTE_TYPE type, gbool
 }
 
 gboolean
-gck_object_get_attribute_ulong (GckObject *self, CK_ATTRIBUTE_TYPE type, gulong *value)
+gck_object_get_attribute_ulong (GckObject *self, GckSession *session,
+                                CK_ATTRIBUTE_TYPE type, gulong *value)
 {
 	CK_ATTRIBUTE attr;
 	CK_ULONG uvalue;
@@ -671,7 +666,7 @@ gck_object_get_attribute_ulong (GckObject *self, CK_ATTRIBUTE_TYPE type, gulong
 	attr.ulValueLen = sizeof (CK_ULONG);
 	attr.pValue = &uvalue;
 	
-	if (gck_object_get_attribute (self, &attr) != CKR_OK)
+	if (gck_object_get_attribute (self, session, &attr) != CKR_OK)
 		return FALSE;
 	
 	*value = uvalue;
@@ -679,7 +674,8 @@ gck_object_get_attribute_ulong (GckObject *self, CK_ATTRIBUTE_TYPE type, gulong
 }
 
 void*
-gck_object_get_attribute_data (GckObject *self, CK_ATTRIBUTE_TYPE type, gsize *n_data)
+gck_object_get_attribute_data (GckObject *self, GckSession *session,
+                               CK_ATTRIBUTE_TYPE type, gsize *n_data)
 {
 	CK_ATTRIBUTE attr;
 	
@@ -690,7 +686,7 @@ gck_object_get_attribute_data (GckObject *self, CK_ATTRIBUTE_TYPE type, gsize *n
 	attr.ulValueLen = 0;
 	attr.pValue = NULL;
 	
-	if (gck_object_get_attribute (self, &attr) != CKR_OK)
+	if (gck_object_get_attribute (self, session, &attr) != CKR_OK)
 		return NULL;
 
 	if (attr.ulValueLen == 0)
@@ -698,7 +694,7 @@ gck_object_get_attribute_data (GckObject *self, CK_ATTRIBUTE_TYPE type, gsize *n
 	
 	attr.pValue = g_malloc0 (attr.ulValueLen);
 	
-	if (gck_object_get_attribute (self, &attr) != CKR_OK) {
+	if (gck_object_get_attribute (self, session, &attr) != CKR_OK) {
 		g_free (attr.pValue);
 		return NULL;
 	}
diff --git a/pkcs11/gck/gck-object.h b/pkcs11/gck/gck-object.h
index 10508e4..814500b 100644
--- a/pkcs11/gck/gck-object.h
+++ b/pkcs11/gck/gck-object.h
@@ -52,12 +52,14 @@ struct _GckObjectClass {
 	
 	/* virtual methods  --------------------------------------------------------- */
     
-	CK_RV (*get_attribute) (GckObject *object, CK_ATTRIBUTE *attr);
+	CK_RV (*get_attribute) (GckObject *object, GckSession *session,
+	                        CK_ATTRIBUTE *attr);
 	
-	void (*set_attribute) (GckObject *object, GckTransaction *transaction, CK_ATTRIBUTE *attr);
+	void (*set_attribute) (GckObject *object, GckSession *session,
+	                       GckTransaction *transaction, CK_ATTRIBUTE *attr);
 	
-	void (*create_attributes) (GckObject *object, GckTransaction *transaction, GckSession *session,
-	                           CK_ATTRIBUTE *attrs, CK_ULONG n_attrs);
+	void (*create_attributes) (GckObject *object, GckSession *session,
+	                           GckTransaction *transaction, CK_ATTRIBUTE *attrs, CK_ULONG n_attrs);
 
 	CK_RV (*unlock) (GckObject *self, GckAuthenticator *auth);
 };
@@ -84,22 +86,26 @@ void                   gck_object_destroy                (GckObject *self,
                                                           GckTransaction *transaction);
 
 gboolean               gck_object_match                  (GckObject *self,
+                                                          GckSession *session,
                                                           CK_ATTRIBUTE_PTR attr);
 
 gboolean               gck_object_match_all              (GckObject *self,
+                                                          GckSession *session,
                                                           CK_ATTRIBUTE_PTR attrs,
                                                           CK_ULONG n_attrs);
 
 CK_RV                  gck_object_get_attribute          (GckObject *self,
+                                                          GckSession *session,
                                                           CK_ATTRIBUTE_PTR attr);
 
 void                   gck_object_set_attribute          (GckObject *self,
+                                                          GckSession *session,
                                                           GckTransaction *transaction,
                                                           CK_ATTRIBUTE_PTR attr);
 
 void                   gck_object_create_attributes      (GckObject *self,
-                                                          GckTransaction *transaction,
                                                           GckSession *session,
+                                                          GckTransaction *transaction,
                                                           CK_ATTRIBUTE_PTR attrs,
                                                           CK_ULONG n_attrs);
 
@@ -107,14 +113,17 @@ void                   gck_object_notify_attribute       (GckObject *self,
                                                           CK_ATTRIBUTE_TYPE attr_type);
 
 gboolean               gck_object_get_attribute_boolean  (GckObject *self,
+                                                          GckSession *session,
                                                           CK_ATTRIBUTE_TYPE type,
                                                           gboolean *value);
 
 gboolean               gck_object_get_attribute_ulong    (GckObject *self,
+                                                          GckSession *session,
                                                           CK_ATTRIBUTE_TYPE type,
                                                           gulong *value);
 
 void*                  gck_object_get_attribute_data     (GckObject *self,
+                                                          GckSession *session,
                                                           CK_ATTRIBUTE_TYPE type,
                                                           gsize *n_data);
 
diff --git a/pkcs11/gck/gck-private-key.c b/pkcs11/gck/gck-private-key.c
index ec19bcf..1d851d7 100644
--- a/pkcs11/gck/gck-private-key.c
+++ b/pkcs11/gck/gck-private-key.c
@@ -183,14 +183,22 @@ acquire_from_authenticator (GckAuthenticator *auth, GckObject *object, gpointer
 	return FALSE;
 }
 
+static gboolean
+have_from_authenticator (GckAuthenticator *auth, GckObject *object, gpointer unused)
+{
+	/* The sexp we stored on the authenticator */
+	return g_object_get_data (G_OBJECT (auth), "private-key-sexp") ? TRUE : FALSE;
+}
+
 /* -----------------------------------------------------------------------------
  * PRIVATE_KEY 
  */
 
 static CK_RV 
-gck_private_key_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
+gck_private_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
 {
 	GckPrivateKey *self = GCK_PRIVATE_KEY (base);
+	gboolean have;
 	
 	switch (attr->type) {
 	case CKA_CLASS:
@@ -230,7 +238,10 @@ gck_private_key_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
 		return CKR_ATTRIBUTE_TYPE_INVALID;
 		
 	case CKA_ALWAYS_AUTHENTICATE:
-		return gck_attribute_set_bool (attr, self->pv->sexp == NULL);
+		have = self->pv->sexp ? TRUE : FALSE;
+		if (!have && session)
+			have = gck_session_for_each_authenticator (session, base, have_from_authenticator, NULL);
+		return gck_attribute_set_bool (attr, !have);
 		
 	case CKA_MODULUS:
 		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "n", attr);
@@ -261,7 +272,7 @@ gck_private_key_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
 		return CKR_ATTRIBUTE_SENSITIVE;
 	};	
 	
-	return GCK_OBJECT_CLASS (gck_private_key_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_private_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static GckSexp*
@@ -384,18 +395,16 @@ gck_private_key_set_unlocked_private (GckPrivateKey *self, GckSexp *sexp)
 
 void
 gck_private_key_set_locked_private (GckPrivateKey *self, GckAuthenticator *auth, 
-                                    GckSexp *sexp, gint num_uses)
+                                    GckSexp *sexp)
 {
 	g_return_if_fail (GCK_IS_PRIVATE_KEY (self));
 	g_return_if_fail (GCK_IS_AUTHENTICATOR (auth));
-	g_return_if_fail (!sexp || num_uses);
 
 	if (sexp == NULL)
 		g_object_set_data (G_OBJECT (auth), "private-key-sexp", NULL);
 	else
 		g_object_set_data_full (G_OBJECT (auth), "private-key-sexp",
 		                        gck_sexp_ref (sexp), gck_sexp_unref);
-	gck_authenticator_set_uses_remaining (auth, num_uses);
 }
 
 GckSexp*
diff --git a/pkcs11/gck/gck-private-key.h b/pkcs11/gck/gck-private-key.h
index 4a7a450..6f78eeb 100644
--- a/pkcs11/gck/gck-private-key.h
+++ b/pkcs11/gck/gck-private-key.h
@@ -55,8 +55,7 @@ void                       gck_private_key_set_unlocked_private   (GckPrivateKey
 
 void                       gck_private_key_set_locked_private     (GckPrivateKey *self,
                                                                    GckAuthenticator *auth,
-                                                                   GckSexp *sexp, 
-                                                                   gint num_uses);               
+                                                                   GckSexp *sexp);               
 
 GckFactoryInfo*            gck_private_key_get_factory            (void);
 
diff --git a/pkcs11/gck/gck-public-key.c b/pkcs11/gck/gck-public-key.c
index ce2fe48..1848956 100644
--- a/pkcs11/gck/gck-public-key.c
+++ b/pkcs11/gck/gck-public-key.c
@@ -161,7 +161,7 @@ factory_create_public_key (GckSession *session, GckTransaction *transaction,
  */
 
 static CK_RV 
-gck_public_key_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
+gck_public_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
 {
 	GckPublicKey *self = GCK_PUBLIC_KEY (base);
 	
@@ -212,7 +212,7 @@ gck_public_key_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
 		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "y", attr);
 	};
 	
-	return GCK_OBJECT_CLASS (gck_public_key_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_public_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static GckSexp*
diff --git a/pkcs11/gck/gck-session.c b/pkcs11/gck/gck-session.c
index 2add459..0d94fa8 100644
--- a/pkcs11/gck/gck-session.c
+++ b/pkcs11/gck/gck-session.c
@@ -144,7 +144,7 @@ prepare_crypto (GckSession *self, CK_MECHANISM_PTR mech,
 		return CKR_KEY_HANDLE_INVALID;
 
 	/* Lookup the mechanisms this object can do */
-	mechanisms = gck_object_get_attribute_data (object, CKA_ALLOWED_MECHANISMS, &n_data);
+	mechanisms = gck_object_get_attribute_data (object, self, CKA_ALLOWED_MECHANISMS, &n_data);
 	g_return_val_if_fail (mechanisms, CKR_GENERAL_ERROR);
 	g_return_val_if_fail (n_data % sizeof (CK_MECHANISM_TYPE) == 0, CKR_GENERAL_ERROR);
 	n_mechanisms = n_data / sizeof (CK_MECHANISM_TYPE);
@@ -160,7 +160,7 @@ prepare_crypto (GckSession *self, CK_MECHANISM_PTR mech,
 		return CKR_KEY_TYPE_INCONSISTENT;
 
 	/* Check that the object can do this method */
-	if (!gck_object_get_attribute_boolean (object, method, &have) || !have)
+	if (!gck_object_get_attribute_boolean (object, self, method, &have) || !have)
 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
 	
 	/* Track the cyrpto object */
@@ -266,7 +266,7 @@ lookup_object_from_handle (GckSession *self, CK_OBJECT_HANDLE handle,
 	 * non-logged in session 
 	 */
 	if (self->pv->logged_in != CKU_USER) {
-		if (!gck_object_get_attribute_boolean (object, CKA_PRIVATE, &is_private))
+		if (!gck_object_get_attribute_boolean (object, self, CKA_PRIVATE, &is_private))
 			is_private = FALSE;
 		if (is_private)
 			return CKR_USER_NOT_LOGGED_IN;
@@ -284,7 +284,7 @@ lookup_object_from_handle (GckSession *self, CK_OBJECT_HANDLE handle,
 			if (self->pv->read_only)
 				return CKR_SESSION_READ_ONLY;
 		}
-		if (!gck_object_get_attribute_boolean (object, CKA_MODIFIABLE, &is_modifiable))
+		if (!gck_object_get_attribute_boolean (object, self, CKA_MODIFIABLE, &is_modifiable))
 			is_modifiable = FALSE;
 		if (!is_modifiable) /* What's a better return code in this case? */
 			return CKR_ATTRIBUTE_READ_ONLY;
@@ -656,9 +656,9 @@ gck_session_login_context_specific (GckSession *self, CK_UTF8CHAR_PTR pin, CK_UL
 	object = self->pv->current_object;
 	g_return_val_if_fail (GCK_IS_OBJECT (object), CKR_GENERAL_ERROR);
 	
-	if (!gck_object_get_attribute_boolean (object, CKA_ALWAYS_AUTHENTICATE, &always_auth))
+	if (!gck_object_get_attribute_boolean (object, self, CKA_ALWAYS_AUTHENTICATE, &always_auth))
 		always_auth = FALSE; 
-	if (!gck_object_get_attribute_boolean (object, CKA_PRIVATE, &is_private))
+	if (!gck_object_get_attribute_boolean (object, self, CKA_PRIVATE, &is_private))
 		is_private = FALSE;
 	
 	/* A strange code, but that's what the spec says */
@@ -870,7 +870,7 @@ gck_session_C_CreateObject (GckSession* self, CK_ATTRIBUTE_PTR template,
 
 		/* Can only create public objects unless logged in */
 		if (gck_session_get_logged_in (self) != CKU_USER &&
-		    gck_object_get_attribute_boolean (object, CKA_PRIVATE, &is_private) && 
+		    gck_object_get_attribute_boolean (object, self, CKA_PRIVATE, &is_private) && 
 		    is_private == TRUE) {
 			gck_transaction_fail (transaction, CKR_USER_NOT_LOGGED_IN);
 		}
@@ -878,7 +878,7 @@ gck_session_C_CreateObject (GckSession* self, CK_ATTRIBUTE_PTR template,
 	
 	/* Give the object a chance to create additional attributes */
 	if (!gck_transaction_get_failed (transaction)) {
-		gck_object_create_attributes (object, transaction, self, attrs, n_attrs);
+		gck_object_create_attributes (object, self, transaction, attrs, n_attrs);
 	}
 
 	/* Find somewhere to store the object */
@@ -893,7 +893,7 @@ gck_session_C_CreateObject (GckSession* self, CK_ATTRIBUTE_PTR template,
 	gck_attributes_consume (attrs, n_attrs, CKA_TOKEN, G_MAXULONG);
 	for (i = 0; i < n_attrs && !gck_transaction_get_failed (transaction); ++i) {
 		if (!gck_attribute_consumed (&attrs[i]))
-			gck_object_set_attribute (object, transaction, &attrs[i]);
+			gck_object_set_attribute (object, self, transaction, &attrs[i]);
 	}
 
 	gck_transaction_complete (transaction);
@@ -948,7 +948,7 @@ gck_session_C_GetAttributeValue (GckSession* self, CK_OBJECT_HANDLE handle,
 	rv = CKR_OK;
 	
 	for (i = 0; i < count; ++i) {
-		code = gck_object_get_attribute (object, &template[i]);
+		code = gck_object_get_attribute (object, self, &template[i]);
 
 		/* Not a true error, keep going */
 		if (code == CKR_ATTRIBUTE_SENSITIVE ||
diff --git a/pkcs11/gck/tests/mock-locked-object.c b/pkcs11/gck/tests/mock-locked-object.c
index 882d100..96a37b1 100644
--- a/pkcs11/gck/tests/mock-locked-object.c
+++ b/pkcs11/gck/tests/mock-locked-object.c
@@ -37,7 +37,7 @@ G_DEFINE_TYPE (MockLockedObject, mock_locked_object, GCK_TYPE_OBJECT);
  */
 
 static CK_RV 
-mock_locked_object_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
+mock_locked_object_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
 {
 	switch (attr->type) {
 	case CKA_CLASS:
@@ -46,7 +46,7 @@ mock_locked_object_real_get_attribute (GckObject *base, CK_ATTRIBUTE* attr)
 		return gck_attribute_set_bool (attr, TRUE);
 	};
 
-	return GCK_OBJECT_CLASS (mock_locked_object_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (mock_locked_object_parent_class)->get_attribute (base, session, attr);
 }
 
 static CK_RV
diff --git a/pkcs11/roots-store/gck-roots-certificate.c b/pkcs11/roots-store/gck-roots-certificate.c
index b3f11da..c2ad9cf 100644
--- a/pkcs11/roots-store/gck-roots-certificate.c
+++ b/pkcs11/roots-store/gck-roots-certificate.c
@@ -56,7 +56,7 @@ G_DEFINE_TYPE (GckRootsCertificate, gck_roots_certificate, GCK_TYPE_CERTIFICATE)
  */
 
 static CK_RV
-gck_roots_certificate_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
+gck_roots_certificate_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE_PTR attr)
 {
 	GckRootsCertificate *self = GCK_ROOTS_CERTIFICATE (base);
 	CK_ULONG category;
@@ -74,7 +74,7 @@ gck_roots_certificate_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
 		return gck_attribute_set_ulong (attr, category);
 	}
 	
-	return GCK_OBJECT_CLASS (gck_roots_certificate_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_roots_certificate_parent_class)->get_attribute (base, session, attr);
 }
 
 static void
diff --git a/pkcs11/ssh-store/gck-ssh-private-key.c b/pkcs11/ssh-store/gck-ssh-private-key.c
index b0b3d1b..b4ee233 100644
--- a/pkcs11/ssh-store/gck-ssh-private-key.c
+++ b/pkcs11/ssh-store/gck-ssh-private-key.c
@@ -135,7 +135,7 @@ realize_and_take_data (GckSshPrivateKey *self, gcry_sexp_t sexp, gchar *comment,
  */
 
 static CK_RV
-gck_ssh_private_key_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
+gck_ssh_private_key_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE_PTR attr)
 {
 	GckSshPrivateKey *self = GCK_SSH_PRIVATE_KEY (base);
 	gchar *digest;
@@ -155,7 +155,7 @@ gck_ssh_private_key_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
 		return rv;
 	}
 	
-	return GCK_OBJECT_CLASS (gck_ssh_private_key_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_ssh_private_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static CK_RV
@@ -174,7 +174,7 @@ gck_ssh_private_key_unlock (GckObject *base, GckAuthenticator *auth)
 	rv = unlock_private_key (self, password, n_password, &wrapper);
 
 	if (rv == CKR_OK) {
-		gck_private_key_set_locked_private (GCK_PRIVATE_KEY (self), auth, wrapper, 1);
+		gck_private_key_set_locked_private (GCK_PRIVATE_KEY (self), auth, wrapper);
 		gck_sexp_unref (wrapper);
 	}
 
diff --git a/pkcs11/ssh-store/gck-ssh-public-key.c b/pkcs11/ssh-store/gck-ssh-public-key.c
index 561d38c..f6e6970 100644
--- a/pkcs11/ssh-store/gck-ssh-public-key.c
+++ b/pkcs11/ssh-store/gck-ssh-public-key.c
@@ -46,7 +46,7 @@ G_DEFINE_TYPE (GckSshPublicKey, gck_ssh_public_key, GCK_TYPE_PUBLIC_KEY);
  */
 
 static CK_RV
-gck_ssh_public_key_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
+gck_ssh_public_key_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE_PTR attr)
 {
 	GckSshPublicKey *self = GCK_SSH_PUBLIC_KEY (base);
 	
@@ -55,7 +55,7 @@ gck_ssh_public_key_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
 		return gck_attribute_set_string (attr, self->label ? self->label : "");
 	}
 	
-	return GCK_OBJECT_CLASS (gck_ssh_public_key_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_ssh_public_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static void
diff --git a/pkcs11/user-store/gck-user-private-key.c b/pkcs11/user-store/gck-user-private-key.c
index a699e65..fff5234 100644
--- a/pkcs11/user-store/gck-user-private-key.c
+++ b/pkcs11/user-store/gck-user-private-key.c
@@ -89,14 +89,14 @@ factory_create_private_key (GckSession *session, GckTransaction *transaction,
  */
 
 static CK_RV
-gck_user_private_key_real_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
+gck_user_private_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE_PTR attr)
 {
 	switch (attr->type) {
 	case CKA_ALWAYS_AUTHENTICATE:
 		return gck_attribute_set_bool (attr, FALSE);
 	}
 	
-	return GCK_OBJECT_CLASS (gck_user_private_key_parent_class)->get_attribute (base, attr);
+	return GCK_OBJECT_CLASS (gck_user_private_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static GckSexp* 
diff --git a/pkcs11/user-store/gck-user-storage.c b/pkcs11/user-store/gck-user-storage.c
index 687c1b3..89c85ec 100644
--- a/pkcs11/user-store/gck-user-storage.c
+++ b/pkcs11/user-store/gck-user-storage.c
@@ -165,14 +165,14 @@ identifier_for_object (GckObject *object)
 	g_return_val_if_fail (ext, NULL);
 	
 	/* First we try to use the CN of a subject */
-	data = gck_object_get_attribute_data (object, CKA_SUBJECT, &n_data);
+	data = gck_object_get_attribute_data (object, NULL, CKA_SUBJECT, &n_data);
 	if (data && n_data) 
 		name = name_for_subject (data, n_data);
 	g_free (data);
 	
 	/* Next we try hex encoding the ID */
 	if (name == NULL) {
-		data = gck_object_get_attribute_data (object, CKA_ID, &n_data);
+		data = gck_object_get_attribute_data (object, NULL, CKA_ID, &n_data);
 		if (data && n_data)
 			name = egg_hex_encode (data, n_data);
 		g_free (data);
@@ -1063,7 +1063,7 @@ gck_user_storage_create (GckUserStorage *self, GckTransaction *transaction, GckO
 	}
 	
 	/* Figure out whether this is a private object */ 
-	if (!gck_object_get_attribute_boolean (object, CKA_PRIVATE, &is_private))
+	if (!gck_object_get_attribute_boolean (object, NULL, CKA_PRIVATE, &is_private))
 		is_private = FALSE;
 	
 	/* Can't serialize private if we're not unlocked */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]