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; }
guchar* gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *password, gsize n_password, gsize *n_data) { gcry_error_t gcry; gcry_cipher_hd_t cih; GNode *asn = NULL; guchar *key, *data; gsize n_key, block = 0; /* Encode the key in normal pkcs8 fashion */ key = gkm_data_der_write_private_pkcs8_plain (skey, &n_key); if (key == NULL) return NULL; asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo"); g_return_val_if_fail (asn, NULL); /* Create a and write out a cipher used for encryption */ cih = prepare_and_encode_pkcs8_cipher (asn, password, n_password, &block); g_return_val_if_fail (cih, NULL); /* Pad the block of data */ if(block > 1) { gsize pad; guchar *padded; pad = block - (n_key % block); if (pad == 0) pad = block; padded = egg_secure_realloc (key, n_key + pad); memset (padded + n_key, pad, pad); key = padded; n_key += pad; } gcry = gcry_cipher_encrypt (cih, key, n_key, NULL, 0); g_return_val_if_fail (gcry == 0, NULL); gcry_cipher_close (cih); if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), key, n_key, egg_secure_free)) g_return_val_if_reached (NULL); data = egg_asn1x_encode (asn, NULL, n_data); if (data == NULL) g_warning ("couldn't encode encrypted pkcs8 key: %s", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); return data; }
GBytes * gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *password, gsize n_password) { gcry_error_t gcry; gcry_cipher_hd_t cih; GNode *asn = NULL; GBytes *key, *data; guchar *raw; gsize n_raw, n_key; gsize block = 0; /* Encode the key in normal pkcs8 fashion */ key = gkm_data_der_write_private_pkcs8_plain (skey); if (key == NULL) return NULL; asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo"); g_return_val_if_fail (asn, NULL); /* Create a and write out a cipher used for encryption */ cih = prepare_and_encode_pkcs8_cipher (asn, password, n_password, &block); g_return_val_if_fail (cih, NULL); n_key = g_bytes_get_size (key); /* Pad the block of data */ if(block > 1) { gsize n_pad = block - (n_key % block); if (n_pad == 0) n_pad = block; raw = egg_secure_alloc (n_key + n_pad); memcpy (raw, g_bytes_get_data (key, NULL), n_key); memset (raw + n_key, (int)n_pad, n_pad); n_raw = n_key + n_pad; /* No padding, probably stream cipher */ } else { raw = egg_secure_alloc (n_key); memcpy (raw, g_bytes_get_data (key, NULL), n_key); n_raw = n_key; } g_bytes_unref (key); gcry = gcry_cipher_encrypt (cih, raw, n_raw, NULL, 0); g_return_val_if_fail (gcry == 0, NULL); gcry_cipher_close (cih); key = g_bytes_new_with_free_func (raw, n_raw, egg_secure_free, raw); egg_asn1x_set_string_as_bytes (egg_asn1x_node (asn, "encryptedData", NULL), key); g_bytes_unref (key); data = egg_asn1x_encode (asn, NULL); if (data == NULL) g_warning ("couldn't encode encrypted pkcs8 key: %s", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); return data; }