From 203cff4d834510408c3ae312bbbc4ce2157d82c0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 2 Feb 2009 01:03:15 -0500 Subject: [PATCH] libnm-util: move crypto tests to libnm-util/tests/ Add testing certs and keys; run crypto tests on 'make check' --- configure.in | 1 + libnm-util/Makefile.am | 31 ++- libnm-util/crypto.c | 22 +- libnm-util/test-crypto.c | 200 -------------- libnm-util/tests/Makefile.am | 25 +- libnm-util/tests/certs/Makefile.am | 14 + libnm-util/tests/certs/test-cert.p12 | Bin 0 -> 4092 bytes libnm-util/tests/certs/test_ca_cert.pem | 27 ++ libnm-util/tests/certs/test_key_and_cert.pem | 119 +++++++++ libnm-util/tests/test-crypto.c | 260 +++++++++++++++++++ 10 files changed, 476 insertions(+), 223 deletions(-) delete mode 100644 libnm-util/test-crypto.c create mode 100644 libnm-util/tests/certs/Makefile.am create mode 100644 libnm-util/tests/certs/test-cert.p12 create mode 100644 libnm-util/tests/certs/test_ca_cert.pem create mode 100644 libnm-util/tests/certs/test_key_and_cert.pem create mode 100644 libnm-util/tests/test-crypto.c diff --git a/configure.in b/configure.in index 0343a5e2e9..a338983dd7 100644 --- a/configure.in +++ b/configure.in @@ -508,6 +508,7 @@ src/backends/Makefile libnm-util/libnm-util.pc libnm-util/Makefile libnm-util/tests/Makefile +libnm-util/tests/certs/Makefile libnm-glib/libnm_glib.pc libnm-glib/libnm_glib_vpn.pc libnm-glib/Makefile diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 95d46b5ec6..177e3b3181 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -71,24 +71,35 @@ endif libnm_util_includedir=$(includedir)/NetworkManager -noinst_PROGRAMS = test-crypto -test_crypto_SOURCES = test-crypto.c crypto.c -test_crypto_CPPFLAGS = $(GLIB_CFLAGS) -D_GNU_SOURCE -test_crypto_LDADD = $(GLIB_LIBS) libnm-util.la +########################################### +# Crypto test library +########################################### + +noinst_LTLIBRARIES = libtest-crypto.la + +libtest_crypto_la_SOURCES = crypto.c + +libtest_crypto_la_CPPFLAGS = \ + $(GLIB_CFLAGS) + +libtest_crypto_la_LIBADD = \ + $(GLIB_LIBS) if WITH_GNUTLS -test_crypto_SOURCES += crypto_gnutls.c -test_crypto_CPPFLAGS += $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS) -test_crypto_LDADD += $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS) +libtest_crypto_la_SOURCES += crypto_gnutls.c +libtest_crypto_la_CPPFLAGS += $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS) +libtest_crypto_la_LIBADD += $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS) endif if WITH_NSS -test_crypto_SOURCES += crypto_nss.c -test_crypto_CPPFLAGS += $(NSS_CFLAGS) -test_crypto_LDADD += $(NSS_LIBS) +libtest_crypto_la_SOURCES += crypto_nss.c +libtest_crypto_la_CPPFLAGS += $(NSS_CFLAGS) +libtest_crypto_la_LIBADD += $(NSS_LIBS) endif + + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-util.pc diff --git a/libnm-util/crypto.c b/libnm-util/crypto.c index 3bd7405cc4..9f4ccd48a5 100644 --- a/libnm-util/crypto.c +++ b/libnm-util/crypto.c @@ -311,9 +311,9 @@ convert_iv (const char *src, GError **error) { int num; - int i; - char conv[3]; - char *c; + int i; + char conv[3]; + char *c; g_return_val_if_fail (src != NULL, NULL); @@ -326,16 +326,16 @@ convert_iv (const char *src, } num /= 2; - c = g_malloc0 (num + 1); - if (c == NULL) { + c = g_malloc0 (num + 1); + if (c == NULL) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_OUT_OF_MEMORY, _("Not enough memory to store the IV.")); return NULL; } - conv[2] = '\0'; - for (i = 0; i < num; i++) { + conv[2] = '\0'; + for (i = 0; i < num; i++) { conv[0] = src[(i * 2)]; conv[1] = src[(i * 2) + 1]; if (!g_ascii_isxdigit (conv[0]) || !g_ascii_isxdigit (conv[1])) { @@ -345,10 +345,10 @@ convert_iv (const char *src, goto error; } - c[i] = strtol(conv, NULL, 16); - } - *out_len = num; - return c; + c[i] = strtol(conv, NULL, 16); + } + *out_len = num; + return c; error: g_free (c); diff --git a/libnm-util/test-crypto.c b/libnm-util/test-crypto.c deleted file mode 100644 index 6134a0d2c9..0000000000 --- a/libnm-util/test-crypto.c +++ /dev/null @@ -1,200 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - -/* - * Dan Williams - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2007 - 2008 Red Hat, Inc. - */ - -#include -#include -#include -#include -#include -#include - -#include "crypto.h" - -static const char *pem_rsa_key_begin = "-----BEGIN RSA PRIVATE KEY-----"; -static const char *pem_rsa_key_end = "-----END RSA PRIVATE KEY-----"; - -static const char *pem_dsa_key_begin = "-----BEGIN DSA PRIVATE KEY-----"; -static const char *pem_dsa_key_end = "-----END DSA PRIVATE KEY-----"; - -static void -dump_key_to_pem (const char *key, gsize key_len, int key_type) -{ - char *b64 = NULL; - GString *str = NULL; - const char *start_tag; - const char *end_tag; - char *p; - - switch (key_type) { - case NM_CRYPTO_KEY_TYPE_RSA: - start_tag = pem_rsa_key_begin; - end_tag = pem_rsa_key_end; - break; - case NM_CRYPTO_KEY_TYPE_DSA: - start_tag = pem_dsa_key_begin; - end_tag = pem_dsa_key_end; - break; - default: - g_warning ("Unknown key type %d", key_type); - return; - } - - b64 = g_base64_encode ((const unsigned char *) key, key_len); - if (!b64) { - g_warning ("Couldn't base64 encode the key."); - goto out; - } - - str = g_string_new (NULL); - if (!str) { - g_warning ("Couldn't allocate buffer to write out key."); - goto out; - } - - g_string_append (str, start_tag); - g_string_append_c (str, '\n'); - - for (p = b64; p < (b64 + strlen (b64)); p += 64) { - g_string_append_len (str, p, strnlen (p, 64)); - g_string_append_c (str, '\n'); - } - - g_string_append (str, end_tag); - g_string_append_c (str, '\n'); - - g_message ("Decrypted private key:\n\n%s", str->str); - -out: - g_free (b64); - if (str) - g_string_free (str, TRUE); -} - -static void -usage (const char *prgname) -{ - fprintf (stderr, "Usage: %s cert \n" - " %s key \n", - prgname, prgname); -} - -#define MODE_CERT 1 -#define MODE_KEY 2 - -int main (int argc, char **argv) -{ - int mode = 0; - const char *file; - GError *error = NULL; - - if (argc < 2) { - usage (argv[0]); - return 1; - } - - if (!strcmp (argv[1], "key")) { - if (argc < 4) { - usage (argv[0]); - return 1; - } - mode = MODE_KEY; - } else if (!strcmp (argv[1], "cert")) { - if (argc < 3) { - usage (argv[0]); - return 1; - } - mode = MODE_CERT; - } else { - usage (argv[0]); - return 1; - } - - if (!crypto_init (&error)) { - g_warning ("Couldn't initialize crypto library: %d %s.", - error->code, error->message); - return 1; - } - - file = argv[2]; - - if (mode == MODE_CERT) { - GByteArray *array; - NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - - array = crypto_load_and_verify_certificate (file, &format, &error); - if (!array) { - g_warning ("Couldn't read certificate file '%s': %d %s", - file, error->code, error->message); - goto out; - } - - switch (format) { - case NM_CRYPTO_FILE_FORMAT_X509: - g_message ("Format: pkcs#1"); - break; - case NM_CRYPTO_FILE_FORMAT_PKCS12: - g_message ("Format: pkcs#12"); - break; - default: - g_message ("Format: unknown"); - break; - } - - g_byte_array_free (array, TRUE); - } else if (mode == MODE_KEY) { - NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; - NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; - const char *password = argv[3]; - GByteArray *array; - - array = crypto_get_private_key (file, password, &key_type, &format, &error); - if (!array) { - g_warning ("Couldn't read key file '%s': %d %s", - file, error->code, error->message); - goto out; - } - - switch (format) { - case NM_CRYPTO_FILE_FORMAT_RAW_KEY: - g_message ("Original format: pkcs#1\n"); - dump_key_to_pem ((const char *) array->data, array->len, key_type); - break; - case NM_CRYPTO_FILE_FORMAT_PKCS12: - g_message ("Original format: pkcs#12"); - break; - default: - g_message ("Original format: unknown"); - break; - } - - g_byte_array_free (array, TRUE); - } else { - g_assert_not_reached (); - } - -out: - crypto_deinit (); - - return 0; -} - diff --git a/libnm-util/tests/Makefile.am b/libnm-util/tests/Makefile.am index 4dfe175abf..c550f74899 100644 --- a/libnm-util/tests/Makefile.am +++ b/libnm-util/tests/Makefile.am @@ -1,8 +1,10 @@ +SUBDIRS=certs + INCLUDES = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-util -noinst_PROGRAMS = test-settings-defaults +noinst_PROGRAMS = test-settings-defaults test-crypto test_settings_defaults_SOURCES = \ test-settings-defaults.c @@ -16,10 +18,29 @@ test_settings_defaults_LDADD = \ $(DBUS_LIBS) \ $(top_builddir)/libnm-util/libnm-util.la +test_crypto_SOURCES = \ + test-crypto.c + +test_crypto_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + -D_GNU_SOURCE + +test_crypto_LDADD = \ + $(GTHREAD_LIBS) \ + $(top_builddir)/libnm-util/libtest-crypto.la + + if WITH_TESTS -check-local: test-settings-defaults +check-local: test-settings-defaults test-crypto $(abs_builddir)/test-settings-defaults + $(abs_builddir)/test-crypto \ + $(top_srcdir)/libnm-util/tests/certs/test_ca_cert.pem \ + $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem \ + $(top_srcdir)/libnm-util/tests/certs/test_key_and_cert.pem \ + "test" \ + $(top_srcdir)/libnm-util/tests/certs/test-cert.p12 \ + "test" endif diff --git a/libnm-util/tests/certs/Makefile.am b/libnm-util/tests/certs/Makefile.am new file mode 100644 index 0000000000..50f066aaec --- /dev/null +++ b/libnm-util/tests/certs/Makefile.am @@ -0,0 +1,14 @@ +# test-cert.p12 created with: +# +# openssl pkcs12 -export \ +# -in test_key_and_cert.pem \ +# -inkey test_key_and_cert.pem \ +# -certfile test_ca_cert.pem \ +# -name "test-pkcs12" \ +# -out test-cert.p12 + +EXTRA_DIST = \ + test_ca_cert.pem \ + test_key_and_cert.pem \ + test-cert.p12 + diff --git a/libnm-util/tests/certs/test-cert.p12 b/libnm-util/tests/certs/test-cert.p12 new file mode 100644 index 0000000000000000000000000000000000000000..ae4a68304973f7e8fec78c8e8f53d169df2afe59 GIT binary patch literal 4092 zcmY+GbyO1!+r~$1glrD!l7>kRP#OtAx)}ma2`Om>aVq5~ky0240wa{JF_3n2OV+?{&*z-)`=0mxJ4XYH~BThq(0VhSFJCm_yqN2ye*m(=5D+EJ%3CftWZt_&Ve&OUDWNf za}UZPveG_kaaQA#6dcwiD)I;Y(l0mqWBa>f)2OG2=WEHyX}aNL{}&pzz2C4(_wn?L z%|{B>*WANgaW9uHLTV)5G#7C1|H@SF!&5r!epnS98!4Z8HC4=H%y@#1N)*V4a&gFx z)vT<0FL5Y7d3f|zT`^x}LFo#}m2W|PhRrZ7d=ODtWD#hx<`UHw{;&e>>7vv~e23Ap zWGJpLDcb=kg5>Q?J(Csqh)geVrUe)uvsYfAs&@M;Cj4ytm$YZXBn|Ego1!(NcQXl{ zmr_<_Q&d#FiIt zR%>3cv!~$0F5;%vKAMl|uKzxb=FG`yUEn!eZrfGZAX$&*Z2-l-{#y_cU)+Sw2QfdRhx#;(g z*^KOeCKS6E7avXBVYkr)+IVI{BkKwgbs{|~$g5#dyl;&H?lh#(NX>X=%YHPedG#2o z%^Px`6K&wyex)L-+ksEsDj&3L<(}Mu%=HLXkcPS}RGlNX6UNjhm>X#%zFdggcx*H6 zCJD;gUSS1iWj+u{U_ua<`f~L&Or^4S6H0m9yrVc@D#ii?p9@^lAGJ?Qq}K zTHtoLp^vAG@1VL6ME9i`@?r_~G3SOwtB59T_O&;IBy{l*f}l){s+40H6T%<^l&>%PMzhq)Pa zaqi0UO{JB$U*?v%N zxJl6u2lLTo!%NeIE)O4(QfmfGGnH zlS6;u0QHr2Zg97E5QM2DYl`Ta`#v66kp1ND!j)ko!$=C2rPR1c_!!plMeF_E&+^jd zYq}%Ff;?)+YSY1(GrmZOg`f!A0ra7`$7&k`o>lHLE_jpf`+nL|Z_k{9&eQjK@jKh5 zAGZF;A1i5iGW17!)C`2UVU&U!!JG2>BE4(-)d5Su=hiMNmoq+BrEc8Ap!G@qcTWYN z?h7+9?Iz;xt`y3w!KXkI*GDqY_;3t>2gcv8|LpruiNFVQiu%L)^P|`zH^`!ps`Dte zKl)VeEH4b0{fS?^!VAw^#PgQz%dlU?TJGy_dwa^#cC{9%GOa;Tw=jnRW{0ahI=5nL z=?QS%E9$YSr{BA`4@FB0d$hW^cP{1BC^2qd&BHYu+%uhq)YNqPX}v=@X860_?0v7YRfei^4sZ)mPi|%_B!wwR^!>IqH#st* z1FGeS(!?4R>fh`+4){F(JP$!lnq?Ynn~W0;fJe;wHaakvUwieI5Dhk)|2j*O=4Z*@ zEFh#aQ07>CC*+usLgMpTxLGnpl&H>eExw#{Z?$Zj{VF@}PIn2Di0ZL9b)OlRUuG;y z)JMVd;jmvkr#@EC^+9aOZ|28pIVnK9016$fG)AQQ;;T`5h0j;Zp`2(BO{(}t=Jlab zA*2wraNuc@${n8>#^DL(j8OZLP=euG{+#9OD{0xf3>{QwEkAqSHaQdj9GZpYic(0x z%N+I~hjP8tupVH<$xQusi0HR1xa{1p4gR|D&L<*=x6El0yR!-pbio-(zME^+i;T$JGTFDifmZS;{cpJ zY)0kSPT=k-2Dl(KA-GB*jg{i;s{J824(9zW)`$Eg$p_vjvh1nz1zZ)k>;+cOly+4F z-=se55%i)xPw|v@al;r_HYwhJ8yp9vxhKhh5DlCDk^TmvPrqd!VU_8mC7Je%K`Y%r z%?5As;O zyIoaqCjkLy`!xN8$SGd<#=vO0`JrG#Pg-*KCt0PjE^6Q3$yaMm-*`PV)BQhb-erPK z5lobMYkU1E^}0|R!!>nW0_(gUhC<30%6#17f?-&nLC4xquv_Tew0Vg>+ZFVRWoi8( zbDeaVRiVS;uk|YGgr+0*O`3Bk1yfn~M~`Q*buKR+0N}W|Hb+1oi%;x0Cokp*js`ma z2OwskftKWGAmXoV{I~Q$*ZvO|sYysP(B#{2H2L~}Q6$+v6uC!gz&}?SS@I7>lB3Bx zaW_=t5o%|x&<`f{yrV2O8u$46z|5oERmHKtc<-&i?oR~o-SJTSjh#NlcE;K?QJiZ> zLBW{xl)<+{4RsCR$xE0C_zgeOJ0|*mj`wV-LG(jBF@T!q^~Er1`9pOA$!nZEVS(A^ zemvs?x*Xy+f$~DTMCl2ykdAvH8Z~ddP+6-;i$lNf9^Qi9Xzl^o?kX0O+mj4AP(R4VFyQQ%_%L(M^iwt8CKc6OCo?*w*l7eL7r6g1;P2xsb+ z&sF^#5UR;xZQUOI9JZvLV!P6mCo{;3qO|dupcjXiNa+{=^D=%CZ)e~A7D+luCv54w zPLz`-`WcSi#fBFc(DU^2%-{+UR@MQ@&T~XJZIlc0m)Lk^=_9_IFIBv@X=!#ub{eoR zgYpkp+vdHCB}&BH55P;==2N(hwO^2vdOL4smbuA7O3~E?&kk-qaSh8qp`;K{iQYWt zQ|<>H2LaqMNlARkxml6=1D;OhkMDDr4G(kj^48#N!MxBZV3fNNO;oTjS4t zRYxO7&4x7X+K(cAIGS)zCPDW8-uGaML|YDa_BfFGyxNDR1`V@=Hs4(nM=0a4%;)3_ z%Gk$?yb&zQJB^j#$muJIT-p+@ZO@c!VKFV7UA8qq)`M+v2^yZ2Eix@@;ej|XoXr0m zqmx@I?zo);QMUL>A?+LPoavC5Z1in%>$ELqjN1MIU4O%mjv*biD2vtm2>sM6rZ_dU z&51MV`lFL8fv677FAtcI#z&gfg&y6~&u?*I=WhTQK$qG~Gl_s#Z&DMV{w%RL?esU= z7h~lLGM!r)0e*VpmP%&Y8IU08Rr(RORZ~0AU7O2PetT%@xPVt13)&^fBE7v@sdI6* zF@4jf=T}bnX=NnqbxHhAE%^(XB}~`wOjZ4-ihvEpM2*CYkI|43K2?%=cfv-?Fjeh= zq&Pr&*&8YWL$j_ZEFvGXa(=>5L`T}_s=Sx6V*P`#hH$zzp>qA^4M_! zV{TEsT_ssX+iuE9`<^Wm>4O+?3Z>6^-vj$u)*%sFxz*x}1pIy-ihXcyP?kD|5@XxG zeh(z%e^Q|CLlqsKMpC+hSa0=waaV^zl~H?Y(d9&1@dMB6`cF1Y$i? zhK!i@vLQY(z)`NpsI_+OU|=jru2E&I6d`93oOcq!PYV!ooU@ObfP~q+Aj}W@{l4MK zIm|ZeD9m5c(rw^`xxY(8TZ7W!*|g=&zfxil9-GsHzNnDb`T9=ta~ze~A&j^lbiVF; z?{;a({^#`xtd@aEQ0lQW-%704X|;@{hMsC^%ZKa2Dv6#LYx=+(5hk_g&(vLnMXF}} zSi)xS_b?M~O@c9WS;&u_b1~YM{w*Wtmd0cfdT`$VPe&>S2}W}IL@r^hc{1U90RdK$ zvK1IXw9np!^Z$E9FTs415#R%G0C@lHq5v;|E8xlBT>>Bpmw + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2008 Red Hat, Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "nm-test-helpers.h" +#include "crypto.h" + +#if 0 +static const char *pem_rsa_key_begin = "-----BEGIN RSA PRIVATE KEY-----"; +static const char *pem_rsa_key_end = "-----END RSA PRIVATE KEY-----"; + +static const char *pem_dsa_key_begin = "-----BEGIN DSA PRIVATE KEY-----"; +static const char *pem_dsa_key_end = "-----END DSA PRIVATE KEY-----"; + +static void +dump_key_to_pem (const char *key, gsize key_len, int key_type) +{ + char *b64 = NULL; + GString *str = NULL; + const char *start_tag; + const char *end_tag; + char *p; + + switch (key_type) { + case NM_CRYPTO_KEY_TYPE_RSA: + start_tag = pem_rsa_key_begin; + end_tag = pem_rsa_key_end; + break; + case NM_CRYPTO_KEY_TYPE_DSA: + start_tag = pem_dsa_key_begin; + end_tag = pem_dsa_key_end; + break; + default: + g_warning ("Unknown key type %d", key_type); + return; + } + + b64 = g_base64_encode ((const unsigned char *) key, key_len); + if (!b64) { + g_warning ("Couldn't base64 encode the key."); + goto out; + } + + str = g_string_new (NULL); + if (!str) { + g_warning ("Couldn't allocate buffer to write out key."); + goto out; + } + + g_string_append (str, start_tag); + g_string_append_c (str, '\n'); + + for (p = b64; p < (b64 + strlen (b64)); p += 64) { + g_string_append_len (str, p, strnlen (p, 64)); + g_string_append_c (str, '\n'); + } + + g_string_append (str, end_tag); + g_string_append_c (str, '\n'); + + g_message ("Decrypted private key:\n\n%s", str->str); + +out: + g_free (b64); + if (str) + g_string_free (str, TRUE); +} +#endif + +static void +test_load_cert (const char *path, const char *desc) +{ + GByteArray *array; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GError *error = NULL; + + array = crypto_load_and_verify_certificate (path, &format, &error); + ASSERT (array != NULL, desc, + "couldn't read certificate file '%s': %d %s", + path, error->code, error->message); + + ASSERT (format == NM_CRYPTO_FILE_FORMAT_X509, desc, + "%s: unexpected certificate format (expected %d, got %d)", + path, NM_CRYPTO_FILE_FORMAT_X509, format); + + g_byte_array_free (array, TRUE); +} + +static void +test_load_private_key (const char *path, + const char *password, + gboolean expect_fail, + const char *desc) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GByteArray *array; + GError *error = NULL; + + array = crypto_get_private_key (path, password, &key_type, &format, &error); + if (expect_fail) { + ASSERT (array == NULL, desc, + "unexpected success reading private key file '%s' with " + "invalid password", + path); + + ASSERT (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN, desc, + "unexpected success determining private key file '%s' " + "format with invalid password (expected %d, got %d)", + path, NM_CRYPTO_FILE_FORMAT_UNKNOWN, format); + return; + } + + ASSERT (array != NULL, desc, + "couldn't read private key file '%s': %d %s", + path, error->code, error->message); + + ASSERT (format == NM_CRYPTO_FILE_FORMAT_RAW_KEY, desc, + "%s: unexpected private key file format (expected %d, got %d)", + path, NM_CRYPTO_FILE_FORMAT_RAW_KEY, format); + + ASSERT (key_type == NM_CRYPTO_KEY_TYPE_RSA, desc, + "%s: unexpected private key type (expected %d, got %d)", + path, NM_CRYPTO_KEY_TYPE_RSA, format); + + g_byte_array_free (array, TRUE); +} + +static void +test_load_pkcs12 (const char *path, + const char *password, + gboolean expect_fail, + const char *desc) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GByteArray *array; + GError *error = NULL; + + array = crypto_get_private_key (path, password, &key_type, &format, &error); + if (expect_fail) { + ASSERT (array == NULL, desc, + "unexpected success reading PKCS#12 private key file " + "'%s' with invalid password", + path); + + /* PKCS#12 file format can be determined even if the password + * is wrong; check that. + */ + ASSERT (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN, desc, + "unexpected success determining PKCS#12 private key " + "'%s' file format with invalid password (expected %d, " + "got %d)", + path, NM_CRYPTO_FILE_FORMAT_UNKNOWN, format); + ASSERT (key_type == NM_CRYPTO_KEY_TYPE_UNKNOWN, desc, + "unexpected success determining PKCS#12 private key " + "'%s' type with invalid password (expected %d, got %d)", + path, NM_CRYPTO_KEY_TYPE_UNKNOWN, key_type); + return; + } + + ASSERT (array != NULL, desc, + "couldn't read PKCS#12 private key file '%s': %d %s", + path, error->code, error->message); + + ASSERT (format == NM_CRYPTO_FILE_FORMAT_PKCS12, desc, + "%s: unexpected PKCS#12 private key file format (expected %d, got %d)", + path, NM_CRYPTO_FILE_FORMAT_RAW_KEY, format); + + ASSERT (key_type == NM_CRYPTO_KEY_TYPE_ENCRYPTED, desc, + "%s: unexpected PKCS#12 private key type (expected %d, got %d)", + path, NM_CRYPTO_KEY_TYPE_ENCRYPTED, format); + + g_byte_array_free (array, TRUE); +} + +static void +test_is_pkcs12 (const char *path, gboolean expect_fail, const char *desc) +{ + gboolean is_pkcs12; + + is_pkcs12 = crypto_is_pkcs12_file (path); + if (expect_fail) { + ASSERT (is_pkcs12 == FALSE, desc, + "unexpected success reading non-PKCS#12 file '%s'", + path); + return; + } + + ASSERT (is_pkcs12 == TRUE, desc, "couldn't read PKCS#12 file '%s'", path); +} + +int main (int argc, char **argv) +{ + GError *error = NULL; + char *progname; + const char *ca_cert; + const char *client_cert; + const char *priv_key; + const char *priv_key_password; + const char *pk12; + const char *pk12_password; + + ASSERT (argc == 7, "test-crypto", + "wrong number of arguments (expected ca-cert, client-cert, " + "private-key, private-key-password, pkcs12-cert, pkcs12-password)"); + + if (!crypto_init (&error)) + FAIL ("crypto-init", "failed to initialize crypto: %s", error->message); + + ca_cert = argv[1]; + client_cert = argv[2]; + priv_key = argv[3]; + priv_key_password = argv[4]; + pk12 = argv[5]; + pk12_password = argv[6]; + + test_load_cert (ca_cert, "ca-cert"); + test_load_cert (client_cert, "client-cert"); + test_load_private_key (priv_key, priv_key_password, FALSE, "private-key"); + test_load_private_key (priv_key, "blahblahblah", TRUE, "private-key-bad-password"); + test_load_pkcs12 (pk12, pk12_password, FALSE, "pkcs12-private-key"); + test_load_pkcs12 (pk12, "blahblahblah", TRUE, "pkcs12-private-key-bad-password"); + test_is_pkcs12 (pk12, FALSE, "is-pkcs12"); + test_is_pkcs12 (priv_key, TRUE, "is-pkcs12-not-pkcs12"); + + crypto_deinit (); + + progname = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", progname); + g_free (progname); + return 0; +} +