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_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_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 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_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_usage (GkmTrust *self, const gchar *purpose, CK_ATTRIBUTE_PTR attr) { GkmTrustLevel level; CK_ULONG trust; level = gkm_trust_get_level_for_purpose (self, purpose); switch (level) { case GKM_TRUST_UNKNOWN: trust = CKT_NETSCAPE_TRUST_UNKNOWN; break; case GKM_TRUST_DISTRUSTED: trust = CKT_NETSCAPE_UNTRUSTED; break; case GKM_TRUST_TRUSTED: trust = CKT_NETSCAPE_TRUSTED; break; case GKM_TRUST_ANCHOR: trust = CKT_NETSCAPE_TRUSTED_DELEGATOR; break; default: g_return_val_if_reached (CKR_GENERAL_ERROR); }; return gkm_attribute_set_ulong (attr, trust); }
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_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_roots_certificate_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr) { GkmRootsCertificate *self = GKM_ROOTS_CERTIFICATE (base); CK_ULONG category; switch (attr->type) { case CKA_TRUSTED: return gkm_attribute_set_bool (attr, TRUE); case CKA_CERTIFICATE_CATEGORY: if (!gkm_certificate_calc_category (GKM_CERTIFICATE (self), session, &category)) return CKR_FUNCTION_FAILED; /* Unknown category, is CA by default in this slot */ if (category == 0) category = 2; return gkm_attribute_set_ulong (attr, category); } return GKM_OBJECT_CLASS (gkm_roots_certificate_parent_class)->get_attribute (base, session, attr); }
static CK_RV gkm_xdg_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr) { GkmXdgTrust *self = GKM_XDG_TRUST (base); switch (attr->type) { case CKA_PRIVATE: return gkm_attribute_set_bool (attr, CK_FALSE); case CKA_TRUST_STEP_UP_APPROVED: return gkm_attribute_set_bool (attr, CK_FALSE); case CKA_CLASS: return gkm_attribute_set_ulong (attr, CKO_NETSCAPE_TRUST); case CKA_MODIFIABLE: return gkm_attribute_set_bool (attr, CK_FALSE); /* Certificate reference values */ case CKA_SUBJECT: return trust_get_der (self, "subject", attr); case CKA_SERIAL_NUMBER: return trust_get_integer (self, "serialNumber", attr); case CKA_ISSUER: return trust_get_der (self, "issuer", attr); case CKA_X_CERTIFICATE_VALUE: return trust_get_complete (self, attr); /* Certificate hash values */ case CKA_CERT_MD5_HASH: return trust_get_hash (self, G_CHECKSUM_MD5, attr); case CKA_CERT_SHA1_HASH: return trust_get_hash (self, G_CHECKSUM_SHA1, attr); default: break; }; return GKM_OBJECT_CLASS (gkm_xdg_trust_parent_class)->get_attribute (base, session, attr); }
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); }
static CK_RV gkm_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr) { GkmTrust *self = GKM_TRUST (base); /* * This object exposes a netscape compatible trust object. However the * primary interface for dealing with trust is through GkmAssertion objects. */ switch (attr->type) { case CKA_PRIVATE: return gkm_attribute_set_bool (attr, CK_FALSE); case CKA_TRUST_STEP_UP_APPROVED: return gkm_attribute_set_bool (attr, CK_FALSE); case CKA_CLASS: return gkm_attribute_set_ulong (attr, CKO_NETSCAPE_TRUST); case CKA_MODIFIABLE: return gkm_attribute_set_bool (attr, CK_FALSE); /* * TODO: Is it even useful to support overriding from certificate * defaults? For now we just return unknown for all of them, and * the caller should use whatever's in the certificate. */ case CKA_TRUST_DIGITAL_SIGNATURE: case CKA_TRUST_NON_REPUDIATION: case CKA_TRUST_KEY_ENCIPHERMENT: case CKA_TRUST_DATA_ENCIPHERMENT: case CKA_TRUST_KEY_AGREEMENT: case CKA_TRUST_KEY_CERT_SIGN: case CKA_TRUST_CRL_SIGN: return gkm_attribute_set_ulong (attr, CKT_NETSCAPE_TRUST_UNKNOWN); /* Various trust flags */ case CKA_TRUST_SERVER_AUTH: return trust_get_usage (self, GKM_OID_EXTUSAGE_SERVER_AUTH, attr); case CKA_TRUST_CLIENT_AUTH: return trust_get_usage (self, GKM_OID_EXTUSAGE_CLIENT_AUTH, attr); case CKA_TRUST_CODE_SIGNING: return trust_get_usage (self, GKM_OID_EXTUSAGE_CODE_SIGNING, attr); case CKA_TRUST_EMAIL_PROTECTION: return trust_get_usage (self, GKM_OID_EXTUSAGE_EMAIL, attr); case CKA_TRUST_IPSEC_END_SYSTEM: return trust_get_usage (self, GKM_OID_EXTUSAGE_IPSEC_ENDPOINT, attr); case CKA_TRUST_IPSEC_TUNNEL: return trust_get_usage (self, GKM_OID_EXTUSAGE_IPSEC_TUNNEL, attr); case CKA_TRUST_IPSEC_USER: return trust_get_usage (self, GKM_OID_EXTUSAGE_IPSEC_USER, attr); case CKA_TRUST_TIME_STAMPING: return trust_get_usage (self, GKM_OID_EXTUSAGE_TIME_STAMPING, attr); /* Certificate reference values */ case CKA_SUBJECT: case CKA_SERIAL_NUMBER: case CKA_ISSUER: case CKA_CERT_MD5_HASH: case CKA_CERT_SHA1_HASH: g_warning ("derived class should have provided these attributes"); return CKR_ATTRIBUTE_TYPE_INVALID; default: break; }; return GKM_OBJECT_CLASS (gkm_trust_parent_class)->get_attribute (base, session, attr); }