gnome-keyring r1005 - in trunk: . pk pk/tests pk/tests/test-data pkcs11
- From: nnielsen svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-keyring r1005 - in trunk: . pk pk/tests pk/tests/test-data pkcs11
- Date: Mon, 14 Jan 2008 01:22:18 +0000 (GMT)
Author: nnielsen
Date: Mon Jan 14 01:22:17 2008
New Revision: 1005
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1005&view=rev
Log:
* pk/gkr-pk-cert.c:
* pk/gkr-pk-cert.h:
* pk/gkr-pk-netscape-trust.c:
* pk/gkr-pk-object-manager.c:
* pk/gkr-pk-object-storage.c:
* pk/gkr-pk-object-storage.h:
* pk/gkr-pk-object.c:
* pk/gkr-pk-object.h:
* pk/gkr-pk-privkey.c:
* pk/gkr-pk-privkey.h:
* pk/gkr-pk-pubkey.c:
* pk/gkr-pk-pubkey.h:
* pk/gkr-pk-util.c:
* pk/gkr-pk-util.h:
* pk/tests/Makefile.am:
* pk/tests/check-attribute.c:
* pk/tests/unit-test-pk-cert.c:
* pk/tests/unit-test-pk-key.c: (added)
* pk/tests/unit-test-pk-netscape-trust.c:
* pk/tests/test-data/privkey-1.key: (renamed from .crt)
* pk/tests/test-data/privkey-3.key: (added)
* pkcs11/gkr-pkcs11-daemon-session.c:
* pkcs11/gkr-pkcs11-dsa.c: Proper support for creating and destroying
objects through PKCS#11 (no token save functionality yet). Also proper
infrastructure for setting of attributes.
Added:
trunk/pk/tests/test-data/privkey-1.key
- copied unchanged from r1003, /trunk/pk/tests/test-data/privkey-1.crt
trunk/pk/tests/test-data/privkey-3.key (contents, props changed)
trunk/pk/tests/unit-test-pk-key.c
Removed:
trunk/pk/tests/test-data/privkey-1.crt
Modified:
trunk/ChangeLog
trunk/pk/gkr-pk-cert.c
trunk/pk/gkr-pk-cert.h
trunk/pk/gkr-pk-netscape-trust.c
trunk/pk/gkr-pk-object-manager.c
trunk/pk/gkr-pk-object-storage.c
trunk/pk/gkr-pk-object-storage.h
trunk/pk/gkr-pk-object.c
trunk/pk/gkr-pk-object.h
trunk/pk/gkr-pk-privkey.c
trunk/pk/gkr-pk-privkey.h
trunk/pk/gkr-pk-pubkey.c
trunk/pk/gkr-pk-pubkey.h
trunk/pk/gkr-pk-util.c
trunk/pk/gkr-pk-util.h
trunk/pk/tests/Makefile.am
trunk/pk/tests/check-attribute.c
trunk/pk/tests/unit-test-pk-cert.c
trunk/pk/tests/unit-test-pk-netscape-trust.c
trunk/pkcs11/gkr-pkcs11-calls.h
trunk/pkcs11/gkr-pkcs11-daemon-session.c
trunk/pkcs11/gkr-pkcs11-dsa.c
trunk/pkcs11/gkr-pkcs11-module.c
Modified: trunk/pk/gkr-pk-cert.c
==============================================================================
--- trunk/pk/gkr-pk-cert.c (original)
+++ trunk/pk/gkr-pk-cert.c Mon Jan 14 01:22:17 2008
@@ -295,6 +295,14 @@
}
static CK_RV
+read_certificate_purpose (GkrPkCert *cert, GQuark oid, CK_ATTRIBUTE_PTR attr)
+{
+ gboolean value = check_certificate_purpose (cert, oid);
+ gkr_pk_attribute_set_boolean (attr, value);
+ return CKR_OK;
+}
+
+static CK_RV
read_certificate_purposes (GkrPkCert *cert, CK_ATTRIBUTE_PTR attr)
{
GQuark *quarks, *q;
@@ -392,162 +400,104 @@
break;
}
}
-
-static CK_RV
-gkr_pk_cert_get_bool_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
+
+static CK_RV
+gkr_pk_cert_get_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
{
GkrPkCert *cert = GKR_PK_CERT (obj);
- gboolean val;
+ const guchar *cdata = NULL;
+ gkrconstunique keyid;
+ CK_ULONG value;
+ gchar *index;
+ guchar *data;
+ gsize n_data;
+ time_t time;
+ CK_RV ret;
+
+ g_assert (!attr->pValue);
switch (attr->type)
{
- case CKA_TOKEN:
- val = TRUE;
- break;
-
- case CKA_PRIVATE:
- case CKA_MODIFIABLE:
- val = FALSE;
- break;
-
case CKA_GNOME_PURPOSE_RESTRICTED:
- val = has_certificate_purposes (cert);
- break;
+ gkr_pk_attribute_set_boolean (attr, has_certificate_purposes (cert));
+ return CKR_OK;
case CKA_GNOME_PURPOSE_SSH_AUTH:
- val = check_certificate_purpose (cert, OID_USAGE_SSH_AUTH);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_SSH_AUTH, attr);
case CKA_GNOME_PURPOSE_SERVER_AUTH:
- val = check_certificate_purpose (cert, OID_USAGE_SERVER_AUTH);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_SERVER_AUTH, attr);
case CKA_GNOME_PURPOSE_CLIENT_AUTH:
- val = check_certificate_purpose (cert, OID_USAGE_CLIENT_AUTH);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_CLIENT_AUTH, attr);
case CKA_GNOME_PURPOSE_CODE_SIGNING:
- val = check_certificate_purpose (cert, OID_USAGE_CODE_SIGNING);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_CODE_SIGNING, attr);
case CKA_GNOME_PURPOSE_EMAIL_PROTECTION:
- val = check_certificate_purpose (cert, OID_USAGE_EMAIL);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_EMAIL, attr);
case CKA_GNOME_PURPOSE_IPSEC_END_SYSTEM:
- val = check_certificate_purpose (cert, OID_USAGE_IPSEC_ENDPOINT);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_IPSEC_ENDPOINT, attr);
case CKA_GNOME_PURPOSE_IPSEC_TUNNEL:
- val = check_certificate_purpose (cert, OID_USAGE_IPSEC_TUNNEL);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_IPSEC_TUNNEL, attr);
case CKA_GNOME_PURPOSE_IPSEC_USER:
- val = check_certificate_purpose (cert, OID_USAGE_IPSEC_USER);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_IPSEC_USER, attr);
case CKA_GNOME_PURPOSE_TIME_STAMPING:
- val = check_certificate_purpose (cert, OID_USAGE_TIME_STAMPING);
- break;
+ return read_certificate_purpose (cert, OID_USAGE_TIME_STAMPING, attr);
/* TODO: Until we can figure out a trust system */
case CKA_TRUSTED:
- val = FALSE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_FALSE);
+ return CKR_OK;
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- gkr_pk_attribute_set_boolean (attr, val);
- return CKR_OK;
-}
-
-static CK_RV
-gkr_pk_cert_get_ulong_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkCert *cert = GKR_PK_CERT (obj);
- gulong val;
- gchar *value;
- guchar *extension;
- gsize n_extension;
- gboolean is_ca;
- CK_RV ret;
- int res;
-
- switch (attr->type)
- {
case CKA_CLASS:
- val = CKO_CERTIFICATE;
- break;
+ gkr_pk_attribute_set_ulong (attr, CKO_CERTIFICATE);
+ return CKR_OK;
case CKA_CERTIFICATE_TYPE:
- val = CKC_X_509;
- break;
+ gkr_pk_attribute_set_ulong (attr, CKC_X_509);
+ return CKR_OK;
case CKA_CERTIFICATE_CATEGORY:
if ((ret = load_certificate (cert)) != CKR_OK)
return ret;
- val = 0; /* unknown */
- extension = gkr_pk_cert_get_extension (cert, OID_BASIC_CONSTRAINTS, &n_extension, NULL);
- if (extension) {
- res = gkr_pkix_der_read_basic_constraints (extension, n_extension, &is_ca, NULL);
- g_free (extension);
+ value = 0; /* unknown */
+ data = gkr_pk_cert_get_extension (cert, OID_BASIC_CONSTRAINTS, &n_data, NULL);
+ if (data) {
+ GkrParseResult res;
+ gboolean is_ca;
+
+ res = gkr_pkix_der_read_basic_constraints (data, n_data, &is_ca, NULL);
+ g_free (data);
if (res != GKR_PARSE_SUCCESS)
return CKR_GENERAL_ERROR;
if (is_ca)
- val = 2; /* authority */
+ value = 2; /* authority */
}
- break;
+ gkr_pk_attribute_set_ulong (attr, value);
+ return CKR_OK;
case CKA_GNOME_USER_TRUST:
- val = CKT_GNOME_UNKNOWN;
+ value = CKT_GNOME_UNKNOWN;
/* Explicity set? */
- value = gkr_pk_index_get_string (obj, "user-trust");
- if (value) {
- if (g_str_equal (value, "trusted"))
- val = CKT_GNOME_TRUSTED;
- else if (g_str_equal (value, "untrusted"))
- val = CKT_GNOME_UNTRUSTED;
- g_free (value);
+ index = gkr_pk_index_get_string (obj, "user-trust");
+ if (index) {
+ if (g_str_equal (index, "trusted"))
+ value = CKT_GNOME_TRUSTED;
+ else if (g_str_equal (index, "untrusted"))
+ value = CKT_GNOME_UNTRUSTED;
+ g_free (index);
/* With a private key it's trusted by default */
} else if (has_private_key (cert)) {
- val = CKT_GNOME_TRUSTED;
-
+ value = CKT_GNOME_TRUSTED;
}
- break;
-
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- gkr_pk_attribute_set_ulong (attr, val);
- return CKR_OK;
-}
-
-static CK_RV
-gkr_pk_cert_get_data_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkCert *cert = GKR_PK_CERT (obj);
- const guchar *cdata = NULL;
- gkrconstunique keyid;
- gchar *label;
- guchar *data;
- gsize n_data;
- CK_RV ret;
-
- g_assert (!attr->pValue);
-
- switch (attr->type)
- {
- case CKA_LABEL:
- g_object_get (obj, "label", &label, NULL);
- if (!label)
- label = gkr_location_to_display (obj->location);
- gkr_pk_attribute_set_string (attr, label);
- g_free (label);
+ gkr_pk_attribute_set_ulong (attr, value);
return CKR_OK;
case CKA_ID:
@@ -606,6 +556,19 @@
gkr_pk_attribute_set_data (attr, data, 3);
g_free (data);
return CKR_OK;
+
+ case CKA_START_DATE:
+ case CKA_END_DATE:
+ if ((ret = load_certificate (cert)) != CKR_OK)
+ return ret;
+ if (!gkr_pkix_asn1_read_time (cert->data->asn1,
+ attr->type == CKA_START_DATE ?
+ "tbsCertificate.validity.notBefore" :
+ "tbsCertificate.validity.notAfter",
+ &time))
+ g_return_val_if_reached (CKR_GENERAL_ERROR);
+ gkr_pk_attribute_set_date (attr, time);
+ return CKR_OK;
/* These are only used for strange online certificates which we don't support */
case CKA_URL:
@@ -620,38 +583,7 @@
break;
};
- return CKR_ATTRIBUTE_TYPE_INVALID;
-}
-
-static CK_RV
-gkr_pk_cert_get_date_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkCert *cert = GKR_PK_CERT (obj);
- time_t time;
- CK_RV ret;
-
- switch (attr->type)
- {
- case CKA_START_DATE:
- if ((ret = load_certificate (cert)) != CKR_OK)
- return ret;
- if (!gkr_pkix_asn1_read_time (cert->data->asn1, "tbsCertificate.validity.notBefore", &time))
- g_return_val_if_reached (CKR_GENERAL_ERROR);
- break;
-
- case CKA_END_DATE:
- if ((ret = load_certificate (cert)) != CKR_OK)
- return ret;
- if (!gkr_pkix_asn1_read_time (cert->data->asn1, "tbsCertificate.validity.notAfter", &time))
- g_return_val_if_reached (CKR_GENERAL_ERROR);
- break;
-
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- gkr_pk_attribute_set_date (attr, time);
- return CKR_OK;
+ return GKR_PK_OBJECT_CLASS (gkr_pk_cert_parent_class)->get_attribute (obj, attr);
}
static void
@@ -683,10 +615,7 @@
gkr_pk_cert_parent_class = g_type_class_peek_parent (klass);
parent_class = GKR_PK_OBJECT_CLASS (klass);
- parent_class->get_bool_attribute = gkr_pk_cert_get_bool_attribute;
- parent_class->get_ulong_attribute = gkr_pk_cert_get_ulong_attribute;
- parent_class->get_data_attribute = gkr_pk_cert_get_data_attribute;
- parent_class->get_date_attribute = gkr_pk_cert_get_date_attribute;
+ parent_class->get_attribute = gkr_pk_cert_get_attribute;
gobject_class->get_property = gkr_pk_cert_get_property;
gobject_class->set_property = gkr_pk_cert_set_property;
@@ -722,6 +651,43 @@
return cert;
}
+CK_RV
+gkr_pk_cert_create (GkrPkObjectManager* manager, GArray* array,
+ GkrPkObject **object)
+{
+ ASN1_TYPE asn;
+ CK_ATTRIBUTE_PTR attr;
+ CK_KEY_TYPE type;
+
+ g_return_val_if_fail (GKR_IS_PK_OBJECT_MANAGER (manager), CKR_GENERAL_ERROR);
+ g_return_val_if_fail (array, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (object, CKR_GENERAL_ERROR);
+
+ *object = NULL;
+
+ if (!gkr_pk_attributes_ulong (array, CKA_CERTIFICATE_TYPE, &type))
+ return CKR_TEMPLATE_INCOMPLETE;
+
+ if (type != CKC_X_509)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ attr = gkr_pk_attributes_find (array, CKA_VALUE);
+ if (!attr)
+ return CKR_TEMPLATE_INCOMPLETE;
+
+ g_return_val_if_fail (attr->pValue, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (attr->ulValueLen, CKR_GENERAL_ERROR);
+
+ if (gkr_pkix_der_read_certificate (attr->pValue, attr->ulValueLen, &asn) != GKR_PARSE_SUCCESS)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ /* All the attributes that we used up */
+ gkr_pk_attributes_consume (array, CKA_CERTIFICATE_TYPE, CKA_VALUE, -1);
+
+ *object = GKR_PK_OBJECT (gkr_pk_cert_new (manager, 0, asn));
+ return CKR_OK;
+}
+
gboolean
gkr_pk_cert_has_extension (GkrPkCert *cert, GQuark oid, gboolean *critical)
{
Modified: trunk/pk/gkr-pk-cert.h
==============================================================================
--- trunk/pk/gkr-pk-cert.h (original)
+++ trunk/pk/gkr-pk-cert.h Mon Jan 14 01:22:17 2008
@@ -55,6 +55,9 @@
GkrPkCert* gkr_pk_cert_new (GkrPkObjectManager *manager,
GQuark location, ASN1_TYPE asn1);
+CK_RV gkr_pk_cert_create (GkrPkObjectManager* manager,
+ GArray* array, GkrPkObject **object);
+
gboolean gkr_pk_cert_has_extension (GkrPkCert *cert, GQuark oid,
gboolean *critical);
Modified: trunk/pk/gkr-pk-netscape-trust.c
==============================================================================
--- trunk/pk/gkr-pk-netscape-trust.c (original)
+++ trunk/pk/gkr-pk-netscape-trust.c Mon Jan 14 01:22:17 2008
@@ -82,7 +82,7 @@
}
static CK_RV
-has_key_usage (GkrPkNetscapeTrust *trust, guint check, gulong *val)
+has_key_usage (GkrPkNetscapeTrust *trust, guint check, CK_ULONG *val)
{
GkrParseResult res;
guchar *extension;
@@ -115,7 +115,17 @@
}
static CK_RV
-has_enhanced_usage (GkrPkNetscapeTrust *trust, CK_ATTRIBUTE_TYPE type, gulong *val)
+read_key_usage (GkrPkNetscapeTrust *trust, guint check, CK_ATTRIBUTE_PTR attr)
+{
+ CK_ULONG value;
+ CK_RV ret = has_key_usage (trust, check, &value);
+ if (ret == CKR_OK)
+ gkr_pk_attribute_set_ulong (attr, value);
+ return ret;
+}
+
+static CK_RV
+has_enhanced_usage (GkrPkNetscapeTrust *trust, CK_ATTRIBUTE_TYPE type, CK_ULONG *val)
{
CK_RV ret;
CK_BBOOL bval;
@@ -167,6 +177,17 @@
}
static CK_RV
+read_enhanced_usage (GkrPkNetscapeTrust *trust, CK_ATTRIBUTE_TYPE type,
+ CK_ATTRIBUTE_PTR attr)
+{
+ CK_ULONG value;
+ CK_RV ret = has_enhanced_usage (trust, type, &value);
+ if (ret == CKR_OK)
+ gkr_pk_attribute_set_ulong (attr, value);
+ return ret;
+}
+
+static CK_RV
hash_certificate (GkrPkNetscapeTrust *trust, int algo, CK_ATTRIBUTE_PTR result)
{
const guchar *raw;
@@ -229,113 +250,72 @@
break;
}
}
-
-static CK_RV
-gkr_pk_netscape_trust_get_bool_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
+
+static CK_RV
+gkr_pk_netscape_trust_get_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
{
- gboolean val;
+ GkrPkNetscapeTrust *trust = GKR_PK_NETSCAPE_TRUST (obj);
+ g_assert (!attr->pValue);
switch (attr->type)
{
- case CKA_TOKEN:
- case CKA_MODIFIABLE:
- val = TRUE;
- break;
-
case CKA_PRIVATE:
case CKA_TRUST_STEP_UP_APPROVED:
- val = FALSE;
- break;
-
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- gkr_pk_attribute_set_boolean (attr, val);
- return CKR_OK;
-}
+ gkr_pk_attribute_set_boolean (attr, CK_FALSE);
+ return CKR_OK;
-static CK_RV
-gkr_pk_netscape_trust_get_ulong_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkNetscapeTrust *trust = GKR_PK_NETSCAPE_TRUST (obj);
- CK_RV ret = CKR_OK;
- gulong val;
-
- switch (attr->type)
- {
case CKA_CLASS:
- val = CKO_NETSCAPE_TRUST;
- break;
+ gkr_pk_attribute_set_ulong (attr, CKO_NETSCAPE_TRUST);
+ return CKR_OK;
/* Key restrictions */
case CKA_TRUST_DIGITAL_SIGNATURE:
- ret = has_key_usage (trust, PKIX_KEY_USAGE_DIGITAL_SIGNATURE, &val);
- break;
+ return read_key_usage (trust, PKIX_KEY_USAGE_DIGITAL_SIGNATURE, attr);
+
case CKA_TRUST_NON_REPUDIATION:
- ret = has_key_usage (trust, PKIX_KEY_USAGE_NON_REPUDIATION, &val);
- break;
+ return read_key_usage (trust, PKIX_KEY_USAGE_NON_REPUDIATION, attr);
+
case CKA_TRUST_KEY_ENCIPHERMENT:
- ret = has_key_usage (trust, PKIX_KEY_USAGE_KEY_ENCIPHERMENT, &val);
- break;
+ return read_key_usage (trust, PKIX_KEY_USAGE_KEY_ENCIPHERMENT, attr);
+
case CKA_TRUST_DATA_ENCIPHERMENT:
- ret = has_key_usage (trust, PKIX_KEY_USAGE_DATA_ENCIPHERMENT, &val);
- break;
+ return read_key_usage (trust, PKIX_KEY_USAGE_DATA_ENCIPHERMENT, attr);
+
case CKA_TRUST_KEY_AGREEMENT:
- ret = has_key_usage (trust, PKIX_KEY_USAGE_KEY_AGREEMENT, &val);
- break;
+ return read_key_usage (trust, PKIX_KEY_USAGE_KEY_AGREEMENT, attr);
+
case CKA_TRUST_KEY_CERT_SIGN:
- ret = has_key_usage (trust, PKIX_KEY_USAGE_KEY_CERT_SIGN, &val);
- break;
+ return read_key_usage (trust, PKIX_KEY_USAGE_KEY_CERT_SIGN, attr);
+
case CKA_TRUST_CRL_SIGN:
- ret = has_key_usage (trust, PKIX_KEY_USAGE_CRL_SIGN, &val);
- break;
+ return read_key_usage (trust, PKIX_KEY_USAGE_CRL_SIGN, attr);
/* Various trust flags */
case CKA_TRUST_SERVER_AUTH:
- ret = has_enhanced_usage (trust, CKA_GNOME_PURPOSE_SERVER_AUTH, &val);
- break;
+ return read_enhanced_usage (trust, CKA_GNOME_PURPOSE_SERVER_AUTH, attr);
+
case CKA_TRUST_CLIENT_AUTH:
- ret = has_enhanced_usage (trust, CKA_GNOME_PURPOSE_CLIENT_AUTH, &val);
- break;
+ return read_enhanced_usage (trust, CKA_GNOME_PURPOSE_CLIENT_AUTH, attr);
+
case CKA_TRUST_CODE_SIGNING:
- ret = has_enhanced_usage (trust, CKA_GNOME_PURPOSE_CODE_SIGNING, &val);
- break;
+ return read_enhanced_usage (trust, CKA_GNOME_PURPOSE_CODE_SIGNING, attr);
+
case CKA_TRUST_EMAIL_PROTECTION:
- ret = has_enhanced_usage (trust, CKA_GNOME_PURPOSE_EMAIL_PROTECTION, &val);
- break;
+ return read_enhanced_usage (trust, CKA_GNOME_PURPOSE_EMAIL_PROTECTION, attr);
+
case CKA_TRUST_IPSEC_END_SYSTEM:
- ret = has_enhanced_usage (trust, CKA_GNOME_PURPOSE_IPSEC_END_SYSTEM, &val);
- break;
+ return read_enhanced_usage (trust, CKA_GNOME_PURPOSE_IPSEC_END_SYSTEM, attr);
+
case CKA_TRUST_IPSEC_TUNNEL:
- ret = has_enhanced_usage (trust, CKA_GNOME_PURPOSE_IPSEC_TUNNEL, &val);
- break;
+ return read_enhanced_usage (trust, CKA_GNOME_PURPOSE_IPSEC_TUNNEL, attr);
+
case CKA_TRUST_IPSEC_USER:
- ret = has_enhanced_usage (trust, CKA_GNOME_PURPOSE_IPSEC_USER, &val);
- break;
- case CKA_TRUST_TIME_STAMPING:
- ret = has_enhanced_usage (trust, CKA_GNOME_PURPOSE_TIME_STAMPING, &val);
- break;
+ return read_enhanced_usage (trust, CKA_GNOME_PURPOSE_IPSEC_USER, attr);
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- if (ret == CKR_OK)
- gkr_pk_attribute_set_ulong (attr, val);
- return ret;
-}
+ case CKA_TRUST_TIME_STAMPING:
+ return read_enhanced_usage (trust, CKA_GNOME_PURPOSE_TIME_STAMPING, attr);
-static CK_RV
-gkr_pk_netscape_trust_get_data_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkNetscapeTrust *trust = GKR_PK_NETSCAPE_TRUST (obj);
-
- g_assert (!attr->pValue);
- switch (attr->type)
- {
case CKA_ID:
- case CKA_LABEL:
case CKA_SUBJECT:
case CKA_SERIAL_NUMBER:
case CKA_ISSUER:
@@ -350,7 +330,7 @@
break;
};
- return CKR_ATTRIBUTE_TYPE_INVALID;
+ return GKR_PK_OBJECT_CLASS (gkr_pk_netscape_trust_parent_class)->get_attribute (obj, attr);
}
static void
@@ -379,9 +359,7 @@
gkr_pk_netscape_trust_parent_class = g_type_class_peek_parent (klass);
parent_class = GKR_PK_OBJECT_CLASS (klass);
- parent_class->get_bool_attribute = gkr_pk_netscape_trust_get_bool_attribute;
- parent_class->get_ulong_attribute = gkr_pk_netscape_trust_get_ulong_attribute;
- parent_class->get_data_attribute = gkr_pk_netscape_trust_get_data_attribute;
+ parent_class->get_attribute = gkr_pk_netscape_trust_get_attribute;
gobject_class->get_property = gkr_pk_netscape_trust_get_property;
gobject_class->set_property = gkr_pk_netscape_trust_set_property;
Modified: trunk/pk/gkr-pk-object-manager.c
==============================================================================
--- trunk/pk/gkr-pk-object-manager.c (original)
+++ trunk/pk/gkr-pk-object-manager.c Mon Jan 14 01:22:17 2008
@@ -85,14 +85,13 @@
}
static void
-add_object_for_unique (GkrPkObjectManager *objmgr, gkrconstunique unique, GkrPkObject *object)
+add_object (GkrPkObjectManager *objmgr, GkrPkObject *object)
{
GkrPkObjectManagerPrivate *pv = GKR_PK_OBJECT_MANAGER_GET_PRIVATE (objmgr);
gpointer k;
- g_assert (unique);
- g_assert (object);
- g_assert (gkr_unique_equals (object->unique, unique));
+ g_assert (GKR_IS_PK_OBJECT (object));
+ g_assert (object->unique);
g_assert (object->manager == NULL);
if (!object->handle) {
@@ -108,9 +107,11 @@
g_assert (g_hash_table_lookup (pv->object_by_handle, k) == NULL);
g_hash_table_replace (pv->object_by_handle, k, object);
- /* Mapping of objects by index key */
+ /*
+ * Mapping of objects by unique key. There may be multiple objects
+ * with a given unique key.
+ */
g_assert (object->unique);
- g_assert (g_hash_table_lookup (pv->object_by_unique, object->unique) == NULL);
g_hash_table_replace (pv->object_by_unique, object->unique, object);
/* Note objects is being managed */
@@ -119,27 +120,25 @@
}
static void
-remove_object_at_unique (GkrPkObjectManager *objmgr, gkrconstunique unique)
+remove_object (GkrPkObjectManager *objmgr, GkrPkObject *object)
{
GkrPkObjectManagerPrivate *pv = GKR_PK_OBJECT_MANAGER_GET_PRIVATE (objmgr);
- GkrPkObject *object;
gpointer k;
- g_assert (unique);
-
- /* Get the object referred to */
- object = (GkrPkObject*)g_hash_table_lookup (pv->object_by_unique, unique);
g_assert (GKR_IS_PK_OBJECT (object));
g_assert (object->manager == objmgr);
-
+
/* Mapping of objects by PKCS#11 'handle' */
k = GUINT_TO_POINTER (object->handle);
g_assert (g_hash_table_lookup (pv->object_by_handle, k) == object);
g_hash_table_remove (pv->object_by_handle, k);
- /* Mapping of objects by index key */
- g_assert (gkr_unique_equals (object->unique, unique));
- g_hash_table_remove (pv->object_by_unique, unique);
+ /*
+ * Mapping of objects by unique key. There may be multiple objects
+ * with a given unique, so just remove if it matches this one.
+ */
+ if (g_hash_table_lookup (pv->object_by_unique, object->unique) == object)
+ g_hash_table_remove (pv->object_by_unique, object->unique);
/* Release object management */
objmgr->objects = g_list_remove (objmgr->objects, object);
@@ -280,7 +279,7 @@
g_return_if_fail (object->manager == NULL);
g_return_if_fail (object->unique);
- add_object_for_unique (objmgr, object->unique, object);
+ add_object (objmgr, object);
}
void
@@ -295,7 +294,7 @@
g_return_if_fail (object->manager == objmgr);
g_return_if_fail (object->unique);
- remove_object_at_unique (objmgr, object->unique);
+ remove_object (objmgr, object);
}
GkrPkObject*
Modified: trunk/pk/gkr-pk-object-storage.c
==============================================================================
--- trunk/pk/gkr-pk-object-storage.c (original)
+++ trunk/pk/gkr-pk-object-storage.c Mon Jan 14 01:22:17 2008
@@ -714,3 +714,19 @@
g_object_unref (obj);
return ret;
}
+
+gboolean
+gkr_pk_object_storage_add (GkrPkObjectStorage *storage, GkrPkObject *obj,
+ GError **err)
+{
+ /* TODO: Need to implement */
+ g_return_val_if_reached (FALSE);
+}
+
+gboolean
+gkr_pk_object_storage_remove (GkrPkObjectStorage *storage, GkrPkObject *obj,
+ GError **err)
+{
+ /* TODO: Need to implement */
+ g_return_val_if_reached (FALSE);
+}
Modified: trunk/pk/gkr-pk-object-storage.h
==============================================================================
--- trunk/pk/gkr-pk-object-storage.h (original)
+++ trunk/pk/gkr-pk-object-storage.h Mon Jan 14 01:22:17 2008
@@ -57,6 +57,12 @@
gboolean gkr_pk_object_storage_load_complete (GkrPkObjectStorage *storage,
GkrPkObject *obj, GError **err);
+gboolean gkr_pk_object_storage_add (GkrPkObjectStorage *storage,
+ GkrPkObject *obj, GError **err);
+
+gboolean gkr_pk_object_storage_remove (GkrPkObjectStorage *storage,
+ GkrPkObject *obj, GError **err);
+
G_END_DECLS
#endif /* __GKR_PK_OBJECT_STORAGE_H__ */
Modified: trunk/pk/gkr-pk-object.c
==============================================================================
--- trunk/pk/gkr-pk-object.c (original)
+++ trunk/pk/gkr-pk-object.c Mon Jan 14 01:22:17 2008
@@ -23,9 +23,12 @@
#include "config.h"
+#include "gkr-pk-cert.h"
#include "gkr-pk-index.h"
#include "gkr-pk-object.h"
#include "gkr-pk-object-manager.h"
+#include "gkr-pk-privkey.h"
+#include "gkr-pk-pubkey.h"
#include "gkr-pk-util.h"
#include "common/gkr-location.h"
@@ -73,56 +76,25 @@
static CK_RV
lookup_attribute (GkrPkObject *object, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE_PTR *attr)
{
- GkrPkObjectPrivate *pv = GKR_PK_OBJECT_GET_PRIVATE(object);
+ GkrPkObjectPrivate *pv = GKR_PK_OBJECT_GET_PRIVATE (object);
GkrPkObjectClass *klass;
CK_ATTRIBUTE cattr;
CK_RV ret = 0;
-
+
*attr = g_hash_table_lookup (pv->attr_cache, GUINT_TO_POINTER (type));
if(*attr)
return CKR_OK;
klass = GKR_PK_OBJECT_GET_CLASS (object);
-
memset (&cattr, 0, sizeof (cattr));
cattr.type = type;
- switch (gkr_pk_attribute_data_type (type))
- {
- case GKR_PK_DATA_BOOL:
- if (!klass->get_bool_attribute)
- return CKR_ATTRIBUTE_TYPE_INVALID;
- ret = (*klass->get_bool_attribute) (object, &cattr);
- break;
-
- case GKR_PK_DATA_ULONG:
- if (!klass->get_ulong_attribute)
- return CKR_ATTRIBUTE_TYPE_INVALID;
- ret = (*klass->get_ulong_attribute) (object, &cattr);
- break;
-
- case GKR_PK_DATA_BYTES:
- if (!klass->get_data_attribute)
- return CKR_ATTRIBUTE_TYPE_INVALID;
- ret = (*klass->get_data_attribute) (object, &cattr);
- break;
-
- case GKR_PK_DATA_DATE:
- if (!klass->get_date_attribute)
- return CKR_ATTRIBUTE_TYPE_INVALID;
- ret = (*klass->get_date_attribute) (object, &cattr);
- break;
-
- case GKR_PK_DATA_UNKNOWN:
- return CKR_ATTRIBUTE_TYPE_INVALID;
-
- default:
- g_assert_not_reached ();
- break;
- };
+ /* Ask derived class for attribute */
+ if (!klass->get_attribute)
+ g_return_val_if_reached (CKR_ATTRIBUTE_TYPE_INVALID);
+ ret = (*klass->get_attribute) (object, &cattr);
- if (ret != CKR_OK)
- {
+ if (ret != CKR_OK) {
/* Shouldn't be returning these */
g_assert (ret != CKR_BUFFER_TOO_SMALL);
return ret;
@@ -177,6 +149,71 @@
return obj;
}
+static CK_RV
+gkr_pk_object_get_attribute_common (GkrPkObject *obj, CK_ATTRIBUTE_PTR attr)
+{
+ CK_OBJECT_CLASS cls;
+ gchar *label;
+
+ switch (attr->type) {
+ case CKA_LABEL:
+ label = gkr_pk_object_get_label (obj);
+ if (!label && obj->location)
+ label = gkr_location_to_display (obj->location);
+ if (!label)
+ label = g_strdup ("");
+ gkr_pk_attribute_set_string (attr, label);
+ g_free (label);
+ return CKR_OK;
+
+ case CKA_TOKEN:
+ gkr_pk_attribute_set_boolean (attr,
+ (obj->handle & GKR_PK_OBJECT_IS_PERMANENT) == GKR_PK_OBJECT_IS_PERMANENT);
+ return CKR_OK;
+
+ case CKA_PRIVATE:
+ gkr_pk_attribute_set_boolean (attr,
+ (gkr_pk_object_get_ulong (obj, CKA_CLASS, &cls) == CKR_OK &&
+ gkc_pk_class_is_private (cls)));
+ return CKR_OK;
+
+ case CKA_MODIFIABLE:
+ /* TODO: Does this need to check somewhere? */
+ gkr_pk_attribute_set_boolean (attr, CK_TRUE);
+ return CKR_OK;
+
+ default:
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ };
+}
+
+static CK_RV
+gkr_pk_object_set_attribute_common (GkrPkObject *obj, CK_ATTRIBUTE_PTR attr)
+{
+ gchar *label;
+
+ switch (attr->type) {
+ case CKA_LABEL:
+ if (!attr->pValue && attr->ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ label = g_strndup (attr->pValue, attr->ulValueLen);
+ gkr_pk_object_set_label (obj, label);
+ g_free (label);
+ return CKR_OK;
+
+ case CKA_TOKEN:
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ return CKR_ATTRIBUTE_READ_ONLY;
+
+ case CKA_CLASS:
+ return CKR_ATTRIBUTE_READ_ONLY;
+
+ default:
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ };
+}
+
static void
gkr_pk_object_get_property (GObject *obj, guint prop_id, GValue *value,
GParamSpec *pspec)
@@ -198,7 +235,7 @@
g_value_set_string (value, pv->orig_label);
break;
case PROP_LABEL:
- g_value_set_string (value, gkr_pk_object_get_label (xobj));
+ g_value_take_string (value, gkr_pk_object_get_label (xobj));
break;
}
}
@@ -265,6 +302,9 @@
gobject_class->get_property = gkr_pk_object_get_property;
gobject_class->set_property = gkr_pk_object_set_property;
gobject_class->finalize = gkr_pk_object_finalize;
+
+ klass->get_attribute = gkr_pk_object_get_attribute_common;
+ klass->set_attribute = gkr_pk_object_set_attribute_common;
g_type_class_add_private (gobject_class, sizeof (GkrPkObjectPrivate));
@@ -293,6 +333,61 @@
* PUBLIC
*/
+CK_RV
+gkr_pk_object_create (GkrPkObjectManager *manager,
+ GArray *attrs, GkrPkObject **object)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_OBJECT_CLASS cls;
+ CK_RV ret;
+ guint i;
+
+ if (!gkr_pk_attributes_ulong (attrs, CKA_CLASS, &cls))
+ return CKR_TEMPLATE_INCOMPLETE;
+ gkr_pk_attributes_consume (attrs, CKA_CLASS, -1);
+
+ switch (cls) {
+ case CKO_PUBLIC_KEY:
+ ret = gkr_pk_pubkey_create (manager, attrs, object);
+ break;
+ case CKO_PRIVATE_KEY:
+ ret = gkr_pk_privkey_create (manager, attrs, object);
+ break;
+ case CKO_CERTIFICATE:
+ ret = gkr_pk_cert_create (manager, attrs, object);
+ break;
+ default:
+ /* TODO: What's a better error code here? */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+ };
+
+ if (ret != CKR_OK)
+ return ret;
+
+ g_return_val_if_fail (*object != NULL, CKR_GENERAL_ERROR);
+
+ /*
+ * Check that all the remaining attributes are either already
+ * set or are settable
+ */
+ for (i = 0; i < attrs->len; ++i) {
+ attr = &(g_array_index (attrs, CK_ATTRIBUTE, i));
+ if (!gkr_pk_attribute_is_consumed (attr)) {
+ ret = gkr_pk_object_set_attribute (*object, attr);
+ if (ret != CKR_OK)
+ break;
+ }
+ }
+
+ /* Unsuccessful so free the object */
+ if (ret != CKR_OK) {
+ g_object_unref (*object);
+ *object = NULL;
+ }
+
+ return ret;
+}
+
void
gkr_pk_object_flush (GkrPkObject *object)
{
@@ -440,6 +535,98 @@
return ret;
}
+CK_RV
+gkr_pk_object_set_attribute (GkrPkObject *object, CK_ATTRIBUTE_PTR attr)
+{
+ GkrPkObjectClass *klass;
+ CK_ATTRIBUTE_PTR cattr;
+ CK_BBOOL bvalue;
+ CK_ULONG nvalue;
+ gboolean found;
+ CK_RV ret = 0;
+
+ /* Get the current value for this attribute */
+ found = (lookup_attribute (object, attr->type, &cattr) == CKR_OK);
+ if (found) {
+
+ /* Compare it with the the new one, and ignore if equal */
+ if (gkr_pk_attribute_equal (attr, cattr))
+ return CKR_OK;
+ }
+
+ klass = GKR_PK_OBJECT_GET_CLASS (object);
+
+ /* A quick early check of the values */
+ switch (gkr_pk_attribute_data_type (attr->type))
+ {
+ case GKR_PK_DATA_BOOL:
+ if (!gkr_pk_attribute_get_boolean (attr, &bvalue))
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ break;
+
+ case GKR_PK_DATA_ULONG:
+ if (!gkr_pk_attribute_get_ulong (attr, &nvalue))
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ break;
+
+ case GKR_PK_DATA_BYTES:
+ break;
+
+ case GKR_PK_DATA_UNKNOWN:
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ };
+
+ /* If we didn't call above, then set via main method */
+ if (klass->set_attribute)
+ ret = (*klass->set_attribute) (object, attr);
+ else
+ ret = CKR_ATTRIBUTE_TYPE_INVALID;
+
+ /*
+ * If a method and value was found for reading, but no method
+ * was found for writing, then this must be a readonly.
+ */
+ if (ret == CKR_ATTRIBUTE_TYPE_INVALID && found)
+ ret = CKR_ATTRIBUTE_READ_ONLY;
+
+ return ret;
+}
+
+CK_RV
+gkr_pk_object_set_ulong (GkrPkObject *object, CK_ATTRIBUTE_TYPE type, CK_ULONG value)
+{
+ CK_ATTRIBUTE attr = { type, &value, sizeof (value) };
+ return gkr_pk_object_set_attribute (object, &attr);
+}
+
+CK_RV
+gkr_pk_object_set_bool (GkrPkObject *object, CK_ATTRIBUTE_TYPE type, CK_BBOOL value)
+{
+ CK_ATTRIBUTE attr = { type, &value, sizeof (value) };
+ return gkr_pk_object_set_attribute (object, &attr);
+}
+
+CK_RV
+gkr_pk_object_set_attributes (GkrPkObject *object, GArray *attrs)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_RV ret = CKR_OK;
+ guint i;
+
+ for (i = 0; i < attrs->len; ++i) {
+ attr = &(g_array_index (attrs, CK_ATTRIBUTE, i));
+ ret = gkr_pk_object_set_attribute (object, attr);
+ if (ret != CKR_OK)
+ break;
+ }
+
+ return ret;
+}
+
gchar*
gkr_pk_object_get_label (GkrPkObject *xobj)
{
Modified: trunk/pk/gkr-pk-object.h
==============================================================================
--- trunk/pk/gkr-pk-object.h (original)
+++ trunk/pk/gkr-pk-object.h Mon Jan 14 01:22:17 2008
@@ -62,14 +62,16 @@
struct _GkrPkObjectClass {
GObjectClass parent_class;
- CK_RV (*get_bool_attribute) (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr);
- CK_RV (*get_ulong_attribute) (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr);
- CK_RV (*get_data_attribute) (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr);
- CK_RV (*get_date_attribute) (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr);
+ /* The attribute getter and setter */
+ CK_RV (*get_attribute) (GkrPkObject *obj, CK_ATTRIBUTE_PTR attr);
+ CK_RV (*set_attribute) (GkrPkObject *obj, CK_ATTRIBUTE_PTR attr);
};
GType gkr_pk_object_get_type (void) G_GNUC_CONST;
+CK_RV gkr_pk_object_create (GkrPkObjectManager *manager,
+ GArray *attrs, GkrPkObject **object);
+
void gkr_pk_object_refresh (GkrPkObject *object);
void gkr_pk_object_flush (GkrPkObject *object);
@@ -98,6 +100,20 @@
CK_RV gkr_pk_object_get_attributes (GkrPkObject *object,
GArray *attrs);
+CK_RV gkr_pk_object_set_attribute (GkrPkObject *object,
+ CK_ATTRIBUTE_PTR attr);
+
+CK_RV gkr_pk_object_set_ulong (GkrPkObject *object,
+ CK_ATTRIBUTE_TYPE type,
+ CK_ULONG value);
+
+CK_RV gkr_pk_object_set_bool (GkrPkObject *object,
+ CK_ATTRIBUTE_TYPE type,
+ CK_BBOOL value);
+
+CK_RV gkr_pk_object_set_attributes (GkrPkObject *object,
+ GArray *attrs);
+
gchar* gkr_pk_object_get_label (GkrPkObject *object);
void gkr_pk_object_set_label (GkrPkObject *object,
Modified: trunk/pk/gkr-pk-privkey.c
==============================================================================
--- trunk/pk/gkr-pk-privkey.c (original)
+++ trunk/pk/gkr-pk-privkey.c Mon Jan 14 01:22:17 2008
@@ -157,6 +157,110 @@
return key->priv->pubkey;
}
+static CK_RV
+create_rsa_private (GArray *attrs, gcry_sexp_t *skey)
+{
+ gcry_error_t gcry;
+ gcry_mpi_t n = NULL;
+ gcry_mpi_t e = NULL;
+ gcry_mpi_t d = NULL;
+ gcry_mpi_t p = NULL;
+ gcry_mpi_t q = NULL;
+ gcry_mpi_t u = NULL;
+ CK_RV ret;
+
+ if (!gkr_pk_attributes_mpi (attrs, CKA_MODULUS, &n) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_PUBLIC_EXPONENT, &e) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_PRIVATE_EXPONENT, &d) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_PRIME_1, &p) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_PRIME_2, &q)) {
+ ret = CKR_TEMPLATE_INCOMPLETE;
+ goto done;
+ }
+
+ /* Fix up the incoming key so gcrypt likes it */
+ if (gcry_mpi_cmp (p, q) > 0)
+ gcry_mpi_swap (p, q);
+
+ /* Compute U. */
+ u = gcry_mpi_snew (gcry_mpi_get_nbits (n));
+ gcry_mpi_invm (u, p, q);
+
+ gcry = gcry_sexp_build (skey, NULL,
+ "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))",
+ n, e, d, p, q, u);
+
+ /* TODO: We should be mapping better return codes */
+ if (gcry != 0) {
+ g_message ("couldn't create RSA key from passed attributes");
+ ret = CKR_GENERAL_ERROR;
+ goto done;
+ }
+
+ gkr_pk_attributes_consume (attrs, CKA_MODULUS, CKA_PUBLIC_EXPONENT,
+ CKA_PRIVATE_EXPONENT, CKA_PRIME_1, CKA_PRIME_2,
+ CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT, -1);
+ ret = CKR_OK;
+
+done:
+ gcry_mpi_release (n);
+ gcry_mpi_release (e);
+ gcry_mpi_release (d);
+ gcry_mpi_release (p);
+ gcry_mpi_release (q);
+ gcry_mpi_release (u);
+ return ret;
+}
+
+static CK_RV
+create_dsa_private (GArray *attrs, gcry_sexp_t *skey)
+{
+ gcry_error_t gcry;
+ gcry_mpi_t p = NULL;
+ gcry_mpi_t q = NULL;
+ gcry_mpi_t g = NULL;
+ gcry_mpi_t y = NULL;
+ gcry_mpi_t value = NULL;
+ CK_RV ret;
+
+ if (!gkr_pk_attributes_mpi (attrs, CKA_PRIME, &p) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_SUBPRIME, &q) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_BASE, &g) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_VALUE, &value)) {
+ ret = CKR_TEMPLATE_INCOMPLETE;
+ goto done;
+ }
+
+ /* Calculate the public part from the private */
+ y = gcry_mpi_snew (gcry_mpi_get_nbits (value));
+ g_return_val_if_fail (y, CKR_GENERAL_ERROR);
+ gcry_mpi_powm (y, g, value, p);
+
+ gcry = gcry_sexp_build (skey, NULL,
+ "(private-key (dsa (p %m) (q %m) (g %m) (y %m) (x %m)))",
+ p, q, g, y, value);
+
+ /* TODO: We should be mapping better return codes */
+ if (gcry != 0) {
+ g_message ("couldn't create DSA key from passed attributes");
+ ret = CKR_GENERAL_ERROR;
+ goto done;
+ }
+
+ gkr_pk_attributes_consume (attrs, CKA_PRIME, CKA_SUBPRIME,
+ CKA_BASE, CKA_VALUE, -1);
+ ret = CKR_OK;
+
+done:
+ gcry_mpi_release (p);
+ gcry_mpi_release (q);
+ gcry_mpi_release (g);
+ gcry_mpi_release (y);
+ gcry_mpi_release (value);
+ return ret;
+}
+
+
static void
initialize_from_key (GkrPkPrivkey *key)
{
@@ -282,11 +386,14 @@
}
}
-static CK_RV
-gkr_pk_privkey_get_bool_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
+static CK_RV
+gkr_pk_privkey_get_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
{
+ GkrPkPrivkey *key = GKR_PK_PRIVKEY (obj);
+ gkrconstunique keyid;
GQuark *quarks;
- gboolean val;
+ guchar *value;
+ gsize len;
switch (attr->type)
{
@@ -295,104 +402,48 @@
case CKA_SENSITIVE:
case CKA_SIGN:
case CKA_SIGN_RECOVER:
- case CKA_TOKEN:
case CKA_WRAP_WITH_TRUSTED:
- val = TRUE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_TRUE);
+ return CKR_OK;
case CKA_DERIVE:
case CKA_EXTRACTABLE:
- case CKA_MODIFIABLE:
case CKA_UNWRAP:
- val = FALSE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_FALSE);
+ return CKR_OK;
case CKA_GNOME_PURPOSE_SSH_AUTH:
quarks = gkr_pk_index_get_quarks (obj, "purposes");
- val = quarks && gkr_pk_index_quarks_has (quarks, SSH_AUTHENTICATION);
+ gkr_pk_attribute_set_boolean (attr, quarks &&
+ gkr_pk_index_quarks_has (quarks, SSH_AUTHENTICATION));
gkr_pk_index_quarks_free (quarks);
- break;
+ return CKR_OK;
/* TODO: Perhaps we can detect this in some way */
case CKA_ALWAYS_SENSITIVE:
case CKA_LOCAL:
case CKA_NEVER_EXTRACTABLE:
- val = FALSE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_FALSE);
+ return CKR_OK;
/* TODO: We may be able to detect this for certain keys */
case CKA_ALWAYS_AUTHENTICATE:
- val = FALSE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_FALSE);
+ return CKR_OK;
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- gkr_pk_attribute_set_boolean (attr, val);
- return CKR_OK;
-}
-
-static CK_RV
-gkr_pk_privkey_get_ulong_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkPrivkey *key = GKR_PK_PRIVKEY (obj);
- gulong val;
-
- switch (attr->type)
- {
case CKA_CLASS:
- val = CKO_PRIVATE_KEY;
- break;
+ gkr_pk_attribute_set_ulong (attr, CKO_PRIVATE_KEY);
+ return CKR_OK;
case CKA_KEY_TYPE:
- if (attribute_from_public (key, attr) == CKR_OK)
- return CKR_OK;
- val = CK_UNAVAILABLE_INFORMATION;
- break;
+ if (attribute_from_public (key, attr) != CKR_OK)
+ gkr_pk_attribute_set_ulong (attr, CK_UNAVAILABLE_INFORMATION);
+ return CKR_OK;
/* TODO: Once we can generate keys, this should change */
case CKA_KEY_GEN_MECHANISM:
- val = CK_UNAVAILABLE_INFORMATION;
- break;
-
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- gkr_pk_attribute_set_ulong (attr, val);
- return CKR_OK;
-}
-
-static CK_RV
-gkr_pk_privkey_get_data_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkPrivkey *key = GKR_PK_PRIVKEY (obj);
- gkrconstunique keyid;
- gchar *label;
- guchar *value;
- gsize len;
- CK_RV ret;
-
- switch (attr->type)
- {
- case CKA_LABEL:
- g_object_get (obj, "label", &label, NULL);
- if (label) {
- gkr_pk_attribute_set_string (attr, label);
- g_free (label);
- return CKR_OK;
- }
-
- ret = attribute_from_certificate (key, attr);
- if (ret == CKR_ATTRIBUTE_TYPE_INVALID) {
- label = gkr_location_to_display (obj->location);
- gkr_pk_attribute_set_string (attr, label);
- g_free (label);
- ret = CKR_OK;
- }
-
- return ret;
+ gkr_pk_attribute_set_ulong (attr, CK_UNAVAILABLE_INFORMATION);
+ return CKR_OK;
case CKA_ID:
keyid = gkr_pk_privkey_get_keyid (key);
@@ -440,26 +491,16 @@
case CKA_UNWRAP_TEMPLATE:
return CKR_ATTRIBUTE_TYPE_INVALID;
- default:
- break;
- };
-
- return CKR_ATTRIBUTE_TYPE_INVALID;
-}
-
-static CK_RV
-gkr_pk_privkey_get_date_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- switch (attr->type)
- {
/* We don't support these */
case CKA_START_DATE:
case CKA_END_DATE:
return CKR_ATTRIBUTE_TYPE_INVALID;
-
+
default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
+ break;
};
+
+ return GKR_PK_OBJECT_CLASS (gkr_pk_privkey_parent_class)->get_attribute (obj, attr);
}
static void
@@ -500,10 +541,7 @@
gkr_pk_privkey_parent_class = g_type_class_peek_parent (klass);
parent_class = GKR_PK_OBJECT_CLASS (klass);
- parent_class->get_bool_attribute = gkr_pk_privkey_get_bool_attribute;
- parent_class->get_ulong_attribute = gkr_pk_privkey_get_ulong_attribute;
- parent_class->get_data_attribute = gkr_pk_privkey_get_data_attribute;
- parent_class->get_date_attribute = gkr_pk_privkey_get_date_attribute;
+ parent_class->get_attribute = gkr_pk_privkey_get_attribute;
gobject_class = (GObjectClass*)klass;
gobject_class->get_property = gkr_pk_privkey_get_property;
@@ -541,6 +579,44 @@
return key;
}
+CK_RV
+gkr_pk_privkey_create (GkrPkObjectManager* manager, GArray* array,
+ GkrPkObject **object)
+{
+ CK_KEY_TYPE type;
+ gcry_sexp_t sexp;
+ CK_RV ret;
+
+ g_return_val_if_fail (GKR_IS_PK_OBJECT_MANAGER (manager), CKR_GENERAL_ERROR);
+ g_return_val_if_fail (array, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (object, CKR_GENERAL_ERROR);
+
+ *object = NULL;
+
+ if (!gkr_pk_attributes_ulong (array, CKA_KEY_TYPE, &type))
+ return CKR_TEMPLATE_INCOMPLETE;
+ gkr_pk_attributes_consume (array, CKA_KEY_TYPE, -1);
+
+ switch (type) {
+ case CKK_RSA:
+ ret = create_rsa_private (array, &sexp);
+ break;
+ case CKK_DSA:
+ ret = create_dsa_private (array, &sexp);
+ break;
+ default:
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ };
+
+ if (ret != CKR_OK)
+ return ret;
+
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ *object = gkr_pk_privkey_new (manager, 0, sexp);
+
+ return CKR_OK;
+}
+
gkrconstunique
gkr_pk_privkey_get_keyid (GkrPkPrivkey *key)
{
Modified: trunk/pk/gkr-pk-privkey.h
==============================================================================
--- trunk/pk/gkr-pk-privkey.h (original)
+++ trunk/pk/gkr-pk-privkey.h Mon Jan 14 01:22:17 2008
@@ -55,8 +55,12 @@
GType gkr_pk_privkey_get_type (void) G_GNUC_CONST;
-GkrPkObject* gkr_pk_privkey_new (GkrPkObjectManager *mgr, GQuark location, gcry_sexp_t skey);
+GkrPkObject* gkr_pk_privkey_new (GkrPkObjectManager *mgr,
+ GQuark location, gcry_sexp_t skey);
+CK_RV gkr_pk_privkey_create (GkrPkObjectManager* manager,
+ GArray* array, GkrPkObject **object);
+
gkrconstunique gkr_pk_privkey_get_keyid (GkrPkPrivkey *pkey);
gkrunique gkr_pk_privkey_make_keyid (gcry_sexp_t skey);
Modified: trunk/pk/gkr-pk-pubkey.c
==============================================================================
--- trunk/pk/gkr-pk-pubkey.c (original)
+++ trunk/pk/gkr-pk-pubkey.c Mon Jan 14 01:22:17 2008
@@ -128,6 +128,80 @@
}
static CK_RV
+create_rsa_public (GArray *attrs, gcry_sexp_t *skey)
+{
+ gcry_error_t gcry;
+ gcry_mpi_t n = NULL;
+ gcry_mpi_t e = NULL;
+ CK_RV ret;
+
+ if (!gkr_pk_attributes_mpi (attrs, CKA_MODULUS, &n) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_PUBLIC_EXPONENT, &e)) {
+ ret = CKR_TEMPLATE_INCOMPLETE;
+ goto done;
+ }
+
+ gcry = gcry_sexp_build (skey, NULL,
+ "(public-key (rsa (n %m) (e %m)))", n, e);
+
+ /* TODO: We should be mapping better return codes */
+ if (gcry != 0) {
+ g_message ("couldn't create RSA key from passed attributes");
+ ret = CKR_GENERAL_ERROR;
+ goto done;
+ }
+
+ gkr_pk_attributes_consume (attrs, CKA_MODULUS, CKA_PUBLIC_EXPONENT, -1);
+ ret = CKR_OK;
+
+done:
+ gcry_mpi_release (n);
+ gcry_mpi_release (e);
+ return ret;
+}
+
+static CK_RV
+create_dsa_public (GArray *attrs, gcry_sexp_t *skey)
+{
+ gcry_error_t gcry;
+ gcry_mpi_t p = NULL;
+ gcry_mpi_t q = NULL;
+ gcry_mpi_t g = NULL;
+ gcry_mpi_t value = NULL;
+ CK_RV ret;
+
+ if (!gkr_pk_attributes_mpi (attrs, CKA_PRIME, &p) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_SUBPRIME, &q) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_BASE, &g) ||
+ !gkr_pk_attributes_mpi (attrs, CKA_VALUE, &value)) {
+ ret = CKR_TEMPLATE_INCOMPLETE;
+ goto done;
+ }
+
+ gcry = gcry_sexp_build (skey, NULL,
+ "(public-key (dsa (p %m) (q %m) (g %m) (y %m)))",
+ p, q, g, value);
+
+ /* TODO: We should be mapping better return codes */
+ if (gcry != 0) {
+ g_message ("couldn't create DSA key from passed attributes");
+ ret = CKR_GENERAL_ERROR;
+ goto done;
+ }
+
+ gkr_pk_attributes_consume (attrs, CKA_PRIME, CKA_SUBPRIME,
+ CKA_BASE, CKA_VALUE, -1);
+ ret = CKR_OK;
+
+done:
+ gcry_mpi_release (p);
+ gcry_mpi_release (q);
+ gcry_mpi_release (g);
+ gcry_mpi_release (value);
+ return ret;
+}
+
+static CK_RV
attribute_from_related (GkrPkPubkey *key, GType type, CK_ATTRIBUTE_PTR attr)
{
GkrPkObject *crt, *obj;
@@ -230,78 +304,60 @@
}
}
-static CK_RV
-gkr_pk_pubkey_get_bool_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
+static CK_RV
+gkr_pk_pubkey_get_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
{
- gboolean val;
+ GkrPkPubkey *key = GKR_PK_PUBKEY (obj);
+ gcry_mpi_t mpi;
+ CK_RV ret;
switch (attr->type)
{
- case CKA_ALWAYS_AUTHENTICATE:
case CKA_ENCRYPT:
case CKA_EXTRACTABLE:
- case CKA_TOKEN:
case CKA_VERIFY:
case CKA_VERIFY_RECOVER:
- val = TRUE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_TRUE);
+ return CKR_OK;
+ case CKA_ALWAYS_AUTHENTICATE:
case CKA_DERIVE:
- case CKA_MODIFIABLE:
case CKA_PRIVATE:
case CKA_SENSITIVE:
case CKA_WRAP:
case CKA_WRAP_WITH_TRUSTED:
- val = FALSE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_FALSE);
+ return CKR_OK;
/* TODO: Use our definition of trusted */
case CKA_TRUSTED:
- val = FALSE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_FALSE);
+ return CKR_OK;
/* TODO: Perhaps we can detect this in some way */
case CKA_LOCAL:
- val = FALSE;
- break;
+ gkr_pk_attribute_set_boolean (attr, CK_FALSE);
+ return CKR_OK;
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- gkr_pk_attribute_set_boolean (attr, val);
- return CKR_OK;
-}
-
-static CK_RV
-gkr_pk_pubkey_get_ulong_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkPubkey *key = GKR_PK_PUBKEY (obj);
- gcry_mpi_t mpi;
- gboolean ret;
- gulong val;
-
- switch (attr->type)
- {
case CKA_CLASS:
- val = CKO_PUBLIC_KEY;
- break;
+ gkr_pk_attribute_set_ulong (attr, CKO_PUBLIC_KEY);
+ return CKR_OK;
case CKA_KEY_TYPE:
if (!load_public_key (key))
return CKR_GENERAL_ERROR;
switch (key->pub->algorithm) {
case GCRY_PK_RSA:
- val = CKK_RSA;
+ gkr_pk_attribute_set_ulong (attr, CKK_RSA);
break;
case GCRY_PK_DSA:
- val = CKK_DSA;
+ gkr_pk_attribute_set_ulong (attr, CKK_DSA);
break;
default:
g_return_val_if_reached (CKR_GENERAL_ERROR);
break;
}
- break;
+ return CKR_OK;
case CKA_MODULUS_BITS:
if (!load_public_key (key))
@@ -311,38 +367,14 @@
g_assert (key->pub->numbers);
ret = gkr_crypto_sexp_extract_mpi (key->pub->numbers, &mpi, "n", NULL);
g_return_val_if_fail (ret, CKR_GENERAL_ERROR);
- val = gcry_mpi_get_nbits (mpi);
+ gkr_pk_attribute_set_ulong (attr, gcry_mpi_get_nbits (mpi));
gcry_mpi_release (mpi);
- break;
+ return CKR_OK;
/* TODO: Once we can generate keys, this should change */
case CKA_KEY_GEN_MECHANISM:
return CK_UNAVAILABLE_INFORMATION;
- default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
- };
-
- gkr_pk_attribute_set_ulong (attr, val);
- return CKR_OK;
-}
-
-static CK_RV
-gkr_pk_pubkey_get_data_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- GkrPkPubkey *key = GKR_PK_PUBKEY (obj);
- gchar *label;
-
- switch (attr->type)
- {
- case CKA_LABEL:
- g_object_get (obj, "label", &label, NULL);
- if (!label)
- label = gkr_location_to_display (obj->location);
- gkr_pk_attribute_set_string (attr, label);
- g_free (label);
- return CKR_OK;
-
case CKA_ID:
/* Always a SHA-1 hash output buffer */
if (!load_public_key (key) || !key->pub->keyid)
@@ -384,26 +416,16 @@
case CKA_UNWRAP_TEMPLATE:
return CKR_ATTRIBUTE_TYPE_INVALID;
- default:
- break;
- };
-
- return CKR_ATTRIBUTE_TYPE_INVALID;
-}
-
-static CK_RV
-gkr_pk_pubkey_get_date_attribute (GkrPkObject* obj, CK_ATTRIBUTE_PTR attr)
-{
- switch (attr->type)
- {
/* We don't support these */
case CKA_START_DATE:
case CKA_END_DATE:
return CKR_ATTRIBUTE_TYPE_INVALID;
default:
- return CKR_ATTRIBUTE_TYPE_INVALID;
+ break;
};
+
+ return GKR_PK_OBJECT_CLASS (gkr_pk_pubkey_parent_class)->get_attribute (obj, attr);
}
static void
@@ -430,10 +452,7 @@
gkr_pk_pubkey_parent_class = g_type_class_peek_parent (klass);
parent_class = GKR_PK_OBJECT_CLASS (klass);
- parent_class->get_bool_attribute = gkr_pk_pubkey_get_bool_attribute;
- parent_class->get_ulong_attribute = gkr_pk_pubkey_get_ulong_attribute;
- parent_class->get_data_attribute = gkr_pk_pubkey_get_data_attribute;
- parent_class->get_date_attribute = gkr_pk_pubkey_get_date_attribute;
+ parent_class->get_attribute = gkr_pk_pubkey_get_attribute;
gobject_class = (GObjectClass*)klass;
gobject_class->get_property = gkr_pk_pubkey_get_property;
@@ -495,6 +514,44 @@
return GKR_PK_PUBKEY (pub);
}
+CK_RV
+gkr_pk_pubkey_create (GkrPkObjectManager* manager, GArray* array,
+ GkrPkObject **object)
+{
+ CK_KEY_TYPE type;
+ gcry_sexp_t sexp;
+ CK_RV ret;
+
+ g_return_val_if_fail (GKR_IS_PK_OBJECT_MANAGER (manager), CKR_GENERAL_ERROR);
+ g_return_val_if_fail (array, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (object, CKR_GENERAL_ERROR);
+
+ *object = NULL;
+
+ if (!gkr_pk_attributes_ulong (array, CKA_KEY_TYPE, &type))
+ return CKR_TEMPLATE_INCOMPLETE;
+ gkr_pk_attributes_consume (array, CKA_KEY_TYPE, -1);
+
+ switch (type) {
+ case CKK_RSA:
+ ret = create_rsa_public (array, &sexp);
+ break;
+ case CKK_DSA:
+ ret = create_dsa_public (array, &sexp);
+ break;
+ default:
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ };
+
+ if (ret != CKR_OK)
+ return ret;
+
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ *object = gkr_pk_pubkey_new (manager, 0, sexp);
+
+ return CKR_OK;
+}
+
gkrconstunique
gkr_pk_pubkey_get_keyid (GkrPkPubkey *key)
{
Modified: trunk/pk/gkr-pk-pubkey.h
==============================================================================
--- trunk/pk/gkr-pk-pubkey.h (original)
+++ trunk/pk/gkr-pk-pubkey.h Mon Jan 14 01:22:17 2008
@@ -60,6 +60,9 @@
GkrPkPubkey* gkr_pk_pubkey_instance (GkrPkObjectManager* manager,
GQuark location, gcry_sexp_t s_key);
+CK_RV gkr_pk_pubkey_create (GkrPkObjectManager* manager,
+ GArray* array, GkrPkObject **object);
+
gkrconstunique gkr_pk_pubkey_get_keyid (GkrPkPubkey *key);
gcry_sexp_t gkr_pk_pubkey_get_key (GkrPkPubkey *key);
Modified: trunk/pk/gkr-pk-util.c
==============================================================================
--- trunk/pk/gkr-pk-util.c (original)
+++ trunk/pk/gkr-pk-util.c Mon Jan 14 01:22:17 2008
@@ -153,12 +153,9 @@
case CKA_CERT_SHA1_HASH:
case CKA_CERT_MD5_HASH:
case CKA_GNOME_PURPOSE_OIDS:
- return GKR_PK_DATA_BYTES;
-
- /* CK_DATE data */
case CKA_START_DATE:
case CKA_END_DATE:
- return GKR_PK_DATA_DATE;
+ return GKR_PK_DATA_BYTES;
/* Arrays are nasty */
case CKA_WRAP_TEMPLATE:
@@ -188,6 +185,21 @@
return nattr;
}
+gboolean
+gkr_pk_attribute_equal (const CK_ATTRIBUTE_PTR one, const CK_ATTRIBUTE_PTR two)
+{
+ if (one->type != two->type)
+ return FALSE;
+
+ if (one->ulValueLen != two->ulValueLen)
+ return FALSE;
+ if (one->pValue == two->pValue)
+ return TRUE;
+ if (!one->pValue || !two->pValue)
+ return FALSE;
+ return memcmp (one->pValue, two->pValue, one->ulValueLen) == 0;
+}
+
void
gkr_pk_attribute_steal (CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR attr)
{
@@ -238,13 +250,13 @@
}
void
-gkr_pk_attribute_set_boolean (CK_ATTRIBUTE_PTR attr, gboolean value)
+gkr_pk_attribute_set_boolean (CK_ATTRIBUTE_PTR attr, CK_BBOOL value)
{
g_assert (attr);
gkr_pk_attribute_clear (attr);
attr->pValue = g_new (CK_BBOOL, 1);
- *((CK_BBOOL*)attr->pValue) = value ? CK_TRUE : CK_FALSE;
+ *((CK_BBOOL*)attr->pValue) = value;
attr->ulValueLen = sizeof (CK_BBOOL);
}
@@ -273,7 +285,7 @@
memcpy (date->year, buf, 4);
g_assert (sizeof (date->month) == 2);
- snprintf ((char*)buf, 3, "%02d", tm.tm_mon);
+ snprintf ((char*)buf, 3, "%02d", tm.tm_mon + 1);
memcpy (date->month, buf, 2);
g_assert (sizeof (date->day) == 2);
@@ -299,7 +311,7 @@
}
void
-gkr_pk_attribute_set_ulong (CK_ATTRIBUTE_PTR attr, gulong value)
+gkr_pk_attribute_set_ulong (CK_ATTRIBUTE_PTR attr, CK_ULONG value)
{
g_assert (attr);
@@ -335,6 +347,24 @@
g_return_if_fail (gcry == 0);
}
+gboolean
+gkr_pk_attribute_get_boolean (const CK_ATTRIBUTE_PTR attr, CK_BBOOL *value)
+{
+ if (attr->ulValueLen != sizeof (CK_BBOOL))
+ return FALSE;
+ *value = *((const CK_BBOOL*)attr->pValue);
+ return TRUE;
+}
+
+gboolean
+gkr_pk_attribute_get_ulong (const CK_ATTRIBUTE_PTR attr, CK_ULONG *value)
+{
+ if (attr->ulValueLen != sizeof (CK_ULONG))
+ return FALSE;
+ *value = *((const CK_ULONG*)attr->pValue);
+ return TRUE;
+}
+
void
gkr_pk_attribute_clear (CK_ATTRIBUTE_PTR attr)
{
@@ -409,6 +439,13 @@
}
void
+gkr_pk_attributes_append (GArray *attrs, CK_ATTRIBUTE_PTR attr)
+{
+ g_array_append_vals (attrs, attr, 1);
+ memset (attr, 0, sizeof (*attr));
+}
+
+void
gkr_pk_attributes_free (GArray *attrs)
{
CK_ATTRIBUTE_PTR attr;
@@ -426,6 +463,50 @@
}
gboolean
+gkr_pk_attribute_is_consumed (CK_ATTRIBUTE_PTR attr)
+{
+ return attr->type == (CK_ULONG)-1;
+}
+
+void
+gkr_pk_attribute_consume (CK_ATTRIBUTE_PTR attr)
+{
+ attr->type = (CK_ULONG)-1;
+}
+
+void
+gkr_pk_attributes_consume (GArray *attrs, ...)
+{
+ CK_ATTRIBUTE_TYPE type;
+ CK_ATTRIBUTE_PTR attr;
+ GArray *types;
+ guint i, j;
+ va_list va;
+
+ /* Convert the var args into an array */
+ types = g_array_new (FALSE, TRUE, sizeof (CK_ATTRIBUTE_TYPE));
+ va_start (va, attrs);
+ while ((type = va_arg (va, CK_ATTRIBUTE_TYPE)) != (CK_ULONG)-1)
+ g_array_append_val (types, type);
+ va_end (va);
+
+ /* Consume each attribute whose type was in the var args */
+ for (i = 0; i < attrs->len; ++i) {
+ attr = &(g_array_index (attrs, CK_ATTRIBUTE, i));
+ if (gkr_pk_attribute_is_consumed (attr))
+ continue;
+ for (j = 0; j < types->len; ++j) {
+ if (attr->type == g_array_index (types, CK_ATTRIBUTE_TYPE, j)) {
+ gkr_pk_attribute_consume (attr);
+ break;
+ }
+ }
+ }
+
+ g_array_free (types, TRUE);
+}
+
+gboolean
gkc_pk_class_is_private (CK_OBJECT_CLASS cls)
{
switch (cls) {
Modified: trunk/pk/gkr-pk-util.h
==============================================================================
--- trunk/pk/gkr-pk-util.h (original)
+++ trunk/pk/gkr-pk-util.h Mon Jan 14 01:22:17 2008
@@ -35,7 +35,6 @@
GKR_PK_DATA_UNKNOWN = 0,
GKR_PK_DATA_BOOL,
GKR_PK_DATA_ULONG,
- GKR_PK_DATA_DATE,
GKR_PK_DATA_BYTES
} GkrPkDataType;
@@ -45,6 +44,9 @@
CK_ATTRIBUTE_PTR gkr_pk_attribute_dup (const CK_ATTRIBUTE_PTR attr);
+gint gkr_pk_attribute_equal (const CK_ATTRIBUTE_PTR one,
+ const CK_ATTRIBUTE_PTR two);
+
void gkr_pk_attribute_free (gpointer attr);
void gkr_pk_attribute_copy (CK_ATTRIBUTE_PTR dest, const CK_ATTRIBUTE_PTR attr);
@@ -62,14 +64,18 @@
void gkr_pk_attribute_set_unique (CK_ATTRIBUTE_PTR attr, gkrconstunique uni);
-void gkr_pk_attribute_set_boolean (CK_ATTRIBUTE_PTR attr, gboolean value);
+void gkr_pk_attribute_set_boolean (CK_ATTRIBUTE_PTR attr, CK_BBOOL value);
void gkr_pk_attribute_set_date (CK_ATTRIBUTE_PTR attr, time_t time);
-void gkr_pk_attribute_set_ulong (CK_ATTRIBUTE_PTR attr, gulong value);
+void gkr_pk_attribute_set_ulong (CK_ATTRIBUTE_PTR attr, CK_ULONG value);
void gkr_pk_attribute_set_mpi (CK_ATTRIBUTE_PTR attr, gcry_mpi_t mpi);
+gboolean gkr_pk_attribute_get_boolean (const CK_ATTRIBUTE_PTR attr, CK_BBOOL *value);
+
+gboolean gkr_pk_attribute_get_ulong (const CK_ATTRIBUTE_PTR attr, CK_ULONG *value);
+
#define gkr_pk_attributes_new() (g_array_new (0, 1, sizeof (CK_ATTRIBUTE)))
CK_ATTRIBUTE_PTR gkr_pk_attributes_find (const GArray* attrs, CK_ATTRIBUTE_TYPE type);
@@ -83,8 +89,22 @@
gboolean gkr_pk_attributes_mpi (const GArray* attrs, CK_ATTRIBUTE_TYPE type,
gcry_mpi_t *mpi);
+void gkr_pk_attributes_append (GArray *attrs, CK_ATTRIBUTE_PTR attr);
+
void gkr_pk_attributes_free (GArray *attrs);
+/*
+ * 'Consumption' of attributes is used during setting of a set of attributes
+ * on an object, those that have been handled somewhere are marked consumed.
+ * This is useful for fallback handling. See gkr_pk_object_set_attribute().
+ */
+gboolean gkr_pk_attribute_is_consumed (const CK_ATTRIBUTE_PTR attr);
+
+void gkr_pk_attribute_consume (CK_ATTRIBUTE_PTR attr);
+
+void gkr_pk_attributes_consume (GArray *attrs, ...);
+
+/* Certain object classes are intrinsically private */
gboolean gkc_pk_class_is_private (CK_OBJECT_CLASS cls);
#endif /*GKRPKUTIL_H_*/
Modified: trunk/pk/tests/Makefile.am
==============================================================================
--- trunk/pk/tests/Makefile.am (original)
+++ trunk/pk/tests/Makefile.am Mon Jan 14 01:22:17 2008
@@ -2,6 +2,7 @@
UNIT_AUTO = \
unit-test-pk-index.c \
unit-test-pk-cert.c \
+ unit-test-pk-key.c \
unit-test-pk-netscape-trust.c
UNIT_PROMPT =
Modified: trunk/pk/tests/check-attribute.c
==============================================================================
--- trunk/pk/tests/check-attribute.c (original)
+++ trunk/pk/tests/check-attribute.c Mon Jan 14 01:22:17 2008
@@ -1,6 +1,8 @@
#ifndef CHECKATTRIBUTE_H_
#define CHECKATTRIBUTE_H_
+#include "pk/gkr-pk-util.h"
+
static void
check_attribute (CuTest *cu, GkrPkObject *obj, CK_ATTRIBUTE_TYPE type,
const char* name, gpointer value, gsize len)
@@ -33,5 +35,18 @@
#define CHECK_BYTE_ATTRIBUTE(cu, obj, type, val, length) \
check_attribute (cu, GKR_PK_OBJECT (obj), type, #type, val, length)
+#define CHECK_DATE_ATTRIBUTE(cu, obj, type, str) { \
+ CK_ATTRIBUTE test = { 0, NULL, 0 }; \
+ struct tm tm; \
+ time_t time; \
+ GDate *date = g_date_new (); \
+ g_date_set_parse (date, str); \
+ g_date_to_struct_tm (date, &tm); \
+ time = timegm (&tm); \
+ g_date_free (date); \
+ gkr_pk_attribute_set_date (&test, time); \
+ check_attribute (cu, GKR_PK_OBJECT (obj), type, #type, test.pValue, test.ulValueLen); \
+ gkr_pk_attribute_clear (&test); \
+}
#endif /*CHECKATTRIBUTE_H_*/
Added: trunk/pk/tests/test-data/privkey-3.key
==============================================================================
Binary file. No diff available.
Modified: trunk/pk/tests/unit-test-pk-cert.c
==============================================================================
--- trunk/pk/tests/unit-test-pk-cert.c (original)
+++ trunk/pk/tests/unit-test-pk-cert.c Mon Jan 14 01:22:17 2008
@@ -82,8 +82,8 @@
certificate_1 = gkr_pk_cert_new (manager, 0, asn1);
CuAssert (cu, "gkr_pk_cert_new returned bad object", GKR_IS_PK_CERT (certificate_1));
- if (!g_file_get_contents ("test-data/privkey-1.crt", &data, &n_data, NULL))
- g_error ("couldn't read privkey-1.crt");
+ if (!g_file_get_contents ("test-data/privkey-1.key", &data, &n_data, NULL))
+ g_error ("couldn't read privkey-1.key");
res = gkr_pkix_der_read_private_key ((const guchar*)data, n_data, &sexp);
g_assert (res == GKR_PARSE_SUCCESS);
@@ -108,9 +108,15 @@
void unit_test_certificate_static (CuTest *cu)
{
- CHECK_BOOL_ATTRIBUTE (cu, certificate_1, CKA_TOKEN, CK_TRUE);
+ CHECK_DATE_ATTRIBUTE (cu, certificate_1, CKA_START_DATE, "2007-12-20");
+ CHECK_DATE_ATTRIBUTE (cu, certificate_1, CKA_END_DATE, "2008-01-19");
+ CHECK_BOOL_ATTRIBUTE (cu, certificate_1, CKA_TOKEN, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, certificate_1, CKA_MODIFIABLE, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, certificate_1, CKA_PRIVATE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, certificate_1, CKA_TRUSTED, CK_FALSE);
CHECK_ULONG_ATTRIBUTE (cu, certificate_1, CKA_CLASS, CKO_CERTIFICATE);
CHECK_ULONG_ATTRIBUTE (cu, certificate_1, CKA_CERTIFICATE_CATEGORY, 0);
+ CHECK_ULONG_ATTRIBUTE (cu, certificate_1, CKA_CERTIFICATE_TYPE, CKC_X_509);
}
void unit_test_certificate_related (CuTest *cu)
@@ -236,3 +242,85 @@
g_strstrip (result);
CuAssert (cu, "Returned invalid oid in purpose", g_str_equal (result, "some-purpose"));
}
+
+void unit_test_certificate_set_attribute (CuTest *cu)
+{
+ GkrPkObject *obj = GKR_PK_OBJECT (certificate_1);
+ CK_RV ret;
+
+ /* Should succeed if twe change class to itself */
+ ret = gkr_pk_object_set_ulong (obj, CKA_CLASS, CKO_CERTIFICATE);
+ CuAssert (cu, "Should allow setting readonly attribute to same value", ret == CKR_OK);
+
+ /* Shouldn't succeed if twe change class to different */
+ ret = gkr_pk_object_set_ulong (obj, CKA_CLASS, CKO_PRIVATE_KEY);
+ CuAssert (cu, "Shouldn't allow changing readonly attribute", ret == CKR_ATTRIBUTE_READ_ONLY);
+
+ /* Should return readonly when no setter exists on object */
+ ret = gkr_pk_object_set_ulong (obj, CKA_CERTIFICATE_TYPE, CKC_WTLS);
+ CuAssert (cu, "Shouldn't allow changing readonly attribute", ret == CKR_ATTRIBUTE_READ_ONLY);
+
+ /* Should return invalid when no getter or setter exists on object */
+ ret = gkr_pk_object_set_ulong (obj, CKA_PIXEL_X, 5);
+ CuAssert (cu, "Shouldn't allow changing readonly attribute", ret == CKR_ATTRIBUTE_TYPE_INVALID);
+
+ /* Should return value invalid when setting wrong type data */
+ ret = gkr_pk_object_set_ulong (obj, CKA_PRIVATE, 5);
+ CuAssert (cu, "Shouldn't allow changing readonly attribute", ret == CKR_ATTRIBUTE_VALUE_INVALID);
+}
+
+void unit_test_certificate_create (CuTest *cu)
+{
+ CK_ATTRIBUTE attr;
+ GkrPkObject *object;
+ GArray *attrs;
+ const guchar *raw;
+ gsize n_raw;
+ CK_RV ret;
+
+ attrs = gkr_pk_attributes_new ();
+
+ memset (&attr, 0, sizeof (attr));
+ attr.type = CKA_CLASS;
+ gkr_pk_attribute_set_ulong (&attr, CKO_CERTIFICATE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ /* Try to create as with a set of invalid attributes */
+ ret = gkr_pk_object_create (manager, attrs, &object);
+ CuAssert (cu, "Certificate creation succeeded wrongly", ret == CKR_TEMPLATE_INCOMPLETE);
+
+ gkr_pk_attributes_free (attrs);
+ attrs = gkr_pk_attributes_new ();
+
+ attr.type = CKA_TOKEN;
+ gkr_pk_attribute_set_boolean (&attr, CK_FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_LABEL;
+ gkr_pk_attribute_set_string (&attr, "A test label");
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_VALUE;
+ raw = gkr_pk_cert_get_raw (certificate_1, &n_raw);
+ gkr_pk_attribute_set_data (&attr, raw, n_raw);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_CLASS;
+ gkr_pk_attribute_set_ulong (&attr, CKO_CERTIFICATE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_CERTIFICATE_TYPE;
+ gkr_pk_attribute_set_ulong (&attr, CKC_X_509);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ /* Now try with a proper set of attributes */
+ ret = gkr_pk_object_create (manager, attrs, &object);
+ CuAssert (cu, "Certificate creation failed", ret == CKR_OK);
+ CuAssert (cu, "Returned invalid object", GKR_IS_PK_CERT (object));
+
+ gkr_pk_attributes_free (attrs);
+
+ /* Free the certificate */
+ g_object_unref (object);
+
+}
Added: trunk/pk/tests/unit-test-pk-key.c
==============================================================================
--- (empty file)
+++ trunk/pk/tests/unit-test-pk-key.c Mon Jan 14 01:22:17 2008
@@ -0,0 +1,379 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-pk-key.c: Test public and private keys
+
+ Copyright (C) 2007 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "config.h"
+
+#include "run-auto-test.h"
+
+#include "common/gkr-crypto.h"
+
+#include "pk/gkr-pk-index.h"
+#include "pk/gkr-pk-object.h"
+#include "pk/gkr-pk-object-manager.h"
+#include "pk/gkr-pk-pubkey.h"
+#include "pk/gkr-pk-privkey.h"
+
+#include "pkcs11/pkcs11.h"
+#include "pkcs11/pkcs11g.h"
+
+#include "pkix/gkr-pkix-der.h"
+
+#include <glib.h>
+#include <memory.h>
+#include <gcrypt.h>
+
+/*
+ * Each test looks like (on one line):
+ * void unit_test_xxxxx (CuTest* cu)
+ *
+ * Each setup looks like (on one line):
+ * void unit_setup_xxxxx (void)
+ *
+ * Each teardown looks like (on one line):
+ * void unit_teardown_xxxxx (void)
+ *
+ * Tests be run in the order specified here.
+ */
+
+static GkrPkObjectManager *manager = NULL;
+
+static GkrPkObject *privkey_1 = NULL;
+static GkrPkObject *privkey_3 = NULL;
+static GkrPkObject *pubkey_1 = NULL;
+
+void unit_setup_keys (void)
+{
+ gkr_crypto_setup ();
+
+ /* Our own object manager */
+ manager = gkr_pk_object_manager_instance_for_client (1232);
+}
+
+void unit_test_create_keys (CuTest* cu)
+{
+ GkrParseResult res;
+ gcry_sexp_t sexp;
+ gchar *data;
+ gsize n_data;
+
+ if (!g_file_get_contents ("test-data/privkey-1.key", &data, &n_data, NULL))
+ g_error ("couldn't read privkey-1.key");
+ res = gkr_pkix_der_read_private_key ((const guchar*)data, n_data, &sexp);
+ g_assert (res == GKR_PARSE_SUCCESS);
+
+ privkey_1 = gkr_pk_privkey_new (manager, 0, sexp);
+ g_assert (GKR_IS_PK_PRIVKEY (privkey_1));
+
+ /* Should automatically create a public key */
+ pubkey_1 = GKR_PK_OBJECT (gkr_pk_privkey_get_public (GKR_PK_PRIVKEY (privkey_1)));
+ if (!pubkey_1)
+ g_error ("couldn't get public key");
+
+ if (!g_file_get_contents ("test-data/privkey-3.key", &data, &n_data, NULL))
+ g_error ("couldn't read privkey-3.key");
+ res = gkr_pkix_der_read_private_key ((const guchar*)data, n_data, &sexp);
+ g_assert (res == GKR_PARSE_SUCCESS);
+
+ privkey_3 = gkr_pk_privkey_new (manager, 0, sexp);
+ g_assert (GKR_IS_PK_PRIVKEY (privkey_3));
+}
+
+#include "check-attribute.c"
+
+void unit_test_privkey_static (CuTest *cu)
+{
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_TOKEN, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_PRIVATE, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_DECRYPT, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_SENSITIVE, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_SIGN, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_SIGN_RECOVER, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_WRAP_WITH_TRUSTED, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_DERIVE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_EXTRACTABLE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_UNWRAP, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_GNOME_PURPOSE_SSH_AUTH, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_ALWAYS_SENSITIVE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_LOCAL, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_NEVER_EXTRACTABLE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, privkey_1, CKA_ALWAYS_AUTHENTICATE, CK_FALSE);
+
+ CHECK_ULONG_ATTRIBUTE (cu, privkey_1, CKA_CLASS, CKO_PRIVATE_KEY);
+ CHECK_ULONG_ATTRIBUTE (cu, privkey_1, CKA_KEY_TYPE, CKK_RSA);
+ CHECK_ULONG_ATTRIBUTE (cu, privkey_1, CKA_KEY_GEN_MECHANISM, CK_UNAVAILABLE_INFORMATION);
+}
+
+void unit_test_pubkey_static (CuTest *cu)
+{
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_TOKEN, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_PRIVATE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_ENCRYPT, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_SENSITIVE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_EXTRACTABLE, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_VERIFY, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_VERIFY_RECOVER, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_ALWAYS_AUTHENTICATE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_DERIVE, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_WRAP, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_WRAP_WITH_TRUSTED, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_TRUSTED, CK_FALSE);
+ CHECK_BOOL_ATTRIBUTE (cu, pubkey_1, CKA_LOCAL, CK_FALSE);
+
+ CHECK_ULONG_ATTRIBUTE (cu, pubkey_1, CKA_CLASS, CKO_PUBLIC_KEY);
+ CHECK_ULONG_ATTRIBUTE (cu, pubkey_1, CKA_KEY_TYPE, CKK_RSA);
+ CHECK_ULONG_ATTRIBUTE (cu, pubkey_1, CKA_MODULUS_BITS, 2048);
+}
+
+void unit_test_privkey_related (CuTest *cu)
+{
+ GkrPkObject *obj;
+ gkrconstunique keyid;
+ gkrconstunique pubid;
+
+ keyid = gkr_pk_privkey_get_keyid (GKR_PK_PRIVKEY (privkey_1));
+ CuAssert (cu, "No key id returned from private key", keyid != NULL);
+
+ obj = gkr_pk_object_manager_find_by_id (manager, GKR_TYPE_PK_PUBKEY, keyid);
+ CuAssert (cu, "No matching public key object found in manager", GKR_IS_PK_PUBKEY (obj));
+
+ pubid = gkr_pk_pubkey_get_keyid (GKR_PK_PUBKEY (obj));
+ CuAssert (cu, "No key id returned from public key", pubid != NULL);
+
+ CuAssert (cu, "private and public key ids do not match", gkr_unique_equals (keyid, pubid));
+}
+
+void unit_test_privkey_rsa_create (CuTest *cu)
+{
+ CK_ATTRIBUTE attr;
+ gcry_sexp_t skey;
+ gcry_mpi_t mpi;
+ GkrPkObject *object;
+ GArray *attrs;
+ CK_RV ret;
+
+ attrs = gkr_pk_attributes_new ();
+
+ memset (&attr, 0, sizeof (attr));
+ attr.type = CKA_CLASS;
+ gkr_pk_attribute_set_ulong (&attr, CKO_PRIVATE_KEY);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_KEY_TYPE;
+ gkr_pk_attribute_set_ulong (&attr, CKK_RSA);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_MODULUS;
+ if (gkr_pk_object_get_attribute (privkey_1, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_PUBLIC_EXPONENT;
+ if (gkr_pk_object_get_attribute (privkey_1, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ skey = gkr_pk_privkey_get_key (GKR_PK_PRIVKEY (privkey_1));
+ CuAssert (cu, "private key has no internal key", skey != NULL);
+
+ attr.type = CKA_PRIVATE_EXPONENT;
+ if (!gkr_crypto_sexp_extract_mpi (skey, &mpi, "private-key", "d", NULL))
+ g_assert (FALSE);
+ gkr_pk_attribute_set_mpi (&attr, mpi);
+ gcry_mpi_release (mpi);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_PRIME_1;
+ if (!gkr_crypto_sexp_extract_mpi (skey, &mpi, "private-key", "p", NULL))
+ g_assert (FALSE);
+ gkr_pk_attribute_set_mpi (&attr, mpi);
+ gcry_mpi_release (mpi);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_PRIME_2;
+ if (!gkr_crypto_sexp_extract_mpi (skey, &mpi, "private-key", "q", NULL))
+ g_assert (FALSE);
+ gkr_pk_attribute_set_mpi (&attr, mpi);
+ gcry_mpi_release (mpi);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ /* Now try with a proper set of attributes */
+ ret = gkr_pk_object_create (manager, attrs, &object);
+ CuAssert (cu, "Private key creation failed", ret == CKR_OK);
+ CuAssert (cu, "Returned invalid object", GKR_IS_PK_PRIVKEY (object));
+
+ gkr_pk_attributes_free (attrs);
+
+ /* Free the private key */
+ g_object_unref (object);
+}
+
+void unit_test_pubkey_rsa_create (CuTest *cu)
+{
+ CK_ATTRIBUTE attr;
+ GkrPkObject *object;
+ GArray *attrs;
+ CK_RV ret;
+
+ attrs = gkr_pk_attributes_new ();
+
+ memset (&attr, 0, sizeof (attr));
+ attr.type = CKA_CLASS;
+ gkr_pk_attribute_set_ulong (&attr, CKO_PUBLIC_KEY);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_KEY_TYPE;
+ gkr_pk_attribute_set_ulong (&attr, CKK_RSA);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_MODULUS;
+ if (gkr_pk_object_get_attribute (privkey_1, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_PUBLIC_EXPONENT;
+ if (gkr_pk_object_get_attribute (privkey_1, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ /* Now try with a proper set of attributes */
+ ret = gkr_pk_object_create (manager, attrs, &object);
+ CuAssert (cu, "Public key creation failed", ret == CKR_OK);
+ CuAssert (cu, "Returned invalid object", GKR_IS_PK_PUBKEY (object));
+
+ gkr_pk_attributes_free (attrs);
+
+ /* Free the private key */
+ g_object_unref (object);
+}
+
+void unit_test_privkey_dsa_create (CuTest *cu)
+{
+ CK_ATTRIBUTE attr;
+ gcry_sexp_t skey;
+ gcry_mpi_t mpi;
+ GkrPkObject *object;
+ GArray *attrs;
+ CK_RV ret;
+
+ attrs = gkr_pk_attributes_new ();
+
+ memset (&attr, 0, sizeof (attr));
+ attr.type = CKA_CLASS;
+ gkr_pk_attribute_set_ulong (&attr, CKO_PRIVATE_KEY);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_KEY_TYPE;
+ gkr_pk_attribute_set_ulong (&attr, CKK_DSA);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_PRIME;
+ if (gkr_pk_object_get_attribute (privkey_3, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_SUBPRIME;
+ if (gkr_pk_object_get_attribute (privkey_3, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_BASE;
+ if (gkr_pk_object_get_attribute (privkey_3, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ skey = gkr_pk_privkey_get_key (GKR_PK_PRIVKEY (privkey_3));
+ CuAssert (cu, "private key has no internal key", skey != NULL);
+
+ attr.type = CKA_VALUE;
+ if (!gkr_crypto_sexp_extract_mpi (skey, &mpi, "private-key", "x", NULL))
+ g_assert (FALSE);
+ gkr_pk_attribute_set_mpi (&attr, mpi);
+ gcry_mpi_release (mpi);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ /* Now try with a proper set of attributes */
+ ret = gkr_pk_object_create (manager, attrs, &object);
+ CuAssert (cu, "Private key creation failed", ret == CKR_OK);
+ CuAssert (cu, "Returned invalid object", GKR_IS_PK_PRIVKEY (object));
+
+ gkr_pk_attributes_free (attrs);
+
+ /* Free the private key */
+ g_object_unref (object);
+}
+
+void unit_test_pubkey_dsa_create (CuTest *cu)
+{
+ CK_ATTRIBUTE attr;
+ GkrPkObject *object;
+ GArray *attrs;
+ gcry_sexp_t skey;
+ gcry_mpi_t mpi;
+ CK_RV ret;
+
+ attrs = gkr_pk_attributes_new ();
+
+ memset (&attr, 0, sizeof (attr));
+ attr.type = CKA_CLASS;
+ gkr_pk_attribute_set_ulong (&attr, CKO_PUBLIC_KEY);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_KEY_TYPE;
+ gkr_pk_attribute_set_ulong (&attr, CKK_DSA);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_PRIME;
+ if (gkr_pk_object_get_attribute (privkey_3, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_SUBPRIME;
+ if (gkr_pk_object_get_attribute (privkey_3, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ attr.type = CKA_BASE;
+ if (gkr_pk_object_get_attribute (privkey_3, &attr) != CKR_OK)
+ g_assert (FALSE);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ skey = gkr_pk_privkey_get_key (GKR_PK_PRIVKEY (privkey_3));
+ CuAssert (cu, "private key has no internal key", skey != NULL);
+
+ attr.type = CKA_VALUE;
+ if (!gkr_crypto_sexp_extract_mpi (skey, &mpi, "private-key", "y", NULL))
+ g_assert (FALSE);
+ gkr_pk_attribute_set_mpi (&attr, mpi);
+ gcry_mpi_release (mpi);
+ gkr_pk_attributes_append (attrs, &attr);
+
+ /* Now try with a proper set of attributes */
+ ret = gkr_pk_object_create (manager, attrs, &object);
+ CuAssert (cu, "Public key creation failed", ret == CKR_OK);
+ CuAssert (cu, "Returned invalid object", GKR_IS_PK_PUBKEY (object));
+
+ gkr_pk_attributes_free (attrs);
+
+ /* Free the private key */
+ g_object_unref (object);
+}
Modified: trunk/pk/tests/unit-test-pk-netscape-trust.c
==============================================================================
--- trunk/pk/tests/unit-test-pk-netscape-trust.c (original)
+++ trunk/pk/tests/unit-test-pk-netscape-trust.c Mon Jan 14 01:22:17 2008
@@ -1,5 +1,5 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* unit-test-pk-cert.c: Test a certificate
+/* unit-test-pk-netscape-trust.c: Test a netscape trust object
Copyright (C) 2007 Stefan Walter
@@ -109,7 +109,7 @@
void unit_test_trust_static (CuTest *cu)
{
- CHECK_BOOL_ATTRIBUTE (cu, trust_1, CKA_TOKEN, CK_TRUE);
+ CHECK_BOOL_ATTRIBUTE (cu, trust_1, CKA_TOKEN, CK_FALSE);
CHECK_BOOL_ATTRIBUTE (cu, trust_1, CKA_TRUST_STEP_UP_APPROVED, CK_FALSE);
CHECK_ULONG_ATTRIBUTE (cu, trust_1, CKA_CLASS, CKO_NETSCAPE_TRUST);
}
Modified: trunk/pkcs11/gkr-pkcs11-calls.h
==============================================================================
--- trunk/pkcs11/gkr-pkcs11-calls.h (original)
+++ trunk/pkcs11/gkr-pkcs11-calls.h Mon Jan 14 01:22:17 2008
@@ -108,7 +108,7 @@
{ PKCS11_CALL_C_DestroyObject, "C_DestroyObject", "u", "" },
{ PKCS11_CALL_C_GetObjectSize, "C_GetObjectSize", "u", "u" },
{ PKCS11_CALL_C_GetAttributeValue, "C_GetAttributeValue", "uaA", "aAu" },
- { PKCS11_CALL_C_SetAttributeValue, "C_SetAttributeValue", "u", "aA" },
+ { PKCS11_CALL_C_SetAttributeValue, "C_SetAttributeValue", "uaA", "" },
{ PKCS11_CALL_C_FindObjectsInit, "C_FindObjectsInit", "aA", "" },
{ PKCS11_CALL_C_FindObjects, "C_FindObjects", "u", "au" },
{ PKCS11_CALL_C_FindObjectsFinal, "C_FindObjectsFinal", "", "" },
Modified: trunk/pkcs11/gkr-pkcs11-daemon-session.c
==============================================================================
--- trunk/pkcs11/gkr-pkcs11-daemon-session.c (original)
+++ trunk/pkcs11/gkr-pkcs11-daemon-session.c Mon Jan 14 01:22:17 2008
@@ -37,6 +37,7 @@
#include "pk/gkr-pk-object.h"
#include "pk/gkr-pk-object-manager.h"
+#include "pk/gkr-pk-object-storage.h"
#include "pk/gkr-pk-util.h"
#include <stdlib.h>
@@ -85,16 +86,16 @@
*/
static void
-session_take_object (SessionInfo *sinfo, GkrPkObject *object)
+session_add_object (SessionInfo *sinfo, GkrPkObject *object)
{
g_assert (sinfo);
- g_return_if_fail (object->handle == 0);
+ g_return_if_fail (object->handle != 0);
g_return_if_fail (object->location == 0);
g_return_if_fail (object->manager == sinfo->manager);
/* We assume the ownership */
- g_assert (object->handle);
+ g_object_ref (object);
g_hash_table_insert (sinfo->objects, GUINT_TO_POINTER (object->handle), object);
}
@@ -427,31 +428,19 @@
* OBJECT OPERATIONS
*/
-static CK_RV
-create_key_object (GkrPkObjectManager *manager, GArray *attrs, GkrPkObject **key)
-{
- CK_KEY_TYPE type;
-
- if (!gkr_pk_attributes_ulong (attrs, CKA_KEY_TYPE, &type))
- return CKR_TEMPLATE_INCOMPLETE;
-
- switch (type) {
- /* TODO: Support RSA key creation */
- case CKK_DSA:
- return gkr_pkcs11_dsa_create_key (manager, attrs, key);
- default:
- return CKR_ATTRIBUTE_VALUE_INVALID;
- };
-}
-
static CK_RV
session_C_CreateObject (SessionInfo *sinfo, GkrPkcs11Message *req,
GkrPkcs11Message *resp)
{
+ GkrPkObjectManager *manager;
+ CK_ATTRIBUTE_PTR attr;
+ CK_OBJECT_CLASS cls;
GkrPkObject *object;
GArray *attrs = NULL;
- CK_OBJECT_CLASS cls;
CK_BBOOL token;
+ GError *err = NULL;
+ gboolean res;
+ guint i;
CK_RV ret;
if (sinfo->operation_type)
@@ -463,7 +452,7 @@
if (!gkr_pk_attributes_ulong (attrs, CKA_CLASS, &cls)) {
ret = CKR_TEMPLATE_INCOMPLETE;
goto done;
- }
+ }
/* Can only create public objects unless logged in */
if (!gkr_keyring_login_is_unlocked () && gkc_pk_class_is_private (cls)) {
@@ -471,43 +460,57 @@
goto done;
}
- /*
- * Can only create session objects
- * TODO: Support token objects.
- * TODO: Take readonly session into account, once we support
- * token objects. CKR_SESSION_READ_ONLY
- */
- if (gkr_pk_attributes_boolean (attrs, CKA_TOKEN, &token) && token) {
- ret = CKR_TOKEN_WRITE_PROTECTED;
- goto done;
+ /* Find out if its a token object or not */
+ token = CK_FALSE;
+ for (i = 0; i < attrs->len; ++i) {
+ attr = &(g_array_index (attrs, CK_ATTRIBUTE, i));
+ if (attr->type == CKA_TOKEN) {
+ if (attr && attr->pValue && attr->ulValueLen == sizeof (CK_BBOOL))
+ token = *((CK_BBOOL*)attr->pValue);
+
+ /* Mark that attribute as used */
+ gkr_pk_attribute_consume (attr);
+ break;
+ }
}
- switch (cls) {
- case CKO_PUBLIC_KEY:
- case CKO_PRIVATE_KEY:
- ret = create_key_object (sinfo->manager, attrs, &object);
- break;
- default:
- /* TODO: What's a better error code here? */
- ret = CKR_FUNCTION_NOT_SUPPORTED;
- break;
- };
+ /* A readonly session cannot create token objects */
+ if (token && sinfo->readonly) {
+ ret = CKR_SESSION_READ_ONLY;
+ goto done;
+ }
- if (ret == CKR_OK) {
+ /* Create the object with the right object manager */
+ manager = token ? gkr_pk_object_manager_for_token () : sinfo->manager;
+ ret = gkr_pk_object_create (manager, attrs, &object);
+
+ if (ret != CKR_OK)
+ goto done;
- g_return_val_if_fail (object, CKR_GENERAL_ERROR);
-
- /*
- * Store it appropriately.
- * TODO: Eventually we will store and write to the token
- * storage here, but for now just the session.
- */
+ g_return_val_if_fail (object, CKR_GENERAL_ERROR);
- session_take_object (sinfo, object);
- gkr_pkcs11_message_write_uint32 (resp, object->handle);
+ /* Token objects get stored in the main object storage */
+ if (token) {
+ g_return_val_if_fail (object->storage != NULL, CKR_GENERAL_ERROR);
+ res = gkr_pk_object_storage_add (gkr_pk_object_storage_get (), object, &err);
+ if (!res) {
+ g_warning ("couldn't write created object to disk: %s",
+ err && err->message ? err->message : "");
+ g_clear_error (&err);
+ ret = CKR_GENERAL_ERROR;
+ goto done;
+ }
+
+ /* Session objects are owned by the session */
+ } else {
+ session_add_object (sinfo, object);
}
+
+ gkr_pkcs11_message_write_uint32 (resp, object->handle);
+ ret = CKR_OK;
done:
+ g_object_unref (object);
gkr_pk_attributes_free (attrs);
return ret;
}
@@ -527,11 +530,65 @@
session_C_DestroyObject (SessionInfo *sinfo, GkrPkcs11Message *req,
GkrPkcs11Message *resp)
{
- /*
- * TODO: We need to implement this, initially perhaps only
- * only for session objects.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
+ CK_OBJECT_HANDLE obj;
+ GkrPkObjectManager *manager;
+ GkrPkObject *object;
+ CK_RV ret = CKR_OK;
+ gboolean res;
+ GError *err = NULL;
+ CK_BBOOL priv;
+
+ if (gkr_pkcs11_message_read_uint32 (req, &obj) != CKR_OK)
+ return PROTOCOL_ERROR;
+
+ /* Find the object in question */
+ if (obj & GKR_PK_OBJECT_IS_PERMANENT)
+ manager = gkr_pk_object_manager_for_token ();
+ else
+ manager = sinfo->manager;
+
+ object = gkr_pk_object_manager_lookup (manager, obj);
+ if (!object)
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ /* We can only destroy public objects unless logged in */
+ if (!gkr_keyring_login_is_unlocked ()) {
+ ret = gkr_pk_object_get_bool (object, CKA_PRIVATE, &priv);
+ g_return_val_if_fail (ret == CKR_OK, CKR_GENERAL_ERROR);
+
+ if (priv)
+ return CKR_USER_NOT_LOGGED_IN;
+ }
+
+ /* A token object */
+ if (obj & GKR_PK_OBJECT_IS_PERMANENT) {
+
+ /* A readonly session cannot destroy token objects */
+ if (sinfo->readonly)
+ return CKR_SESSION_READ_ONLY;
+
+ g_return_val_if_fail (object->storage, CKR_GENERAL_ERROR);
+ res = gkr_pk_object_storage_remove (object->storage, object, &err);
+ if (!res) {
+ g_warning ("couldn't remove object from disk: %s",
+ err && err->message ? err->message : "");
+ g_clear_error (&err);
+ ret = CKR_GENERAL_ERROR;
+ }
+
+ /* A session object */
+ } else {
+ /*
+ * TODO: This just hides the object, does not destroy.
+ * The problem is that we need to locate the actual
+ * session where this is owned, which we currently
+ * don't track.
+ */
+ gkr_pk_object_manager_unregister (manager, object);
+ ret = CKR_OK;
+ }
+
+ return ret;
}
static CK_RV
@@ -539,7 +596,7 @@
GkrPkcs11Message *resp)
{
/* TODO: We need to implement this */
- return CKR_OBJECT_HANDLE_INVALID;
+ return CKR_FUNCTION_NOT_SUPPORTED;
}
static CK_RV
@@ -588,8 +645,21 @@
session_C_SetAttributeValue (SessionInfo *sinfo, GkrPkcs11Message *req,
GkrPkcs11Message *resp)
{
- /* TODO: We need to implement this */
- return CKR_FUNCTION_NOT_SUPPORTED;
+ GkrPkObject *object;
+ GArray* attrs;
+ CK_RV ret;
+
+ ret = read_object (req, sinfo, &object);
+ if (ret != CKR_OK)
+ return ret;
+
+ if (!(attrs = read_attribute_array (req)))
+ return PROTOCOL_ERROR;
+
+ ret = gkr_pk_object_set_attributes (object, attrs);
+ gkr_pk_attributes_free (attrs);
+
+ return ret;
}
static void
Modified: trunk/pkcs11/gkr-pkcs11-dsa.c
==============================================================================
--- trunk/pkcs11/gkr-pkcs11-dsa.c (original)
+++ trunk/pkcs11/gkr-pkcs11-dsa.c Mon Jan 14 01:22:17 2008
@@ -188,84 +188,3 @@
return CKR_OK;
}
-
-CK_RV
-gkr_pkcs11_dsa_create_key (GkrPkObjectManager *mgr, const GArray* attrs, GkrPkObject **key)
-{
- CK_OBJECT_CLASS cls;
- gcry_sexp_t skey;
- gcry_error_t gcry;
- gcry_mpi_t p = NULL;
- gcry_mpi_t q = NULL;
- gcry_mpi_t g = NULL;
- gcry_mpi_t value = NULL;
- gcry_mpi_t y = NULL;
- gboolean priv;
- CK_RV ret;
-
- g_return_val_if_fail (attrs, CKR_GENERAL_ERROR);
- g_return_val_if_fail (key, CKR_GENERAL_ERROR);
-
- /* Figure out if it's public or private */
- if (!gkr_pk_attributes_ulong (attrs, CKA_CLASS, &cls)) {
- ret = CKR_TEMPLATE_INCOMPLETE;
- goto done;
- }
- if (cls == CKO_PRIVATE_KEY)
- priv = TRUE;
- else if (cls == CKO_PUBLIC_KEY)
- priv = FALSE;
- else {
- ret = CKR_ATTRIBUTE_VALUE_INVALID;
- goto done;
- }
-
- if (!gkr_pk_attributes_mpi (attrs, CKA_PRIME, &p) ||
- !gkr_pk_attributes_mpi (attrs, CKA_SUBPRIME, &q) ||
- !gkr_pk_attributes_mpi (attrs, CKA_BASE, &g) ||
- !gkr_pk_attributes_mpi (attrs, CKA_VALUE, &value)) {
- ret = CKR_TEMPLATE_INCOMPLETE;
- goto done;
- }
-
- /* Create a private key */
- if (priv) {
-
- /* Calculate the public part from the private */
- y = gcry_mpi_snew (gcry_mpi_get_nbits (value));
- gcry_mpi_powm (y, g, value, p);
-
- gcry = gcry_sexp_build (&skey, NULL, "(private-key (dsa (p %m) (q %m) (g %m) (y %m) (x %m)))",
- p, q, g, value);
-
- /* Create a public key */
- } else {
-
- gcry = gcry_sexp_build (&skey, NULL, "(public-key (dsa (p %m) (q %m) (g %m) (y %m)))",
- p, q, g, value);
- }
-
- /* TODO: We should be mapping better return codes */
- if (gcry != 0) {
- g_message ("couldn't create DSA key from passed attributes");
- ret = CKR_GENERAL_ERROR;
- goto done;
- }
-
- if (priv)
- *key = gkr_pk_privkey_new (mgr, 0, skey);
- else
- *key = gkr_pk_pubkey_new (mgr, 0, skey);
-
- /* TODO: We should verify remainder of attributes */
- ret = CKR_OK;
-
-done:
- gcry_mpi_release (p);
- gcry_mpi_release (q);
- gcry_mpi_release (g);
- gcry_mpi_release (y);
- gcry_mpi_release (value);
-
- return CKR_OK;
-}
Modified: trunk/pkcs11/gkr-pkcs11-module.c
==============================================================================
--- trunk/pkcs11/gkr-pkcs11-module.c (original)
+++ trunk/pkcs11/gkr-pkcs11-module.c Mon Jan 14 01:22:17 2008
@@ -1946,8 +1946,8 @@
{
BEGIN_CALL (session, C_SetAttributeValue);
IN_HANDLE (object);
- PROCESS_CALL;
IN_ATTRIBUTE_ARRAY (template, count);
+ PROCESS_CALL;
END_CALL;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]