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; }
static gboolean perform_decrypt (GcrSecretExchange *self, GKeyFile *input, guchar **secret, gsize *n_secret) { GcrSecretExchangeClass *klass; gpointer iv, value; guchar *result; gsize n_result, n_iv, n_value; gboolean ret; klass = GCR_SECRET_EXCHANGE_GET_CLASS (self); g_return_val_if_fail (klass->decrypt_transport_data, FALSE); iv = key_file_get_base64 (input, GCR_SECRET_EXCHANGE_PROTOCOL_1, "iv", &n_iv); value = key_file_get_base64 (input, GCR_SECRET_EXCHANGE_PROTOCOL_1, "secret", &n_value); if (value == NULL) { g_message ("secret-exchange: invalid or missing value"); g_free (iv); return FALSE; } ret = (klass->decrypt_transport_data) (self, egg_secure_realloc, value, n_value, iv, n_iv, &result, &n_result); g_free (value); g_free (iv); if (!ret) return FALSE; /* Reallocate a null terminator */ if (result) { result = egg_secure_realloc (result, n_result + 1); result[n_result] = 0; } *secret = result; *n_secret = n_result; return TRUE; }
static gchar* read_login_password (int fd) { /* We only accept a max of 8K as the login password */ #define MAX_LENGTH 8192 #define MAX_BLOCK 256 /* * When --login is specified then the login password is passed * in on stdin. All data (including newlines) are part of the * password. A zero length password is no password. */ gchar *buf = egg_secure_alloc (MAX_BLOCK); gchar *ret = NULL; int r, len = 0; for (;;) { r = read (fd, buf, MAX_BLOCK); if (r < 0) { if (errno == EAGAIN) continue; egg_secure_free (ret); egg_secure_free (buf); return NULL; } else if (r == 0 || len > MAX_LENGTH) { break; } else { ret = egg_secure_realloc (ret, len + r + 1); memset (ret + len, 0, r + 1); len = len + r; strncat (ret, buf, r); } } egg_secure_free (buf); return ret; }