==7347== 1,201 bytes in 1 blocks are definitely lost in loss record 5,016 of 5,107
==7347== at 0x4A06B0F: calloc (vg_replace_malloc.c:593)
==7347== by 0x39B90548E6: g_malloc0 (gmem.c:189)
==7347== by 0x39B9026F8D: g_base64_decode (gbase64.c:407)
==7347== by 0x4C51CA1: parse_old_openssl_key_file (crypto.c:227)
==7347== by 0x4C51EC3: crypto_decrypt_private_key_data (crypto.c:497)
==7347== by 0x4C529BE: crypto_verify_private_key_data (crypto.c:706)
==7347== by 0x4C52B7B: crypto_verify_private_key (crypto.c:735)
==7347== by 0x4C5CCC5: nm_setting_802_1x_set_private_key (nm-setting-8021x.c:1633)
==7347== by 0xC8F64D4: eap_tls_reader (reader.c:2270)
==7347== by 0xC8F4886: fill_8021x (reader.c:2704)
==7347== by 0xC8F8311: wireless_connection_from_ifcfg (reader.c:2825)
==7347== by 0xC8FAFD2: connection_from_file (reader.c:4303)
'str' was not freed anywhere.
==23089== 2,072 (24 direct, 2,048 indirect) bytes in 1 blocks are definitely lost in loss record 5,063 of 5,123
==23089== at 0x4A0881C: malloc (vg_replace_malloc.c:270)
==23089== by 0x39B905488E: g_malloc (gmem.c:159)
==23089== by 0x39B9068CA1: g_slice_alloc (gslice.c:1003)
==23089== by 0x39B906C7FA: g_string_sized_new (gstring.c:121)
==23089== by 0x39B906CE75: g_string_new_len (gstring.c:186)
==23089== by 0x31FC0149CE: parse_old_openssl_key_file (crypto.c:150)
==23089== by 0x31FC014E33: crypto_decrypt_private_key_data (crypto.c:494)
==23089== by 0x31FC01592E: crypto_verify_private_key_data (crypto.c:703)
==23089== by 0x31FC015AEB: crypto_verify_private_key (crypto.c:732)
==23089== by 0x31FC0200E5: nm_setting_802_1x_set_private_key (nm-setting-8021x.c:1640)
==23089== by 0xC694304: eap_tls_reader (reader.c:2280)
==23089== by 0xC692756: fill_8021x (reader.c:2714)
g_malloc(), etc, never return NULL, by API contract. Likewise, by
extension, no other glib function ever returns NULL due to lack of
memory. So remove lots of unnecessary checks (the vast majority of
which would have immediately crashed had they ever run anyway, since
g_set_error(), g_warning(), and nm_log_*() all need to allocate
memory).
https://bugzilla.gnome.org/show_bug.cgi?id=693678
Neither gnutls nor NSS fully support PKCS#8 so we don't have complete
support here, but at least recognize the keys and make an attempt to
check the private key if we can.
First, it was not easily possible to set a private key without
also providing a password. This used to be OK, but now with
secret flags it may be the case that when the connection is read,
there's no private key password. So functions that set the
private key must account for NULL passwords.
Unfortunately, the crytpo code did not handle this case well.
We need to be able to independently (a) verify that a file looks
like a certificate or private key and (b) that a given password
decrypts a private key. Previously the crypto code would fail
to verify the file when the password was NULL.
So this change fixes up the crytpo code for a more distinct
split between these two operations, such that if no password is
given, the file is still checked to ensure that it's a private
key or a certificate. If a password is given, the password is
checked against the private key file.
This commit also changes how private keys and certificates were
handled with the BLOB scheme. Previously only the first certificate
or first private key was included in the property data, while now
the entire file is encoded in the data. This is intended to fix
cases where multiple private keys or certificates are present in
a PEM file. It also allows clients to push certificate data to
NetworkManager for storage in system settings locations, which was
not as flexible before when only part of the certificate or key
was sent as the data.
To be backwards compatible clients need to handle both paths to private
keys and the decrypted private key data, which is what used to get passed
in the private-key and phase2-private-key attributes of the 802.1x setting.
When moving a connection around between system-settings and user-settings,
if the private key is decrypted data, the settings service needs to store
that decrypted data somewhere so that the key can be sent to NM during
the connection process.
But we don't want to store the decrypted private key data, so we have to
re-encrypt it (possibly generating a private key password if one wasn't
sent with the decrypted data) and save it to disk, then send NM a path
to that private key during connection.
To help clients do this, and so that they don't have to carry around
multiple crypto implementations depending on whether they want to use
NSS or gnutls/gcrypt, add a helper to libnm-util.
Furthermore, I misunderstood a bunch of stuff with crypto padding when
writing the encrypt/decrypt functions long ago, so fix that up. Don't
return padding as part of the decrypted data, and make sure to verify
the padding's expected lengths and values when decrypting. Many thanks
to Nalin Dahyabhai for pointing me in the right direction.
Overload the certificate and key properties to allow paths to the
certificates and keys using a special prefix for the property data.
Add API to libnm-util for easy certificate path handling, and
documentation for NMSetting8021x.
Add support for PKCS#12 private keys (bgo #558982)
* libnm-util/crypto.c
libnm-util/crypto.h
- (parse_old_openssl_key_file): rename from parse_key_file(); adapt to
take a GByteArray instead of a filename
- (file_to_g_byte_array): handle private key files too
- (decrypt_key): take a GByteArray rather than data + len
- (crypto_get_private_key_data): refactor crypto_get_private_key() into
one function that takes a filename, and one that takes raw data;
detect pkcs#12 files as well
- (crypto_load_and_verify_certificate): detect file type
- (crypto_is_pkcs12_data, crypto_is_pkcs12_file): add pkcs#12 detection
functions
* libnm-util/crypto_gnutls.c
- (crypto_decrypt): take GByteArray rather than data + len; fix a bug
whereby tail padding was incorrectly handled, leading to erroneous
successes when trying to decrypt the data
- (crypto_verify_cert): rework somewhat
- (crypto_verify_pkcs12): validate pkcs#12 keys
* libnm-util/crypto_nss.c
- (crypto_init): enable various pkcs#12 ciphers
- (crypto_decrypt): take a GByteArray rather than data + len
- (crypto_verify_cert): clean up
- (crypto_verify_pkcs12): validate pkcs#12 keys
* libnm-util/test-crypto.c
- Handle pkcs#12 keys
* libnm-util/nm-setting-8021x.c
libnm-util/nm-setting-8021x.h
libnm-util/libnm-util.ver
- Add two new properties, 'private-key-password' and
'phase2-private-key-password', to be used in conjunction with
pkcs#12 keys
- (nm_setting_802_1x_set_ca_cert_from_file,
nm_setting_802_1x_set_client_cert_from_file,
nm_setting_802_1x_set_phase2_ca_cert_from_file,
nm_setting_802_1x_set_phase2_client_from_file): return certificate
type
- (nm_setting_802_1x_get_private_key_password,
nm_setting_802_1x_get_phase2_private_key_password): return private
key passwords
- (nm_setting_802_1x_set_private_key_from_file,
nm_setting_802_1x_set_phase2_private_key_from_file): set the private
key from a file, and update the private key password at the same time
- (nm_setting_802_1x_get_private_key_type,
nm_setting_802_1x_get_phase2_private_key_type): return the private
key type
* src/supplicant-manager/nm-supplicant-settings-verify.c
- Whitelist private key passwords
* src/supplicant-manager/nm-supplicant-config.c
- (nm_supplicant_config_add_setting_8021x): for pkcs#12 private keys,
add the private key password to the supplicant config, but do not
add the client certificate (as required by wpa_supplicant)
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4280 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
Move crypto functions from nm-applet to libnm-util.
* libnm-util/nm-setting-8021x.c (nm_setting_802_1x_set_ca_cert)
(nm_setting_802_1x_set_client_cert)
(nm_setting_802_1x_set_phase2_ca_cert)
(nm_setting_802_1x_set_phase2_client_cert)
(nm_setting_802_1x_set_private_key)
(nm_setting_802_1x_set_phase2_private_key): Implement. Given a certificate
file (or private key and it's password), read the certificate data.
* libnm-util/crypto_nss.c:
* libnm-util/crypto_gnutls.c:
* libnm-util/crypto.[ch]: Move here from nm-applet.
* configure.in: Check for NSS and gnutls here (moved here from nm-applet).
* system-settings/plugins/ifcfg-suse/parser.c (read_wpa_eap_settings):
Imlement WPA-EAP configuration reading from sysconfig.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3673 4912f4e0-d625-0410-9fb7-b9a5a253dbdc