Example #1
0
static void
test_encrypt_private_key (const char *path,
                          const char *password,
                          const char *desc)
{
	NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN;
	GByteArray *array, *encrypted, *re_decrypted;
	GError *error = NULL;

	array = crypto_decrypt_private_key (path, password, &key_type, &error);
	ASSERT (array != NULL, desc,
	        "couldn't read private key file '%s': %d %s",
	        path, error->code, error->message);

	ASSERT (key_type == NM_CRYPTO_KEY_TYPE_RSA, desc,
	        "%s: unexpected private key type (expected %d, got %d)",
	        path, NM_CRYPTO_KEY_TYPE_RSA, key_type);

	/* Now re-encrypt the private key */
	if (is_cipher_aes (path))
		encrypted = nm_utils_rsa_key_encrypt_aes (array, password, NULL, &error);
	else
		encrypted = nm_utils_rsa_key_encrypt (array, password, NULL, &error);
	ASSERT (encrypted != NULL, desc,
	        "couldn't re-encrypt private key file '%s': %d %s",
	        path, error->code, error->message);

	/* Then re-decrypt the private key */
	key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN;
	re_decrypted = crypto_decrypt_private_key_data (encrypted, password, &key_type, &error);
	ASSERT (re_decrypted != NULL, desc,
	        "couldn't read private key file '%s': %d %s",
	        path, error->code, error->message);

	ASSERT (key_type == NM_CRYPTO_KEY_TYPE_RSA, desc,
	        "%s: unexpected private key type (expected %d, got %d)",
	        path, NM_CRYPTO_KEY_TYPE_RSA, key_type);

	/* Compare the original decrypted key with the re-decrypted key */
	ASSERT (array->len == re_decrypted->len, desc,
	        "%s: unexpected re-decrypted private key length (expected %d, got %d)",
	        path, array->len, re_decrypted->len);

	ASSERT (!memcmp (array->data, re_decrypted->data, array->len), desc,
	        "%s: unexpected private key data",
	        path);

	g_byte_array_free (re_decrypted, TRUE);
	g_byte_array_free (encrypted, TRUE);
	g_byte_array_free (array, TRUE);
}
Example #2
0
GByteArray *
crypto_decrypt_private_key (const char *file,
                            const char *password,
                            NMCryptoKeyType *out_key_type,
                            GError **error)
{
	GByteArray *contents;
	GByteArray *key = NULL;

	contents = file_to_g_byte_array (file, error);
	if (contents) {
		key = crypto_decrypt_private_key_data (contents, password, out_key_type, error);
		g_byte_array_free (contents, TRUE);
	}
	return key;
}
Example #3
0
/* Verifies that a private key can be read, and if a password is given, that
 * the private key can be decrypted with that password.
 */
NMCryptoFileFormat
crypto_verify_private_key_data (const GByteArray *contents,
                                const char *password,
                                GError **error)
{
	GByteArray *tmp;
	NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
	NMCryptoKeyType ktype = NM_CRYPTO_KEY_TYPE_UNKNOWN;
	gboolean is_encrypted = FALSE;

	g_return_val_if_fail (contents != NULL, FALSE);

	/* Check for PKCS#12 first */
	if (crypto_is_pkcs12_data (contents)) {
		if (!password || crypto_verify_pkcs12 (contents, password, error))
			format = NM_CRYPTO_FILE_FORMAT_PKCS12;
	} else {
		/* Maybe it's PKCS#8 */
		tmp = parse_pkcs8_key_file (contents, &is_encrypted, error);
		if (tmp) {
			if (!password || crypto_verify_pkcs8 (tmp, is_encrypted, password, error))
				format = NM_CRYPTO_FILE_FORMAT_RAW_KEY;
		} else {
			g_clear_error (error);

			/* Or it's old-style OpenSSL */
			tmp = crypto_decrypt_private_key_data (contents, password, &ktype, error);
			if (tmp)
				format = NM_CRYPTO_FILE_FORMAT_RAW_KEY;
			else if (!password && (ktype != NM_CRYPTO_KEY_TYPE_UNKNOWN))
				format = NM_CRYPTO_FILE_FORMAT_RAW_KEY;
		}

		if (tmp) {
			/* Don't leave decrypted key data around */
			memset (tmp->data, 0, tmp->len);
			g_byte_array_free (tmp, TRUE);
		}
	}

	return format;
}