예제 #1
0
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));
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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));
}
예제 #5
0
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;
}
예제 #6
0
/**
 * 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);
}
예제 #7
0
/**
 * 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;
}
예제 #8
0
/**
 * 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;
}
예제 #9
0
/**
 * 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;
}
예제 #10
0
/**
 * 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;
}
예제 #11
0
/**
 * 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);
}
예제 #12
0
static gboolean
check_x509_attributes (GckBuilder *builder)
{
	const GckAttribute *value = gck_builder_find (builder, CKA_VALUE);
	return (value && !gck_attribute_is_invalid (value));
}
예제 #13
0
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;
}