LCOV - code coverage report
Current view: top level - egg - test-openssl.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.8 % 85 84
Test Date: 2024-12-15 20:37:51 Functions: 100.0 % 11 11

            Line data    Source code
       1              : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
       2              : /* test-openssl.c: Test openssl
       3              : 
       4              :    Copyright (C) 2008 Stefan Walter
       5              : 
       6              :    The Gnome Keyring Library is free software; you can redistribute it and/or
       7              :    modify it under the terms of the GNU Library General Public License as
       8              :    published by the Free Software Foundation; either version 2 of the
       9              :    License, or (at your option) any later version.
      10              : 
      11              :    The Gnome Keyring Library is distributed in the hope that it will be useful,
      12              :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :    Library General Public License for more details.
      15              : 
      16              :    You should have received a copy of the GNU Library General Public
      17              :    License along with the Gnome Library; see the file COPYING.LIB.  If not,
      18              :    <http://www.gnu.org/licenses/>.
      19              : 
      20              :    Author: Stef Walter <stef@memberwebs.com>
      21              : */
      22              : 
      23              : #include "config.h"
      24              : 
      25              : #include "egg/egg-armor.h"
      26              : #include "egg/egg-symkey.h"
      27              : #include "egg/egg-openssl.h"
      28              : #include "egg/egg-secure-memory.h"
      29              : #include "egg/egg-testing.h"
      30              : 
      31              : #include <glib.h>
      32              : 
      33              : #include <stdlib.h>
      34              : #include <stdio.h>
      35              : #include <string.h>
      36              : #include <unistd.h>
      37              : 
      38           98 : EGG_SECURE_DEFINE_GLIB_GLOBALS ();
      39              : 
      40              : typedef struct {
      41              :         GBytes *input;
      42              :         GQuark reftype;
      43              :         guchar *refenc;
      44              :         guchar *refdata;
      45              :         gsize n_refenc;
      46              :         gsize n_refdata;
      47              :         GHashTable *refheaders;
      48              : } Test;
      49              : 
      50              : static void
      51            4 : setup (Test *test, gconstpointer unused)
      52              : {
      53              :         gchar *contents;
      54              :         gsize length;
      55              : 
      56            4 :         if (!g_file_get_contents (SRCDIR "/egg/fixtures/pem-rsa-enc.key", &contents, &length, NULL))
      57            0 :                 g_assert_not_reached ();
      58              : 
      59            4 :         test->input = g_bytes_new_take (contents, length);
      60            4 : }
      61              : 
      62              : static void
      63            4 : teardown (Test *test, gconstpointer unused)
      64              : {
      65            4 :         g_bytes_unref (test->input);
      66            4 :         g_free (test->refenc);
      67            4 :         egg_secure_free (test->refdata);
      68            4 :         g_hash_table_destroy (test->refheaders);
      69            4 : }
      70              : 
      71              : static void
      72            8 : copy_each_key_value (gpointer key, gpointer value, gpointer user_data)
      73              : {
      74            8 :         g_hash_table_insert ((GHashTable*)user_data, g_strdup ((gchar*)key), g_strdup ((gchar*)value));
      75            8 : }
      76              : 
      77              : static void
      78            4 : parse_reference (GQuark type,
      79              :                  GBytes *data,
      80              :                  GBytes *outer,
      81              :                  GHashTable *headers,
      82              :                  gpointer user_data)
      83              : {
      84            4 :         Test *test = user_data;
      85              :         const gchar *dekinfo;
      86              : 
      87            4 :         g_assert (type);
      88            4 :         test->reftype = type;
      89              : 
      90            4 :         g_assert ("no data in PEM callback" && data != NULL);
      91            4 :         g_assert ("no data in PEM callback" && g_bytes_get_size (data) > 0);
      92            4 :         test->refenc = g_memdup (g_bytes_get_data (data, NULL), g_bytes_get_size (data));
      93            4 :         test->n_refenc = g_bytes_get_size (data);
      94              : 
      95            4 :         g_assert ("no headers present in file" && headers != NULL);
      96            4 :         g_assert (!test->refheaders);
      97            4 :         test->refheaders = egg_armor_headers_new ();
      98            4 :         g_hash_table_foreach (headers, copy_each_key_value, test->refheaders);
      99            4 :         dekinfo = egg_openssl_get_dekinfo (headers);
     100            4 :         g_assert ("no dekinfo in headers" && dekinfo != NULL);
     101              : 
     102            4 :         test->refdata = egg_openssl_decrypt_block (dekinfo, "booo", 4, data, &test->n_refdata);
     103            4 :         g_assert ("no data returned from openssl decrypt" && test->refdata != NULL);
     104            4 :         g_assert ("invalid amount of data returned from openssl decrypt" && test->n_refdata == g_bytes_get_size (data));
     105            4 : }
     106              : 
     107              : static void
     108            1 : test_parse_reference (Test *test, gconstpointer unused)
     109              : {
     110              :         guint num;
     111              : 
     112            1 :         num = egg_armor_parse (test->input, parse_reference, test);
     113            1 :         g_assert ("couldn't PEM block in reference data" && num == 1);
     114              : 
     115            1 :         g_assert ("parse_reference() wasn't called" && test->refdata != NULL);
     116            1 : }
     117              : 
     118              : static void
     119            1 : test_write_reference (Test *test, gconstpointer unused)
     120              : {
     121              :         const gchar *dekinfo;
     122              :         guchar *encrypted;
     123              :         gsize n_encrypted;
     124              :         GBytes *data;
     125              :         guint num;
     126              : 
     127            1 :         num = egg_armor_parse (test->input, parse_reference, test);
     128            1 :         g_assert ("couldn't PEM block in reference data" && num == 1);
     129              : 
     130            1 :         dekinfo = egg_openssl_get_dekinfo (test->refheaders);
     131            1 :         g_assert ("no dekinfo in headers" && dekinfo != NULL);
     132              : 
     133            1 :         data = g_bytes_new_static (test->refdata, test->n_refdata);
     134            1 :         encrypted = egg_openssl_encrypt_block (dekinfo, "booo", 4, data, &n_encrypted);
     135            1 :         g_bytes_unref (data);
     136              : 
     137            1 :         g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
     138            1 :         g_assert ("invalid amount of data returned from openssl encrypt" && test->n_refdata <= n_encrypted);
     139              : 
     140            1 :         g_assert ("data length doesn't match input length" && n_encrypted == test->n_refenc);
     141            1 :         g_assert ("data doesn't match input" && memcmp (encrypted, test->refenc, n_encrypted) == 0);
     142              : 
     143            1 :         g_free (encrypted);
     144            1 : }
     145              : 
     146              : static void
     147            1 : test_write_exactly_same (Test *test, gconstpointer unused)
     148              : {
     149              :         guchar *result;
     150              :         gsize n_result;
     151              :         guint num;
     152              : 
     153            1 :         num = egg_armor_parse (test->input, parse_reference, test);
     154            1 :         g_assert ("couldn't PEM block in reference data" && num == 1);
     155              : 
     156            1 :         result = egg_armor_write (test->refenc, test->n_refenc, test->reftype,
     157              :                                   test->refheaders, &n_result);
     158              : 
     159              :         /*
     160              :          * Yes sirrr. Openssl's parser is so fragile, that we have to make it
     161              :          * character for character identical. This includes line breaks, whitespace
     162              :          * and line endings.
     163              :          */
     164              : 
     165            1 :         egg_assert_cmpbytes (test->input, ==, result, n_result);
     166            1 :         g_free (result);
     167            1 : }
     168              : 
     169              : /* 29 bytes (prime number, so block length has bad chance of matching */
     170              : static const guchar *TEST_DATA = (guchar*)"ABCDEFGHIJKLMNOPQRSTUVWXYZ123";
     171              : const gsize TEST_DATA_L = 29;
     172              : 
     173              : static void
     174            1 : test_openssl_roundtrip (Test *test, gconstpointer unused)
     175              : {
     176              :         const gchar *dekinfo;
     177              :         guchar *encrypted, *decrypted;
     178              :         gsize n_encrypted, n_decrypted;
     179              :         GBytes *data;
     180              :         int i;
     181              :         guint num;
     182              : 
     183            1 :         num = egg_armor_parse (test->input, parse_reference, test);
     184            1 :         g_assert ("couldn't PEM block in reference data" && num == 1);
     185              : 
     186            1 :         dekinfo = egg_openssl_prep_dekinfo (test->refheaders);
     187              : 
     188            1 :         data = g_bytes_new_static (TEST_DATA, TEST_DATA_L);
     189            1 :         encrypted = egg_openssl_encrypt_block (dekinfo, "password", -1, data, &n_encrypted);
     190            1 :         g_bytes_unref (data);
     191              : 
     192            1 :         g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
     193            1 :         g_assert ("invalid amount of data returned from openssl encrypt" && TEST_DATA_L <= n_encrypted);
     194              : 
     195            1 :         data = g_bytes_new_with_free_func (encrypted, n_encrypted, egg_secure_free, encrypted);
     196            1 :         decrypted = egg_openssl_decrypt_block (dekinfo, "password", 8, data, &n_decrypted);
     197            1 :         g_bytes_unref (data);
     198              : 
     199            1 :         g_assert ("no data returned from openssl decrypt" && decrypted != NULL);
     200              : 
     201              :         /* Check that the data was decrypted properly */
     202            1 :         g_assert ("decrypted data doesn't match length" && n_decrypted >= TEST_DATA_L);
     203            1 :         g_assert ("decrypted data doesn't match" && memcmp (TEST_DATA, decrypted, TEST_DATA_L) == 0);
     204              : 
     205              :         /* Check that the remainder is all zeros */
     206            4 :         for (i = TEST_DATA_L; i < n_decrypted; ++i)
     207            3 :                 g_assert ("non null byte in padding" && decrypted[i] == 0);
     208              : 
     209            1 :         egg_secure_free (decrypted);
     210            1 : }
     211              : 
     212              : int
     213            1 : main (int argc, char **argv)
     214              : {
     215            1 :         g_test_init (&argc, &argv, NULL);
     216              : 
     217            1 :         g_test_add ("/openssl/parse_reference", Test, NULL, setup, test_parse_reference, teardown);
     218            1 :         g_test_add ("/openssl/write_reference", Test, NULL, setup, test_write_reference, teardown);
     219            1 :         g_test_add ("/openssl/write_exactly_same", Test, NULL, setup, test_write_exactly_same, teardown);
     220            1 :         g_test_add ("/openssl/openssl_roundtrip", Test, NULL, setup, test_openssl_roundtrip, teardown);
     221              : 
     222            1 :         return g_test_run ();
     223              : }
        

Generated by: LCOV version 2.0-1