示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}