static CK_RV gkm_generic_key_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE *attr) { GkmGenericKey *self = GKM_GENERIC_KEY (base); switch (attr->type) { case CKA_KEY_TYPE: return gkm_attribute_set_ulong (attr, CKK_GENERIC_SECRET); case CKA_DERIVE: return gkm_attribute_set_bool (attr, CK_TRUE); case CKA_UNWRAP: case CKA_WRAP: return gkm_attribute_set_bool (attr, CK_FALSE); case CKA_VALUE: return gkm_attribute_set_data (attr, self->value, self->n_value); case CKA_VALUE_LEN: return gkm_attribute_set_ulong (attr, self->n_value); case CKA_CHECK_VALUE: return attribute_set_check_value (self, attr); case CKA_ALLOWED_MECHANISMS: return gkm_attribute_set_data (attr, (CK_VOID_PTR)GKM_GENERIC_MECHANISMS, sizeof (GKM_GENERIC_MECHANISMS)); }; return GKM_OBJECT_CLASS (gkm_generic_key_parent_class)->get_attribute (base, session, attr); }
static CK_RV gkm_null_key_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE *attr) { switch (attr->type) { case CKA_KEY_TYPE: return gkm_attribute_set_ulong (attr, CKK_G_NULL); case CKA_UNWRAP: case CKA_WRAP: return gkm_attribute_set_bool (attr, CK_TRUE); case CKA_VALUE: return gkm_attribute_set_empty (attr); case CKA_VALUE_LEN: return gkm_attribute_set_ulong (attr, 0); case CKA_CHECK_VALUE: return gkm_attribute_set_data (attr, "\0\0\0", 3); case CKA_ALLOWED_MECHANISMS: return gkm_attribute_set_data (attr, (CK_VOID_PTR)GKM_NULL_MECHANISMS, sizeof (GKM_NULL_MECHANISMS)); }; return GKM_OBJECT_CLASS (gkm_null_key_parent_class)->get_attribute (base, session, attr); }
static CK_RV trust_get_integer (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr) { GNode *node; gpointer integer; gsize n_integer; CK_RV rv; g_assert (GKM_XDG_IS_TRUST (self)); node = egg_asn1x_node (self->pv->asn, "reference", "certReference", part, NULL); g_return_val_if_fail (node, CKR_GENERAL_ERROR); /* If the assertion doesn't contain this info ... */ if (!egg_asn1x_have (node)) return CKR_ATTRIBUTE_TYPE_INVALID; integer = egg_asn1x_get_integer_as_raw (node, NULL, &n_integer); g_return_val_if_fail (integer, CKR_GENERAL_ERROR); rv = gkm_attribute_set_data (attr, integer, n_integer); g_free (integer); return rv; }
static CK_RV gkm_credential_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE *attr) { GkmCredential *self = GKM_CREDENTIAL (base); CK_OBJECT_HANDLE handle; gconstpointer value; gsize n_value; switch (attr->type) { case CKA_CLASS: return gkm_attribute_set_ulong (attr, CKO_G_CREDENTIAL); case CKA_PRIVATE: return gkm_attribute_set_bool (attr, TRUE); case CKA_G_OBJECT: handle = self->pv->object ? gkm_object_get_handle (self->pv->object) : 0; return gkm_attribute_set_ulong (attr, handle); case CKA_VALUE: if (gkm_session_is_for_application (session)) return CKR_ATTRIBUTE_SENSITIVE; if (!self->pv->secret) { value = NULL; n_value = 0; } else { value = gkm_secret_get (self->pv->secret, &n_value); } return gkm_attribute_set_data (attr, value, n_value); }; return GKM_OBJECT_CLASS (gkm_credential_parent_class)->get_attribute (base, session, attr); }
static CK_RV gkm_secret_item_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr) { GkmSecretItem *self = GKM_SECRET_ITEM (base); GkmSecretData *sdata; const gchar *identifier; const guchar *secret; gsize n_secret = 0; CK_RV rv; g_return_val_if_fail (self->collection, CKR_GENERAL_ERROR); switch (attr->type) { case CKA_CLASS: return gkm_attribute_set_ulong (attr, CKO_SECRET_KEY); case CKA_VALUE: sdata = gkm_secret_collection_unlocked_use (self->collection, session); if (sdata == NULL) return CKR_USER_NOT_LOGGED_IN; identifier = gkm_secret_object_get_identifier (GKM_SECRET_OBJECT (self)); secret = gkm_secret_data_get_raw (sdata, identifier, &n_secret); rv = gkm_attribute_set_data (attr, secret, n_secret); gkm_object_mark_used (base); g_object_unref (sdata); return rv; case CKA_G_COLLECTION: g_return_val_if_fail (self->collection, CKR_GENERAL_ERROR); identifier = gkm_secret_object_get_identifier (GKM_SECRET_OBJECT (self->collection)); return gkm_attribute_set_string (attr, identifier); case CKA_G_FIELDS: if (!self->fields) return gkm_attribute_set_data (attr, NULL, 0); return gkm_secret_fields_serialize (attr, self->fields, self->schema); case CKA_G_SCHEMA: return gkm_attribute_set_string (attr, self->schema); } return GKM_OBJECT_CLASS (gkm_secret_item_parent_class)->get_attribute (base, session, attr); }
static CK_RV gkm_secret_key_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE* attr) { GkmSecretKey *self = GKM_SECRET_KEY (base); switch (attr->type) { case CKA_CLASS: return gkm_attribute_set_ulong (attr, CKO_SECRET_KEY); case CKA_SENSITIVE: case CKA_ENCRYPT: case CKA_DECRYPT: case CKA_SIGN: case CKA_VERIFY: case CKA_WRAP: case CKA_UNWRAP: case CKA_DERIVE: return gkm_attribute_set_bool (attr, FALSE); case CKA_EXTRACTABLE: return gkm_attribute_set_bool (attr, TRUE); case CKA_ALWAYS_SENSITIVE: return gkm_attribute_set_bool (attr, FALSE); case CKA_NEVER_EXTRACTABLE: return gkm_attribute_set_bool (attr, FALSE); case CKA_WRAP_WITH_TRUSTED: return gkm_attribute_set_bool (attr, FALSE); case CKA_TRUSTED: return gkm_attribute_set_bool (attr, FALSE); case CKA_WRAP_TEMPLATE: case CKA_UNWRAP_TEMPLATE: return CKR_ATTRIBUTE_TYPE_INVALID; case CKA_START_DATE: case CKA_END_DATE: return gkm_attribute_set_empty (attr); case CKA_LOCAL: return gkm_attribute_set_bool (attr, FALSE); case CKA_ID: return gkm_attribute_set_data (attr, self->pv->id, self->pv->n_id); case CKA_KEY_GEN_MECHANISM: return gkm_attribute_set_ulong (attr, CK_UNAVAILABLE_INFORMATION); }; return GKM_OBJECT_CLASS (gkm_secret_key_parent_class)->get_attribute (base, session, attr); }
static CK_RV gkm_dh_key_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE* attr) { GkmDhKey *self = GKM_DH_KEY (base); switch (attr->type) { case CKA_KEY_TYPE: return gkm_attribute_set_ulong (attr, CKK_DH); case CKA_START_DATE: case CKA_END_DATE: return gkm_attribute_set_empty (attr); case CKA_LOCAL: return gkm_attribute_set_bool (attr, FALSE); case CKA_KEY_GEN_MECHANISM: return gkm_attribute_set_ulong (attr, CK_UNAVAILABLE_INFORMATION); case CKA_ALLOWED_MECHANISMS: return gkm_attribute_set_data (attr, (CK_VOID_PTR)GKM_DH_MECHANISMS, sizeof (GKM_DH_MECHANISMS)); case CKA_ID: return gkm_attribute_set_data (attr, self->pv->id, self->pv->n_id); case CKA_SUBJECT: return gkm_attribute_set_empty (attr); case CKA_PRIME: return gkm_attribute_set_mpi (attr, self->pv->prime); case CKA_BASE: return gkm_attribute_set_mpi (attr, self->pv->base); }; return GKM_OBJECT_CLASS (gkm_dh_key_parent_class)->get_attribute (base, session, attr); }
static CK_RV gkm_object_real_get_attribute (GkmObject *self, GkmSession *session, CK_ATTRIBUTE* attr) { CK_OBJECT_HANDLE handle = 0; CK_RV rv; switch (attr->type) { case CKA_CLASS: g_warning ("Derived class should have overridden CKA_CLASS"); return CKR_GENERAL_ERROR; case CKA_MODIFIABLE: return gkm_attribute_set_bool (attr, self->pv->store ? TRUE : FALSE); case CKA_PRIVATE: return gkm_attribute_set_bool (attr, FALSE); case CKA_TOKEN: return gkm_attribute_set_bool (attr, gkm_object_is_token (self)); case CKA_G_CREDENTIAL: gkm_credential_for_each (session, GKM_OBJECT (self), find_credential, &handle); return gkm_attribute_set_ulong (attr, handle); case CKA_MATE_UNIQUE: if (self->pv->unique) return gkm_attribute_set_string (attr, self->pv->unique); return CKR_ATTRIBUTE_TYPE_INVALID; case CKA_MATE_TRANSIENT: return gkm_attribute_set_bool (attr, self->pv->transient ? TRUE : FALSE); case CKA_G_DESTRUCT_AFTER: return gkm_attribute_set_ulong (attr, self->pv->transient ? self->pv->transient->timed_after : 0); case CKA_G_DESTRUCT_IDLE: return gkm_attribute_set_ulong (attr, self->pv->transient ? self->pv->transient->timed_idle : 0); case CKA_G_DESTRUCT_USES: return gkm_attribute_set_ulong (attr, self->pv->transient ? self->pv->transient->uses_remaining : 0); }; /* Give store a shot */ if (self->pv->store) { rv = gkm_store_get_attribute (self->pv->store, self, attr); if (rv != CKR_ATTRIBUTE_TYPE_INVALID) return rv; } /* Now some more defaults */ switch (attr->type) { case CKA_LABEL: return gkm_attribute_set_data (attr, "", 0); } return CKR_ATTRIBUTE_TYPE_INVALID; }
static CK_RV trust_get_complete (GkmXdgTrust *self, CK_ATTRIBUTE_PTR attr) { GNode *cert; gconstpointer element; gsize n_element; cert = egg_asn1x_node (self->pv->asn, "reference", "certComplete", NULL); g_return_val_if_fail (cert, CKR_GENERAL_ERROR); /* If it's not stored, then this attribute is not present */ if (!egg_asn1x_have (cert)) return CKR_ATTRIBUTE_TYPE_INVALID; element = egg_asn1x_get_raw_element (cert, &n_element); g_return_val_if_fail (element, CKR_GENERAL_ERROR); return gkm_attribute_set_data (attr, element, n_element); }
static CK_RV trust_get_der (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr) { GNode *node; gconstpointer element; gsize n_element; g_assert (GKM_XDG_IS_TRUST (self)); node = egg_asn1x_node (self->pv->asn, "reference", "certReference", part, NULL); g_return_val_if_fail (node, CKR_GENERAL_ERROR); /* If the assertion doesn't contain this info ... */ if (!egg_asn1x_have (node)) return CKR_ATTRIBUTE_TYPE_INVALID; element = egg_asn1x_get_raw_element (node, &n_element); return gkm_attribute_set_data (attr, element, n_element); }
static CK_RV attribute_set_check_value (GkmGenericKey *self, CK_ATTRIBUTE *attr) { guchar buffer[20]; g_assert (GKM_IS_GENERIC_KEY (self)); g_assert (attr); /* Just asking for the length */ if (!attr->pValue) { attr->ulValueLen = 3; return CKR_OK; } /* Just the a sha1 of the value */ gcry_md_hash_buffer (GCRY_MD_SHA1, buffer, self->value, self->n_value); /* Use the first three bytes */ return gkm_attribute_set_data (attr, buffer, 3); }
static CK_RV attribute_set_check_value (GkmAesKey *self, CK_ATTRIBUTE *attr) { gcry_cipher_hd_t cih; gcry_error_t gcry; gpointer data; CK_RV rv; g_assert (GKM_IS_AES_KEY (self)); g_assert (attr); /* Just asking for the length */ if (!attr->pValue) { attr->ulValueLen = 3; return CKR_OK; } cih = gkm_aes_key_get_cipher (self, GCRY_CIPHER_MODE_ECB); if (cih == NULL) return CKR_FUNCTION_FAILED; /* Buffer of zeros */ data = g_malloc0 (self->n_value); /* Encrypt it */ gcry = gcry_cipher_encrypt (cih, data, self->n_value, NULL, 0); g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); /* Use the first three bytes */ g_assert (self->n_value > 3); rv = gkm_attribute_set_data (attr, data, 3); gcry_cipher_close (cih); g_free (data); 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); }