mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 06:28:05 +02:00
libnm/crypto: refactor to use enum for supported ciphers
We need to (and already did) define our own identifier for ciphers, because the gnutls/nss identifiers must be abstracted. Don't use a string for that. The number of supported ciphers is not generic but fixed and known at compiler time. An enum is better suited.
This commit is contained in:
parent
1f550790bb
commit
858d5c3e91
5 changed files with 193 additions and 137 deletions
|
|
@ -33,7 +33,32 @@
|
|||
#include "nm-utils/nm-secret-utils.h"
|
||||
#include "nm-errors.h"
|
||||
|
||||
#define SALT_LEN 8
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_get_cipher_info (NMCryptoCipherType cipher,
|
||||
int *out_cipher_mech,
|
||||
guint8 *out_real_iv_len)
|
||||
{
|
||||
static const int cipher_mechs[] = {
|
||||
[NM_CRYPTO_CIPHER_DES_EDE3_CBC] = GNUTLS_CIPHER_3DES_CBC,
|
||||
[NM_CRYPTO_CIPHER_DES_CBC] = GNUTLS_CIPHER_DES_CBC,
|
||||
[NM_CRYPTO_CIPHER_AES_128_CBC] = GNUTLS_CIPHER_AES_128_CBC,
|
||||
[NM_CRYPTO_CIPHER_AES_192_CBC] = GNUTLS_CIPHER_AES_192_CBC,
|
||||
[NM_CRYPTO_CIPHER_AES_256_CBC] = GNUTLS_CIPHER_AES_256_CBC,
|
||||
};
|
||||
|
||||
g_return_val_if_fail (_NM_INT_NOT_NEGATIVE (cipher) && (gsize) cipher < G_N_ELEMENTS (cipher_mechs), FALSE);
|
||||
|
||||
if (cipher_mechs[cipher] == 0)
|
||||
return FALSE;
|
||||
|
||||
NM_SET_OUT (out_cipher_mech, cipher_mechs[cipher]);
|
||||
NM_SET_OUT (out_real_iv_len, nm_crypto_cipher_get_info (cipher)->real_iv_len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
|
|
@ -56,7 +81,7 @@ _nm_crypto_init (GError **error)
|
|||
}
|
||||
|
||||
guint8 *
|
||||
_nmtst_crypto_decrypt (const char *cipher,
|
||||
_nmtst_crypto_decrypt (NMCryptoCipherType cipher,
|
||||
const guint8 *data,
|
||||
gsize data_len,
|
||||
const guint8 *iv,
|
||||
|
|
@ -72,39 +97,24 @@ _nmtst_crypto_decrypt (const char *cipher,
|
|||
int cipher_mech, i;
|
||||
char *output = NULL;
|
||||
gboolean success = FALSE;
|
||||
gsize pad_len, real_iv_len;
|
||||
gsize pad_len;
|
||||
guint8 real_iv_len;
|
||||
|
||||
if (!_get_cipher_info (cipher, &cipher_mech, &real_iv_len)) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
|
||||
_("Unsupported key cipher for decryption"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_nm_crypto_init (error))
|
||||
return NULL;
|
||||
|
||||
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
|
||||
cipher_mech = GNUTLS_CIPHER_3DES_CBC;
|
||||
real_iv_len = SALT_LEN;
|
||||
} else if (!strcmp (cipher, CIPHER_DES_CBC)) {
|
||||
cipher_mech = GNUTLS_CIPHER_DES_CBC;
|
||||
real_iv_len = SALT_LEN;
|
||||
} else if (!strcmp (cipher, CIPHER_AES_128_CBC)) {
|
||||
cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
|
||||
real_iv_len = 16;
|
||||
} else if (!strcmp (cipher, CIPHER_AES_192_CBC)) {
|
||||
cipher_mech = GNUTLS_CIPHER_AES_192_CBC;
|
||||
real_iv_len = 16;
|
||||
} else if (!strcmp (cipher, CIPHER_AES_256_CBC)) {
|
||||
cipher_mech = GNUTLS_CIPHER_AES_256_CBC;
|
||||
real_iv_len = 16;
|
||||
} else {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
|
||||
_("Private key cipher '%s' was unknown."),
|
||||
cipher);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (iv_len < real_iv_len) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_INVALID_DATA,
|
||||
_("Invalid IV length (must be at least %zd)."),
|
||||
real_iv_len);
|
||||
_("Invalid IV length (must be at least %u)."),
|
||||
(guint) real_iv_len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +180,7 @@ out:
|
|||
}
|
||||
|
||||
guint8 *
|
||||
_nmtst_crypto_encrypt (const char *cipher,
|
||||
_nmtst_crypto_encrypt (NMCryptoCipherType cipher,
|
||||
const guint8 *data,
|
||||
gsize data_len,
|
||||
const guint8 *iv,
|
||||
|
|
@ -190,25 +200,17 @@ _nmtst_crypto_encrypt (const char *cipher,
|
|||
char *padded_buf = NULL;
|
||||
guint32 i;
|
||||
|
||||
if (!_nm_crypto_init (error))
|
||||
return NULL;
|
||||
|
||||
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC))
|
||||
cipher_mech = GNUTLS_CIPHER_3DES_CBC;
|
||||
else if (!strcmp (cipher, CIPHER_AES_128_CBC))
|
||||
cipher_mech = GNUTLS_CIPHER_AES_128_CBC;
|
||||
else if (!strcmp (cipher, CIPHER_AES_192_CBC))
|
||||
cipher_mech = GNUTLS_CIPHER_AES_192_CBC;
|
||||
else if (!strcmp (cipher, CIPHER_AES_256_CBC))
|
||||
cipher_mech = GNUTLS_CIPHER_AES_256_CBC;
|
||||
else {
|
||||
if ( cipher == NM_CRYPTO_CIPHER_DES_CBC
|
||||
|| !_get_cipher_info (cipher, &cipher_mech, NULL)) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
|
||||
_("Private key cipher '%s' was unknown."),
|
||||
cipher);
|
||||
_("Unsupported key cipher for encryption"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_nm_crypto_init (error))
|
||||
return NULL;
|
||||
|
||||
/* If data_len % ivlen == 0, then we add another complete block
|
||||
* onto the end so that the decrypter knows there's padding.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ gboolean _nm_crypto_verify_pkcs8 (const guint8 *data,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint8 *_nmtst_crypto_encrypt (const char *cipher,
|
||||
guint8 *_nmtst_crypto_encrypt (NMCryptoCipherType cipher,
|
||||
const guint8 *data,
|
||||
gsize data_len,
|
||||
const guint8 *iv,
|
||||
|
|
@ -61,7 +61,7 @@ guint8 *_nmtst_crypto_encrypt (const char *cipher,
|
|||
gsize *out_len,
|
||||
GError **error);
|
||||
|
||||
guint8 *_nmtst_crypto_decrypt (const char *cipher,
|
||||
guint8 *_nmtst_crypto_decrypt (NMCryptoCipherType cipher,
|
||||
const guint8 *data,
|
||||
gsize data_len,
|
||||
const guint8 *iv,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,33 @@
|
|||
#include "nm-utils/nm-secret-utils.h"
|
||||
#include "nm-errors.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_get_cipher_info (NMCryptoCipherType cipher,
|
||||
CK_MECHANISM_TYPE *out_cipher_mech,
|
||||
guint8 *out_real_iv_len)
|
||||
{
|
||||
static const CK_MECHANISM_TYPE cipher_mechs[] = {
|
||||
[NM_CRYPTO_CIPHER_DES_EDE3_CBC] = CKM_DES3_CBC_PAD,
|
||||
[NM_CRYPTO_CIPHER_DES_CBC] = CKM_DES_CBC_PAD,
|
||||
[NM_CRYPTO_CIPHER_AES_128_CBC] = CKM_AES_CBC_PAD,
|
||||
[NM_CRYPTO_CIPHER_AES_192_CBC] = CKM_AES_CBC_PAD,
|
||||
[NM_CRYPTO_CIPHER_AES_256_CBC] = CKM_AES_CBC_PAD,
|
||||
};
|
||||
|
||||
g_return_val_if_fail (_NM_INT_NOT_NEGATIVE (cipher) && (gsize) cipher < G_N_ELEMENTS (cipher_mechs), FALSE);
|
||||
|
||||
if (!cipher_mechs[cipher])
|
||||
return FALSE;
|
||||
|
||||
NM_SET_OUT (out_cipher_mech, cipher_mechs[cipher]);
|
||||
NM_SET_OUT (out_real_iv_len, nm_crypto_cipher_get_info (cipher)->real_iv_len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
gboolean
|
||||
|
|
@ -72,7 +99,7 @@ _nm_crypto_init (GError **error)
|
|||
}
|
||||
|
||||
guint8 *
|
||||
_nmtst_crypto_decrypt (const char *cipher,
|
||||
_nmtst_crypto_decrypt (NMCryptoCipherType cipher,
|
||||
const guint8 *data,
|
||||
gsize data_len,
|
||||
const guint8 *iv,
|
||||
|
|
@ -93,35 +120,24 @@ _nmtst_crypto_decrypt (const char *cipher,
|
|||
SECStatus s;
|
||||
gboolean success = FALSE;
|
||||
unsigned pad_len = 0, extra = 0;
|
||||
guint32 i, real_iv_len = 0;
|
||||
guint32 i;
|
||||
guint8 real_iv_len;
|
||||
|
||||
if (!_get_cipher_info (cipher, &cipher_mech, &real_iv_len)) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
|
||||
_("Unsupported key cipher for decryption"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_nm_crypto_init (error))
|
||||
return NULL;
|
||||
|
||||
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
|
||||
cipher_mech = CKM_DES3_CBC_PAD;
|
||||
real_iv_len = 8;
|
||||
} else if (!strcmp (cipher, CIPHER_DES_CBC)) {
|
||||
cipher_mech = CKM_DES_CBC_PAD;
|
||||
real_iv_len = 8;
|
||||
} else if (NM_IN_STRSET (cipher, CIPHER_AES_128_CBC,
|
||||
CIPHER_AES_192_CBC,
|
||||
CIPHER_AES_256_CBC)) {
|
||||
cipher_mech = CKM_AES_CBC_PAD;
|
||||
real_iv_len = 16;
|
||||
} else {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
|
||||
_("Private key cipher '%s' was unknown."),
|
||||
cipher);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (iv_len < real_iv_len) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_INVALID_DATA,
|
||||
_("Invalid IV length (must be at least %d)."),
|
||||
real_iv_len);
|
||||
_("Invalid IV length (must be at least %u)."),
|
||||
(guint) real_iv_len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +258,7 @@ out:
|
|||
}
|
||||
|
||||
guint8 *
|
||||
_nmtst_crypto_encrypt (const char *cipher,
|
||||
_nmtst_crypto_encrypt (NMCryptoCipherType cipher,
|
||||
const guint8 *data,
|
||||
gsize data_len,
|
||||
const guint8 *iv,
|
||||
|
|
@ -269,18 +285,11 @@ _nmtst_crypto_encrypt (const char *cipher,
|
|||
if (!_nm_crypto_init (error))
|
||||
return NULL;
|
||||
|
||||
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC))
|
||||
cipher_mech = CKM_DES3_CBC_PAD;
|
||||
else if (NM_IN_STRSET (cipher,
|
||||
CIPHER_AES_128_CBC,
|
||||
CIPHER_AES_192_CBC,
|
||||
CIPHER_AES_256_CBC))
|
||||
cipher_mech = CKM_AES_CBC_PAD;
|
||||
else {
|
||||
if ( cipher == NM_CRYPTO_CIPHER_DES_CBC
|
||||
|| !_get_cipher_info (cipher, &cipher_mech, NULL)) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
|
||||
_("Private key cipher '%s' was unknown."),
|
||||
cipher);
|
||||
_("Unsupported key cipher for encryption"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,64 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const NMCryptoCipherInfo cipher_infos[] = {
|
||||
#define _CI(_cipher, _name, _digest_len, _real_iv_len) \
|
||||
[(_cipher) - 1] = { .cipher = _cipher, .name = ""_name"", .digest_len = _digest_len, .real_iv_len = _real_iv_len }
|
||||
_CI (NM_CRYPTO_CIPHER_DES_EDE3_CBC, "DES-EDE3-CBC", 24, 8),
|
||||
_CI (NM_CRYPTO_CIPHER_DES_CBC, "DES-CBC", 8, 8),
|
||||
_CI (NM_CRYPTO_CIPHER_AES_128_CBC, "AES-128-CBC", 16, 16),
|
||||
_CI (NM_CRYPTO_CIPHER_AES_192_CBC, "AES-192-CBC", 24, 16),
|
||||
_CI (NM_CRYPTO_CIPHER_AES_256_CBC, "AES-256-CBC", 32, 16),
|
||||
};
|
||||
|
||||
const NMCryptoCipherInfo *
|
||||
nm_crypto_cipher_get_info (NMCryptoCipherType cipher)
|
||||
{
|
||||
g_return_val_if_fail (cipher > NM_CRYPTO_CIPHER_UNKNOWN && (gsize) cipher < G_N_ELEMENTS (cipher_infos) + 1, NULL);
|
||||
|
||||
#if NM_MORE_ASSERTS > 10
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < (int) G_N_ELEMENTS (cipher_infos); i++) {
|
||||
const NMCryptoCipherInfo *info = &cipher_infos[i];
|
||||
|
||||
nm_assert (info->cipher == (NMCryptoCipherType) (i + 1));
|
||||
nm_assert (info->name && info->name[0]);
|
||||
for (j = 0; j < i; j++)
|
||||
nm_assert (g_ascii_strcasecmp (info->name, cipher_infos[j].name) != 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return &cipher_infos[cipher - 1];
|
||||
}
|
||||
|
||||
const NMCryptoCipherInfo *
|
||||
nm_crypto_cipher_get_info_by_name (const char *cipher_name, gssize p_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
nm_assert (nm_crypto_cipher_get_info (NM_CRYPTO_CIPHER_DES_CBC)->cipher == NM_CRYPTO_CIPHER_DES_CBC);
|
||||
|
||||
if (p_len < 0) {
|
||||
if (!cipher_name)
|
||||
return FALSE;
|
||||
p_len = strlen (cipher_name);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int) G_N_ELEMENTS (cipher_infos); i++) {
|
||||
const NMCryptoCipherInfo *info = &cipher_infos[i];
|
||||
|
||||
if ( (gsize) p_len == strlen (info->name)
|
||||
&& g_ascii_strncasecmp (info->name, cipher_name, p_len) == 0)
|
||||
return info;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
find_tag (const char *tag,
|
||||
const guint8 *data,
|
||||
|
|
@ -119,7 +177,7 @@ parse_old_openssl_key_file (const guint8 *data,
|
|||
gsize data_len,
|
||||
NMSecretPtr *out_parsed,
|
||||
NMCryptoKeyType *out_key_type,
|
||||
const char **out_cipher,
|
||||
NMCryptoCipherType *out_cipher,
|
||||
char **out_iv,
|
||||
GError **error)
|
||||
{
|
||||
|
|
@ -132,7 +190,7 @@ parse_old_openssl_key_file (const guint8 *data,
|
|||
nm_auto_clear_secret_ptr NMSecretPtr parsed = { 0 };
|
||||
nm_auto_clear_secret_ptr NMSecretPtr data_content = { 0 };
|
||||
nm_auto_free_secret char *iv = NULL;
|
||||
const char *cipher = NULL;
|
||||
NMCryptoCipherType cipher = NM_CRYPTO_CIPHER_UNKNOWN;
|
||||
const char *start_tag;
|
||||
const char *end_tag;
|
||||
const guint8 *data_start, *data_end;
|
||||
|
|
@ -141,7 +199,7 @@ parse_old_openssl_key_file (const guint8 *data,
|
|||
nm_assert (!out_iv || !*out_iv);
|
||||
|
||||
NM_SET_OUT (out_key_type, NM_CRYPTO_KEY_TYPE_UNKNOWN);
|
||||
*out_cipher = NULL;
|
||||
NM_SET_OUT (out_cipher, NM_CRYPTO_CIPHER_UNKNOWN);
|
||||
|
||||
if (find_tag (PEM_RSA_KEY_BEGIN, data, data_len, 0, &start)) {
|
||||
key_type = NM_CRYPTO_KEY_TYPE_RSA;
|
||||
|
|
@ -202,14 +260,9 @@ parse_old_openssl_key_file (const guint8 *data,
|
|||
return FALSE;
|
||||
}
|
||||
} else if (!strncmp (p, DEK_INFO_TAG, strlen (DEK_INFO_TAG))) {
|
||||
static const char *const known_ciphers[] = { CIPHER_DES_EDE3_CBC,
|
||||
CIPHER_DES_CBC,
|
||||
CIPHER_AES_128_CBC,
|
||||
CIPHER_AES_192_CBC,
|
||||
CIPHER_AES_256_CBC };
|
||||
const NMCryptoCipherInfo *cipher_info;
|
||||
char *comma;
|
||||
gsize p_len;
|
||||
guint i;
|
||||
|
||||
if (enc_tags++ != 1 || str_p != str) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
|
|
@ -240,20 +293,15 @@ parse_old_openssl_key_file (const guint8 *data,
|
|||
iv = g_strdup (comma);
|
||||
|
||||
/* Get the private key cipher */
|
||||
for (i = 0; i < G_N_ELEMENTS (known_ciphers); i++) {
|
||||
if ( strlen (known_ciphers[i]) == p_len
|
||||
&& !g_ascii_strncasecmp (p, known_ciphers[i], p_len)) {
|
||||
cipher = known_ciphers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cipher) {
|
||||
cipher_info = nm_crypto_cipher_get_info_by_name (p, p_len);
|
||||
if (!cipher_info) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_INVALID_DATA,
|
||||
_("Malformed PEM file: unknown private key cipher '%s'."),
|
||||
p);
|
||||
return FALSE;
|
||||
}
|
||||
cipher = cipher_info->cipher;
|
||||
} else {
|
||||
if (enc_tags == 1) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
|
|
@ -277,7 +325,7 @@ parse_old_openssl_key_file (const guint8 *data,
|
|||
|
||||
NM_SET_OUT (out_key_type, key_type);
|
||||
NM_SET_OUT (out_iv, g_steal_pointer (&iv));
|
||||
*out_cipher = cipher;
|
||||
NM_SET_OUT (out_cipher, cipher);
|
||||
nm_secret_ptr_move (out_parsed, &parsed);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -419,7 +467,7 @@ _nmtst_convert_iv (const char *src,
|
|||
}
|
||||
|
||||
guint8 *
|
||||
nm_crypto_make_des_aes_key (const char *cipher,
|
||||
nm_crypto_make_des_aes_key (NMCryptoCipherType cipher,
|
||||
const guint8 *salt,
|
||||
gsize salt_len,
|
||||
const char *password,
|
||||
|
|
@ -427,9 +475,8 @@ nm_crypto_make_des_aes_key (const char *cipher,
|
|||
GError **error)
|
||||
{
|
||||
guint8 *key;
|
||||
gsize digest_len;
|
||||
const NMCryptoCipherInfo *cipher_info;
|
||||
|
||||
g_return_val_if_fail (cipher != NULL, NULL);
|
||||
g_return_val_if_fail (salt != NULL, NULL);
|
||||
g_return_val_if_fail (salt_len >= 8, NULL);
|
||||
g_return_val_if_fail (password != NULL, NULL);
|
||||
|
|
@ -437,42 +484,28 @@ nm_crypto_make_des_aes_key (const char *cipher,
|
|||
|
||||
*out_len = 0;
|
||||
|
||||
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC))
|
||||
digest_len = 24;
|
||||
else if (!strcmp (cipher, CIPHER_DES_CBC))
|
||||
digest_len = 8;
|
||||
else if (!strcmp (cipher, CIPHER_AES_128_CBC))
|
||||
digest_len = 16;
|
||||
else if (!strcmp (cipher, CIPHER_AES_192_CBC))
|
||||
digest_len = 24;
|
||||
else if (!strcmp (cipher, CIPHER_AES_256_CBC))
|
||||
digest_len = 32;
|
||||
else {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
|
||||
_("Private key cipher '%s' was unknown."),
|
||||
cipher);
|
||||
return NULL;
|
||||
}
|
||||
cipher_info = nm_crypto_cipher_get_info (cipher);
|
||||
|
||||
g_return_val_if_fail (cipher_info, NULL);
|
||||
|
||||
if (password[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
key = g_malloc (digest_len);
|
||||
key = g_malloc (cipher_info->digest_len);
|
||||
|
||||
nm_crypto_md5_hash (salt,
|
||||
8,
|
||||
(guint8 *) password,
|
||||
strlen (password),
|
||||
key,
|
||||
digest_len);
|
||||
cipher_info->digest_len);
|
||||
|
||||
*out_len = digest_len;
|
||||
*out_len = cipher_info->digest_len;
|
||||
return key;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_nmtst_decrypt_key (const char *cipher,
|
||||
_nmtst_decrypt_key (NMCryptoCipherType cipher,
|
||||
const guint8 *data,
|
||||
gsize data_len,
|
||||
const char *iv,
|
||||
|
|
@ -485,7 +518,7 @@ _nmtst_decrypt_key (const char *cipher,
|
|||
gs_free char *output = NULL;
|
||||
|
||||
nm_assert (password);
|
||||
nm_assert (cipher);
|
||||
nm_assert (cipher != NM_CRYPTO_CIPHER_UNKNOWN);
|
||||
nm_assert (iv);
|
||||
nm_assert (parsed);
|
||||
nm_assert (!parsed->bin);
|
||||
|
|
@ -535,7 +568,7 @@ nmtst_crypto_decrypt_openssl_private_key_data (const guint8 *data,
|
|||
NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN;
|
||||
nm_auto_clear_secret_ptr NMSecretPtr parsed = { 0 };
|
||||
nm_auto_free_secret char *iv = NULL;
|
||||
const char *cipher = NULL;
|
||||
NMCryptoCipherType cipher = NM_CRYPTO_CIPHER_UNKNOWN;
|
||||
|
||||
g_return_val_if_fail (data != NULL, NULL);
|
||||
|
||||
|
|
@ -556,7 +589,7 @@ nmtst_crypto_decrypt_openssl_private_key_data (const guint8 *data,
|
|||
if (password) {
|
||||
nm_auto_clear_secret_ptr NMSecretPtr parsed2 = { 0 };
|
||||
|
||||
if (!cipher || !iv) {
|
||||
if (cipher == NM_CRYPTO_CIPHER_UNKNOWN || !iv) {
|
||||
g_set_error (error, NM_CRYPTO_ERROR,
|
||||
NM_CRYPTO_ERROR_INVALID_PASSWORD,
|
||||
_("Password provided, but key was not encrypted."));
|
||||
|
|
@ -575,7 +608,7 @@ nmtst_crypto_decrypt_openssl_private_key_data (const guint8 *data,
|
|||
return nm_secret_copy_to_gbytes (parsed2.bin, parsed2.len);
|
||||
}
|
||||
|
||||
if (cipher || iv)
|
||||
if (cipher != NM_CRYPTO_CIPHER_UNKNOWN || iv)
|
||||
return NULL;
|
||||
|
||||
return nm_secret_copy_to_gbytes (parsed.bin, parsed.len);
|
||||
|
|
@ -796,13 +829,13 @@ nm_crypto_verify_private_key_data (const guint8 *data,
|
|||
|| _nm_crypto_verify_pkcs8 (parsed.bin, parsed.len, is_encrypted, password, error))
|
||||
format = NM_CRYPTO_FILE_FORMAT_RAW_KEY;
|
||||
} else {
|
||||
const char *cipher;
|
||||
NMCryptoCipherType cipher;
|
||||
nm_auto_free_secret char *iv = NULL;
|
||||
|
||||
/* Or it's old-style OpenSSL */
|
||||
if (parse_old_openssl_key_file (data, data_len, NULL, NULL, &cipher, &iv, NULL)) {
|
||||
format = NM_CRYPTO_FILE_FORMAT_RAW_KEY;
|
||||
is_encrypted = (cipher && iv);
|
||||
is_encrypted = (cipher != NM_CRYPTO_CIPHER_UNKNOWN && iv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -936,11 +969,11 @@ nmtst_crypto_rsa_key_encrypt (const guint8 *data,
|
|||
if (!nm_crypto_randomize (salt, sizeof (salt), error))
|
||||
return NULL;
|
||||
|
||||
key.bin = nm_crypto_make_des_aes_key (CIPHER_DES_EDE3_CBC, salt, sizeof (salt), in_password, &key.len, NULL);
|
||||
key.bin = nm_crypto_make_des_aes_key (NM_CRYPTO_CIPHER_DES_EDE3_CBC, salt, sizeof (salt), in_password, &key.len, NULL);
|
||||
if (!key.bin)
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
enc.bin = _nmtst_crypto_encrypt (CIPHER_DES_EDE3_CBC, data, len, salt, sizeof (salt), key.bin, key.len, &enc.len, error);
|
||||
enc.bin = _nmtst_crypto_encrypt (NM_CRYPTO_CIPHER_DES_EDE3_CBC, data, len, salt, sizeof (salt), key.bin, key.len, &enc.len, error);
|
||||
if (!enc.bin)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -956,7 +989,8 @@ nmtst_crypto_rsa_key_encrypt (const guint8 *data,
|
|||
g_ptr_array_add (pem, g_strdup ("Proc-Type: 4,ENCRYPTED\n"));
|
||||
|
||||
/* Convert the salt to a hex string */
|
||||
g_ptr_array_add (pem, g_strdup ("DEK-Info: "CIPHER_DES_EDE3_CBC","));
|
||||
g_ptr_array_add (pem, g_strdup_printf ("DEK-Info: %s,",
|
||||
nm_crypto_cipher_get_info (NM_CRYPTO_CIPHER_DES_EDE3_CBC)->name));
|
||||
g_ptr_array_add (pem, nm_utils_bin2hexstr (salt, sizeof (salt), sizeof (salt) * 2));
|
||||
g_ptr_array_add (pem, g_strdup ("\n\n"));
|
||||
|
||||
|
|
|
|||
|
|
@ -28,13 +28,24 @@
|
|||
#error Cannot use this header.
|
||||
#endif
|
||||
|
||||
#define MD5_HASH_LEN 20
|
||||
typedef enum {
|
||||
NM_CRYPTO_CIPHER_UNKNOWN,
|
||||
NM_CRYPTO_CIPHER_DES_EDE3_CBC,
|
||||
NM_CRYPTO_CIPHER_DES_CBC,
|
||||
NM_CRYPTO_CIPHER_AES_128_CBC,
|
||||
NM_CRYPTO_CIPHER_AES_192_CBC,
|
||||
NM_CRYPTO_CIPHER_AES_256_CBC,
|
||||
} NMCryptoCipherType;
|
||||
|
||||
#define CIPHER_DES_EDE3_CBC "DES-EDE3-CBC"
|
||||
#define CIPHER_DES_CBC "DES-CBC"
|
||||
#define CIPHER_AES_128_CBC "AES-128-CBC"
|
||||
#define CIPHER_AES_192_CBC "AES-192-CBC"
|
||||
#define CIPHER_AES_256_CBC "AES-256-CBC"
|
||||
typedef struct {
|
||||
const char *name;
|
||||
NMCryptoCipherType cipher;
|
||||
guint8 digest_len;
|
||||
guint8 real_iv_len;
|
||||
} NMCryptoCipherInfo;
|
||||
|
||||
const NMCryptoCipherInfo *nm_crypto_cipher_get_info (NMCryptoCipherType cipher);
|
||||
const NMCryptoCipherInfo *nm_crypto_cipher_get_info_by_name (const char *cipher_name, gssize p_len);
|
||||
|
||||
typedef enum {
|
||||
NM_CRYPTO_KEY_TYPE_UNKNOWN = 0,
|
||||
|
|
@ -81,7 +92,7 @@ void nm_crypto_md5_hash (const guint8 *salt,
|
|||
guint8 *buffer,
|
||||
gsize buflen);
|
||||
|
||||
guint8 *nm_crypto_make_des_aes_key (const char *cipher,
|
||||
guint8 *nm_crypto_make_des_aes_key (NMCryptoCipherType cipher,
|
||||
const guint8 *salt,
|
||||
gsize salt_len,
|
||||
const char *password,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue