void* gkm_object_get_attribute_data (GkmObject *self, GkmSession *session, CK_ATTRIBUTE_TYPE type, gsize *n_data) { CK_ATTRIBUTE attr; g_return_val_if_fail (GKM_IS_OBJECT (self), NULL); g_return_val_if_fail (n_data, NULL); attr.type = type; attr.ulValueLen = 0; attr.pValue = NULL; if (gkm_object_get_attribute (self, session, &attr) != CKR_OK) return NULL; if (attr.ulValueLen == 0) attr.ulValueLen = 1; attr.pValue = g_malloc0 (attr.ulValueLen); if (gkm_object_get_attribute (self, session, &attr) != CKR_OK) { g_free (attr.pValue); return NULL; } *n_data = attr.ulValueLen; return attr.pValue; }
gboolean gkm_object_match (GkmObject *self, GkmSession *session, CK_ATTRIBUTE_PTR match) { CK_ATTRIBUTE attr; gboolean matched = FALSE; CK_RV rv; g_return_val_if_fail (GKM_IS_OBJECT (self), FALSE); if (!match->pValue) return FALSE; attr.type = match->type; attr.pValue = g_malloc0 (match->ulValueLen > 4 ? match->ulValueLen : 4); attr.ulValueLen = match->ulValueLen; matched = FALSE; rv = gkm_object_get_attribute (self, session, &attr); matched = (rv == CKR_OK) && (match->ulValueLen == attr.ulValueLen) && (memcmp (match->pValue, attr.pValue, attr.ulValueLen) == 0); g_free (attr.pValue); return matched; }
static CK_RV gkm_certificate_key_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr) { GkmCertificateKey *self = GKM_CERTIFICATE_KEY (base); switch (attr->type) { case CKA_LABEL: if (self->pv->certificate) return gkm_object_get_attribute (GKM_OBJECT (self->pv->certificate), session, attr); return gkm_attribute_set_string (attr, ""); } return GKM_OBJECT_CLASS (gkm_certificate_key_parent_class)->get_attribute (base, session, attr); }
static CK_RV retrieve_length (GkmSession *session, GkmObject *wrapped, gsize *length) { CK_ATTRIBUTE attr; CK_RV rv; attr.type = CKA_VALUE; attr.pValue = NULL; attr.ulValueLen = 0; rv = gkm_object_get_attribute (wrapped, session, &attr); if (rv == CKR_OK) *length = attr.ulValueLen; return rv; }
static void gkm_object_real_set_attribute (GkmObject *self, GkmSession *session, GkmTransaction* transaction, CK_ATTRIBUTE* attr) { CK_ATTRIBUTE check; CK_RV rv; switch (attr->type) { case CKA_TOKEN: case CKA_PRIVATE: case CKA_MODIFIABLE: case CKA_CLASS: gkm_transaction_fail (transaction, CKR_ATTRIBUTE_READ_ONLY); return; case CKA_MATE_UNIQUE: gkm_transaction_fail (transaction, self->pv->unique ? CKR_ATTRIBUTE_READ_ONLY : CKR_ATTRIBUTE_TYPE_INVALID); return; }; /* Give store a shot */ if (self->pv->store) { gkm_store_set_attribute (self->pv->store, transaction, self, attr); return; } /* Now some more defaults */ switch (attr->type) { case CKA_LABEL: gkm_transaction_fail (transaction, CKR_ATTRIBUTE_READ_ONLY); return; } /* Check if this attribute exists */ check.type = attr->type; check.pValue = 0; check.ulValueLen = 0; rv = gkm_object_get_attribute (self, session, &check); if (rv == CKR_ATTRIBUTE_TYPE_INVALID) gkm_transaction_fail (transaction, CKR_ATTRIBUTE_TYPE_INVALID); else gkm_transaction_fail (transaction, CKR_ATTRIBUTE_READ_ONLY); }
gboolean gkm_object_get_attribute_ulong (GkmObject *self, GkmSession *session, CK_ATTRIBUTE_TYPE type, gulong *value) { CK_ATTRIBUTE attr; CK_ULONG uvalue; g_return_val_if_fail (GKM_IS_OBJECT (self), FALSE); g_return_val_if_fail (value, FALSE); attr.type = type; attr.ulValueLen = sizeof (CK_ULONG); attr.pValue = &uvalue; if (gkm_object_get_attribute (self, session, &attr) != CKR_OK) return FALSE; *value = uvalue; return TRUE; }
gboolean gkm_object_get_attribute_boolean (GkmObject *self, GkmSession *session, CK_ATTRIBUTE_TYPE type, gboolean *value) { CK_ATTRIBUTE attr; CK_BBOOL bvalue; g_return_val_if_fail (GKM_IS_OBJECT (self), FALSE); g_return_val_if_fail (value, FALSE); attr.type = type; attr.ulValueLen = sizeof (CK_BBOOL); attr.pValue = &bvalue; if (gkm_object_get_attribute (self, session, &attr) != CKR_OK) return FALSE; *value = (bvalue == CK_TRUE) ? TRUE : FALSE; return TRUE; }
static CK_RV retrieve_value (GkmSession *session, GkmObject *wrapped, gpointer *value, gsize *n_value) { CK_ATTRIBUTE attr; CK_RV rv; rv = retrieve_length (session, wrapped, n_value); if (rv != CKR_OK) return rv; attr.type = CKA_VALUE; attr.pValue = egg_secure_alloc (*n_value); attr.ulValueLen = *n_value; rv = gkm_object_get_attribute (wrapped, session, &attr); if (rv == CKR_OK) *value = attr.pValue; else egg_secure_free (attr.pValue); return rv; }
static CK_RV gkm_certificate_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE* attr) { GkmCertificate *self = GKM_CERTIFICATE (base); CK_ULONG category; const guchar *cdata; guchar *data; gsize n_data; time_t when; CK_RV rv; switch (attr->type) { case CKA_CLASS: return gkm_attribute_set_ulong (attr, CKO_CERTIFICATE); case CKA_PRIVATE: return gkm_attribute_set_bool (attr, FALSE); case CKA_LABEL: return gkm_attribute_set_string (attr, gkm_certificate_get_label (self)); case CKA_CERTIFICATE_TYPE: return gkm_attribute_set_ulong (attr, CKC_X_509); case CKA_TRUSTED: return gkm_attribute_set_bool (attr, FALSE); case CKA_CERTIFICATE_CATEGORY: if (!gkm_certificate_calc_category (self, session, &category)) return CKR_FUNCTION_FAILED; return gkm_attribute_set_ulong (attr, category); case CKA_CHECK_VALUE: g_return_val_if_fail (self->pv->data, CKR_GENERAL_ERROR); n_data = gcry_md_get_algo_dlen (GCRY_MD_SHA1); g_return_val_if_fail (n_data && n_data > 3, CKR_GENERAL_ERROR); data = g_new0 (guchar, n_data); gcry_md_hash_buffer (GCRY_MD_SHA1, data, self->pv->data, self->pv->n_data); rv = gkm_attribute_set_data (attr, data, 3); g_free (data); return rv; case CKA_START_DATE: case CKA_END_DATE: g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR); when = egg_asn1x_get_time_as_long (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "validity", attr->type == CKA_START_DATE ? "notBefore" : "notAfter", NULL)); if (when < 0) return CKR_FUNCTION_FAILED; return gkm_attribute_set_date (attr, when); case CKA_SUBJECT: g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR); cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "subject", NULL), &n_data); g_return_val_if_fail (cdata, CKR_GENERAL_ERROR); return gkm_attribute_set_data (attr, cdata, n_data); case CKA_ID: if (!self->pv->key) return gkm_attribute_set_data (attr, NULL, 0); return gkm_object_get_attribute (GKM_OBJECT (self->pv->key), session, attr); case CKA_ISSUER: g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR); cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "issuer", NULL), &n_data); g_return_val_if_fail (cdata, CKR_GENERAL_ERROR); return gkm_attribute_set_data (attr, cdata, n_data); case CKA_SERIAL_NUMBER: g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR); cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "serialNumber", NULL), &n_data); g_return_val_if_fail (cdata, CKR_GENERAL_ERROR); return gkm_attribute_set_data (attr, cdata, n_data); case CKA_VALUE: g_return_val_if_fail (self->pv->data, CKR_GENERAL_ERROR); return gkm_attribute_set_data (attr, self->pv->data, self->pv->n_data); /* These are only used for strange online certificates which we don't support */ case CKA_URL: case CKA_HASH_OF_SUBJECT_PUBLIC_KEY: case CKA_HASH_OF_ISSUER_PUBLIC_KEY: return gkm_attribute_set_data (attr, "", 0); /* What in the world is this doing in the spec? */ case CKA_JAVA_MIDP_SECURITY_DOMAIN: return gkm_attribute_set_ulong (attr, 0); /* 0 = unspecified */ }; return GKM_OBJECT_CLASS (gkm_certificate_parent_class)->get_attribute (base, session, attr); }