コード例 #1
0
static gint
find_certificate_extension (GkmCertificate *self, GQuark oid)
{
	GQuark exoid;
	GNode *node;
	guint index;

	g_assert (oid);
	g_assert (GKM_IS_CERTIFICATE (self));
	g_assert (self->pv->asn1);

	for (index = 1; TRUE; ++index) {

		/* Make sure it is present */
		node = egg_asn1x_node (self->pv->asn1, "tbsCertificate", "extensions", index, NULL);
		if (node == NULL)
			break;

		/* See if it's the same */
		exoid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));

		if(exoid == oid)
			return index;
	}

	return 0;
}
コード例 #2
0
ファイル: gcr-subject-public-key.c プロジェクト: UIKit0/gcr
guint
_gcr_subject_public_key_calculate_size (GNode *subject_public_key)
{
	GBytes *key;
	GNode *params;
	guint key_size = 0;
	guint n_bits;
	GQuark oid;

	/* Figure out the algorithm */
	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (subject_public_key,
	                                                  "algorithm", "algorithm", NULL));
	g_return_val_if_fail (oid != 0, 0);

	/* RSA keys are stored in the main subjectPublicKey field */
	if (oid == GCR_OID_PKIX1_RSA) {
		key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (subject_public_key, "subjectPublicKey", NULL), &n_bits);
		g_return_val_if_fail (key != NULL, 0);
		key_size = calculate_rsa_key_size (key);
		g_bytes_unref (key);

	/* The DSA key size is discovered by the prime in params */
	} else if (oid == GCR_OID_PKIX1_DSA) {
		params = egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL);
		key_size = calculate_dsa_params_size (params);

	} else {
		g_message ("unsupported key algorithm: %s", g_quark_to_string (oid));
	}

	return key_size;
}
コード例 #3
0
ファイル: gkm-data-der.c プロジェクト: bhull2010/mate-keyring
GkmDataResult
gkm_data_der_read_enhanced_usage (const guchar *data, gsize n_data, GQuark **usage_oids)
{
	GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
	GNode *asn = NULL;
	GNode *node;
	GArray *array;
	GQuark oid;
	int i;

	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtKeyUsageSyntax", data, n_data);
	if (!asn)
		goto done;

	ret = GKM_DATA_FAILURE;

	array = g_array_new (TRUE, TRUE, sizeof (GQuark));
	for (i = 0; TRUE; ++i) {
		node = egg_asn1x_node (asn, i + 1, NULL);
		if (node == NULL)
			break;

		oid = egg_asn1x_get_oid_as_quark (node);
		g_array_append_val (array, oid);
	}

	*usage_oids = (GQuark*)g_array_free (array, FALSE);
	ret = GKM_DATA_SUCCESS;

done:
	egg_asn1x_destroy (asn);
	return ret;
}
コード例 #4
0
ファイル: gkm-data-der.c プロジェクト: bhull2010/mate-keyring
GkmDataResult
gkm_data_der_read_public_key_info (const guchar* data, gsize n_data, gcry_sexp_t* s_key)
{
	GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
	GQuark oid;
	GNode *asn = NULL;
	gsize n_params;
	guint n_bits;
	const guchar *params;
	guchar *key = NULL;

	init_quarks ();

	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data, n_data);
	if (!asn)
		goto done;

	ret = GKM_DATA_FAILURE;

	/* Figure out the algorithm */
	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "algorithm", "algorithm", NULL));
	if (!oid)
		goto done;

	/* A bit string so we cannot process in place */
	key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), NULL, &n_bits);
	if (!key)
		goto done;

	/* An RSA key is simple */
	if (oid == OID_PKIX1_RSA) {
		ret = gkm_data_der_read_public_key_rsa (key, n_bits / 8, s_key);

	/* A DSA key paramaters are stored separately */
	} else if (oid == OID_PKIX1_DSA) {
		params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL), &n_params);
		if (!params)
			goto done;
		ret = gkm_data_der_read_public_key_dsa_parts (key, n_bits / 8, params, n_params, s_key);

	} else {
		g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
		ret = GKM_DATA_UNRECOGNIZED;
		goto done;
	}

done:
	egg_asn1x_destroy (asn);
	g_free (key);

	if (ret == GKM_DATA_FAILURE)
		g_message ("invalid subject public-key info");

	return ret;
}
static gboolean
append_extension (GcrCertificateDetailsWidget *self, GNode *asn,
                  const guchar *data, gsize n_data, gint index)
{
	GQuark oid;
	gchar *display;
	gsize n_value;
	const guchar *value;
	const gchar *text;
	gboolean critical;
	GNode *node;

	/* Make sure it is present */
	asn = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
	if (asn == NULL)
		return FALSE;

	/* Dig out the OID */
	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "extnID", NULL));
	g_return_val_if_fail (oid, FALSE);


	append_heading (self, _("Extension"));


	/* Extension type */
	text = egg_oid_get_description (oid);
	append_field_and_value (self, _("Identifier"), text, FALSE);


	/* Extension value */
	value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "extnValue", NULL), &n_value);

	/* TODO: Parsing of extensions that we understand */
	display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
	append_field_and_value (self, _("Value"), display, TRUE);
	g_free (display);


	/* Critical */
	node = egg_asn1x_node (asn, "critical", NULL);
	if (node != NULL) {
		if (egg_asn1x_get_boolean (node, &critical))
			append_field_and_value (self, _("Critical"), critical ? _("Yes") : _("No"), FALSE);
	}

	return TRUE;
}
コード例 #6
0
static gboolean
prepare_subject_public_key_and_mechanisms (GcrCertificateRequest *self,
                                           GNode *subject_public_key,
                                           GQuark *algorithm,
                                           const gulong **mechanisms,
                                           gsize *n_mechanisms,
                                           GError **error)
{
	GBytes *encoded;
	GNode *node;
	GQuark oid;

	g_assert (algorithm != NULL);
	g_assert (mechanisms != NULL);
	g_assert (n_mechanisms != NULL);

	encoded = egg_asn1x_encode (subject_public_key, NULL);
	g_return_val_if_fail (encoded != NULL, FALSE);

	node = egg_asn1x_node (subject_public_key, "algorithm", "algorithm", NULL);
	oid = egg_asn1x_get_oid_as_quark (node);

	if (oid == GCR_OID_PKIX1_RSA) {
		*mechanisms = RSA_MECHANISMS;
		*n_mechanisms = G_N_ELEMENTS (RSA_MECHANISMS);
		*algorithm = GCR_OID_PKIX1_SHA1_WITH_RSA;

	} else if (oid == GCR_OID_PKIX1_DSA) {
		*mechanisms = DSA_MECHANISMS;
		*n_mechanisms = G_N_ELEMENTS (DSA_MECHANISMS);
		*algorithm = GCR_OID_PKIX1_SHA1_WITH_DSA;

	} else {
		g_bytes_unref (encoded);
		g_set_error (error, GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED,
		             _("Unsupported key type for certificate request"));
		return FALSE;
	}

	node = egg_asn1x_node (self->asn, "certificationRequestInfo", "subjectPKInfo", NULL);
	if (!egg_asn1x_decode (node, encoded))
		g_return_val_if_reached (FALSE);

	g_bytes_unref (encoded);
	return TRUE;
}
コード例 #7
0
static guint
calculate_key_size (GcrCertificateInfo *info)
{
	GNode *asn;
	gconstpointer data, params;
	gsize n_data, n_params;
	guint key_size = 0, n_bits;
	guchar *key = NULL;
	GQuark oid;

	data = egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), &n_data);
	g_return_val_if_fail (data != NULL, 0);

	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data, n_data);
	g_return_val_if_fail (asn, 0);

	/* Figure out the algorithm */
	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "algorithm", "algorithm", NULL));
	g_return_val_if_fail (oid, 0);

	/* RSA keys are stored in the main subjectPublicKey field */
	if (oid == OID_RSA_KEY) {

		/* A bit string so we cannot process in place */
		key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), NULL, &n_bits);
		g_return_val_if_fail (key, 0);
		key_size = calculate_rsa_key_size (key, n_bits / 8);
		g_free (key);

	/* The DSA key size is discovered by the prime in params */
	} else if (oid == OID_DSA_KEY) {
		params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL), &n_params);
		key_size = calculate_dsa_params_size (params, n_params);

	} else {
		g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
	}

	egg_asn1x_destroy (asn);

	return key_size;
}
static void
refresh_display (GcrCertificateDetailsWidget *self)
{
	GtkTextIter start, iter;
	const guchar *data, *value;
	gsize n_data, n_value;
	const gchar *text;
	gulong version;
	guint index, size, n_bits;
	gchar *display;
	guchar *bits;
	GNode *asn;
	GQuark oid;
	GDate date;

	gtk_text_buffer_get_start_iter (self->pv->buffer, &start);
	gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
	gtk_text_buffer_delete (self->pv->buffer, &start, &iter);
	
	if (!self->pv->certificate)
		return;
	
	data = gcr_certificate_get_der_data (self->pv->certificate, &n_data);
	g_return_if_fail (data);

	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
	g_return_if_fail (asn);

	/* The subject */
	append_heading (self, _("Subject Name"));
	egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, self);

	/* The Issuer */
	append_heading (self, _("Issuer Name"));
	egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, self);

	/* The Issued Parameters */
	append_heading (self, _("Issued Certificate"));

	if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version))
		g_return_if_reached ();
	display = g_strdup_printf ("%lu", version + 1);
	append_field_and_value (self, _("Version"), display, FALSE);
	g_free (display);

	value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), &n_value);
	g_return_if_fail (value);
	display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
	append_field_and_value (self, _("Serial Number"), display, TRUE);
	g_free (display);
	
	display = g_malloc0 (128);
	if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
		if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
			g_return_if_reached ();
		append_field_and_value (self, _("Not Valid Before"), display, FALSE);
	}
	if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
		if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
			g_return_if_reached ();
		append_field_and_value (self, _("Not Valid After"), display, FALSE);
	}
	g_free (display);
	
	/* Signature */
	append_heading (self, _("Signature"));

	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
	text = egg_oid_get_description (oid);
	append_field_and_value (self, _("Signature Algorithm"), text, FALSE);

	value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value);
	if (value && n_value) {
		display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
		append_field_and_value (self, _("Signature Parameters"), display, TRUE);
		g_free (display);
	}
	
	value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "signature", NULL), &n_value);
	g_return_if_fail (value);
	display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
	append_field_and_value (self, _("Signature"), display, TRUE);
	g_free (display);

	/* Public Key Info */
	append_heading (self, _("Public Key Info"));

	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "algorithm", "algorithm", NULL));
	text = egg_oid_get_description (oid);
	append_field_and_value (self, _("Key Algorithm"), text, FALSE);

	value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "algorithm", "parameters", NULL), &n_value);
	if (value && n_value) {
		display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
		append_field_and_value (self, _("Key Parameters"), display, TRUE);
		g_free (display);
	}

	size = gcr_certificate_get_key_size (self->pv->certificate);
	if (size > 0) {
		display = g_strdup_printf ("%u", size); 
		append_field_and_value (self, _("Key Size"), display, FALSE);
		g_free (display);
	}

	bits = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "subjectPublicKey", NULL), NULL, &n_bits);
	g_return_if_fail (bits);
	display = egg_hex_encode_full (bits, n_bits / 8, TRUE, ' ', 1);
	append_field_and_value (self, _("Public Key"), display, TRUE);
	g_free (display);
	g_free (bits);

	/* Fingerprints */
	append_heading (self, _("Fingerprints"));
	
	append_fingerprint (self, data, n_data, "SHA1", G_CHECKSUM_SHA1);
	append_fingerprint (self, data, n_data, "MD5", G_CHECKSUM_MD5);
	
	/* Extensions */
	for (index = 1; TRUE; ++index) {
		if (!append_extension (self, asn, data, n_data, index))
			break;
	}

	egg_asn1x_destroy (asn);
}
コード例 #9
0
ファイル: gkm-data-der.c プロジェクト: bhull2010/mate-keyring
GkmDataResult
gkm_data_der_read_private_pkcs8_crypted (const guchar *data, gsize n_data, const gchar *password,
                                         gsize n_password, gcry_sexp_t *s_key)
{
	GNode *asn = NULL;
	gcry_cipher_hd_t cih = NULL;
	gcry_error_t gcry;
	GkmDataResult ret, r;
	GQuark scheme;
	guchar *crypted = NULL;
	const guchar *params;
	gsize n_crypted, n_params;
	gint l;

	init_quarks ();

	ret = GKM_DATA_UNRECOGNIZED;

	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
	if (!asn)
		goto done;

	ret = GKM_DATA_FAILURE;

	/* Figure out the type of encryption */
	scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL));
	if (!scheme)
		goto done;

	params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
	if (!params)
		goto done;

	/*
	 * Parse the encryption stuff into a cipher.
	 */
	r = egg_symkey_read_cipher (scheme, password, n_password, params, n_params, &cih);
	if (r == GKM_DATA_UNRECOGNIZED) {
		ret = GKM_DATA_FAILURE;
		goto done;
	} else if (r != GKM_DATA_SUCCESS) {
		ret = r;
		goto done;
	}

	crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL),
	                                       egg_secure_realloc, &n_crypted);
	if (!crypted)
		goto done;

	gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
	gcry_cipher_close (cih);
	cih = NULL;

	if (gcry != 0) {
		g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry));
		goto done;
	}

	/* Unpad the DER data */
	l = egg_asn1x_element_length (crypted, n_crypted);
	if (l <= 0 || l > n_crypted) {
		ret = GKM_DATA_LOCKED;
		goto done;
	}
	n_crypted = l;

	/* Try to parse the resulting key */
	ret = gkm_data_der_read_private_pkcs8_plain (crypted, n_crypted, s_key);
	egg_secure_free (crypted);
	crypted = NULL;

	/* If unrecognized we assume bad password */
	if (ret == GKM_DATA_UNRECOGNIZED)
		ret = GKM_DATA_LOCKED;

done:
	if (cih)
		gcry_cipher_close (cih);
	egg_asn1x_destroy (asn);
	egg_secure_free (crypted);

	return ret;
}
コード例 #10
0
ファイル: gkm-data-der.c プロジェクト: bhull2010/mate-keyring
GkmDataResult
gkm_data_der_read_private_pkcs8_plain (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
{
	GNode *asn = NULL;
	GkmDataResult ret;
	int algorithm;
	GQuark key_algo;
	const guchar *keydata;
	gsize n_keydata;
	const guchar *params;
	gsize n_params;

	ret = GKM_DATA_UNRECOGNIZED;

	init_quarks ();

	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
	if (!asn)
		goto done;

	ret = GKM_DATA_FAILURE;
	algorithm = 0;

	key_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL));
	if (!key_algo)
		goto done;
	else if (key_algo == OID_PKIX1_RSA)
		algorithm = GCRY_PK_RSA;
	else if (key_algo == OID_PKIX1_DSA)
		algorithm = GCRY_PK_DSA;

	if (!algorithm) {
		ret = GKM_DATA_UNRECOGNIZED;
		goto done;
	}

	keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL), &n_keydata);
	if (!keydata)
		goto done;

	params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL),
	                                    &n_params);

	ret = GKM_DATA_SUCCESS;

done:
	if (ret == GKM_DATA_SUCCESS) {
		switch (algorithm) {
		case GCRY_PK_RSA:
			ret = gkm_data_der_read_private_key_rsa (keydata, n_keydata, s_key);
			break;
		case GCRY_PK_DSA:
			/* Try the normal one block format */
			ret = gkm_data_der_read_private_key_dsa (keydata, n_keydata, s_key);

			/* Otherwise try the two part format that everyone seems to like */
			if (ret == GKM_DATA_UNRECOGNIZED && params && n_params)
				ret = gkm_data_der_read_private_key_dsa_parts (keydata, n_keydata,
				                                               params, n_params, s_key);
			break;
		default:
			g_message ("invalid or unsupported key type in PKCS#8 key");
			ret = GKM_DATA_UNRECOGNIZED;
			break;
		};

	} else if (ret == GKM_DATA_FAILURE) {
		g_message ("invalid PKCS#8 key");
	}

	egg_asn1x_destroy (asn);
	return ret;
}