return nfound;
}
-#ifdef UNTESTED_CODE
-
static void
append_each_header (gpointer key, gpointer value, gpointer user_data)
{
{
GString *string;
gint state, save;
- gsize length, n_prefix;
+ gsize i, length;
+ gsize n_prefix, estimate;
g_return_val_if_fail (data || !n_data, NULL);
g_return_val_if_fail (type, NULL);
}
/* Resize string to fit the base64 data. Algorithm from Glib reference */
- length = n_data * 4 / 3 + n_data * 4 / (3 * 72) + 7;
+ estimate = n_data * 4 / 3 + n_data * 4 / (3 * 65) + 7;
n_prefix = string->len;
- g_string_set_size (string, n_prefix + length);
+ g_string_set_size (string, n_prefix + estimate);
- /* The actual base64 data */
+ /* The actual base64 data, without line breaks */
state = save = 0;
- length = g_base64_encode_step (data, n_data, TRUE,
- string->str + string->len, &state, &save);
+ length = g_base64_encode_step (data, n_data, FALSE,
+ string->str + n_prefix, &state, &save);
+ length += g_base64_encode_close (TRUE, string->str + n_prefix + length,
+ &state, &save);
+
+ g_assert (length <= estimate);
g_string_set_size (string, n_prefix + length);
+ /*
+ * OpenSSL is absolutely certain that it wants its PEM base64
+ * lines to be 64 characters in length. So go through and break
+ * those lines up.
+ */
+
+ for (i = 64; i < length; i += 64) {
+ g_string_insert_c (string, n_prefix + i, '\n');
+ ++length;
+ ++i;
+ }
+
/* The suffix */
- g_string_append_c (string, '\n');
g_string_append_len (string, PEM_PREF_END, PEM_PREF_END_L);
g_string_append (string, g_quark_to_string (type));
g_string_append_len (string, PEM_SUFF, PEM_SUFF_L);
return (guchar*)g_string_free (string, FALSE);
}
-#endif /* UNTESTED_CODE */
-
/* ----------------------------------------------------------------------------
* DEFINITIONS
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
EGG_SECURE_GLIB_DEFINITIONS ();
typedef struct {
guchar *input;
gsize n_input;
+ GQuark reftype;
guchar *refenc;
guchar *refdata;
gsize n_refenc;
gboolean res;
const gchar *dekinfo;
+ g_assert (type);
+ test->reftype = type;
+
g_assert ("no data in PEM callback" && data != NULL);
g_assert ("no data in PEM callback" && n_data > 0);
test->refenc = g_memdup (data, n_data);
g_assert ("data doesn't match input" && memcmp (encrypted, test->refenc, n_encrypted) == 0);
}
+static void
+test_write_exactly_same (Test *test, gconstpointer unused)
+{
+ guchar *result;
+ gsize n_result;
+ guint num;
+
+ num = egg_openssl_pem_parse (test->input, test->n_input, parse_reference, test);
+ g_assert ("couldn't PEM block in reference data" && num == 1);
+
+ result = egg_openssl_pem_write (test->refenc, test->n_refenc, test->reftype,
+ test->refheaders, &n_result);
+
+ /*
+ * Yes sirrr. Openssl's parser is so fragile, that we have to make it
+ * character for character identical. This includes line breaks, whitespace
+ * and line endings.
+ */
+
+ egg_assert_cmpmem (test->input, test->n_input, ==, result, n_result);
+ g_free (result);
+}
+
/* 29 bytes (prime number, so block length has bad chance of matching */
static const guchar *TEST_DATA = (guchar*)"ABCDEFGHIJKLMNOPQRSTUVWXYZ123";
const gsize TEST_DATA_L = 29;
g_test_add ("/openssl/parse_reference", Test, NULL, setup, test_parse_reference, teardown);
g_test_add ("/openssl/write_reference", Test, NULL, setup, test_write_reference, teardown);
+ g_test_add ("/openssl/write_exactly_same", Test, NULL, setup, test_write_exactly_same, teardown);
g_test_add ("/openssl/openssl_roundtrip", Test, NULL, setup, test_openssl_roundtrip, teardown);
return g_test_run ();