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; }
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); }
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; }
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; }
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; }