static gboolean check_rsa_attributes (GckBuilder *builder) { const GckAttribute *modulus; const GckAttribute *exponent; modulus = gck_builder_find (builder, CKA_MODULUS); exponent = gck_builder_find (builder, CKA_PUBLIC_EXPONENT); return (modulus && !gck_attribute_is_invalid (modulus) && exponent && !gck_attribute_is_invalid (exponent)); }
static gboolean rsa_subject_public_key_from_attributes (GckAttributes *attrs, GNode *info_asn) { const GckAttribute *modulus; const GckAttribute *exponent; GNode *key_asn; GNode *params_asn; GBytes *key; GBytes *usg; modulus = gck_attributes_find (attrs, CKA_MODULUS); exponent = gck_attributes_find (attrs, CKA_PUBLIC_EXPONENT); if (modulus == NULL || gck_attribute_is_invalid (modulus) || exponent == NULL || gck_attribute_is_invalid (exponent)) return FALSE; key_asn = egg_asn1x_create (pk_asn1_tab, "RSAPublicKey"); g_return_val_if_fail (key_asn, FALSE); params_asn = egg_asn1x_create (pk_asn1_tab, "RSAParameters"); g_return_val_if_fail (params_asn, FALSE); usg = g_bytes_new_with_free_func (modulus->value, modulus->length, gck_attributes_unref, gck_attributes_ref (attrs)); egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "modulus", NULL), usg); g_bytes_unref (usg); usg = g_bytes_new_with_free_func (exponent->value, exponent->length, gck_attributes_unref, gck_attributes_ref (attrs)); egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "publicExponent", NULL), usg); g_bytes_unref (usg); key = egg_asn1x_encode (key_asn, NULL); egg_asn1x_destroy (key_asn); egg_asn1x_set_null (params_asn); egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL), key, g_bytes_get_size (key) * 8); egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_RSA); egg_asn1x_set_any_from (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params_asn); egg_asn1x_destroy (params_asn); g_bytes_unref (key); return TRUE; }
static GNode * cert_subject_public_key_from_attributes (GckAttributes *attributes) { const GckAttribute *attr; GBytes *bytes; GNode *cert; GNode *asn; attr = gck_attributes_find (attributes, CKA_VALUE); if (attr == NULL || gck_attribute_is_invalid (attr)) { _gcr_debug ("no value attribute for certificate"); return NULL; } bytes = g_bytes_new_with_free_func (attr->value, attr->length, gck_attributes_unref, gck_attributes_ref (attributes)); cert = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", bytes); g_bytes_unref (bytes); if (cert == NULL) { _gcr_debug ("couldn't parse certificate value"); return NULL; } asn = egg_asn1x_node (cert, "tbsCertificate", "subjectPublicKeyInfo", NULL); g_return_val_if_fail (asn != NULL, NULL); /* Remove the subject public key out of the certificate */ g_node_unlink (asn); egg_asn1x_destroy (cert); return asn; }
static gboolean check_dsa_attributes (GckBuilder *builder) { const GckAttribute *prime; const GckAttribute *subprime; const GckAttribute *base; const GckAttribute *value; prime = gck_builder_find (builder, CKA_PRIME); subprime = gck_builder_find (builder, CKA_SUBPRIME); base = gck_builder_find (builder, CKA_BASE); value = gck_builder_find (builder, CKA_VALUE); return (prime && !gck_attribute_is_invalid (prime) && subprime && !gck_attribute_is_invalid (subprime) && base && !gck_attribute_is_invalid (base) && value && !gck_attribute_is_invalid (value)); }
static GckObject * lookup_public_key (GckObject *object, GCancellable *cancellable, GError **lerror) { GckBuilder builder = GCK_BUILDER_INIT; gulong attr_types[] = { CKA_ID }; GckAttributes *attrs; GError *error = NULL; GckSession *session; GckObject *result; const GckAttribute *id; GList *objects; attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types), cancellable, &error); if (error != NULL) { _gcr_debug ("couldn't load private key id: %s", error->message); g_propagate_error (lerror, error); return NULL; } id = gck_attributes_find (attrs, CKA_ID); if (id == NULL || gck_attribute_is_invalid (id)) { gck_attributes_unref (attrs); _gcr_debug ("couldn't load private key id"); g_set_error_literal (lerror, GCK_ERROR, CKR_ATTRIBUTE_TYPE_INVALID, gck_message_from_rv (CKR_ATTRIBUTE_TYPE_INVALID)); return NULL; } gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY); gck_builder_add_attribute (&builder, id); gck_attributes_unref (attrs); session = gck_object_get_session (object); objects = gck_session_find_objects (session, gck_builder_end (&builder), cancellable, &error); g_object_unref (session); if (error != NULL) { _gcr_debug ("couldn't lookup public key: %s", error->message); g_propagate_error (lerror, error); return NULL; } if (!objects) return NULL; result = g_object_ref (objects->data); gck_list_unref_free (objects); return result; }
/** * gck_attribute_get_string: * @attr: The attribute to retrieve value from. * * Get the string value of a PKCS#11 attribute. No * conversion is performed. It is an error to pass an attribute * to this function unless you're know it's supposed to contain * a value of the right type. * * Return value: A null terminated string, to be freed with g_free(), * or NULL if the value contained a NULL string. */ gchar* gck_attribute_get_string (GckAttribute *attr) { g_return_val_if_fail (attr, NULL); if (gck_attribute_is_invalid (attr)) return NULL; if (!attr->value) return NULL; return g_strndup ((gchar*)attr->value, attr->length); }
/** * gck_attribute_get_ulong: * @attr: The attribute to retrieve value from. * * Get the CK_ULONG value of a PKCS#11 attribute. No * conversion is performed. It is an error to pass an attribute * to this function unless you're know it's supposed to contain * a value of the right type. * * Return value: The ulong value of the attribute. */ gulong gck_attribute_get_ulong (GckAttribute *attr) { gulong value; g_return_val_if_fail (attr, FALSE); if (gck_attribute_is_invalid (attr)) return 0; if (!gck_value_to_ulong (attr->value, attr->length, &value)) g_return_val_if_reached ((gulong)-1); return value; }
/** * gck_attribute_get_boolean: * @attr: The attribute to retrieve value from. * * Get the CK_BBOOL of a PKCS#11 attribute. No conversion * is performed. It is an error to pass an attribute to this * function unless you're know it's supposed to contain a * boolean value. * * Return value: The boolean value of the attribute. */ gboolean gck_attribute_get_boolean (GckAttribute *attr) { gboolean value; g_return_val_if_fail (attr, FALSE); if (gck_attribute_is_invalid (attr)) return FALSE; if (!gck_value_to_boolean (attr->value, attr->length, &value)) g_return_val_if_reached (FALSE); return value; }
/** * gck_attributes_find_date: * @attrs: The attributes array to search. * @attr_type: The type of attribute to find. * @value: The resulting GDate value. * * Find an attribute with the specified type in the array. * * The attribute (if found) must be of the right size to store * a date value (ie: CK_DATE). If the attribute is marked invalid * then it will be treated as not found. * * Return value: Whether a value was found or not. **/ gboolean gck_attributes_find_date (GckAttributes *attrs, gulong attr_type, GDate *value) { GckAttribute *attr; g_return_val_if_fail (value, FALSE); g_return_val_if_fail (!attrs->locked, FALSE); attr = gck_attributes_find (attrs, attr_type); if (!attr || gck_attribute_is_invalid (attr)) return FALSE; gck_attribute_get_date (attr, value); return TRUE; }
/** * gck_attributes_find_string: * @attrs: The attributes array to search. * @attr_type: The type of attribute to find. * @value: The resulting string value. * * Find an attribute with the specified type in the array. * * If the attribute is marked invalid then it will be treated as not found. * The resulting string will be null-terminated, and must be freed by the caller * using g_free(). * * Return value: Whether a value was found or not. **/ gboolean gck_attributes_find_string (GckAttributes *attrs, gulong attr_type, gchar **value) { GckAttribute *attr; g_return_val_if_fail (value, FALSE); g_return_val_if_fail (!attrs->locked, FALSE); attr = gck_attributes_find (attrs, attr_type); if (!attr || gck_attribute_is_invalid (attr)) return FALSE; *value = gck_attribute_get_string (attr); return TRUE; }
/** * gck_attribute_get_date: * @attr: The attribute to retrieve value from. * @value: The date value to fill in with the parsed date. * * Get the CK_DATE of a PKCS#11 attribute. No * conversion is performed. It is an error to pass an attribute * to this function unless you're know it's supposed to contain * a value of the right type. */ void gck_attribute_get_date (GckAttribute *attr, GDate *value) { guint year, month, day; gchar buffer[5]; CK_DATE *date; gchar *end; g_return_if_fail (attr); if (gck_attribute_is_invalid (attr)) { g_date_clear (value, 1); return; } g_return_if_fail (attr->length == sizeof (CK_DATE)); g_return_if_fail (attr->value); date = (CK_DATE*)attr->value; memset (&buffer, 0, sizeof (buffer)); memcpy (buffer, date->year, 4); year = strtol (buffer, &end, 10); g_return_if_fail (end != buffer && !*end); memset (&buffer, 0, sizeof (buffer)); memcpy (buffer, date->month, 2); month = strtol (buffer, &end, 10); g_return_if_fail (end != buffer && !*end); memset (&buffer, 0, sizeof (buffer)); memcpy (buffer, date->day, 2); day = strtol (buffer, &end, 10); g_return_if_fail (end != buffer && !*end); g_date_set_dmy (value, day, month, year); }
static gboolean check_x509_attributes (GckBuilder *builder) { const GckAttribute *value = gck_builder_find (builder, CKA_VALUE); return (value && !gck_attribute_is_invalid (value)); }
static gboolean dsa_subject_public_key_from_attributes (GckAttributes *attrs, gulong klass, GNode *info_asn) { const GckAttribute *value, *g, *q, *p; GNode *key_asn, *params_asn; GBytes *key; p = gck_attributes_find (attrs, CKA_PRIME); q = gck_attributes_find (attrs, CKA_SUBPRIME); g = gck_attributes_find (attrs, CKA_BASE); value = gck_attributes_find (attrs, CKA_VALUE); if (p == NULL || gck_attribute_is_invalid (p) || q == NULL || gck_attribute_is_invalid (q) || g == NULL || gck_attribute_is_invalid (g) || value == NULL || gck_attribute_is_invalid (value)) return FALSE; key_asn = egg_asn1x_create (pk_asn1_tab, "DSAPublicPart"); g_return_val_if_fail (key_asn, FALSE); params_asn = egg_asn1x_create (pk_asn1_tab, "DSAParameters"); g_return_val_if_fail (params_asn, FALSE); egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "p", NULL), g_bytes_new_with_free_func (p->value, p->length, gck_attributes_unref, gck_attributes_ref (attrs))); egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "q", NULL), g_bytes_new_with_free_func (q->value, q->length, gck_attributes_unref, gck_attributes_ref (attrs))); egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "g", NULL), g_bytes_new_with_free_func (g->value, g->length, gck_attributes_unref, gck_attributes_ref (attrs))); /* Are these attributes for a public or private key? */ if (klass == CKO_PRIVATE_KEY) { /* We need to calculate the public from the private key */ if (!dsa_subject_public_key_from_private (key_asn, p, q, g, value)) g_return_val_if_reached (FALSE); } else if (klass == CKO_PUBLIC_KEY) { egg_asn1x_take_integer_as_usg (key_asn, g_bytes_new_with_free_func (value->value, value->length, gck_attributes_unref, gck_attributes_ref (attrs))); } else { g_assert_not_reached (); } key = egg_asn1x_encode (key_asn, NULL); egg_asn1x_destroy (key_asn); egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL), key, g_bytes_get_size (key) * 8); egg_asn1x_set_any_from (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params_asn); egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_DSA); g_bytes_unref (key); egg_asn1x_destroy (params_asn); return TRUE; }