mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-04 04:50:30 +01:00
libnm-core: add nm_utils_file_is_certificate() and _file_is_private_key()
Add nm-utils methods to check if a file is a certificate or private key file. nm-applet currently has its own internal versions of these, but they ended up having to duplicate a bunch of logic that we already have in crypto.c.
This commit is contained in:
parent
7c74e71e91
commit
1c4f41c610
5 changed files with 136 additions and 1 deletions
|
|
@ -2236,17 +2236,91 @@ nm_utils_rsa_key_encrypt_aes (const guint8 *data,
|
|||
error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_has_extension (const char *filename, const char *extensions[])
|
||||
{
|
||||
const char *ext;
|
||||
int i;
|
||||
|
||||
ext = strrchr (filename, '.');
|
||||
if (!ext)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; extensions[i]; i++) {
|
||||
if (!g_ascii_strcasecmp (ext, extensions[i]))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_file_is_certificate:
|
||||
* @filename: name of the file to test
|
||||
*
|
||||
* Tests if @filename has a valid extension for an X.509 certificate file
|
||||
* (".cer", ".crt", ".der", or ".pem"), and contains a certificate in a format
|
||||
* recognized by NetworkManager.
|
||||
*
|
||||
* Returns: %TRUE if the file is a certificate, %FALSE if it is not
|
||||
**/
|
||||
gboolean
|
||||
nm_utils_file_is_certificate (const char *filename)
|
||||
{
|
||||
const char *extensions[] = { ".der", ".pem", ".crt", ".cer", NULL };
|
||||
NMCryptoFileFormat file_format;
|
||||
GByteArray *cert;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
|
||||
if (!file_has_extension (filename, extensions))
|
||||
return FALSE;
|
||||
|
||||
cert = crypto_load_and_verify_certificate (filename, &file_format, NULL);
|
||||
if (cert)
|
||||
g_byte_array_unref (cert);
|
||||
|
||||
return file_format = NM_CRYPTO_FILE_FORMAT_X509;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_file_is_private_key:
|
||||
* @filename: name of the file to test
|
||||
* @out_encrypted: (out): on return, whether the file is encrypted
|
||||
*
|
||||
* Tests if @filename has a valid extension for an X.509 private key file
|
||||
* (".der", ".key", ".pem", or ".p12"), and contains a private key in a format
|
||||
* recognized by NetworkManager.
|
||||
*
|
||||
* Returns: %TRUE if the file is a private key, %FALSE if it is not
|
||||
**/
|
||||
gboolean
|
||||
nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted)
|
||||
{
|
||||
const char *extensions[] = { ".der", ".pem", ".p12", ".key", NULL };
|
||||
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (out_encrypted == NULL || *out_encrypted == FALSE, FALSE);
|
||||
|
||||
if (!file_has_extension (filename, extensions))
|
||||
return FALSE;
|
||||
|
||||
return crypto_verify_private_key (filename, NULL, out_encrypted, NULL) != NM_CRYPTO_FILE_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_file_is_pkcs12:
|
||||
* @filename: name of the file to test
|
||||
*
|
||||
* Utility function to find out if the @filename is in PKCS#<!-- -->12 format.
|
||||
* Tests if @filename is a PKCS#<!-- -->12 file.
|
||||
*
|
||||
* Returns: %TRUE if the file is PKCS#<!-- -->12, %FALSE if it is not
|
||||
**/
|
||||
gboolean
|
||||
nm_utils_file_is_pkcs12 (const char *filename)
|
||||
{
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
|
||||
return crypto_is_pkcs12_file (filename, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -137,6 +137,8 @@ GByteArray *nm_utils_rsa_key_encrypt_aes (const guint8 *data,
|
|||
const char *in_password,
|
||||
char **out_password,
|
||||
GError **error);
|
||||
gboolean nm_utils_file_is_certificate (const char *filename);
|
||||
gboolean nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted);
|
||||
gboolean nm_utils_file_is_pkcs12 (const char *filename);
|
||||
|
||||
guint32 nm_utils_wifi_freq_to_channel (guint32 freq);
|
||||
|
|
|
|||
27
libnm-core/tests/certs/test-key-only-decrypted.pem
Normal file
27
libnm-core/tests/certs/test-key-only-decrypted.pem
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAztLp+/SkzmaHzIst0sO4+r7qUwiVnidKBHgxoTbS5UL1dvck
|
||||
cbjTEP23V4ZoKQIb6ZMrr8B+PVgWNBAlhX4oLUL8NH/WTwrntrlAUcjliWDNc1Fj
|
||||
Z+FZNjFe0IdLXZeKQiLTQvKDYnmERVvYIJfi0TQjXuy/ikF8rYBQ85scUV3kKRzB
|
||||
xnyhAHAP9nl3AyL1S6t2yiCr4U5TbIZo6dYPbpVLtbXP02zUc9vAPR0gIHKrPiW7
|
||||
P81fLXf91wuo6wxzwD90JxdWzzGaqe3BOSfHqul3SPRtVok1XHlb9i+Mn5O8ExzQ
|
||||
dF8wGxVDcY7/Gt9lZWnCilqrBEqA3iApjUgcgwIDAQABAoIBAQC77HCmepf04ryp
|
||||
Yhz00NoXG7mWUMqBtXlPrlaKAWKG5dxbiBwZKLK/UYlxgbLK8BuklBCx1Nnfq1Yh
|
||||
YDp3nTWsSp0WpsF3eJUqNhD3Pu8xcD+9dEo6bUu+LgXUu9oC5Fq/1RzYS7qNk5RX
|
||||
4Sf0FY4GQLWS3tL7MJ20mE71yg5k7qRbDydOyhTh1m1CpRYONWxSsWVLM8KGRDJp
|
||||
iF0cdPfD5yoPFpgDk8gwzrnXJH2Wqzv8GvyYykRK5AW7tE50y0rTAM42WZ7YS6aZ
|
||||
FNMmtYxeyzXLY3LgPP0uko5anz3OXRcqCfHfFANG0y7B9MehbrjMgI6S1BbzFl07
|
||||
V1zVQVqhAoGBAPIfrWMlh1fHlRh4iRGXK2Hvxyv2oNz9KvQ4qRaLV9ejRDzdt7Pi
|
||||
/utbi5LGBuDw9016nXM3I77b6PukHzsHFnWGRnyRSbkMMt6mE17nggmNqcpFWfE8
|
||||
E7HcKMhk4gbuo5AHD3Ee1Gac2AUDnzYiE+sS6WI3O9d77cc5ych5jZ+nAoGBANqt
|
||||
VZCttjY0E+hEyTP37eaE8u0jfdK8AflTJlNUHWKXglES525iu8I/Bso8KaQYsYF3
|
||||
SezGRd3KQepQhtMjFKfSpF+tbnboP57Y3XGo8xhbxqV4kRX+XGsVoW3Vg2nPKBrR
|
||||
+dIY5nMwua+gkHWp9RDcemD2reiIZBVx95fK8dfFAoGAdCSH2pBs/MlrFqLzNTHr
|
||||
iH4pb0hN39O9YAsx6POMfo79s6izbyHLIID4Ub6WHB7ashrIHjVr+yin+NXAeWMr
|
||||
/dIcS7Kxx4c3e5/0mMi6kvSWZsWfoF0uIVo3YfEqjyK36OXKHXwpbNN9t+IF5ESy
|
||||
g0e+FfPiy7nR1Ig+5+CO8+8CgYEAp/75+Ug677FaidouaMpT7gC9UAkwJLFjItQK
|
||||
YYIBgTi8WOSY/2jCrhwVb1CA/RwrYjbuiARasGUt9oEe0x3kRHnC5e4rKxaJqdMZ
|
||||
bLRK7a+0EHNrouXiwjG/7s1VQ/ht6wzdS9btVBlezdogoQSMzQNU0SExwa7mlMMV
|
||||
X3v+B7ECgYAK+Yt4jnLH1LNWoDTU0Ug5hyXsQXV8lVBSnrkvS7GtP6ZA/4OqG7lJ
|
||||
/bTYFZGoiAGzOnC+YlAqSIu45CEnpr2xBsThQiWUVxspmQD1lEWWFcd77DPUwn3C
|
||||
59pLgx0AqJE3n6lBOwehiXbFKBdVzX8PfPZpuCK6qc/RiTILktwURA==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
@ -109,6 +109,8 @@ test_cert (gconstpointer test_data)
|
|||
g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_X509);
|
||||
|
||||
g_byte_array_free (array, TRUE);
|
||||
|
||||
g_assert (nm_utils_file_is_certificate (path));
|
||||
}
|
||||
|
||||
static GByteArray *
|
||||
|
|
@ -134,9 +136,13 @@ test_load_private_key (const char *path,
|
|||
int expected_error)
|
||||
{
|
||||
NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN;
|
||||
gboolean is_encrypted = FALSE;
|
||||
GByteArray *array, *decrypted;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (nm_utils_file_is_private_key (path, &is_encrypted));
|
||||
g_assert (is_encrypted);
|
||||
|
||||
array = crypto_decrypt_openssl_private_key (path, password, &key_type, &error);
|
||||
/* Even if the password is wrong, we should determine the key type */
|
||||
g_assert_cmpint (key_type, ==, NM_CRYPTO_KEY_TYPE_RSA);
|
||||
|
|
@ -178,6 +184,8 @@ test_load_pkcs12 (const char *path,
|
|||
gboolean is_encrypted = FALSE;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (nm_utils_file_is_private_key (path, NULL));
|
||||
|
||||
format = crypto_verify_private_key (path, password, &is_encrypted, &error);
|
||||
if (expected_error != -1) {
|
||||
g_assert_error (error, NM_CRYPTO_ERROR, expected_error);
|
||||
|
|
@ -197,6 +205,8 @@ test_load_pkcs12_no_password (const char *path)
|
|||
gboolean is_encrypted = FALSE;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (nm_utils_file_is_private_key (path, NULL));
|
||||
|
||||
/* We should still get a valid returned crypto file format */
|
||||
format = crypto_verify_private_key (path, NULL, &is_encrypted, &error);
|
||||
g_assert_no_error (error);
|
||||
|
|
@ -231,6 +241,8 @@ test_load_pkcs8 (const char *path,
|
|||
gboolean is_encrypted = FALSE;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (nm_utils_file_is_private_key (path, NULL));
|
||||
|
||||
format = crypto_verify_private_key (path, password, &is_encrypted, &error);
|
||||
if (expected_error != -1) {
|
||||
g_assert_error (error, NM_CRYPTO_ERROR, expected_error);
|
||||
|
|
@ -329,6 +341,21 @@ test_key (gconstpointer test_data)
|
|||
g_strfreev (parts);
|
||||
}
|
||||
|
||||
static void
|
||||
test_key_decrypted (gconstpointer test_data)
|
||||
{
|
||||
const char *file = (const char *) test_data;
|
||||
gboolean is_encrypted = FALSE;
|
||||
char *path;
|
||||
|
||||
path = g_build_filename (TEST_CERT_DIR, file, NULL);
|
||||
|
||||
g_assert (nm_utils_file_is_private_key (path, &is_encrypted));
|
||||
g_assert (!is_encrypted);
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_pkcs12 (gconstpointer test_data)
|
||||
{
|
||||
|
|
@ -418,6 +445,9 @@ main (int argc, char **argv)
|
|||
g_test_add_data_func ("/libnm/crypto/key/aes",
|
||||
"test-aes-key.pem, test-aes-password",
|
||||
test_key);
|
||||
g_test_add_data_func ("/libnm/crypto/key/decrypted",
|
||||
"test-key-only-decrypted.pem",
|
||||
test_key_decrypted);
|
||||
|
||||
g_test_add_data_func ("/libnm/crypto/PKCS#12/1",
|
||||
"test-cert.p12, test",
|
||||
|
|
|
|||
|
|
@ -756,7 +756,9 @@ global:
|
|||
nm_utils_check_virtual_device_compatibility;
|
||||
nm_utils_deinit;
|
||||
nm_utils_escape_ssid;
|
||||
nm_utils_file_is_certificate;
|
||||
nm_utils_file_is_pkcs12;
|
||||
nm_utils_file_is_private_key;
|
||||
nm_utils_hexstr2bin;
|
||||
nm_utils_hwaddr_atoba;
|
||||
nm_utils_hwaddr_aton;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue