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 0000000000..ae4a683049 Binary files /dev/null and b/libnm-util/tests/certs/test-cert.p12 differ diff --git a/libnm-util/tests/certs/test_ca_cert.pem b/libnm-util/tests/certs/test_ca_cert.pem new file mode 100644 index 0000000000..faa3fc2905 --- /dev/null +++ b/libnm-util/tests/certs/test_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEhjCCA26gAwIBAgIJAOZMXJYmXtbQMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD +VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw +FQYDVQQKEw5NeSBDb21wYW55IEx0ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxME +dGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAyMDIwMjIx +NTJaFw0xOTAxMzEwMjIxNTJaMIGIMQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVy +a3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0 +ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3DQEJARYN +dGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZz +iHfFR6Gqdz5Gq1elSaf7J2tznfialPyMkRoqngSItrM3JWlkfBu3ZIpGSYG8+Z8H +JjaKh/zkCCH73HcjADCocm/XtgxlOlccDtBvfDqifb2dBikcmcfh0tX0o4JU9L+z +WP7sVcUkJG7C5811lA5pAsLVooJxrZnrta6XstGvFgTSxI2Y4Jowf0syM5b/AHIQ ++htsVhSyj1DWM9day3QsEMZl55SCxCLTB6ZIJLF6NmTYwdnzWWTQf4k7kcptZJU8 +Fqv60b/ATvvUf7S+ZMGLopFIIlmc1Kkn7VTseIKy4ycYuDpyimQy3Yw4flC00vhl +hTijH+5dlVOUFrRh0bsCAwEAAaOB8DCB7TAdBgNVHQ4EFgQUUjMuImZ5guVBLo07 +suXM+r6ZM44wgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6ZM46hgY6k +gYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcT +B05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQLEwR0ZXN0 +MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA +5kxcliZe1tAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAZsWzGp9D +10NWf8ts3A9mhcEb8oDgKNpCOZF9gqr2usZygJjY9MX2n0n81T8XaWDk1wZLlcDW +hzIalCY8rpE57Dj3MEmdCmYr3BrAy6GVlc/MO7ffTHxogl9ouScSYo8ETTtNMKCg +zwkDnXjGzmb1e59DIXMVHBBbTmJXJbM8XP9A2azJkVUyE2fSdWksXMP0XklGbW2p +DksJ+8G1IWkyRhnINV5GZLLNAT5gBA6sUv/iqQKwk8r2dsweMPtLoLWZPAaZErYh +sthGy00Q0GJkmkJpQl8QIlPq5vylNcMUhvc8tmzwk+rDVUj3jTJWqFwMtnHAaNyC +FXl9ynWpe5J28w== +-----END CERTIFICATE----- diff --git a/libnm-util/tests/certs/test_key_and_cert.pem b/libnm-util/tests/certs/test_key_and_cert.pem new file mode 100644 index 0000000000..c00495d0b0 --- /dev/null +++ b/libnm-util/tests/certs/test_key_and_cert.pem @@ -0,0 +1,119 @@ +-----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 +-----BEGIN CERTIFICATE----- +MIIErjCCA5agAwIBAgIBATANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCVVMx +EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO +TXkgQ29tcGFueSBMdGQxDTALBgNVBAsTBHRlc3QxDTALBgNVBAMTBHRlc3QxHDAa +BgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMjAyMDIyMjI1WhcNMTkw +MTMxMDIyMjI1WjCBizELMAkGA1UEBhMCVVMxEjAQBgNVBAgTCUJlcmtzaGlyZTEX +MBUGA1UEChMOTXkgQ29tcGFueSBMdGQxFDASBgNVBAsTC3Rlc3QtY2xpZW50MRQw +EgYDVQQDEwt0ZXN0LWNsaWVudDEjMCEGCSqGSIb3DQEJARYUdGVzdC1jbGllbnRA +dGVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDO0un79KTO +ZofMiy3Sw7j6vupTCJWeJ0oEeDGhNtLlQvV29yRxuNMQ/bdXhmgpAhvpkyuvwH49 +WBY0ECWFfigtQvw0f9ZPCue2uUBRyOWJYM1zUWNn4Vk2MV7Qh0tdl4pCItNC8oNi +eYRFW9ggl+LRNCNe7L+KQXytgFDzmxxRXeQpHMHGfKEAcA/2eXcDIvVLq3bKIKvh +TlNshmjp1g9ulUu1tc/TbNRz28A9HSAgcqs+Jbs/zV8td/3XC6jrDHPAP3QnF1bP +MZqp7cE5J8eq6XdI9G1WiTVceVv2L4yfk7wTHNB0XzAbFUNxjv8a32VlacKKWqsE +SoDeICmNSByDAgMBAAGjggEcMIIBGDAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQf +Fh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNOlc2PzH +r/dd9BPTghrNUg9Kuwswgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6Z +M46hgY6kgYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO +BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQL +EwR0ZXN0MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3Qu +Y29tggkA5kxcliZe1tAwDQYJKoZIhvcNAQEEBQADggEBAIjE3cVKpo4fNmKAMWsr +hTQNbKfc4Vo83XRX21m+i/J5QC29m+GrDgN1IHUv6pf51H4VdcKC9bE35Isk1O8C +OxlqVrufw6W0xDmgZJZbw6gZdOwLzzPf8xLz4qsdfd4hZM2xoG96d4TUYopQ5nZd +rzrvGocOGjjE+Q0vFOAgMkwucNJxgtXlyRMsTrTIY2UdSOjDVm2IhFdlEx5CSLQD +JXFOEp0aiGXVcSE7Dr43HPCIa0UMDmzlYMuGv79AMMTPlPgcYNQb34gCekV+0cbz +B7mxjypVL753n9FGZAW3Z8WyrIxCj2pRpA0rFqTWOaX4Je1oJRO1Gaxs6ezuA2uA +OG4= +-----END CERTIFICATE----- diff --git a/libnm-util/tests/test-crypto.c b/libnm-util/tests/test-crypto.c new file mode 100644 index 0000000000..75e34d3ad7 --- /dev/null +++ b/libnm-util/tests/test-crypto.c @@ -0,0 +1,260 @@ +/* -*- 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 "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; +} +