コード例 #1
0
static gconstpointer
_gcr_certificate_get_subject_const (GcrCertificate *self, gsize *n_data)
{
	GcrCertificateInfo *info;

	info = certificate_info_load (self);
	g_return_val_if_fail (info, NULL);

	return egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subject", NULL), n_data);
}
コード例 #2
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;
}
コード例 #3
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;
}
コード例 #4
0
static gboolean
load_assertions (GkmXdgTrust *self, GNode *asn)
{
	gconstpointer element;
	GHashTable *assertions;
	GkmAssertion *assertion;
	gsize n_element;
	GByteArray *key;
	GNode *node;
	guint count, i;

	g_assert (self);
	g_assert (asn);

	assertions = self->pv->assertions;
	self->pv->assertions = create_assertions ();

	count = egg_asn1x_count (egg_asn1x_node (asn, "assertions", NULL));

	for (i = 0; i < count; ++i) {
		node = egg_asn1x_node (asn, "assertions", i + 1, NULL);
		g_return_val_if_fail (node, FALSE);

		/* We use the raw DER encoding as an assertion */
		element = egg_asn1x_get_raw_element (node, &n_element);
		g_return_val_if_fail (node, FALSE);

		/* Double check that this is valid, because it's how we hash */
		key = g_byte_array_new ();
		g_byte_array_append (key, element, n_element);

		/* Already have this assertion? */
		assertion = g_hash_table_lookup (assertions, key);
		if (assertion) {
			if (!g_hash_table_steal (assertions, key))
				g_assert_not_reached ();

		/* Create a new assertion */
		} else {
			assertion = create_assertion (self, node);
		}

		add_assertion_to_trust (self, assertion, NULL);
		g_byte_array_unref (key);
		g_object_unref (assertion);
	}

	/* Override the stored assertions and netscape trust */
	g_hash_table_remove_all (assertions);
	g_hash_table_unref (assertions);

	return TRUE;
}
コード例 #5
0
static CK_RV
trust_get_complete (GkmXdgTrust *self, CK_ATTRIBUTE_PTR attr)
{
	GNode *cert;
	gconstpointer element;
	gsize n_element;

	cert = egg_asn1x_node (self->pv->asn, "reference", "certComplete", NULL);
	g_return_val_if_fail (cert, CKR_GENERAL_ERROR);

	/* If it's not stored, then this attribute is not present */
	if (!egg_asn1x_have (cert))
		return CKR_ATTRIBUTE_TYPE_INVALID;

	element = egg_asn1x_get_raw_element (cert, &n_element);
	g_return_val_if_fail (element, CKR_GENERAL_ERROR);

	return gkm_attribute_set_data (attr, element, n_element);
}
コード例 #6
0
static CK_RV
trust_get_der (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
{
	GNode *node;
	gconstpointer element;
	gsize n_element;

	g_assert (GKM_XDG_IS_TRUST (self));

	node = egg_asn1x_node (self->pv->asn, "reference", "certReference", part, NULL);
	g_return_val_if_fail (node, CKR_GENERAL_ERROR);

	/* If the assertion doesn't contain this info ... */
	if (!egg_asn1x_have (node))
		return CKR_ATTRIBUTE_TYPE_INVALID;

	element = egg_asn1x_get_raw_element (node, &n_element);
	return gkm_attribute_set_data (attr, element, n_element);
}
コード例 #7
0
static void
dump_certificate_complete (GNode *asn)
{
	GNode *cert;
	gchar *issuer, *serial, *subject;
	gconstpointer element;
	gpointer data;
	gsize n_data, n_element;

	/* Parse the certificate out */
	cert = egg_asn1x_create (pkix_asn1_tab, "Certificate");
	g_return_if_fail (cert);
	element = egg_asn1x_get_raw_element (asn, &n_element);
	g_return_if_fail (element);
	if (!egg_asn1x_decode (cert, element, n_element))
		barf_and_die ("couldn't parse certificate", egg_asn1x_message (cert));

	issuer = egg_dn_read (egg_asn1x_node (asn, "issuer", NULL));
	g_return_if_fail (issuer);

	subject = egg_dn_read (egg_asn1x_node (asn, "subject", NULL));
	g_return_if_fail (subject);

	data = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "serial", NULL), NULL, &n_data);
	g_return_if_fail (data && n_data);
	serial = egg_hex_encode (data, n_data);
	g_free (data);

	g_print ("Complete\n");
	g_print ("    issuer: %s\n", issuer);
	g_print ("    subject: %s\n", subject);
	g_print ("    serial: 0x%s\n", serial);

	egg_asn1x_destroy (cert);

	g_free (data);
	g_free (serial);
	g_free (issuer);
	g_free (subject);
}
コード例 #8
0
static void
dump_certificate_reference (GNode *asn)
{
	gchar *issuer, *serial;
	gpointer data;
	gsize n_data;
	GNode *name;
	gconstpointer element;
	gsize n_element;

	/* Parse the name out */
	name = egg_asn1x_create (pkix_asn1_tab, "Name");
	g_return_if_fail (name);
	element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "issuer", NULL), &n_element);
	g_return_if_fail (element);
	if (!egg_asn1x_decode (name, element, n_element))
		barf_and_die ("couldn't parse certificate", egg_asn1x_message (name));

	issuer = egg_dn_read (name);
	g_return_if_fail (issuer);

	data = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "serial", NULL), NULL, &n_data);
	g_return_if_fail (data && n_data);
	serial = egg_hex_encode (data, n_data);
	g_free (data);

	g_print ("Reference\n");
	g_print ("    issuer: %s\n", issuer);
	g_print ("    serial: 0x%s\n", serial);

	egg_asn1x_destroy (name);

	g_free (data);
	g_free (serial);
	g_free (issuer);
}
コード例 #9
0
static CK_RV
gkm_certificate_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE* attr)
{
	GkmCertificate *self = GKM_CERTIFICATE (base);
	CK_ULONG category;
	const guchar *cdata;
	guchar *data;
	gsize n_data;
	time_t when;
	CK_RV rv;

	switch (attr->type) {

	case CKA_CLASS:
		return gkm_attribute_set_ulong (attr, CKO_CERTIFICATE);

	case CKA_PRIVATE:
		return gkm_attribute_set_bool (attr, FALSE);

	case CKA_LABEL:
		return gkm_attribute_set_string (attr, gkm_certificate_get_label (self));

	case CKA_CERTIFICATE_TYPE:
		return gkm_attribute_set_ulong (attr, CKC_X_509);

	case CKA_TRUSTED:
		return gkm_attribute_set_bool (attr, FALSE);

	case CKA_CERTIFICATE_CATEGORY:
		if (!gkm_certificate_calc_category (self, session, &category))
			return CKR_FUNCTION_FAILED;
		return gkm_attribute_set_ulong (attr, category);

	case CKA_CHECK_VALUE:
		g_return_val_if_fail (self->pv->data, CKR_GENERAL_ERROR);
		n_data = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
		g_return_val_if_fail (n_data && n_data > 3, CKR_GENERAL_ERROR);
		data = g_new0 (guchar, n_data);
		gcry_md_hash_buffer (GCRY_MD_SHA1, data, self->pv->data, self->pv->n_data);
		rv = gkm_attribute_set_data (attr, data, 3);
		g_free (data);
		return rv;

	case CKA_START_DATE:
	case CKA_END_DATE:
		g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
		when = egg_asn1x_get_time_as_long (egg_asn1x_node (self->pv->asn1,
		                                                   "tbsCertificate", "validity",
		                                                   attr->type == CKA_START_DATE ? "notBefore" : "notAfter",
		                                                   NULL));
		if (when < 0)
			return CKR_FUNCTION_FAILED;
		return gkm_attribute_set_date (attr, when);

	case CKA_SUBJECT:
		g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
		cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "subject", NULL), &n_data);
		g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
		return gkm_attribute_set_data (attr, cdata, n_data);

	case CKA_ID:
		if (!self->pv->key)
			return gkm_attribute_set_data (attr, NULL, 0);
		return gkm_object_get_attribute (GKM_OBJECT (self->pv->key), session, attr);

	case CKA_ISSUER:
		g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
		cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "issuer", NULL), &n_data);
		g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
		return gkm_attribute_set_data (attr, cdata, n_data);

	case CKA_SERIAL_NUMBER:
		g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
		cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "serialNumber", NULL), &n_data);
		g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
		return gkm_attribute_set_data (attr, cdata, n_data);

	case CKA_VALUE:
		g_return_val_if_fail (self->pv->data, CKR_GENERAL_ERROR);
		return gkm_attribute_set_data (attr, self->pv->data, self->pv->n_data);

	/* These are only used for strange online certificates which we don't support */
	case CKA_URL:
	case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
	case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
		return gkm_attribute_set_data (attr, "", 0);

	/* What in the world is this doing in the spec? */
	case CKA_JAVA_MIDP_SECURITY_DOMAIN:
		return gkm_attribute_set_ulong (attr, 0); /* 0 = unspecified */
	};

	return GKM_OBJECT_CLASS (gkm_certificate_parent_class)->get_attribute (base, session, attr);
}
コード例 #10
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;
}
コード例 #11
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;
}