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_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 gboolean decrypt_buffer (EggBuffer *buffer, GkmSecret *master, guchar salt[8], int iterations) { const gchar *password = NULL; gcry_cipher_hd_t cih; gcry_error_t gerr; guchar *key, *iv; gsize n_password = 0; size_t pos; g_assert (buffer->len % 16 == 0); g_assert (16 == gcry_cipher_get_algo_blklen (GCRY_CIPHER_AES128)); g_assert (16 == gcry_cipher_get_algo_keylen (GCRY_CIPHER_AES128)); /* No password is set, try an null password */ if (master == NULL) { password = NULL; n_password = 0; } else { password = gkm_secret_get_password (master, &n_password); } if (!egg_symkey_generate_simple (GCRY_CIPHER_AES128, GCRY_MD_SHA256, password, n_password, salt, 8, iterations, &key, &iv)) return FALSE; gerr = gcry_cipher_open (&cih, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0); if (gerr) { g_warning ("couldn't create aes cipher context: %s", gcry_strerror (gerr)); egg_secure_free (key); g_free (iv); return FALSE; } /* 16 = 128 bits */ gerr = gcry_cipher_setkey (cih, key, 16); g_return_val_if_fail (!gerr, FALSE); egg_secure_free (key); /* 16 = 128 bits */ gerr = gcry_cipher_setiv (cih, iv, 16); g_return_val_if_fail (!gerr, FALSE); g_free (iv); for (pos = 0; pos < buffer->len; pos += 16) { /* In place encryption */ gerr = gcry_cipher_decrypt (cih, buffer->buf + pos, 16, NULL, 0); g_return_val_if_fail (!gerr, FALSE); } gcry_cipher_close (cih); return TRUE; }
const gchar* gkm_credential_get_password (GkmCredential *self, gsize *n_password) { g_return_val_if_fail (GKM_IS_CREDENTIAL (self), NULL); g_return_val_if_fail (n_password, NULL); if (!self->pv->secret) { *n_password = 0; return NULL; } return gkm_secret_get_password (self->pv->secret, n_password); }
static GkmSexp* gkm_gnome2_private_key_real_acquire_crypto_sexp (GkmSexpKey *base, GkmSession *unused) { GkmGnome2PrivateKey *self = GKM_GNOME2_PRIVATE_KEY (base); gcry_sexp_t sexp; GkmDataResult res; const gchar *password; gsize n_password; /* Non encrypted case */ if (self->private_sexp) return gkm_sexp_ref (self->private_sexp); g_return_val_if_fail (self->login, NULL); g_return_val_if_fail (self->is_encrypted, NULL); password = gkm_secret_get_password (self->login, &n_password); res = gkm_data_der_read_private_pkcs8 (self->private_bytes, password, n_password, &sexp); g_return_val_if_fail (res == GKM_DATA_SUCCESS, NULL); return gkm_sexp_new (sexp); }
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; }