Exemplo n.º 1
0
static void
realize_and_take_data (GkmSshPrivateKey *self,
                       gcry_sexp_t sexp,
                       gchar *comment,
                       GBytes *private_data)
{
	GkmSexp *wrapper;

	g_assert (GKM_IS_SSH_PRIVATE_KEY (self));

	/* The base public key gets setup. */
	wrapper = gkm_sexp_new (sexp);
	gkm_sexp_key_set_base (GKM_SEXP_KEY (self), wrapper);
	gkm_sexp_key_set_base (GKM_SEXP_KEY (self->pubkey), wrapper);
	gkm_sexp_unref (wrapper);

	/* Own the comment */
	gkm_ssh_public_key_set_label (self->pubkey, comment);
	gkm_ssh_private_key_set_label (self, comment);
	g_free (comment);

	/* Own the data */
	if (self->private_bytes)
		g_bytes_unref (self->private_bytes);
	self->private_bytes = private_data;

	/* Try to parse the private data, and note if it's not actually encrypted */
	self->is_encrypted = TRUE;
	if (unlock_private_key (self, "", 0, &wrapper) == CKR_OK) {
		self->is_encrypted = FALSE;
		gkm_private_xsa_key_set_unlocked_private (GKM_PRIVATE_XSA_KEY (self), wrapper);
		gkm_sexp_unref (wrapper);
	}
}
static GkmObject*
factory_create_private_key (GkmSession *session, GkmTransaction *transaction,
                            CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
	GkmGnome2PrivateKey *key;
	GkmSexp *sexp;

	g_return_val_if_fail (attrs || !n_attrs, NULL);

	sexp = gkm_private_xsa_key_create_sexp (session, transaction, attrs, n_attrs);
	if (sexp == NULL)
		return NULL;

	key = g_object_new (GKM_TYPE_GNOME2_PRIVATE_KEY, "base-sexp", sexp,
	                    "module", gkm_session_get_module (session),
	                    "manager", gkm_manager_for_template (attrs, n_attrs, session),
	                    NULL);
	g_return_val_if_fail (!key->private_sexp, NULL);
	key->private_sexp = gkm_sexp_ref (sexp);

	gkm_sexp_unref (sexp);

	/* TODO: We don't support setting these yet, so ignore them */
	gkm_attributes_consume (attrs, n_attrs,
	                        CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_ID,
	                        G_MAXULONG);

	gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (key),
	                                      TRUE, attrs, n_attrs);
	return GKM_OBJECT (key);
}
static GBytes *
gkm_gnome2_private_key_real_save (GkmSerializable *base, GkmSecret *login)
{
	GkmGnome2PrivateKey *self = GKM_GNOME2_PRIVATE_KEY (base);
	const gchar *password = NULL;
	gsize n_password;
	GkmSexp *sexp;
	GBytes *result;

	g_return_val_if_fail (GKM_IS_GNOME2_PRIVATE_KEY (self), FALSE);

	sexp = gkm_gnome2_private_key_real_acquire_crypto_sexp (GKM_SEXP_KEY (self), NULL);
	g_return_val_if_fail (sexp, FALSE);

	if (login != NULL)
		password = gkm_secret_get_password (login, &n_password);
	if (password == NULL) {
		result = gkm_data_der_write_private_pkcs8_plain (gkm_sexp_get (sexp));
	} else {
		result = gkm_data_der_write_private_pkcs8_crypted (gkm_sexp_get (sexp), password,
		                                                   n_password);
	}

	gkm_sexp_unref (sexp);
	return result;
}
Exemplo n.º 4
0
static gboolean
gkm_mate2_public_key_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data)
{
	GkmMate2PublicKey *self = GKM_MATE2_PUBLIC_KEY (base);
	GkmDataResult res;
	GkmSexp *wrapper;
	gcry_sexp_t sexp;

	g_return_val_if_fail (GKM_IS_MATE2_PUBLIC_KEY (self), FALSE);
	g_return_val_if_fail (data, FALSE);

	res = gkm_data_der_read_public_key (data, n_data, &sexp);

	switch (res) {
	case GKM_DATA_LOCKED:
		g_message ("public key is locked");
		return FALSE;
	case GKM_DATA_FAILURE:
		g_message ("couldn't parse public key");
		return FALSE;
	case GKM_DATA_UNRECOGNIZED:
		g_message ("invalid or unrecognized public key");
		return FALSE;
	case GKM_DATA_SUCCESS:
		break;
	default:
		g_assert_not_reached();
	}

	wrapper = gkm_sexp_new (sexp);
	gkm_sexp_key_set_base (GKM_SEXP_KEY (self), wrapper);
	gkm_sexp_unref (wrapper);

	return TRUE;
}
static GkmObject*
factory_create_private_key (GkmSession *session, GkmTransaction *transaction,
                            CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
	GkmMate2PrivateKey *key;
	GkmSexp *sexp;

	g_return_val_if_fail (attrs || !n_attrs, NULL);

	sexp = gkm_private_xsa_key_create_sexp (session, transaction, attrs, n_attrs);
	if (sexp == NULL)
		return NULL;

	key = g_object_new (GKM_TYPE_MATE2_PRIVATE_KEY, "base-sexp", sexp,
	                    "module", gkm_session_get_module (session),
	                    "manager", gkm_manager_for_template (attrs, n_attrs, session),
	                    NULL);
	g_return_val_if_fail (!key->private_sexp, NULL);
	key->private_sexp = gkm_sexp_ref (sexp);

	gkm_sexp_unref (sexp);

	gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (key),
	                                      TRUE, attrs, n_attrs);
	return GKM_OBJECT (key);
}
static gboolean
gkm_mate2_private_key_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data, gsize *n_data)
{
	GkmMate2PrivateKey *self = GKM_MATE2_PRIVATE_KEY (base);
	const gchar *password;
	gsize n_password;
	GkmSexp *sexp;
	guchar *key;

	g_return_val_if_fail (GKM_IS_MATE2_PRIVATE_KEY (self), FALSE);
	g_return_val_if_fail (data, FALSE);
	g_return_val_if_fail (n_data, FALSE);

	sexp = gkm_mate2_private_key_real_acquire_crypto_sexp (GKM_SEXP_KEY (self), NULL);
	g_return_val_if_fail (sexp, FALSE);

	password = gkm_secret_get_password (login, &n_password);
	if (password == NULL) {
		key = gkm_data_der_write_private_pkcs8_plain (gkm_sexp_get (sexp), n_data);

		/*
		 * Caller is expecting normal memory buffer, which makes sense since
		 * this is being written to disk, and won't be 'secure' anyway.
		 */
		*data = g_memdup (key, *n_data);
		egg_secure_free (key);
	} else {
		*data = gkm_data_der_write_private_pkcs8_crypted (gkm_sexp_get (sexp), password,
		                                                  n_password, n_data);
	}

	gkm_sexp_unref (sexp);
	return *data != NULL;
}
static void
gkm_gnome2_private_key_finalize (GObject *obj)
{
	GkmGnome2PrivateKey *self = GKM_GNOME2_PRIVATE_KEY (obj);

	g_assert (self->login == NULL);

	if (self->private_bytes)
		g_bytes_unref (self->private_bytes);

	if (self->private_sexp)
		gkm_sexp_unref (self->private_sexp);
	self->private_sexp = NULL;

	G_OBJECT_CLASS (gkm_gnome2_private_key_parent_class)->finalize (obj);
}
static void
gkm_mate2_private_key_finalize (GObject *obj)
{
	GkmMate2PrivateKey *self = GKM_MATE2_PRIVATE_KEY (obj);

	g_assert (self->login == NULL);

	g_free (self->private_data);
	self->private_data = NULL;

	if (self->private_sexp)
		gkm_sexp_unref (self->private_sexp);
	self->private_sexp = NULL;

	G_OBJECT_CLASS (gkm_mate2_private_key_parent_class)->finalize (obj);
}
Exemplo n.º 9
0
static GkmObject*
factory_create_public_key (GkmSession *session, GkmTransaction *transaction,
                           CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
	GkmObject *object = NULL;
	GkmSexp *sexp;

	g_return_val_if_fail (attrs || !n_attrs, NULL);

	sexp = gkm_public_xsa_key_create_sexp (session, transaction, attrs, n_attrs);
	if (sexp != NULL) {
		object = g_object_new (GKM_TYPE_MATE2_PUBLIC_KEY, "base-sexp", sexp,
		                       "module", gkm_session_get_module (session),
		                       "manager", gkm_manager_for_template (attrs, n_attrs, session),
		                       NULL);
		gkm_sexp_unref (sexp);
		gkm_session_complete_object_creation (session, transaction, object,
		                                      TRUE, attrs, n_attrs);
	}

	return object;
}
Exemplo n.º 10
0
static CK_RV
gkm_ssh_private_key_unlock (GkmObject *base, GkmCredential *cred)
{
	GkmSshPrivateKey *self = GKM_SSH_PRIVATE_KEY (base);
	const gchar *password;
	GkmSexp *wrapper;
	gsize n_password;
	CK_RV rv;

	if (!self->is_encrypted)
		return CKR_OK;

	password = gkm_credential_get_password (cred, &n_password);
	rv = unlock_private_key (self, password, n_password, &wrapper);

	if (rv == CKR_OK) {
		gkm_private_xsa_key_set_locked_private (GKM_PRIVATE_XSA_KEY (self), cred, wrapper);
		gkm_sexp_unref (wrapper);
	}

	return rv;
}
static gboolean
gkm_gnome2_private_key_real_load (GkmSerializable *base,
                                  GkmSecret *login,
                                  GBytes *data)
{
	GkmGnome2PrivateKey *self = GKM_GNOME2_PRIVATE_KEY (base);
	GkmDataResult res;
	gcry_sexp_t sexp, pub;
	GkmSexp *wrapper;
	const gchar *password;
	gsize n_password;

	if (g_bytes_get_size (data) == 0)
		return FALSE;

	res = gkm_data_der_read_private_pkcs8 (data, NULL, 0, &sexp);

	/* An unencrypted pkcs8 file */
	if (res == GKM_DATA_SUCCESS) {
		self->is_encrypted = FALSE;

	/* If it's locked, then use our token password */
	} else if (res == GKM_DATA_LOCKED) {
		self->is_encrypted = TRUE;

		if (!login) {
			g_message ("encountered private key but no private key present");
			return FALSE;
		}

		password = gkm_secret_get_password (login, &n_password);
		res = gkm_data_der_read_private_pkcs8 (data, password, n_password, &sexp);
	}

	switch (res) {
	case GKM_DATA_LOCKED:
		g_message ("private key is encrypted with wrong password");
		return FALSE;
	case GKM_DATA_FAILURE:
		g_message ("couldn't parse private key");
		return FALSE;
	case GKM_DATA_UNRECOGNIZED:
		g_message ("invalid or unrecognized private key");
		return FALSE;
	case GKM_DATA_SUCCESS:
		break;
	default:
		g_assert_not_reached();
	}

	/* Calculate a public key as our 'base' */
	if (!gkm_sexp_key_to_public (sexp, &pub))
		g_return_val_if_reached (FALSE);

	/* Keep the public part of the key around for answering queries */
	wrapper = gkm_sexp_new (pub);
	gkm_sexp_key_set_base (GKM_SEXP_KEY (self), wrapper);
	gkm_sexp_unref (wrapper);

	/* Encrypted private key, keep login and data */
	if (self->is_encrypted) {
		if (self->private_bytes)
			g_bytes_unref (self->private_bytes);
		self->private_bytes = g_bytes_ref (data);

		g_object_ref (login);
		if (self->login)
			g_object_unref (self->login);
		self->login = login;

		/* Don't need the private key any more */
		gcry_sexp_release (sexp);

	/* Not encrypted, just keep the parsed key */
	} else {
		wrapper = gkm_sexp_new (sexp);
		if (self->private_sexp)
			gkm_sexp_unref (self->private_sexp);
		self->private_sexp = wrapper;

		if (self->login)
			g_object_unref (login);
		self->login = NULL;
	}

	return TRUE;
}
Exemplo n.º 12
0
static gboolean
gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data)
{
	GkmCertificate *self = GKM_CERTIFICATE (base);
	GNode *asn1 = NULL;
	GkmDataResult res;
	guchar *copy, *keydata;
	gsize n_keydata;
	gcry_sexp_t sexp;
	GkmSexp *wrapper;

	g_return_val_if_fail (GKM_IS_CERTIFICATE (self), FALSE);

	if (!data || !n_data) {
		g_message ("cannot load empty certificate file");
		return FALSE;
	}

	copy = g_memdup (data, n_data);

	/* Parse the ASN1 data */
	res = gkm_data_der_read_certificate (copy, n_data, &asn1);
	if (res != GKM_DATA_SUCCESS) {
		g_message ("couldn't parse certificate data");
		g_free (copy);
		return FALSE;
	}

	/* Generate a raw public key from our certificate */
	keydata = egg_asn1x_encode (egg_asn1x_node (asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), NULL, &n_keydata);
	g_return_val_if_fail (keydata, FALSE);

	/* Now create us a nice public key with that identifier */
	res = gkm_data_der_read_public_key_info (keydata, n_keydata, &sexp);
	g_free (keydata);

	switch (res) {

	/* Create ourselves a public key with that */
	case GKM_DATA_SUCCESS:
		wrapper = gkm_sexp_new (sexp);
		if (!self->pv->key)
			self->pv->key = gkm_certificate_key_new (gkm_object_get_module (GKM_OBJECT (self)),
			                                         gkm_object_get_manager (GKM_OBJECT (self)),
			                                         self);
		gkm_sexp_key_set_base (GKM_SEXP_KEY (self->pv->key), wrapper);
		gkm_sexp_unref (wrapper);
		break;

	/* Unknown type of public key for this certificate, just ignore */
	case GKM_DATA_UNRECOGNIZED:
		if (self->pv->key)
			g_object_unref (self->pv->key);
		self->pv->key = NULL;
		break;

	/* Bad key, drop certificate */
	case GKM_DATA_FAILURE:
	case GKM_DATA_LOCKED:
		g_warning ("couldn't parse certificate key data");
		g_free (copy);
		egg_asn1x_destroy (asn1);
		return FALSE;

	default:
		g_assert_not_reached ();
		break;
	}

	g_free (self->pv->data);
	self->pv->data = copy;
	self->pv->n_data = n_data;

	egg_asn1x_destroy (self->pv->asn1);
	self->pv->asn1 = asn1;

	return TRUE;
}