From 4274edf47dfc1341704311d9587dc6951db480e9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 8 Dec 2009 16:52:24 -0800 Subject: [PATCH] libnm-util: client certificate should not be required to set private key (bgo #585570) Not sure what I was thinking originally; there's no way this was correct in the first place. --- libnm-util/nm-setting-8021x.c | 263 +++++++++--------- libnm-util/tests/Makefile.am | 32 ++- libnm-util/tests/certs/Makefile.am | 4 +- .../tests/certs/test-key-only-decrypted.der | Bin 0 -> 1192 bytes libnm-util/tests/certs/test-key-only.pem | 92 ++++++ libnm-util/tests/test-setting-8021x.c | 163 +++++++++++ 6 files changed, 413 insertions(+), 141 deletions(-) create mode 100644 libnm-util/tests/certs/test-key-only-decrypted.der create mode 100644 libnm-util/tests/certs/test-key-only.pem create mode 100644 libnm-util/tests/test-setting-8021x.c diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index 19c86994b5..eea6ba5e7c 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -1576,7 +1576,7 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *self, if (!value) return TRUE; - /* First verify private key password */ + /* Verify the key and the private key password */ data = crypto_get_private_key (value, password, &key_type, @@ -1591,77 +1591,69 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *self, return FALSE; } - memset (data->data, 0, data->len); - g_byte_array_free (data, TRUE); - /* Regular file verification */ - format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - data = crypto_load_and_verify_certificate (value, &format, error); - if (data) { - /* wpa_supplicant can only use raw x509 CA certs */ - switch (format) { - case NM_CRYPTO_FILE_FORMAT_RAW_KEY: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; - break; - case NM_CRYPTO_FILE_FORMAT_X509: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; - break; - case NM_CRYPTO_FILE_FORMAT_PKCS12: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; - break; - default: - g_byte_array_free (data, TRUE); - data = NULL; - g_set_error (error, - NM_SETTING_802_1X_ERROR, - NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, - NM_SETTING_802_1X_PRIVATE_KEY); - break; - } - - if (data) { - if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { - priv->private_key = data; - - /* Always update the private key for blob + pkcs12 since the - * pkcs12 files are encrypted - */ - if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) - priv->private_key_password = g_strdup (password); - } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Add the path scheme tag to the front, then the fielname */ - priv->private_key = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); - g_byte_array_append (priv->private_key, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (priv->private_key, (const guint8 *) value, strlen (value)); - g_byte_array_append (priv->private_key, (const guint8 *) "\0", 1); - - /* Always update the private key with paths since the key the - * cert refers to is encrypted. - */ - priv->private_key_password = g_strdup (password); - } else - g_assert_not_reached (); - - /* As required by NM and wpa_supplicant, set the client-cert - * property to the same PKCS#12 data. - */ - if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { - if (priv->client_cert) - g_byte_array_free (priv->client_cert, TRUE); - - priv->client_cert = g_byte_array_sized_new (priv->private_key->len); - g_byte_array_append (priv->client_cert, priv->private_key->data, priv->private_key->len); - } - } - } else { - /* As a special case for private keys, even if the decrypt fails, - * return the key's file type. - */ - if (out_format && crypto_is_pkcs12_file (value, NULL)) + switch (format) { + case NM_CRYPTO_FILE_FORMAT_RAW_KEY: + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; + break; + case NM_CRYPTO_FILE_FORMAT_X509: + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; + break; + case NM_CRYPTO_FILE_FORMAT_PKCS12: + if (out_format) *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; + break; + default: + memset (data->data, 0, data->len); + g_byte_array_free (data, TRUE); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } + + g_assert (data); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + priv->private_key = data; + data = NULL; + + /* Always update the private key for blob + pkcs12 since the + * pkcs12 files are encrypted + */ + if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) + priv->private_key_password = g_strdup (password); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + /* Add the path scheme tag to the front, then the fielname */ + priv->private_key = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); + g_byte_array_append (priv->private_key, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); + g_byte_array_append (priv->private_key, (const guint8 *) value, strlen (value)); + g_byte_array_append (priv->private_key, (const guint8 *) "\0", 1); + + /* Always update the private key with paths since the key the + * cert refers to is encrypted. + */ + priv->private_key_password = g_strdup (password); + } else + g_assert_not_reached (); + + /* Clear and free private key data if it's no longer needed */ + if (data) { + memset (data->data, 0, data->len); + g_byte_array_free (data, TRUE); + } + + /* As required by NM and wpa_supplicant, set the client-cert + * property to the same PKCS#12 data. + */ + if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { + if (priv->client_cert) + g_byte_array_free (priv->client_cert, TRUE); + + priv->client_cert = g_byte_array_sized_new (priv->private_key->len); + g_byte_array_append (priv->client_cert, priv->private_key->data, priv->private_key->len); } return priv->private_key != NULL; @@ -1956,7 +1948,7 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *self, if (!value) return TRUE; - /* First verify private key password */ + /* Verify the key and the private key password */ data = crypto_get_private_key (value, password, &key_type, @@ -1971,76 +1963,69 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *self, return FALSE; } - memset (data->data, 0, data->len); - g_byte_array_free (data, TRUE); - format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - data = crypto_load_and_verify_certificate (value, &format, error); - if (data) { - /* wpa_supplicant can only use raw x509 CA certs */ - switch (format) { - case NM_CRYPTO_FILE_FORMAT_RAW_KEY: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; - break; - case NM_CRYPTO_FILE_FORMAT_X509: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; - break; - case NM_CRYPTO_FILE_FORMAT_PKCS12: - if (out_format) - *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; - break; - default: - g_byte_array_free (data, TRUE); - data = NULL; - g_set_error (error, - NM_SETTING_802_1X_ERROR, - NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, - NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); - break; - } - - if (data) { - if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { - priv->phase2_private_key = data; - - /* Always update the private key for blob + pkcs12 since the - * pkcs12 files are encrypted - */ - if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) - priv->phase2_private_key_password = g_strdup (password); - } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { - /* Add the path scheme tag to the front, then the fielname */ - priv->phase2_private_key = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); - g_byte_array_append (priv->phase2_private_key, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (priv->phase2_private_key, (const guint8 *) value, strlen (value)); - g_byte_array_append (priv->phase2_private_key, (const guint8 *) "\0", 1); - - /* Always update the private key with paths since the key the - * cert refers to is encrypted. - */ - priv->phase2_private_key_password = g_strdup (password); - } else - g_assert_not_reached (); - - /* As required by NM and wpa_supplicant, set the client-cert - * property to the same PKCS#12 data. - */ - if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { - if (priv->phase2_client_cert) - g_byte_array_free (priv->phase2_client_cert, TRUE); - - priv->phase2_client_cert = g_byte_array_sized_new (priv->phase2_private_key->len); - g_byte_array_append (priv->phase2_client_cert, priv->phase2_private_key->data, priv->phase2_private_key->len); - } - } - } else { - /* As a special case for private keys, even if the decrypt fails, - * return the key's file type. - */ - if (out_format && crypto_is_pkcs12_file (value, NULL)) + switch (format) { + case NM_CRYPTO_FILE_FORMAT_RAW_KEY: + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; + break; + case NM_CRYPTO_FILE_FORMAT_X509: + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; + break; + case NM_CRYPTO_FILE_FORMAT_PKCS12: + if (out_format) *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; + break; + default: + memset (data->data, 0, data->len); + g_byte_array_free (data, TRUE); + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } + + g_assert (data); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + priv->phase2_private_key = data; + data = NULL; + + /* Always update the private key for blob + pkcs12 since the + * pkcs12 files are encrypted + */ + if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) + priv->phase2_private_key_password = g_strdup (password); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + /* Add the path scheme tag to the front, then the fielname */ + priv->phase2_private_key = g_byte_array_sized_new (strlen (value) + strlen (SCHEME_PATH) + 1); + g_byte_array_append (priv->phase2_private_key, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); + g_byte_array_append (priv->phase2_private_key, (const guint8 *) value, strlen (value)); + g_byte_array_append (priv->phase2_private_key, (const guint8 *) "\0", 1); + + /* Always update the private key with paths since the key the + * cert refers to is encrypted. + */ + priv->phase2_private_key_password = g_strdup (password); + } else + g_assert_not_reached (); + + /* Clear and free private key data if it's no longer needed */ + if (data) { + memset (data->data, 0, data->len); + g_byte_array_free (data, TRUE); + } + + /* As required by NM and wpa_supplicant, set the client-cert + * property to the same PKCS#12 data. + */ + if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { + if (priv->phase2_client_cert) + g_byte_array_free (priv->phase2_client_cert, TRUE); + + priv->phase2_client_cert = g_byte_array_sized_new (priv->phase2_private_key->len); + g_byte_array_append (priv->phase2_client_cert, priv->phase2_private_key->data, priv->phase2_private_key->len); } return priv->phase2_private_key != NULL; diff --git a/libnm-util/tests/Makefile.am b/libnm-util/tests/Makefile.am index e805199f80..378a7388a4 100644 --- a/libnm-util/tests/Makefile.am +++ b/libnm-util/tests/Makefile.am @@ -8,7 +8,8 @@ noinst_PROGRAMS = \ test-settings-defaults \ test-crypto \ test-need-secrets \ - test-general + test-general \ + test-setting-8021x test_settings_defaults_SOURCES = \ test-settings-defaults.c @@ -58,6 +59,18 @@ test_general_LDADD = \ $(GLIB_LIBS) \ $(DBUS_LIBS) +test_setting_8021x_SOURCES = \ + test-setting-8021x.c + +test_setting_8021x_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +test_setting_8021x_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) + if WITH_TESTS check-local: test-settings-defaults test-crypto test-need-secrets @@ -65,6 +78,23 @@ check-local: test-settings-defaults test-crypto test-need-secrets $(abs_builddir)/test-need-secrets $(abs_builddir)/test-general +# Private key and CA certificate in the same file (PEM) + $(abs_builddir)/test-setting-8021x \ + $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem \ + "test" \ + $(top_srcdir)/libnm-util/tests/certs/test-key-only-decrypted.der + +# Private key by itself (PEM) + $(abs_builddir)/test-setting-8021x \ + $(top_srcdir)/libnm-util/tests/certs/test-key-only.pem \ + "test" \ + $(top_srcdir)/libnm-util/tests/certs/test-key-only-decrypted.der + +# Private key and CA certificate in the same file (pkcs12) + $(abs_builddir)/test-setting-8021x \ + $(top_srcdir)/libnm-util/tests/certs/test-cert.p12 \ + "test" + # Normal CA certificate $(abs_builddir)/test-crypto --cert \ $(top_srcdir)/libnm-util/tests/certs/test_ca_cert.pem diff --git a/libnm-util/tests/certs/Makefile.am b/libnm-util/tests/certs/Makefile.am index b0dda3658f..4cd8a24bc6 100644 --- a/libnm-util/tests/certs/Makefile.am +++ b/libnm-util/tests/certs/Makefile.am @@ -14,5 +14,7 @@ EXTRA_DIST = \ test2_ca_cert.pem \ test2_key_and_cert.pem \ test2-cert.p12 \ - ca-no-ending-newline.pem + ca-no-ending-newline.pem \ + test-key-only.pem \ + test-key-only-decrypted.der diff --git a/libnm-util/tests/certs/test-key-only-decrypted.der b/libnm-util/tests/certs/test-key-only-decrypted.der new file mode 100644 index 0000000000000000000000000000000000000000..c8652537a6c49d5c06bff9f56e247dec4f5c1489 GIT binary patch literal 1192 zcmV;Z1Xueof&`=j0RRGm0RaHc(&_v3q|RoC%!@73!?^ms>Qe}no+nBKcrl?i(&a++ zcK0N4xYH2*w^xQ}DFPemlPj;lemz(gG!P|)ekd(M{4{^oPYUO@xj<3K<%wX;b5Ubw z;aN5@UeJe2U6+bNBGW?hgJOAvMO)Y)m*UYhBVO#kia~s>fKcu#OSQGn(`?jp+rT{?ARuz9J|(+9&0j5d{nrbq z>kMEyFvDDe$t5zXkI(MBltV*30ronf3l`1w6_df42 za6i3tN;+*zzAgpSyV?TeTEEpC*h{*NlayECC-fDL20*ov-qQOpowS%v^~w%p?xb4} zCr-)~;nrNcqeML2x3l8@>syPG#s=W<_f2}8b2lTt+vxkGA3FyYb%sWKkx97>GTx>WUgv@d zjj75-S@Ap*vD_%gWa0+yqmTy=aURrWoY(~epEe>B>k{c=H#^sR?Z-LE$a#&Qrvib2 z0NSlpkgc{hG!y7V$usxu=7jR?BYo1m0r^uVQ&b&dmx56e=Wb%V!aoMeJSn6Yv4M9< z?8Zgi%0cQ-hSMVyr_!Wft!{ScKc3j#aj5ecTgIh$krn=2YZakw)q`ozC>qiE(irA* zFuAXwkael`5ZroT_O0lMWEFAum&)t`kZk)?w)QCRk;Ewa} z0)c@5r~di*NILJaT8Y{&Xv$OW0KHHNFeI^KBGd|Df&qazyjbLz|7gOl92IX+fc+dR zVm9uG1X{3VE%t#P(;ehQdBWxHD=QX>snZ#3v`X!-v=DP^qUGYkF~9E3RYUk~>kQpX z*6maoUd`Gdp#+T0160u=F~P3pl*1KYd;SNp0)c=E`HOgta>vxOR-iQ0(MUOmCG0_U ze3ejAp1Chev8_L*K>vfP8@WmSwAdAqsE7fxI&i*XP%21^xa1)xroFKS#Nk3Elvf)m znE>^aMV1xEd+amR!hOQ$+Dn5S0H~2SpQ%AR2cd~}#V8k5&3_Mk_G!2xx~b36i82e4 G+!RDNNKuIZ literal 0 HcmV?d00001 diff --git a/libnm-util/tests/certs/test-key-only.pem b/libnm-util/tests/certs/test-key-only.pem new file mode 100644 index 0000000000..5ef530e9ab --- /dev/null +++ b/libnm-util/tests/certs/test-key-only.pem @@ -0,0 +1,92 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 + +KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k +r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ +PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj +5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ +amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj +yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR +PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV +xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg +T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab +HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu +Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev +0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB +m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf +rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f +FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S +uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN +vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt +1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh +ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw +l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v +tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm +aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco +0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD +u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj +DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=test, CN=test/emailAddress=test@test.com + Validity + Not Before: Feb 2 02:22:25 2009 GMT + Not After : Jan 31 02:22:25 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: + b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: + d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: + 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: + 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: + 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: + 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: + 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: + 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: + a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: + ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: + cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: + bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: + 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: + 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: + bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: + 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: + 1c:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B + X509v3 Authority Key Identifier: + keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com + serial:E6:4C:5C:96:26:5E:D6:D0 + + Signature Algorithm: md5WithRSAEncryption + 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: + a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: + e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: + b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: + 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: + ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: + 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: + 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: + e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: + 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: + 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: + 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: + d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: + a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: + 6b:80:38:6e + diff --git a/libnm-util/tests/test-setting-8021x.c b/libnm-util/tests/test-setting-8021x.c new file mode 100644 index 0000000000..6202a1427f --- /dev/null +++ b/libnm-util/tests/test-setting-8021x.c @@ -0,0 +1,163 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2009 Red Hat, Inc. + * + */ + +#include +#include +#include + +#include "nm-test-helpers.h" +#include + +#include "nm-setting-connection.h" +#include "nm-setting-8021x.h" + +static void +compare_decrypted (const char *test, + const char *decrypted_path, + const GByteArray *key) +{ + char *contents = NULL; + gsize len = 0; + GError *error = NULL; + gboolean success; + + success = g_file_get_contents (decrypted_path, &contents, &len, &error); + ASSERT (success == TRUE, + test, "failed to read decrypted key file: %s", error->message); + + ASSERT (len > 0, test, "decrypted key file invalid (size 0)"); + + ASSERT (len == key->len, + test, "decrypted key file (%d) and decrypted key data (%d) lengths don't match", + len, key->len); + + ASSERT (memcmp (contents, key->data, len) == 0, + test, "decrypted key file and decrypted key data don't match"); + + g_free (contents); +} + +static void +test_private_key_import (const char *path, + const char *password, + const char *decrypted_path, + NMSetting8021xCKScheme scheme) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "private-key-import", "setting was NULL"); + + success = nm_setting_802_1x_set_private_key (s_8021x, + path, + password, + scheme, + &format, + &error); + ASSERT (success == TRUE, + "private-key-import", "error reading private key: %s", error->message); + + if ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB + && format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + const GByteArray *key; + + ASSERT (decrypted_path != NULL, "private-key-import", "missing decrypted key file"); + + key = nm_setting_802_1x_get_private_key_blob (s_8021x); + ASSERT (key != NULL, "private-key-import", "missing private key blob"); + compare_decrypted ("private-key-import", decrypted_path, key); + } + + g_object_unref (s_8021x); +} + +static void +test_phase2_private_key_import (const char *path, + const char *password, + const char *decrypted_path, + NMSetting8021xCKScheme scheme) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "phase2-private-key-import", "setting was NULL"); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + path, + password, + scheme, + &format, + &error); + ASSERT (success == TRUE, + "phase2-private-key-import", "error reading private key: %s", error->message); + + if ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB + && format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + const GByteArray *key; + + ASSERT (decrypted_path != NULL, "phase2-private-key-import", "missing decrypted key file"); + + key = nm_setting_802_1x_get_phase2_private_key_blob (s_8021x); + ASSERT (key != NULL, "phase2-private-key-import", "missing private key blob"); + compare_decrypted ("phase2-private-key-import", decrypted_path, key); + } + + g_object_unref (s_8021x); +} + +int main (int argc, char **argv) +{ + GError *error = NULL; + DBusGConnection *bus; + char *base; + const char *decrypted = NULL; + + if (argc < 3) + FAIL ("init", "need at least two arguments: [decrypted private key]"); + + if (argc == 4) + decrypted = argv[3]; + + g_type_init (); + bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL); + + if (!nm_utils_init (&error)) + FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); + + /* The tests */ + test_private_key_import (argv[1], argv[2], NULL, NM_SETTING_802_1X_CK_SCHEME_PATH); + test_phase2_private_key_import (argv[1], argv[2], NULL, NM_SETTING_802_1X_CK_SCHEME_PATH); + + test_private_key_import (argv[1], argv[2], decrypted, NM_SETTING_802_1X_CK_SCHEME_BLOB); + test_phase2_private_key_import (argv[1], argv[2], decrypted, NM_SETTING_802_1X_CK_SCHEME_BLOB); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} +