[gcr/ecc: 8/10] WIP subject pulbic key support for EC
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcr/ecc: 8/10] WIP subject pulbic key support for EC
- Date: Thu, 17 Apr 2014 06:52:34 +0000 (UTC)
commit e06e8b088c025ab54617a1fa4414d9398a2862ee
Author: Stef Walter <stefw redhat com>
Date: Thu Apr 17 07:16:13 2014 +0200
WIP subject pulbic key support for EC
gcr/gcr-subject-public-key.c | 193 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 193 insertions(+), 0 deletions(-)
---
diff --git a/gcr/gcr-subject-public-key.c b/gcr/gcr-subject-public-key.c
index 359307c..e0c9e9d 100644
--- a/gcr/gcr-subject-public-key.c
+++ b/gcr/gcr-subject-public-key.c
@@ -293,6 +293,45 @@ load_dsa_attributes (GckObject *object,
}
static gboolean
+check_ec_attributes (GckBuilder *builder)
+{
+ const GckAttribute *ec_params;
+
+ ec_params = gck_builder_find (builder, CKA_EC_PARAMS);
+ return (ec_params && !gck_attribute_is_invalid (ec_params));
+}
+
+
+static gboolean
+load_ec_attributes (GckObject *object,
+ GckBuilder *builder,
+ GCancellable *cancellable,
+ GError **lerror)
+{
+ gulong attr_types[] = { CKA_MODULUS, CKA_PUBLIC_EXPONENT };
+ GckAttributes *attrs;
+ GError *error = NULL;
+
+ if (check_rsa_attributes (builder)) {
+ _gcr_debug ("rsa attributes already loaded");
+ return TRUE;
+ }
+
+ attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
+ cancellable, &error);
+ if (error != NULL) {
+ _gcr_debug ("couldn't load rsa attributes: %s", error->message);
+ g_propagate_error (lerror, error);
+ return FALSE;
+ }
+
+ gck_builder_set_all (builder, attrs);
+ gck_attributes_unref (attrs);
+
+ return check_rsa_attributes (builder);
+}
+
+static gboolean
load_attributes (GckObject *object,
GckBuilder *builder,
GCancellable *cancellable,
@@ -328,6 +367,14 @@ load_attributes (GckObject *object,
case CKK_DSA:
ret = load_dsa_attributes (object, builder, cancellable, lerror);
break;
+ case CKK_EC:
+ if (klass == CKO_PRIVATE_KEY) {
+ _gcr_debug ("cannot convert elliptic curve private key to public");
+ ret = FALSE;
+ } else {
+ ret = load_ec_attributes (object, builder, cancellable, lerror);
+ }
+ break;
default:
_gcr_debug ("unsupported key type: %lu", type);
break;
@@ -373,6 +420,8 @@ check_attributes (GckBuilder *builder)
return check_rsa_attributes (builder);
case CKK_DSA:
return check_dsa_attributes (builder);
+ case CKK_EC:
+ return check_ec_attributes (builder);
default:
return FALSE;
}
@@ -681,6 +730,55 @@ dsa_subject_public_key_from_attributes (GckAttributes *attrs,
return TRUE;
}
+static gboolean
+ec_subject_public_key_from_attributes (GckAttributes *attrs,
+ gulong klass,
+ GNode *info_asn)
+{
+ const GckAttribute *ec_params, *ec_point;
+ GNode *key_asn, *params_asn;
+ GBytes *bytes;
+
+ if (klass == CKO_PRIVATE_KEY)
+ return FALSE;
+
+ ec_params = gck_attributes_find (attrs, CKA_EC_PARAMS);
+ ec_point = gck_attributes_find (attrs, CKA_EC_POINT);
+
+ if (ec_params == NULL || gck_attribute_is_invalid (ec_params) ||
+ ec_point == NULL || gck_attribute_is_invalid (ec_point))
+ return FALSE;
+
+ bytes = g_bytes_new_with_free_func (ec_params->value, ec_params->length,
+ gck_attributes_unref, gck_attributes_ref (attrs));
+ params_asn = egg_asn1x_create_and_decode (pk_asn1_tab, "ECParameters", bytes);
+ g_bytes_unref (bytes);
+
+ if (params_asn == NULL)
+ return FALSE;
+
+ key_asn = egg_asn1x_create (pk_asn1_tab, "ECPoint");
+ g_return_val_if_fail (key_asn, FALSE);
+
+ bytes = g_bytes_new_with_free_func (ec_point->value, ec_point->length,
+ gck_attributes_unref, gck_attributes_ref (attrs));
+ egg_asn1x_set_string_as_bytes (key_asn, bytes);
+ g_bytes_unref (bytes);
+
+ bytes = egg_asn1x_encode (key_asn, NULL);
+ egg_asn1x_destroy (key_asn);
+
+ egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
+ bytes, g_bytes_get_size (bytes) * 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_EC);
+
+ g_bytes_unref (bytes);
+ egg_asn1x_destroy (params_asn);
+ return TRUE;
+}
+
static GNode *
cert_subject_public_key_from_attributes (GckAttributes *attributes)
{
@@ -747,6 +845,9 @@ _gcr_subject_public_key_for_attributes (GckAttributes *attributes)
} else if (key_type == CKK_DSA) {
ret = dsa_subject_public_key_from_attributes (attributes, klass, asn);
+ } else if (key_type == CKK_ECDSA) {
+ ret = ec_subject_public_key_from_attributes (attributes, klass, asn);
+
} else {
_gcr_debug ("unsupported key type: %lu", key_type);
ret = FALSE;
@@ -844,6 +945,92 @@ attributes_dsa_key_size (GckAttributes *attrs)
return 0;
}
+static guint
+named_curve_size (GNode *params)
+{
+ GQuark oid;
+ guint size;
+
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (params, "namedCurve", NULL));
+
+ if (oid == GCR_OID_EC_SECP192R1)
+ size = 192;
+ else if (oid == GCR_OID_EC_SECT163K1)
+ size = 163;
+ else if (oid == GCR_OID_EC_SECT163R2)
+ size = 163;
+ else if (GCR_OID_EC_SECP224R1)
+ size = 224;
+ else if (GCR_OID_EC_SECT233K1)
+ size = 233;
+ else if (GCR_OID_EC_SECT233R1)
+ size = 233;
+ else if (GCR_OID_EC_SECP256R1)
+ size = 256;
+ else if (GCR_OID_EC_SECT283K1)
+ size = 283;
+ else if (GCR_OID_EC_SECT283R1)
+ size = 283;
+ else if (GCR_OID_EC_SECP384R1)
+ size = 384;
+ else if (GCR_OID_EC_SECT409K1)
+ size = 409;
+ else if (GCR_OID_EC_SECT409R1)
+ size = 409;
+ else if (GCR_OID_EC_SECP521R1)
+ size = 521;
+ else if (GCR_OID_EC_SECP571K1)
+ size = 571;
+ else if (GCR_OID_EC_SECT571R1)
+ size = 571;
+ else
+ size = 0;
+
+ return size;
+
+}
+
+static guint
+calculate_ec_params_size (GNode *params)
+{
+ GNode *asn;
+ guint size;
+
+ asn = egg_asn1x_get_any_as (params, pk_asn1_tab, "ECParameters");
+ g_return_val_if_fail (asn, 0);
+
+ size = named_curve_size (asn);
+ egg_asn1x_destroy (asn);
+
+ return size;
+}
+
+static guint
+attributes_ec_params_size (GckAttributes *attrs)
+{
+ GNode *asn;
+ const GckAttribute *attr;
+ GBytes *bytes;
+ guint size = 0;
+
+ attr = gck_attributes_find (attrs, CKA_EC_PARAMS);
+
+ /* Calculate the bit length, and remove the complement */
+ if (attr && !gck_attribute_is_invalid (attr)) {
+ bytes = g_bytes_new_with_free_func (attr->value, attr->length,
+ gck_attributes_unref,
+ gck_attributes_ref (attrs));
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "ECParameters", bytes);
+ g_bytes_unref (bytes);
+
+ if (asn)
+ size = named_curve_size (asn);
+ egg_asn1x_destroy (asn);
+ }
+
+ return size;
+}
+
guint
_gcr_subject_public_key_calculate_size (GNode *subject_public_key)
{
@@ -870,6 +1057,10 @@ _gcr_subject_public_key_calculate_size (GNode *subject_public_key)
params = egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL);
key_size = calculate_dsa_params_size (params);
+ } else if (oid == GCR_OID_PKIX1_EC) {
+ params = egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL);
+ key_size = calculate_ec_params_size (params);
+
} else {
g_message ("unsupported key algorithm: %s", g_quark_to_string (oid));
}
@@ -890,6 +1081,8 @@ _gcr_subject_public_key_attributes_size (GckAttributes *attrs)
return attributes_rsa_key_size (attrs);
case CKK_DSA:
return attributes_dsa_key_size (attrs);
+ case CKK_EC:
+ return attributes_ec_params_size (attrs);
default:
g_message ("unsupported key algorithm: %lu", key_type);
return 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]