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