[gnome-keyring] gcr: Add support for getting friendly name out of a PKCS#12 file.



commit d2c7739096fa5f41f044d72904988caf796b2de2
Author: Stef Walter <stefw collabora co uk>
Date:   Thu Sep 1 13:39:54 2011 +0200

    gcr: Add support for getting friendly name out of a PKCS#12 file.

 egg/egg-asn1x.c   |   19 ++++++++++++++++++
 egg/egg-asn1x.h   |    2 +
 gcr/gcr-oids.list |    3 ++
 gcr/gcr-parser.c  |   56 ++++++++++++++++++++++++++++++++++++++++++++++------
 4 files changed, 73 insertions(+), 7 deletions(-)
---
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index 46d302c..1463d3b 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -2796,6 +2796,25 @@ egg_asn1x_set_string_as_raw (GNode *node, guchar *data, gsize n_data, GDestroyNo
 	return TRUE;
 }
 
+gchar *
+egg_asn1x_get_bmpstring_as_utf8 (GNode *node)
+{
+	gchar *string;
+	gsize n_string;
+	gchar *utf8;
+
+	g_return_val_if_fail (node, NULL);
+
+	string = (gchar*)egg_asn1x_get_string_as_raw (node, NULL, &n_string);
+	if (!string)
+		return NULL;
+
+	utf8 = g_convert (string, n_string, "UTF-8", "UTF-16BE", NULL, NULL, NULL);
+	g_free (string);
+
+	return utf8;
+}
+
 gchar*
 egg_asn1x_get_string_as_utf8 (GNode *node, EggAllocator allocator)
 {
diff --git a/egg/egg-asn1x.h b/egg/egg-asn1x.h
index 06e94e3..86b76c5 100644
--- a/egg/egg-asn1x.h
+++ b/egg/egg-asn1x.h
@@ -156,6 +156,8 @@ gboolean            egg_asn1x_set_string_as_utf8     (GNode *node,
                                                       gchar *data,
                                                       GDestroyNotify destroy);
 
+gchar *             egg_asn1x_get_bmpstring_as_utf8  (GNode *node);
+
 glong               egg_asn1x_get_time_as_long       (GNode *node);
 
 gboolean            egg_asn1x_set_time_as_long       (GNode *node,
diff --git a/gcr/gcr-oids.list b/gcr/gcr-oids.list
index 1b87675..552c601 100644
--- a/gcr/gcr-oids.list
+++ b/gcr/gcr-oids.list
@@ -10,10 +10,13 @@ PKIX1_DSA	1.2.840.10040.4.1
 PKCS7_DATA			1.2.840.113549.1.7.1
 PKCS7_SIGNED_DATA		1.2.840.113549.1.7.2
 PKCS7_ENCRYPTED_DATA		1.2.840.113549.1.7.6
+PKCS9_ATTRIBUTE_FRIENDLY	1.2.840.113549.1.9.20
+PKCS9_ATTRIBUTE_LOCAL_KEY_ID	1.2.840.113549.1.9.21
 PKCS12_BAG_PKCS8_KEY		1.2.840.113549.1.12.10.1.1
 PKCS12_BAG_PKCS8_ENCRYPTED_KEY	1.2.840.113549.1.12.10.1.2
 PKCS12_BAG_CERTIFICATE		1.2.840.113549.1.12.10.1.3
 PKCS12_BAG_CRL			1.2.840.113549.1.12.10.1.4
 
+
 ALT_NAME_XMPP_ADDR		1.3.6.1.5.5.7.8.5
 ALT_NAME_DNS_SRV		1.3.6.1.5.5.7.8.7
diff --git a/gcr/gcr-parser.c b/gcr/gcr-parser.c
index e9b24de..b051752 100644
--- a/gcr/gcr-parser.c
+++ b/gcr/gcr-parser.c
@@ -251,10 +251,7 @@ parsing_begin (GcrParser *self,
 	else 
 		self->pv->parsed_attrs = gck_attributes_new ();
 	gck_attributes_add_ulong (self->pv->parsed_attrs, CKA_CLASS, klass);
-	
-	g_free (self->pv->parsed_label);
-	self->pv->parsed_label = NULL;
-	
+
 	switch (klass) {
 	case CKO_PRIVATE_KEY:
 		self->pv->parsed_desc = _("Private Key");
@@ -697,8 +694,8 @@ parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
 static gint
 parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
 {
+	gchar *name = NULL;
 	GNode *asn;
-	gchar *name;
 
 	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
 	if (asn == NULL)
@@ -708,7 +705,9 @@ parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
 
 	parsed_ulong (self, CKA_CERTIFICATE_TYPE, CKC_X_509);
 
-	name = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
+	if (self->pv->parsed_label == NULL)
+		name = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
+
 	egg_asn1x_destroy (asn);
 
 	if (name != NULL) {
@@ -853,6 +852,41 @@ done:
 	return ret;
 }
 
+static gchar *
+parse_pkcs12_bag_friendly_name (GNode *asn)
+{
+	guint count, i;
+	GQuark oid;
+	GNode *node;
+	gconstpointer element;
+	gsize n_element;
+	GNode *asn_str;
+	gchar *result;
+
+	if (asn == NULL)
+		return NULL;
+
+	count = egg_asn1x_count (asn);
+	for (i = 1; i <= count; i++) {
+		oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, i, "type", NULL));
+		if (oid == GCR_OID_PKCS9_ATTRIBUTE_FRIENDLY) {
+			node = egg_asn1x_node (asn, i, "values", 1, NULL);
+			if (node != NULL) {
+				element = egg_asn1x_get_raw_element (node, &n_element);
+				asn_str = egg_asn1x_create_and_decode (pkix_asn1_tab, "BMPString",
+				                                       element, n_element);
+				if (asn_str) {
+					result = egg_asn1x_get_bmpstring_as_utf8 (asn_str);
+					egg_asn1x_destroy (asn_str);
+					return result;
+				}
+			}
+		}
+	}
+
+	return NULL;
+}
+
 static gint
 handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
 {
@@ -861,6 +895,7 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
 	guint count = 0;
 	GQuark oid;
 	const guchar *element;
+	gchar *friendly;
 	gsize n_element;
 	guint i;
 
@@ -889,6 +924,10 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
 		if (!element)
 			goto done;
 
+		friendly = parse_pkcs12_bag_friendly_name (egg_asn1x_node (asn, i, "bagAttributes", NULL));
+		if (friendly != NULL)
+			parsed_label (self, friendly);
+
 		/* A normal unencrypted key */
 		if (oid == GCR_OID_PKCS12_BAG_PKCS8_KEY) {
 			r = parse_der_pkcs8_plain (self, element, n_element);
@@ -905,7 +944,10 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
 		} else {
 			r = GCR_ERROR_UNRECOGNIZED;
 		}
-		 
+
+		if (friendly != NULL)
+			parsed_label (self, NULL);
+
 		if (r == GCR_ERROR_FAILURE || r == GCR_ERROR_CANCELLED) {
 			ret = r;
 			goto done;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]