libnm-core: replace GByteArray with pointer + length in some APIs

APIs that take arbitrary data should take it in the form of a pointer
and length, not a GByteArray, so that you can use them regardless of
what format you have the data in (GByteArray, GBytes, plain array,
etc).
This commit is contained in:
Dan Winship
2014-06-26 09:25:06 -04:00
parent 9837565789
commit 3fbabde4c3
18 changed files with 224 additions and 159 deletions

View File

@@ -528,7 +528,7 @@ fill_output_access_point (gpointer data, gpointer user_data)
/* Convert to strings */
if (ssid) {
ssid_str = nm_utils_ssid_to_utf8 (ssid);
ssid_str = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
ssid_hex_str = ssid_to_hex ((const char *) ssid->data, ssid->len);
}
channel_str = g_strdup_printf ("%u", nm_utils_wifi_freq_to_channel (freq));
@@ -2052,7 +2052,8 @@ find_ap_on_device (NMDevice *device, GByteArray *bssid, const char *ssid)
candidate_ssid = nm_access_point_get_ssid (candidate_ap);
if (candidate_ssid) {
char *ssid_tmp = nm_utils_ssid_to_utf8 (candidate_ssid);
char *ssid_tmp = nm_utils_ssid_to_utf8 (candidate_ssid->data,
candidate_ssid->len);
/* Compare SSIDs */
if (strcmp (ssid, ssid_tmp) == 0) {

View File

@@ -1387,7 +1387,7 @@ nmc_property_olpc_get_ssid (NMSetting *setting)
ssid = nm_setting_olpc_mesh_get_ssid (s_olpc_mesh);
if (ssid)
ssid_str = nm_utils_ssid_to_utf8 (ssid);
ssid_str = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
return ssid_str;
}
@@ -1530,7 +1530,7 @@ nmc_property_wireless_get_ssid (NMSetting *setting)
ssid = nm_setting_wireless_get_ssid (s_wireless);
if (ssid)
ssid_str = nm_utils_ssid_to_utf8 (ssid);
ssid_str = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
return ssid_str;
}

View File

@@ -266,6 +266,7 @@ add_connections_for_aps (NmtConnectDevice *nmtdev,
NMAccessPoint *ap;
const GPtrArray *aps;
GHashTable *seen_ssids;
const GByteArray *ssid;
char *ap_hash;
GSList *iter;
int i;
@@ -292,7 +293,8 @@ add_connections_for_aps (NmtConnectDevice *nmtdev,
nmtconn = g_slice_new0 (NmtConnectConnection);
nmtconn->device = nmtdev->device;
nmtconn->ap = g_object_ref (ap);
nmtconn->ssid = nm_utils_ssid_to_utf8 (nm_access_point_get_ssid (ap));
ssid = nm_access_point_get_ssid (ap);
nmtconn->ssid = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
for (iter = connections; iter; iter = iter->next) {
conn = iter->data;

View File

@@ -138,7 +138,7 @@ ssid_transform_to_entry (GBinding *binding,
char *utf8;
ssid = g_value_get_boxed (source_value);
utf8 = nm_utils_ssid_to_utf8 (ssid);
utf8 = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
g_value_take_string (target_value, utf8);
return TRUE;
}
@@ -158,7 +158,7 @@ ssid_transform_from_entry (GBinding *binding,
text = g_value_get_string (source_value);
old_ssid = nm_setting_wireless_get_ssid (s_wireless);
utf8 = nm_utils_ssid_to_utf8 (old_ssid);
utf8 = nm_utils_ssid_to_utf8 (old_ssid->data, old_ssid->len);
if (!g_strcmp0 (text, utf8)) {
g_free (utf8);

View File

@@ -329,13 +329,15 @@ request_secrets_from_ui (NmtSecretAgentRequest *request)
if (nm_connection_is_type (request->connection, NM_SETTING_WIRELESS_SETTING_NAME)) {
NMSettingWireless *s_wireless;
char *ssid;
const GByteArray *ssid;
char *ssid_utf8;
s_wireless = nm_connection_get_setting_wireless (request->connection);
ssid = nm_utils_ssid_to_utf8 (nm_setting_wireless_get_ssid (s_wireless));
ssid = nm_setting_wireless_get_ssid (s_wireless);
ssid_utf8 = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
title = _("Authentication required by wireless network");
msg = g_strdup_printf (_("Passwords or encryption keys are required to access the wireless network '%s'."), ssid);
msg = g_strdup_printf (_("Passwords or encryption keys are required to access the wireless network '%s'."), ssid_utf8);
ok = add_wireless_secrets (request, secrets);
} else if (nm_connection_is_type (request->connection, NM_SETTING_WIRED_SETTING_NAME)) {

View File

@@ -97,7 +97,7 @@ show_access_point_info (NMAccessPoint *ap)
strength = nm_access_point_get_strength (ap);
/* Convert to strings */
ssid_str = nm_utils_ssid_to_utf8 (ssid);
ssid_str = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
freq_str = g_strdup_printf ("%u MHz", freq);
bitrate_str = g_strdup_printf ("%u Mbit/s", bitrate/1000);
strength_str = g_strdup_printf ("%u", strength);
@@ -163,7 +163,7 @@ show_wifi_device_info (NMDevice *device)
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
if ((active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device)))) {
active_ssid = nm_access_point_get_ssid (active_ap);
active_ssid_str = nm_utils_ssid_to_utf8 (active_ssid);
active_ssid_str = nm_utils_ssid_to_utf8 (active_ssid->data, active_ssid->len);
}
}

View File

@@ -60,19 +60,20 @@ _nm_crypto_error_quark (void)
static gboolean
find_tag (const char *tag,
const GByteArray *array,
const guint8 *data,
gsize data_len,
gsize start_at,
gsize *out_pos)
{
gsize i, taglen;
gsize len = array->len - start_at;
gsize len = data_len - start_at;
g_return_val_if_fail (out_pos != NULL, FALSE);
taglen = strlen (tag);
if (len >= taglen) {
for (i = 0; i < len - taglen + 1; i++) {
if (memcmp (array->data + start_at + i, tag, taglen) == 0) {
if (memcmp (data + start_at + i, tag, taglen) == 0) {
*out_pos = start_at + i;
return TRUE;
}
@@ -85,7 +86,8 @@ find_tag (const char *tag,
#define PROC_TYPE_TAG "Proc-Type: "
static GByteArray *
parse_old_openssl_key_file (const GByteArray *contents,
parse_old_openssl_key_file (const guint8 *data,
gsize data_len,
int key_type,
char **out_cipher,
char **out_iv,
@@ -123,11 +125,11 @@ parse_old_openssl_key_file (const GByteArray *contents,
return NULL;
}
if (!find_tag (start_tag, contents, 0, &start))
if (!find_tag (start_tag, data, data_len, 0, &start))
goto parse_error;
start += strlen (start_tag);
if (!find_tag (end_tag, contents, start, &end)) {
if (!find_tag (end_tag, data, data_len, start, &end)) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_FILE_FORMAT_INVALID,
_("PEM key file had no end tag '%s'."),
@@ -135,10 +137,10 @@ parse_old_openssl_key_file (const GByteArray *contents,
goto parse_error;
}
save_end = contents->data[end];
contents->data[end] = '\0';
lines = g_strsplit ((const char *) (contents->data + start), "\n", 0);
contents->data[end] = save_end;
save_end = data[end];
((guint8 *)data)[end] = '\0';
lines = g_strsplit ((const char *) (data + start), "\n", 0);
((guint8 *)data)[end] = save_end;
if (!lines || g_strv_length (lines) <= 1) {
g_set_error (error, NM_CRYPTO_ERROR,
@@ -258,7 +260,8 @@ parse_error:
}
static GByteArray *
parse_pkcs8_key_file (const GByteArray *contents,
parse_pkcs8_key_file (const guint8 *data,
gsize data_len,
gboolean *out_encrypted,
GError **error)
{
@@ -271,11 +274,11 @@ parse_pkcs8_key_file (const GByteArray *contents,
gboolean encrypted = FALSE;
/* Try encrypted first, decrypted next */
if (find_tag (PEM_PKCS8_ENC_KEY_BEGIN, contents, 0, &start)) {
if (find_tag (PEM_PKCS8_ENC_KEY_BEGIN, data, data_len, 0, &start)) {
start_tag = PEM_PKCS8_ENC_KEY_BEGIN;
end_tag = PEM_PKCS8_ENC_KEY_END;
encrypted = TRUE;
} else if (find_tag (PEM_PKCS8_DEC_KEY_BEGIN, contents, 0, &start)) {
} else if (find_tag (PEM_PKCS8_DEC_KEY_BEGIN, data, data_len, 0, &start)) {
start_tag = PEM_PKCS8_DEC_KEY_BEGIN;
end_tag = PEM_PKCS8_DEC_KEY_END;
encrypted = FALSE;
@@ -287,7 +290,7 @@ parse_pkcs8_key_file (const GByteArray *contents,
}
start += strlen (start_tag);
if (!find_tag (end_tag, contents, start, &end)) {
if (!find_tag (end_tag, data, data_len, start, &end)) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_FILE_FORMAT_INVALID,
_("Failed to find expected PKCS#8 end tag '%s'."),
@@ -296,10 +299,10 @@ parse_pkcs8_key_file (const GByteArray *contents,
}
/* g_base64_decode() wants a NULL-terminated string */
save_end = contents->data[end];
contents->data[end] = '\0';
der = g_base64_decode ((const char *) (contents->data + start), &length);
contents->data[end] = save_end;
save_end = data[end];
((guint8 *)data)[end] = '\0';
der = g_base64_decode ((const char *) (data + start), &length);
((guint8 *)data)[end] = save_end;
if (der && length) {
key = g_byte_array_sized_new (length);
@@ -439,7 +442,8 @@ error:
static GByteArray *
decrypt_key (const char *cipher,
int key_type,
GByteArray *data,
const guint8 *data,
gsize data_len,
const char *iv,
const char *password,
GError **error)
@@ -464,7 +468,7 @@ decrypt_key (const char *cipher,
goto out;
output = crypto_decrypt (cipher, key_type,
data,
data, data_len,
bin_iv, bin_iv_len,
key, key_len,
&decrypted_len,
@@ -486,32 +490,33 @@ out:
}
GByteArray *
crypto_decrypt_private_key_data (const GByteArray *contents,
crypto_decrypt_private_key_data (const guint8 *data,
gsize data_len,
const char *password,
NMCryptoKeyType *out_key_type,
GError **error)
{
GByteArray *decrypted = NULL;
NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_RSA;
GByteArray *data;
GByteArray *parsed;
char *iv = NULL;
char *cipher = NULL;
g_return_val_if_fail (contents != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
if (out_key_type)
g_return_val_if_fail (*out_key_type == NM_CRYPTO_KEY_TYPE_UNKNOWN, NULL);
/* OpenSSL non-standard legacy PEM files */
/* Try RSA keys first */
data = parse_old_openssl_key_file (contents, key_type, &cipher, &iv, error);
if (!data) {
parsed = parse_old_openssl_key_file (data, data_len, key_type, &cipher, &iv, error);
if (!parsed) {
g_clear_error (error);
/* DSA next */
key_type = NM_CRYPTO_KEY_TYPE_DSA;
data = parse_old_openssl_key_file (contents, key_type, &cipher, &iv, error);
if (!data) {
parsed = parse_old_openssl_key_file (data, data_len, key_type, &cipher, &iv, error);
if (!parsed) {
g_clear_error (error);
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_FILE_FORMAT_INVALID,
@@ -519,7 +524,7 @@ crypto_decrypt_private_key_data (const GByteArray *contents,
}
}
if (data) {
if (parsed) {
/* return the key type even if decryption failed */
if (out_key_type)
*out_key_type = key_type;
@@ -527,12 +532,13 @@ crypto_decrypt_private_key_data (const GByteArray *contents,
if (password) {
decrypted = decrypt_key (cipher,
key_type,
data,
parsed->data,
parsed->len,
iv,
password,
error);
}
g_byte_array_free (data, TRUE);
g_byte_array_free (parsed, TRUE);
}
g_free (cipher);
@@ -552,7 +558,8 @@ crypto_decrypt_private_key (const char *file,
contents = file_to_g_byte_array (file, error);
if (contents) {
key = crypto_decrypt_private_key_data (contents, password, out_key_type, error);
key = crypto_decrypt_private_key_data (contents->data, contents->len,
password, out_key_type, error);
g_byte_array_free (contents, TRUE);
}
return key;
@@ -567,7 +574,7 @@ extract_pem_cert_data (GByteArray *contents, GError **error)
guint8 save_end;
gsize length = 0;
if (!find_tag (PEM_CERT_BEGIN, contents, 0, &start)) {
if (!find_tag (PEM_CERT_BEGIN, contents->data, contents->len, 0, &start)) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_FILE_FORMAT_INVALID,
_("PEM certificate had no start tag '%s'."),
@@ -576,7 +583,7 @@ extract_pem_cert_data (GByteArray *contents, GError **error)
}
start += strlen (PEM_CERT_BEGIN);
if (!find_tag (PEM_CERT_END, contents, start, &end)) {
if (!find_tag (PEM_CERT_END, contents->data, contents->len, start, &end)) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_FILE_FORMAT_INVALID,
_("PEM certificate had no end tag '%s'."),
@@ -621,7 +628,7 @@ crypto_load_and_verify_certificate (const char *file,
return NULL;
/* Check for PKCS#12 */
if (crypto_is_pkcs12_data (contents)) {
if (crypto_is_pkcs12_data (contents->data, contents->len)) {
*out_file_format = NM_CRYPTO_FILE_FORMAT_PKCS12;
return contents;
}
@@ -649,14 +656,15 @@ crypto_load_and_verify_certificate (const char *file,
}
gboolean
crypto_is_pkcs12_data (const GByteArray *data)
crypto_is_pkcs12_data (const guint8 *data,
gsize data_len)
{
GError *error = NULL;
gboolean success;
g_return_val_if_fail (data != NULL, FALSE);
success = crypto_verify_pkcs12 (data, NULL, &error);
success = crypto_verify_pkcs12 (data, data_len, NULL, &error);
if (success == FALSE) {
/* If the error was just a decryption error, then it's pkcs#12 */
if (error) {
@@ -678,7 +686,7 @@ crypto_is_pkcs12_file (const char *file, GError **error)
contents = file_to_g_byte_array (file, error);
if (contents) {
success = crypto_is_pkcs12_data (contents);
success = crypto_is_pkcs12_data (contents->data, contents->len);
g_byte_array_free (contents, TRUE);
}
return success;
@@ -688,7 +696,8 @@ crypto_is_pkcs12_file (const char *file, GError **error)
* the private key can be decrypted with that password.
*/
NMCryptoFileFormat
crypto_verify_private_key_data (const GByteArray *contents,
crypto_verify_private_key_data (const guint8 *data,
gsize data_len,
const char *password,
GError **error)
{
@@ -697,23 +706,23 @@ crypto_verify_private_key_data (const GByteArray *contents,
NMCryptoKeyType ktype = NM_CRYPTO_KEY_TYPE_UNKNOWN;
gboolean is_encrypted = FALSE;
g_return_val_if_fail (contents != NULL, FALSE);
g_return_val_if_fail (data != NULL, FALSE);
/* Check for PKCS#12 first */
if (crypto_is_pkcs12_data (contents)) {
if (!password || crypto_verify_pkcs12 (contents, password, error))
if (crypto_is_pkcs12_data (data, data_len)) {
if (!password || crypto_verify_pkcs12 (data, data_len, password, error))
format = NM_CRYPTO_FILE_FORMAT_PKCS12;
} else {
/* Maybe it's PKCS#8 */
tmp = parse_pkcs8_key_file (contents, &is_encrypted, error);
tmp = parse_pkcs8_key_file (data, data_len, &is_encrypted, error);
if (tmp) {
if (crypto_verify_pkcs8 (tmp, is_encrypted, password, error))
if (crypto_verify_pkcs8 (tmp->data, tmp->len, 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);
tmp = crypto_decrypt_private_key_data (data, data_len, password, &ktype, error);
if (tmp)
format = NM_CRYPTO_FILE_FORMAT_RAW_KEY;
else if (!password && (ktype != NM_CRYPTO_KEY_TYPE_UNKNOWN))
@@ -742,7 +751,7 @@ crypto_verify_private_key (const char *filename,
contents = file_to_g_byte_array (filename, error);
if (contents) {
format = crypto_verify_private_key_data (contents, password, error);
format = crypto_verify_private_key_data (contents->data, contents->len, password, error);
g_byte_array_free (contents, TRUE);
}
return format;

View File

@@ -72,7 +72,8 @@ gboolean crypto_init (GError **error);
void crypto_deinit (void);
GByteArray *crypto_decrypt_private_key_data (const GByteArray *contents,
GByteArray *crypto_decrypt_private_key_data (const guint8 *data,
gsize data_len,
const char *password,
NMCryptoKeyType *out_key_type,
GError **error);
@@ -88,9 +89,10 @@ GByteArray *crypto_load_and_verify_certificate (const char *file,
gboolean crypto_is_pkcs12_file (const char *file, GError **error);
gboolean crypto_is_pkcs12_data (const GByteArray *data);
gboolean crypto_is_pkcs12_data (const guint8 *data, gsize len);
NMCryptoFileFormat crypto_verify_private_key_data (const GByteArray *contents,
NMCryptoFileFormat crypto_verify_private_key_data (const guint8 *data,
gsize data_len,
const char *password,
GError **error);
@@ -110,7 +112,8 @@ gboolean crypto_md5_hash (const char *salt,
char * crypto_decrypt (const char *cipher,
int key_type,
GByteArray *data,
const guint8 *data,
gsize data_len,
const char *iv,
const gsize iv_len,
const char *key,
@@ -119,7 +122,8 @@ char * crypto_decrypt (const char *cipher,
GError **error);
char * crypto_encrypt (const char *cipher,
const GByteArray *data,
const guint8 *data,
gsize data_len,
const char *iv,
gsize iv_len,
const char *key,
@@ -129,15 +133,17 @@ char * crypto_encrypt (const char *cipher,
gboolean crypto_randomize (void *buffer, gsize buffer_len, GError **error);
NMCryptoFileFormat crypto_verify_cert (const unsigned char *data,
NMCryptoFileFormat crypto_verify_cert (const guint8 *data,
gsize len,
GError **error);
gboolean crypto_verify_pkcs12 (const GByteArray *data,
gboolean crypto_verify_pkcs12 (const guint8 *data,
gsize data_len,
const char *password,
GError **error);
gboolean crypto_verify_pkcs8 (const GByteArray *data,
gboolean crypto_verify_pkcs8 (const guint8 *data,
gsize data_len,
gboolean is_encrypted,
const char *password,
GError **error);

View File

@@ -120,7 +120,8 @@ crypto_md5_hash (const char *salt,
char *
crypto_decrypt (const char *cipher,
int key_type,
GByteArray *data,
const guint8 *data,
gsize data_len,
const char *iv,
const gsize iv_len,
const char *key,
@@ -160,7 +161,7 @@ crypto_decrypt (const char *cipher,
return NULL;
}
output = g_malloc0 (data->len);
output = g_malloc0 (data_len);
err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0);
if (err) {
@@ -189,7 +190,7 @@ crypto_decrypt (const char *cipher,
goto out;
}
err = gcry_cipher_decrypt (ctx, output, data->len, data->data, data->len);
err = gcry_cipher_decrypt (ctx, output, data_len, data, data_len);
if (err) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
@@ -197,7 +198,7 @@ crypto_decrypt (const char *cipher,
gcry_strsource (err), gcry_strerror (err));
goto out;
}
pad_len = output[data->len - 1];
pad_len = output[data_len - 1];
/* Check if the padding at the end of the decrypted data is valid */
if (pad_len == 0 || pad_len > real_iv_len) {
@@ -211,7 +212,7 @@ crypto_decrypt (const char *cipher,
* should contain the padding size.
*/
for (i = 1; i <= pad_len; ++i) {
if (output[data->len - i] != pad_len) {
if (output[data_len - i] != pad_len) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
_("Failed to decrypt the private key."));
@@ -219,14 +220,14 @@ crypto_decrypt (const char *cipher,
}
}
*out_len = data->len - pad_len;
*out_len = data_len - pad_len;
success = TRUE;
out:
if (!success) {
if (output) {
/* Don't expose key material */
memset (output, 0, data->len);
memset (output, 0, data_len);
g_free (output);
output = NULL;
}
@@ -237,7 +238,8 @@ out:
char *
crypto_encrypt (const char *cipher,
const GByteArray *data,
const guint8 *data,
gsize data_len,
const char *iv,
const gsize iv_len,
const char *key,
@@ -269,16 +271,16 @@ crypto_encrypt (const char *cipher,
return NULL;
}
/* If data->len % ivlen == 0, then we add another complete block
/* If data_len % ivlen == 0, then we add another complete block
* onto the end so that the decrypter knows there's padding.
*/
pad_len = iv_len - (data->len % iv_len);
output_len = padded_buf_len = data->len + pad_len;
pad_len = iv_len - (data_len % iv_len);
output_len = padded_buf_len = data_len + pad_len;
padded_buf = g_malloc0 (padded_buf_len);
memcpy (padded_buf, data->data, data->len);
memcpy (padded_buf, data, data_len);
for (i = 0; i < pad_len; i++)
padded_buf[data->len + i] = (guint8) (pad_len & 0xFF);
padded_buf[data_len + i] = (guint8) (pad_len & 0xFF);
output = g_malloc0 (output_len);
@@ -382,7 +384,8 @@ crypto_verify_cert (const unsigned char *data,
}
gboolean
crypto_verify_pkcs12 (const GByteArray *data,
crypto_verify_pkcs12 (const guint8 *data,
gsize data_len,
const char *password,
GError **error)
{
@@ -393,8 +396,8 @@ crypto_verify_pkcs12 (const GByteArray *data,
g_return_val_if_fail (data != NULL, FALSE);
dt.data = (unsigned char *) data->data;
dt.size = data->len;
dt.data = (unsigned char *) data;
dt.size = data_len;
err = gnutls_pkcs12_init (&p12);
if (err < 0) {
@@ -435,7 +438,8 @@ out:
}
gboolean
crypto_verify_pkcs8 (const GByteArray *data,
crypto_verify_pkcs8 (const guint8 *data,
gsize data_len,
gboolean is_encrypted,
const char *password,
GError **error)
@@ -446,8 +450,8 @@ crypto_verify_pkcs8 (const GByteArray *data,
g_return_val_if_fail (data != NULL, FALSE);
dt.data = (unsigned char *) data->data;
dt.size = data->len;
dt.data = (unsigned char *) data;
dt.size = data_len;
err = gnutls_x509_privkey_init (&p8);
if (err < 0) {

View File

@@ -134,7 +134,8 @@ crypto_md5_hash (const char *salt,
char *
crypto_decrypt (const char *cipher,
int key_type,
GByteArray *data,
const guint8 *data,
gsize data_len,
const char *iv,
const gsize iv_len,
const char *key,
@@ -180,7 +181,7 @@ crypto_decrypt (const char *cipher,
return NULL;
}
output = g_malloc0 (data->len);
output = g_malloc0 (data_len);
slot = PK11_GetBestSlot (cipher_mech, NULL);
if (!slot) {
@@ -221,9 +222,9 @@ crypto_decrypt (const char *cipher,
s = PK11_CipherOp (ctx,
(unsigned char *) output,
&decrypted_len,
data->len,
data->data,
data->len);
data_len,
data,
data_len);
if (s != SECSuccess) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
@@ -232,7 +233,7 @@ crypto_decrypt (const char *cipher,
goto out;
}
if (decrypted_len > data->len) {
if (decrypted_len > data_len) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
_("Failed to decrypt the private key: decrypted data too large."));
@@ -242,7 +243,7 @@ crypto_decrypt (const char *cipher,
s = PK11_DigestFinal (ctx,
(unsigned char *) (output + decrypted_len),
&extra,
data->len - decrypted_len);
data_len - decrypted_len);
if (s != SECSuccess) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
@@ -251,7 +252,7 @@ crypto_decrypt (const char *cipher,
goto out;
}
decrypted_len += extra;
pad_len = data->len - decrypted_len;
pad_len = data_len - decrypted_len;
/* Check if the padding at the end of the decrypted data is valid */
if (pad_len == 0 || pad_len > real_iv_len) {
@@ -265,7 +266,7 @@ crypto_decrypt (const char *cipher,
* should contain the padding size.
*/
for (i = pad_len; i > 0; i--) {
if (output[data->len - i] != pad_len) {
if (output[data_len - i] != pad_len) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
_("Failed to decrypt the private key."));
@@ -289,7 +290,7 @@ out:
if (!success) {
if (output) {
/* Don't expose key material */
memset (output, 0, data->len);
memset (output, 0, data_len);
g_free (output);
output = NULL;
}
@@ -299,7 +300,8 @@ out:
char *
crypto_encrypt (const char *cipher,
const GByteArray *data,
const guint8 *data,
gsize data_len,
const char *iv,
gsize iv_len,
const char *key,
@@ -336,13 +338,13 @@ crypto_encrypt (const char *cipher,
/* If data->len % ivlen == 0, then we add another complete block
* onto the end so that the decrypter knows there's padding.
*/
pad_len = iv_len - (data->len % iv_len);
output_len = padded_buf_len = data->len + pad_len;
pad_len = iv_len - (data_len % iv_len);
output_len = padded_buf_len = data_len + pad_len;
padded_buf = g_malloc0 (padded_buf_len);
memcpy (padded_buf, data->data, data->len);
memcpy (padded_buf, data, data_len);
for (i = 0; i < pad_len; i++)
padded_buf[data->len + i] = (guint8) (pad_len & 0xFF);
padded_buf[data_len + i] = (guint8) (pad_len & 0xFF);
output = g_malloc0 (output_len);
@@ -440,7 +442,8 @@ crypto_verify_cert (const unsigned char *data,
}
gboolean
crypto_verify_pkcs12 (const GByteArray *data,
crypto_verify_pkcs12 (const guint8 *data,
gsize data_len,
const char *password,
GError **error)
{
@@ -498,7 +501,7 @@ crypto_verify_pkcs12 (const GByteArray *data,
goto error;
}
s = SEC_PKCS12DecoderUpdate (p12ctx, data->data, data->len);
s = SEC_PKCS12DecoderUpdate (p12ctx, (guint8 *)data, data_len);
if (s != SECSuccess) {
g_set_error (error, NM_CRYPTO_ERROR,
NM_CRYPTO_ERR_FILE_FORMAT_INVALID,
@@ -532,7 +535,8 @@ error:
}
gboolean
crypto_verify_pkcs8 (const GByteArray *data,
crypto_verify_pkcs8 (const guint8 *data,
gsize data_len,
gboolean is_encrypted,
const char *password,
GError **error)

View File

@@ -1872,7 +1872,7 @@ nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting)
switch (nm_setting_802_1x_get_private_key_scheme (setting)) {
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
if (crypto_is_pkcs12_data (priv->private_key))
if (crypto_is_pkcs12_data (priv->private_key->data, priv->private_key->len))
return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
case NM_SETTING_802_1X_CK_SCHEME_PATH:
@@ -2152,7 +2152,8 @@ nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting)
switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) {
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
if (crypto_is_pkcs12_data (priv->phase2_private_key))
if (crypto_is_pkcs12_data (priv->phase2_private_key->data,
priv->phase2_private_key->len))
return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
case NM_SETTING_802_1X_CK_SCHEME_PATH:
@@ -2209,7 +2210,8 @@ need_private_key_password (const GByteArray *blob,
if (path)
format = crypto_verify_private_key (path, password, NULL);
else if (blob)
format = crypto_verify_private_key_data (blob, password, NULL);
format = crypto_verify_private_key_data (blob->data, blob->len,
password, NULL);
else
g_warning ("%s: unknown private key password scheme", __func__);
}
@@ -2298,7 +2300,8 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error)
}
/* If the private key is PKCS#12, check that it matches the client cert */
if (crypto_is_pkcs12_data (priv->phase2_private_key)) {
if (crypto_is_pkcs12_data (priv->phase2_private_key->data,
priv->phase2_private_key->len)) {
if (priv->phase2_private_key->len != priv->phase2_client_cert->len) {
g_set_error (error,
NM_SETTING_802_1X_ERROR,
@@ -2356,7 +2359,8 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error)
}
/* If the private key is PKCS#12, check that it matches the client cert */
if (crypto_is_pkcs12_data (priv->private_key)) {
if (crypto_is_pkcs12_data (priv->private_key->data,
priv->private_key->len)) {
if (priv->private_key->len != priv->client_cert->len) {
g_set_error (error,
NM_SETTING_802_1X_ERROR,

View File

@@ -261,7 +261,8 @@ nm_utils_deinit (void)
/**
* nm_utils_ssid_to_utf8:
* @ssid: a byte array containing the SSID data
* @ssid: pointer to a buffer containing the SSID data
* @len: length of the SSID data in @ssid
*
* Wi-Fi SSIDs are byte arrays, they are _not_ strings. Thus, an SSID may
* contain embedded NULLs and other unprintable characters. Often it is
@@ -291,15 +292,15 @@ nm_utils_deinit (void)
* Returns %NULL on errors.
**/
char *
nm_utils_ssid_to_utf8 (const GByteArray *ssid)
nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len)
{
char *converted = NULL;
char *lang, *e1 = NULL, *e2 = NULL, *e3 = NULL;
g_return_val_if_fail (ssid != NULL, NULL);
if (g_utf8_validate ((const gchar *) ssid->data, ssid->len, NULL))
return g_strndup ((const gchar *) ssid->data, ssid->len);
if (g_utf8_validate ((const gchar *) ssid, len, NULL))
return g_strndup ((const gchar *) ssid, len);
/* LANG may be a good encoding hint */
g_get_charset ((const char **)(&e1));
@@ -314,15 +315,15 @@ nm_utils_ssid_to_utf8 (const GByteArray *ssid)
g_free (lang);
}
converted = g_convert ((const gchar *) ssid->data, ssid->len, "UTF-8", e1, NULL, NULL, NULL);
converted = g_convert ((const gchar *) ssid, len, "UTF-8", e1, NULL, NULL, NULL);
if (!converted && e2)
converted = g_convert ((const gchar *) ssid->data, ssid->len, "UTF-8", e2, NULL, NULL, NULL);
converted = g_convert ((const gchar *) ssid, len, "UTF-8", e2, NULL, NULL, NULL);
if (!converted && e3)
converted = g_convert ((const gchar *) ssid->data, ssid->len, "UTF-8", e3, NULL, NULL, NULL);
converted = g_convert ((const gchar *) ssid, len, "UTF-8", e3, NULL, NULL, NULL);
if (!converted) {
converted = g_convert_with_fallback ((const gchar *) ssid->data, ssid->len,
converted = g_convert_with_fallback ((const gchar *) ssid, len,
"UTF-8", e1, "?", NULL, NULL, NULL);
}
@@ -342,7 +343,7 @@ nm_utils_ssid_to_utf8 (const GByteArray *ssid)
* Returns: %TRUE if the SSID is "empty", %FALSE if it is not
**/
gboolean
nm_utils_is_empty_ssid (const guint8 * ssid, int len)
nm_utils_is_empty_ssid (const guint8 *ssid, gsize len)
{
/* Single white space is for Linksys APs */
if (len == 1 && ssid[0] == ' ')
@@ -372,7 +373,7 @@ nm_utils_is_empty_ssid (const guint8 * ssid, int len)
* and will be overwritten by subsequent calls to this function
**/
const char *
nm_utils_escape_ssid (const guint8 * ssid, guint32 len)
nm_utils_escape_ssid (const guint8 *ssid, gsize len)
{
static char escaped[ESSID_MAX_SIZE * 2 + 1];
const guint8 *s = ssid;
@@ -399,8 +400,10 @@ nm_utils_escape_ssid (const guint8 * ssid, guint32 len)
/**
* nm_utils_same_ssid:
* @ssid1: first SSID data to compare
* @ssid2: second SSID data to compare
* @ssid1: the first SSID to compare
* @len1: length of the SSID data in @ssid1
* @ssid2: the second SSID to compare
* @len2: length of the SSID data in @ssid2
* @ignore_trailing_null: %TRUE to ignore one trailing NULL byte
*
* Earlier versions of the Linux kernel added a NULL byte to the end of the
@@ -413,30 +416,29 @@ nm_utils_escape_ssid (const guint8 * ssid, guint32 len)
* Returns: %TRUE if the SSIDs are the same, %FALSE if they are not
**/
gboolean
nm_utils_same_ssid (const GByteArray * ssid1,
const GByteArray * ssid2,
nm_utils_same_ssid (const guint8 *ssid1, gsize len1,
const guint8 *ssid2, gsize len2,
gboolean ignore_trailing_null)
{
guint32 ssid1_len, ssid2_len;
g_return_val_if_fail (ssid1 != NULL || len1 == 0, FALSE);
g_return_val_if_fail (ssid2 != NULL || len2 == 0, FALSE);
if (ssid1 == ssid2)
if (ssid1 == ssid2 && len1 == len2)
return TRUE;
if (!ssid1 || !ssid2)
return FALSE;
ssid1_len = ssid1->len;
ssid2_len = ssid2->len;
if (ssid1_len && ssid2_len && ignore_trailing_null) {
if (ssid1->data[ssid1_len - 1] == '\0')
ssid1_len--;
if (ssid2->data[ssid2_len - 1] == '\0')
ssid2_len--;
if (ignore_trailing_null) {
if (len1 && ssid1[len1 - 1] == '\0')
len1--;
if (len2 && ssid2[len2 - 1] == '\0')
len2--;
}
if (ssid1_len != ssid2_len)
if (len1 != len2)
return FALSE;
return memcmp (ssid1->data, ssid2->data, ssid1_len) == 0 ? TRUE : FALSE;
return memcmp (ssid1, ssid2, len1) == 0 ? TRUE : FALSE;
}
static void
@@ -2123,6 +2125,7 @@ make_key (const char *cipher,
* nm_utils_rsa_key_encrypt_helper:
* @cipher: cipher to use for encryption ("DES-EDE3-CBC" or "AES-128-CBC")
* @data: RSA private key data to be encrypted
* @len: length of @data
* @in_password: (allow-none): existing password to use, if any
* @out_password: (out) (allow-none): if @in_password was %NULL, a random password will be generated
* and returned in this argument
@@ -2137,7 +2140,8 @@ make_key (const char *cipher,
**/
static GByteArray *
nm_utils_rsa_key_encrypt_helper (const char *cipher,
const GByteArray *data,
const guint8 *data,
gsize len,
const char *in_password,
char **out_password,
GError **error)
@@ -2154,7 +2158,7 @@ nm_utils_rsa_key_encrypt_helper (const char *cipher,
g_return_val_if_fail (!g_strcmp0 (cipher, CIPHER_DES_EDE3_CBC) || !g_strcmp0 (cipher, CIPHER_AES_CBC), NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->len > 0, NULL);
g_return_val_if_fail (len > 0, NULL);
if (out_password)
g_return_val_if_fail (*out_password == NULL, NULL);
@@ -2177,7 +2181,7 @@ nm_utils_rsa_key_encrypt_helper (const char *cipher,
if (!key)
goto out;
enc = crypto_encrypt (cipher, data, salt, salt_len, key, key_len, &enc_len, error);
enc = crypto_encrypt (cipher, data, len, salt, salt_len, key, key_len, &enc_len, error);
if (!enc)
goto out;
@@ -2231,6 +2235,7 @@ out:
/**
* nm_utils_rsa_key_encrypt:
* @data: RSA private key data to be encrypted
* @len: length of @data
* @in_password: (allow-none): existing password to use, if any
* @out_password: (out) (allow-none): if @in_password was %NULL, a random password will be generated
* and returned in this argument
@@ -2244,7 +2249,8 @@ out:
* certificate/private key file.
**/
GByteArray *
nm_utils_rsa_key_encrypt (const GByteArray *data,
nm_utils_rsa_key_encrypt (const guint8 *data,
gsize len,
const char *in_password,
char **out_password,
GError **error)
@@ -2252,7 +2258,7 @@ nm_utils_rsa_key_encrypt (const GByteArray *data,
return nm_utils_rsa_key_encrypt_helper (CIPHER_DES_EDE3_CBC,
data,
data, len,
in_password,
out_password,
error);
@@ -2261,6 +2267,7 @@ nm_utils_rsa_key_encrypt (const GByteArray *data,
/**
* nm_utils_rsa_key_encrypt_aes:
* @data: RSA private key data to be encrypted
* @len: length of @data
* @in_password: (allow-none): existing password to use, if any
* @out_password: (out) (allow-none): if @in_password was %NULL, a random password will be generated
* and returned in this argument
@@ -2274,14 +2281,15 @@ nm_utils_rsa_key_encrypt (const GByteArray *data,
* certificate/private key file.
**/
GByteArray *
nm_utils_rsa_key_encrypt_aes (const GByteArray *data,
nm_utils_rsa_key_encrypt_aes (const guint8 *data,
gsize len,
const char *in_password,
char **out_password,
GError **error)
{
return nm_utils_rsa_key_encrypt_helper (CIPHER_AES_CBC,
data,
data, len,
in_password,
out_password,
error);

View File

@@ -42,12 +42,12 @@ gboolean nm_utils_init (GError **error);
void nm_utils_deinit (void);
/* SSID helpers */
gboolean nm_utils_is_empty_ssid (const guint8 *ssid, int len);
const char *nm_utils_escape_ssid (const guint8 *ssid, guint32 len);
gboolean nm_utils_same_ssid (const GByteArray *ssid1,
const GByteArray *ssid2,
gboolean nm_utils_is_empty_ssid (const guint8 *ssid, gsize len);
const char *nm_utils_escape_ssid (const guint8 *ssid, gsize len);
gboolean nm_utils_same_ssid (const guint8 *ssid1, gsize len1,
const guint8 *ssid2, gsize len2,
gboolean ignore_trailing_null);
char * nm_utils_ssid_to_utf8 (const GByteArray *ssid);
char * nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len);
GHashTable *nm_utils_gvalue_hash_dup (GHashTable *hash);
@@ -117,11 +117,13 @@ void nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value);
char *nm_utils_uuid_generate (void);
char *nm_utils_uuid_generate_from_string (const char *s);
GByteArray *nm_utils_rsa_key_encrypt (const GByteArray *data,
GByteArray *nm_utils_rsa_key_encrypt (const guint8 *data,
gsize len,
const char *in_password,
char **out_password,
GError **error);
GByteArray *nm_utils_rsa_key_encrypt_aes (const GByteArray *data,
GByteArray *nm_utils_rsa_key_encrypt_aes (const guint8 *data,
gsize len,
const char *in_password,
char **out_password,
GError **error);

View File

@@ -301,16 +301,17 @@ test_encrypt_private_key (const char *path,
/* Now re-encrypt the private key */
if (is_cipher_aes (path))
encrypted = nm_utils_rsa_key_encrypt_aes (array, password, NULL, &error);
encrypted = nm_utils_rsa_key_encrypt_aes (array->data, array->len, password, NULL, &error);
else
encrypted = nm_utils_rsa_key_encrypt (array, password, NULL, &error);
encrypted = nm_utils_rsa_key_encrypt (array->data, array->len, 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);
re_decrypted = crypto_decrypt_private_key_data (encrypted->data, encrypted->len,
password, &key_type, &error);
ASSERT (re_decrypted != NULL, desc,
"couldn't read private key file '%s': %d %s",
path, error->code, error->message);

View File

@@ -420,9 +420,15 @@ find_active_ap (NMDeviceWifi *self,
continue;
}
if ((i == 0) && !nm_utils_same_ssid (ssid, ap_ssid, TRUE)) {
_LOGD (LOGD_WIFI, " SSID mismatch");
continue;
if (i == 0) {
if ( (ssid && !ap_ssid)
|| (ap_ssid && !ssid)
|| (ssid && ap_ssid && !nm_utils_same_ssid (ssid->data, ssid->len,
ap_ssid->data, ap_ssid->len,
TRUE))) {
_LOGD (LOGD_WIFI, " SSID mismatch");
continue;
}
}
apmode = nm_ap_get_mode (ap);
@@ -1097,7 +1103,7 @@ complete_connection (NMDevice *device,
}
g_assert (ssid);
str_ssid = nm_utils_ssid_to_utf8 (ssid);
str_ssid = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
nm_utils_complete_generic (connection,
NM_SETTING_WIRELESS_SETTING_NAME,
@@ -1508,11 +1514,13 @@ request_wireless_scan (gpointer user_data)
if (nm_logging_enabled (LOGL_DEBUG, LOGD_WIFI_SCAN)) {
if (ssids) {
const GByteArray *ssid;
guint i;
char *foo;
for (i = 0; i < ssids->len; i++) {
foo = nm_utils_ssid_to_utf8 (g_ptr_array_index (ssids, i));
ssid = g_ptr_array_index (ssids, i);
foo = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
_LOGD (LOGD_WIFI_SCAN, "(%d) probe scanning SSID '%s'",
i, foo ? foo : "<hidden>");
g_free (foo);

View File

@@ -1109,6 +1109,7 @@ nm_ap_check_compatible (NMAccessPoint *self,
NMAccessPointPrivate *priv;
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
const GByteArray *ssid;
const char *mode;
const char *band;
const char *bssid;
@@ -1123,7 +1124,15 @@ nm_ap_check_compatible (NMAccessPoint *self,
if (s_wireless == NULL)
return FALSE;
if (!nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), priv->ssid, TRUE))
ssid = nm_setting_wireless_get_ssid (s_wireless);
if ( (ssid && !priv->ssid)
|| (priv->ssid && !ssid))
return FALSE;
if ( ssid && priv->ssid &&
!nm_utils_same_ssid (ssid->data, ssid->len,
priv->ssid->data, priv->ssid->len,
TRUE))
return FALSE;
bssid = nm_setting_wireless_get_bssid (s_wireless);
@@ -1233,8 +1242,13 @@ nm_ap_match_in_list (NMAccessPoint *find_ap,
* let matching continue on BSSID and other properties
*/
if ( (!list_ssid && find_ssid)
|| (list_ssid && !find_ssid)
|| !nm_utils_same_ssid (list_ssid, find_ssid, TRUE))
|| (list_ssid && !find_ssid))
continue;
if ( list_ssid
&& find_ssid
&& !nm_utils_same_ssid (list_ssid->data, list_ssid->len,
find_ssid->data, find_ssid->len,
TRUE))
continue;
/* BSSID match */

View File

@@ -3443,7 +3443,7 @@ wireless_connection_from_ifcfg (const char *file,
ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (wireless_setting));
if (ssid)
printable_ssid = nm_utils_ssid_to_utf8 (ssid);
printable_ssid = nm_utils_ssid_to_utf8 (ssid->data, ssid->len);
else
printable_ssid = g_strdup_printf ("unmanaged");

View File

@@ -1911,7 +1911,7 @@ write_8021x_certs (NMSetting8021x *s_8021x,
if (blob && !is_pkcs12) {
/* Encrypt the unencrypted private key with the fake password */
enc_key =
nm_utils_rsa_key_encrypt (blob, password, &generated_pw,
nm_utils_rsa_key_encrypt (blob->data, blob->len, password, &generated_pw,
error);
if (!enc_key)
goto out;