Пример #1
0
static void
gkm_certificate_class_init (GkmCertificateClass *klass)
{
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
	GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);

	gkm_certificate_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (GkmCertificatePrivate));

	gobject_class->constructor = gkm_certificate_constructor;
	gobject_class->dispose = gkm_certificate_dispose;
	gobject_class->finalize = gkm_certificate_finalize;
	gobject_class->set_property = gkm_certificate_set_property;
	gobject_class->get_property = gkm_certificate_get_property;

	gkm_class->get_attribute = gkm_certificate_real_get_attribute;

	g_object_class_install_property (gobject_class, PROP_PUBLIC_KEY,
	           g_param_spec_object ("public-key", "Public Key", "Public key contained in certificate",
	                                GKM_TYPE_CERTIFICATE_KEY, G_PARAM_READABLE));

	g_object_class_install_property (gobject_class, PROP_PUBLIC_KEY,
	           g_param_spec_string ("label", "Label", "Label of the certificate",
	                                "", G_PARAM_READWRITE));

	init_quarks ();
}
Пример #2
0
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 void
gkm_xdg_trust_class_init (GkmXdgTrustClass *klass)
{
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
	GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
	GkmTrustClass *trust_class = GKM_TRUST_CLASS (klass);

	gobject_class->finalize = gkm_xdg_trust_finalize;
	gkm_class->get_attribute = gkm_xdg_trust_get_attribute;
	gkm_class->expose_object = gkm_xdg_trust_expose_object;
	trust_class->get_trust_level = gkm_xdg_trust_get_level;

	QDATA_ASSERTION_KEY = g_quark_from_static_string ("gkm-xdg-trust-assertion-key");
	g_type_class_add_private (klass, sizeof (GkmXdgTrustPrivate));

	init_quarks ();
}
Пример #4
0
const char *quark(const char *str)
{
  Array *bucket;
  char *value;
  size_t index;

  init_quarks();

  bucket = quarks->items[hash_function(str, 0) % HASH_SIZE];
  value = array_find_not(bucket, (array_item_predicate_t)strcmp, str);

  if (!value)
    {
      value = strdup(str);
      array_append(bucket, value);

      index = array_lower_bound(quarks_index, value, ptr_less);
      array_insert(quarks_index, index, value);
    }

  return value;
}
Пример #5
0
static gcry_cipher_hd_t
prepare_and_encode_pkcs8_cipher (GNode *asn, const gchar *password,
                                 gsize n_password, gsize *n_block)
{
	GNode *asn1_params = NULL;
	gcry_cipher_hd_t cih;
	guchar salt[8];
	gcry_error_t gcry;
	guchar *key, *iv, *portion;
	gsize n_key, n_portion;
	int iterations;

	init_quarks ();

	/* Make sure the encryption algorithm works */
	g_return_val_if_fail (gcry_cipher_algo_info (OID_PKCS12_PBE_3DES_SHA1,
	                                             GCRYCTL_TEST_ALGO, NULL, 0), NULL);

	/* The encryption algorithm */
	if(!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL),
	                                OID_PKCS12_PBE_3DES_SHA1))
		g_return_val_if_reached (NULL);

	/* Randomize some input for the password based secret */
	iterations = 1000 + (int) (1000.0 * rand () / (RAND_MAX + 1.0));
	gcry_create_nonce (salt, sizeof (salt));

	/* Allocate space for the key and iv */
	n_key = gcry_cipher_get_algo_keylen (GCRY_CIPHER_3DES);
	*n_block = gcry_cipher_get_algo_blklen (GCRY_MD_SHA1);
	g_return_val_if_fail (n_key && *n_block, NULL);

	if (!egg_symkey_generate_pkcs12 (GCRY_CIPHER_3DES, GCRY_MD_SHA1,
	                                        password, n_password, salt,
	                                        sizeof (salt), iterations, &key, &iv))
		g_return_val_if_reached (NULL);

	/* Now write out the parameters */
	asn1_params = egg_asn1x_create (pkix_asn1_tab, "pkcs-12-PbeParams");
	g_return_val_if_fail (asn1_params, NULL);
	if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn1_params, "salt", NULL), salt, sizeof (salt), NULL))
		g_return_val_if_reached (NULL);
	if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn1_params, "iterations", NULL), iterations))
		g_return_val_if_reached (NULL);
	portion = egg_asn1x_encode (asn1_params, NULL, &n_portion);
	if (portion == NULL) {
		g_warning ("couldn't encode pkcs8 params key: %s", egg_asn1x_message (asn1_params));
		g_return_val_if_reached (NULL);
	}

	if (!egg_asn1x_set_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL),
	                                portion, n_portion, g_free))
		g_return_val_if_reached (NULL);

	/* Now make a cipher that matches what we wrote out */
	gcry = gcry_cipher_open (&cih, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
	g_return_val_if_fail (gcry == 0, NULL);
	g_return_val_if_fail (cih, NULL);

	gcry_cipher_setiv (cih, iv, *n_block);
	gcry_cipher_setkey (cih, key, n_key);

	g_free (iv);
	egg_secure_free (key);
	egg_asn1x_destroy (asn1_params);

	return cih;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
guchar*
gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
{
	GNode *asn = NULL;
	int algorithm;
	gboolean is_priv;
	GQuark oid;
	guchar *params, *key, *data;
	gsize n_params, n_key;

	init_quarks ();

	/* Parse and check that the key is for real */
	if (!gkm_sexp_parse_key (skey, &algorithm, &is_priv, NULL))
		g_return_val_if_reached (NULL);
	g_return_val_if_fail (is_priv == TRUE, NULL);

	asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo");
	g_return_val_if_fail (asn, NULL);

	/* Write out the version */
	if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
		g_return_val_if_reached (NULL);

	/* Per algorithm differences */
	switch (algorithm)
	{
	/* RSA gets encoded in a standard simple way */
	case GCRY_PK_RSA:
		oid = OID_PKIX1_RSA;
		params = NULL;
		n_params = 0;
		key = gkm_data_der_write_private_key_rsa (skey, &n_key);
		break;

	/* DSA gets incoded with the params seperate */
	case GCRY_PK_DSA:
		oid = OID_PKIX1_DSA;
		key = gkm_data_der_write_private_key_dsa_part (skey, &n_key);
		params = gkm_data_der_write_private_key_dsa_params (skey, &n_params);
		break;

	default:
		g_warning ("trying to serialize unsupported private key algorithm: %d", algorithm);
		return NULL;
	};

	/* Write out the algorithm */
	if (!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL), oid))
		g_return_val_if_reached (NULL);

	/* Write out the parameters */
	if (params) {
		if (!egg_asn1x_set_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL),
		                                params, n_params, egg_secure_free))
			g_return_val_if_reached (NULL);
	}

	/* Write out the key portion */
	if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "privateKey", NULL),
	                                  key, n_key, egg_secure_free))
		g_return_val_if_reached (NULL);

	data = egg_asn1x_encode (asn, egg_secure_realloc, n_data);
	if (data == NULL)
		g_warning ("couldn't encode private pkcs8 key: %s", egg_asn1x_message (asn));

	egg_asn1x_destroy (asn);
	return data;
}
Пример #9
0
static gcry_cipher_hd_t
prepare_and_encode_pkcs8_cipher (GNode *asn, const gchar *password,
                                 gsize n_password, gsize *n_block)
{
	GNode *asn1_params = NULL;
	gcry_cipher_hd_t cih;
	guchar *salt;
	gsize n_salt;
	gcry_error_t gcry;
	guchar *key, *iv;
	gsize n_key;
	int iterations;

	init_quarks ();

	/* Make sure the encryption algorithm works */
	g_return_val_if_fail (gcry_cipher_algo_info (gcry_cipher_map_name (g_quark_to_string (OID_PKCS12_PBE_3DES_SHA1)),
	                                             GCRYCTL_TEST_ALGO, NULL, 0) == 0, NULL);

	/* The encryption algorithm */
	if(!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL),
	                                OID_PKCS12_PBE_3DES_SHA1))
		g_return_val_if_reached (NULL);

	/* Randomize some input for the password based secret */
	iterations = g_random_int_range (1000, 4096);
	n_salt = 8;
	salt = g_malloc (n_salt);
	gcry_create_nonce (salt, n_salt);

	/* Allocate space for the key and iv */
	n_key = gcry_cipher_get_algo_keylen (GCRY_CIPHER_3DES);
	*n_block = gcry_cipher_get_algo_blklen (GCRY_MD_SHA1);
	g_return_val_if_fail (n_key && *n_block, NULL);

	if (!egg_symkey_generate_pkcs12 (GCRY_CIPHER_3DES, GCRY_MD_SHA1,
	                                        password, n_password, salt,
	                                        sizeof (salt), iterations, &key, &iv))
		g_return_val_if_reached (NULL);

	/* Now write out the parameters */
	asn1_params = egg_asn1x_create (pkix_asn1_tab, "pkcs-12-PbeParams");
	g_return_val_if_fail (asn1_params, NULL);
	egg_asn1x_set_string_as_raw (egg_asn1x_node (asn1_params, "salt", NULL), salt, n_salt, g_free);
	egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn1_params, "iterations", NULL), iterations);
	egg_asn1x_set_any_from (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), asn1_params);

	/* Now make a cipher that matches what we wrote out */
	gcry = gcry_cipher_open (&cih, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
	g_return_val_if_fail (gcry == 0, NULL);
	g_return_val_if_fail (cih, NULL);

	gcry_cipher_setiv (cih, iv, *n_block);
	gcry_cipher_setkey (cih, key, n_key);

	g_free (iv);
	egg_secure_free (key);
	egg_asn1x_destroy (asn1_params);

	return cih;
}