LCOV - code coverage report
Current view: top level - gcr - test-certificate-chain.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 338 357 94.7 %
Date: 2022-09-04 10:20:22 Functions: 33 33 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 100 196 51.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
       2                 :            : /*
       3                 :            :    Copyright (C) 2010 Collabora Ltd
       4                 :            : 
       5                 :            :    The Gnome Keyring Library is free software; you can redistribute it and/or
       6                 :            :    modify it under the terms of the GNU Library General Public License as
       7                 :            :    published by the Free Software Foundation; either version 2 of the
       8                 :            :    License, or (at your option) any later version.
       9                 :            : 
      10                 :            :    The Gnome Keyring Library is distributed in the hope that it will be useful,
      11                 :            :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12                 :            :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13                 :            :    Library General Public License for more details.
      14                 :            : 
      15                 :            :    You should have received a copy of the GNU Library General Public
      16                 :            :    License along with the Gnome Library; see the file COPYING.LIB.  If not,
      17                 :            :    see <http://www.gnu.org/licenses/>.
      18                 :            : 
      19                 :            :    Author: Stef Walter <stefw@collabora.co.uk>
      20                 :            : */
      21                 :            : 
      22                 :            : #include "config.h"
      23                 :            : 
      24                 :            : #include "gcr/gcr.h"
      25                 :            : #include "gcr/gcr-internal.h"
      26                 :            : 
      27                 :            : #include "egg/egg-asn1x.h"
      28                 :            : #include "egg/egg-asn1-defs.h"
      29                 :            : #include "egg/egg-testing.h"
      30                 :            : 
      31                 :            : #include "gck/gck-mock.h"
      32                 :            : #include "gck/gck-test.h"
      33                 :            : #include <p11-kit/pkcs11.h>
      34                 :            : #include "gck/pkcs11x.h"
      35                 :            : 
      36                 :            : #include <glib.h>
      37                 :            : 
      38                 :            : #include <errno.h>
      39                 :            : #include <string.h>
      40                 :            : 
      41                 :            : /* ---------------------------------------------------------------------------
      42                 :            :  * A Mock certificate that checks that it's always called on the
      43                 :            :  * same thread. A GcrCertificate implemented on top of a non-thread-safe
      44                 :            :  * crypto library would require this behavior.
      45                 :            :  */
      46                 :            : 
      47                 :            : GType               mock_certificate_get_type               (void);
      48                 :            : 
      49                 :            : #define MOCK_CERTIFICATE(obj) \
      50                 :            :         (G_TYPE_CHECK_INSTANCE_CAST ((obj), mock_certificate_get_type (), MockCertificate))
      51                 :            : 
      52                 :            : typedef struct _MockCertificate {
      53                 :            :         GObject parent;
      54                 :            :         GThread *created_on;
      55                 :            :         gpointer data;
      56                 :            :         gsize n_data;
      57                 :            : } MockCertificate;
      58                 :            : 
      59                 :            : typedef struct _MockCertificateClass {
      60                 :            :         GObjectClass parent_class;
      61                 :            : } MockCertificateClass;
      62                 :            : 
      63                 :            : static void mock_certificate_iface (GcrCertificateIface *iface);
      64   [ +  +  +  -  :        210 : G_DEFINE_TYPE_WITH_CODE (MockCertificate, mock_certificate, G_TYPE_OBJECT,
                   +  + ]
      65                 :            :         G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, mock_certificate_iface);
      66                 :            : );
      67                 :            : 
      68                 :            : static void
      69                 :         75 : mock_certificate_init (MockCertificate *self)
      70                 :            : {
      71                 :         75 :         self->created_on = g_thread_self ();
      72                 :         75 : }
      73                 :            : 
      74                 :            : static void
      75                 :         75 : mock_certificate_finalize (GObject *obj)
      76                 :            : {
      77                 :         75 :         MockCertificate *self = MOCK_CERTIFICATE (obj);
      78         [ -  + ]:         75 :         g_assert (self->created_on == g_thread_self ());
      79                 :         75 :         g_free (self->data);
      80                 :         75 :         G_OBJECT_CLASS (mock_certificate_parent_class)->finalize (obj);
      81                 :         75 : }
      82                 :            : 
      83                 :            : static void
      84                 :          1 : mock_certificate_class_init (MockCertificateClass *klass)
      85                 :            : {
      86                 :          1 :         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
      87                 :          1 :         gobject_class->finalize = mock_certificate_finalize;
      88                 :          1 :         gobject_class->get_property = gcr_certificate_mixin_get_property;
      89                 :          1 :         gcr_certificate_mixin_class_init (gobject_class);
      90                 :          1 : }
      91                 :            : 
      92                 :            : static gconstpointer
      93                 :         58 : mock_certificate_real_get_der_data (GcrCertificate *base, gsize *n_data)
      94                 :            : {
      95                 :         58 :         MockCertificate *self = MOCK_CERTIFICATE (base);
      96         [ -  + ]:         58 :         g_assert (self->created_on == g_thread_self ());
      97                 :         58 :         *n_data = self->n_data;
      98                 :         58 :         return self->data;
      99                 :            : }
     100                 :            : 
     101                 :            : static void
     102                 :          1 : mock_certificate_iface (GcrCertificateIface *iface)
     103                 :            : {
     104                 :          1 :         iface->get_der_data = (gpointer)mock_certificate_real_get_der_data;
     105                 :          1 : }
     106                 :            : 
     107                 :            : static GcrCertificate*
     108                 :         75 : mock_certificate_new (gconstpointer data, gsize n_data)
     109                 :            : {
     110                 :         75 :         MockCertificate *self = g_object_new (mock_certificate_get_type (), NULL);
     111                 :         75 :         self->data = g_memdup2 (data, n_data);
     112                 :         75 :         self->n_data = n_data;
     113         [ -  + ]:         75 :         g_assert (self->created_on == g_thread_self ());
     114                 :         75 :         return GCR_CERTIFICATE (self);
     115                 :            : }
     116                 :            : 
     117                 :            : /* ----------------------------------------------------------------------------
     118                 :            :  * TESTS
     119                 :            :  */
     120                 :            : 
     121                 :            : typedef struct {
     122                 :            :         /* A self signed certificate */
     123                 :            :         GcrCertificate *cert_self;
     124                 :            : 
     125                 :            :         /* Simple CA + issued */
     126                 :            :         GcrCertificate *cert_ca;
     127                 :            :         GcrCertificate *cert_signed;
     128                 :            : 
     129                 :            :         /* Root + intermediate + issued */
     130                 :            :         GcrCertificate *cert_root;
     131                 :            :         GcrCertificate *cert_inter;
     132                 :            :         GcrCertificate *cert_host;
     133                 :            : 
     134                 :            :         CK_FUNCTION_LIST funcs;
     135                 :            : } Test;
     136                 :            : 
     137                 :            : static void
     138                 :         15 : setup (Test *test, gconstpointer unused)
     139                 :            : {
     140                 :         15 :         GList *modules = NULL;
     141                 :            :         CK_FUNCTION_LIST_PTR f;
     142                 :            :         gchar *contents;
     143                 :            :         gsize n_contents;
     144                 :            :         const gchar *uris[2];
     145                 :            :         CK_RV rv;
     146                 :            :         GckModule *module;
     147                 :            : 
     148                 :         15 :         rv = gck_mock_C_GetFunctionList (&f);
     149         [ -  + ]:         15 :         gck_assert_cmprv (rv, ==, CKR_OK);
     150                 :         15 :         memcpy (&test->funcs, f, sizeof (test->funcs));
     151                 :            : 
     152                 :            :         /* Open a session */
     153                 :         15 :         rv = (test->funcs.C_Initialize) (NULL);
     154         [ -  + ]:         15 :         gck_assert_cmprv (rv, ==, CKR_OK);
     155                 :            : 
     156         [ -  + ]:         15 :         g_assert (!modules);
     157                 :         15 :         module = gck_module_new (&test->funcs);
     158                 :         15 :         modules = g_list_prepend (modules, module);
     159                 :         15 :         gcr_pkcs11_set_modules (modules);
     160                 :         15 :         uris[0] = GCK_MOCK_SLOT_ONE_URI;
     161                 :         15 :         uris[1] = NULL;
     162                 :         15 :         gcr_pkcs11_set_trust_lookup_uris (uris);
     163                 :         15 :         gcr_pkcs11_set_trust_store_uri (GCK_MOCK_SLOT_ONE_URI);
     164   [ +  -  +  - ]:         15 :         g_clear_list (&modules, g_object_unref);
     165                 :            : 
     166                 :            :         /* A self-signed certificate */
     167         [ -  + ]:         15 :         if (!g_file_get_contents (SRCDIR "/gcr/fixtures/der-certificate.crt", &contents, &n_contents, NULL))
     168                 :          0 :                 g_assert_not_reached ();
     169                 :         15 :         test->cert_self = gcr_simple_certificate_new ((const guchar *)contents, n_contents);
     170                 :         15 :         g_free (contents);
     171                 :            : 
     172                 :            :         /* A signed certificate */
     173         [ -  + ]:         15 :         if (!g_file_get_contents (SRCDIR "/gcr/fixtures/dhansak-collabora.cer", &contents, &n_contents, NULL))
     174                 :          0 :                 g_assert_not_reached ();
     175                 :         15 :         test->cert_signed = mock_certificate_new (contents, n_contents);
     176                 :         15 :         g_free (contents);
     177                 :            : 
     178                 :            :         /* The signer for the above certificate */
     179         [ -  + ]:         15 :         if (!g_file_get_contents (SRCDIR "/gcr/fixtures/collabora-ca.cer", &contents, &n_contents, NULL))
     180                 :          0 :                 g_assert_not_reached ();
     181                 :         15 :         test->cert_ca = mock_certificate_new (contents, n_contents);
     182                 :         15 :         g_free (contents);
     183                 :            : 
     184                 :            :         /* A root CA */
     185         [ -  + ]:         15 :         if (!g_file_get_contents (SRCDIR "/gcr/fixtures/startcom-ca.cer", &contents, &n_contents, NULL))
     186                 :          0 :                 g_assert_not_reached ();
     187                 :         15 :         test->cert_root = mock_certificate_new (contents, n_contents);
     188                 :         15 :         g_free (contents);
     189                 :            : 
     190                 :            :         /* An intermediate */
     191         [ -  + ]:         15 :         if (!g_file_get_contents (SRCDIR "/gcr/fixtures/startcom-intermediate.cer", &contents, &n_contents, NULL))
     192                 :          0 :                 g_assert_not_reached ();
     193                 :         15 :         test->cert_inter = mock_certificate_new (contents, n_contents);
     194                 :         15 :         g_free (contents);
     195                 :            : 
     196                 :            :         /* Signed by above intermediate */
     197         [ -  + ]:         15 :         if (!g_file_get_contents (SRCDIR "/gcr/fixtures/jabber-server.cer", &contents, &n_contents, NULL))
     198                 :          0 :                 g_assert_not_reached ();
     199                 :         15 :         test->cert_host = mock_certificate_new (contents, n_contents);
     200                 :         15 :         g_free (contents);
     201                 :         15 : }
     202                 :            : 
     203                 :            : static void
     204                 :          5 : add_certificate_to_module (GcrCertificate *certificate)
     205                 :            : {
     206                 :          5 :         GckBuilder builder = GCK_BUILDER_INIT;
     207                 :            :         gconstpointer data;
     208                 :            :         gsize n_data, n_subject;
     209                 :            :         gpointer subject;
     210                 :            : 
     211                 :          5 :         data = gcr_certificate_get_der_data (certificate, &n_data);
     212         [ -  + ]:          5 :         g_assert (data);
     213                 :            : 
     214                 :          5 :         subject = gcr_certificate_get_subject_raw (certificate, &n_subject);
     215         [ -  + ]:          5 :         g_assert (subject);
     216                 :            : 
     217                 :            :         /* Add a certificate to the module */
     218                 :          5 :         gck_builder_add_data (&builder, CKA_VALUE, data, n_data);
     219                 :          5 :         gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
     220                 :          5 :         gck_builder_add_ulong (&builder, CKA_CERTIFICATE_TYPE, CKC_X_509);
     221                 :          5 :         gck_builder_add_data (&builder, CKA_SUBJECT, subject, n_subject);
     222                 :          5 :         gck_mock_module_add_object (gck_builder_end (&builder));
     223                 :            : 
     224                 :          5 :         g_free (subject);
     225                 :          5 : }
     226                 :            : 
     227                 :            : static void
     228                 :          3 : add_anchor_to_module (GcrCertificate *certificate, const gchar *purpose)
     229                 :            : {
     230                 :          3 :         GckBuilder builder = GCK_BUILDER_INIT;
     231                 :            :         gconstpointer data;
     232                 :            :         gsize n_data;
     233                 :            : 
     234                 :          3 :         data = gcr_certificate_get_der_data (certificate, &n_data);
     235         [ -  + ]:          3 :         g_assert (data);
     236                 :            : 
     237                 :            :         /* And add a pinned certificate for the signed certificate */
     238                 :          3 :         gck_builder_add_data (&builder, CKA_X_CERTIFICATE_VALUE, data, n_data);
     239                 :          3 :         gck_builder_add_ulong (&builder, CKA_CLASS, CKO_X_TRUST_ASSERTION);
     240                 :          3 :         gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_ANCHORED_CERTIFICATE);
     241                 :          3 :         gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
     242                 :          3 :         gck_mock_module_add_object (gck_builder_end (&builder));
     243                 :          3 : }
     244                 :            : 
     245                 :            : static void
     246                 :          1 : add_pinned_to_module (GcrCertificate *certificate, const gchar *purpose, const gchar *host)
     247                 :            : {
     248                 :          1 :         GckBuilder builder = GCK_BUILDER_INIT;
     249                 :            :         gconstpointer data;
     250                 :            :         gsize n_data;
     251                 :            : 
     252                 :          1 :         data = gcr_certificate_get_der_data (certificate, &n_data);
     253         [ -  + ]:          1 :         g_assert (data);
     254                 :            : 
     255                 :            :         /* And add a pinned certificate for the signed certificate */
     256                 :          1 :         gck_builder_add_data (&builder, CKA_X_CERTIFICATE_VALUE, data, n_data);
     257                 :          1 :         gck_builder_add_ulong (&builder, CKA_CLASS, CKO_X_TRUST_ASSERTION);
     258                 :          1 :         gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_PINNED_CERTIFICATE);
     259                 :          1 :         gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
     260                 :          1 :         gck_builder_add_string (&builder, CKA_X_PEER, host);
     261                 :          1 :         gck_mock_module_add_object (gck_builder_end (&builder));
     262                 :          1 : }
     263                 :            : 
     264                 :            : void
     265                 :         75 : on_toggle_notify (gpointer data,
     266                 :            :                   GObject *object,
     267                 :            :                   gboolean is_last_ref)
     268                 :            : {
     269                 :         75 :         gboolean *last_ref = data;
     270                 :            : 
     271                 :         75 :         *last_ref = is_last_ref;
     272                 :         75 : }
     273                 :            : 
     274                 :            : static void
     275                 :         75 : wait_for_object_finalized (GObject *object)
     276                 :            : {
     277                 :         75 :         gpointer weak_object = object;
     278                 :         75 :         gboolean last_ref = FALSE;
     279                 :            : 
     280                 :            :         /* GTask may release the object later than us as per GNOME/glib#1346,
     281                 :            :          * causing the test to fail when checking in which thread the objects
     282                 :            :          * are finalized. To ensure that the order is preserved we need then
     283                 :            :          * to wait that the GTask releases its last reference before we do.
     284                 :            :          */
     285                 :         75 :         g_object_add_weak_pointer (object, &weak_object);
     286                 :         75 :         g_object_add_toggle_ref (object, on_toggle_notify, &last_ref);
     287                 :         75 :         g_object_unref (object);
     288         [ -  + ]:         75 :         egg_test_wait_for_gtask_thread (!last_ref);
     289                 :            : 
     290                 :         75 :         g_object_remove_toggle_ref (object, on_toggle_notify, &last_ref);
     291         [ -  + ]:         75 :         g_assert_null (weak_object);
     292                 :         75 : }
     293                 :            : 
     294                 :            : static void
     295                 :         15 : teardown (Test *test, gconstpointer unused)
     296                 :            : {
     297                 :            :         CK_RV rv;
     298                 :            : 
     299                 :         15 :         g_object_unref (test->cert_self);
     300                 :         15 :         wait_for_object_finalized (G_OBJECT (test->cert_signed));
     301                 :         15 :         wait_for_object_finalized (G_OBJECT (test->cert_ca));
     302                 :         15 :         wait_for_object_finalized (G_OBJECT (test->cert_host));
     303                 :         15 :         wait_for_object_finalized (G_OBJECT (test->cert_inter));
     304                 :         15 :         wait_for_object_finalized (G_OBJECT (test->cert_root));
     305                 :            : 
     306                 :         15 :         rv = (test->funcs.C_Finalize) (NULL);
     307         [ -  + ]:         15 :         gck_assert_cmprv (rv, ==, CKR_OK);
     308                 :            : 
     309                 :         15 :         _gcr_uninitialize_library ();
     310                 :         15 : }
     311                 :            : 
     312                 :            : static void
     313                 :          1 : test_new (Test *test, gconstpointer unused)
     314                 :            : {
     315                 :            :         GcrCertificateChain *chain;
     316                 :            : 
     317                 :          1 :         chain = gcr_certificate_chain_new ();
     318                 :            : 
     319         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     320                 :            :                           GCR_CERTIFICATE_CHAIN_UNKNOWN);
     321         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 0);
     322                 :            : 
     323         [ -  + ]:          1 :         g_assert (gcr_certificate_chain_get_endpoint (chain) == NULL);
     324                 :            : 
     325                 :          1 :         g_object_unref (chain);
     326                 :          1 : }
     327                 :            : 
     328                 :            : static void
     329                 :          1 : test_new_with_cert (Test *test, gconstpointer unused)
     330                 :            : {
     331                 :            :         GcrCertificateChain *chain;
     332                 :            :         GcrCertificate *check;
     333                 :            :         guint status, length;
     334                 :            : 
     335                 :          1 :         chain = gcr_certificate_chain_new ();
     336                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     337                 :          1 :         gcr_certificate_chain_add (chain, test->cert_ca);
     338                 :            : 
     339         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     340                 :            :                           GCR_CERTIFICATE_CHAIN_UNKNOWN);
     341         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
     342                 :            : 
     343                 :          1 :         status = G_MAXUINT;
     344                 :          1 :         length = 0;
     345                 :          1 :         g_object_get (chain, "status", &status, "length", &length, NULL);
     346         [ -  + ]:          1 :         g_assert_cmpuint (status, ==, GCR_CERTIFICATE_CHAIN_UNKNOWN);
     347         [ -  + ]:          1 :         g_assert_cmpuint (length, ==, 2);
     348                 :            : 
     349                 :          1 :         check = gcr_certificate_chain_get_certificate (chain, 1);
     350         [ -  + ]:          1 :         g_assert (check == test->cert_ca);
     351                 :            : 
     352                 :            :         /* Not yet completed */
     353                 :          1 :         check = gcr_certificate_chain_get_anchor (chain);
     354         [ -  + ]:          1 :         g_assert (check == NULL);
     355                 :            : 
     356                 :          1 :         check = gcr_certificate_chain_get_endpoint (chain);
     357         [ -  + ]:          1 :         g_assert (check == test->cert_signed);
     358                 :            : 
     359                 :          1 :         g_object_unref (chain);
     360                 :          1 : }
     361                 :            : 
     362                 :            : static void
     363                 :          1 : test_selfsigned (Test *test, gconstpointer unused)
     364                 :            : {
     365                 :            :         GcrCertificateChain *chain;
     366                 :          1 :         GError *error = NULL;
     367                 :            : 
     368                 :          1 :         chain = gcr_certificate_chain_new ();
     369                 :            : 
     370                 :            :         /* Add a self-signed certificate */
     371                 :          1 :         gcr_certificate_chain_add (chain, test->cert_self);
     372                 :            : 
     373         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     374                 :            :                                           NULL, 0, NULL, &error))
     375                 :          0 :                 g_assert_not_reached ();
     376         [ -  + ]:          1 :         g_assert_no_error (error);
     377                 :            : 
     378         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     379                 :            :                           GCR_CERTIFICATE_CHAIN_SELFSIGNED);
     380                 :            : 
     381                 :          1 :         g_object_unref (chain);
     382                 :          1 : }
     383                 :            : 
     384                 :            : static void
     385                 :          1 : test_incomplete (Test *test, gconstpointer unused)
     386                 :            : {
     387                 :            :         GcrCertificateChain *chain;
     388                 :          1 :         GError *error = NULL;
     389                 :            : 
     390                 :          1 :         chain = gcr_certificate_chain_new ();
     391                 :            : 
     392                 :            :         /* Add a signed certificate */
     393                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     394                 :            : 
     395         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     396                 :            :                                           NULL, 0, NULL, &error))
     397                 :          0 :                 g_assert_not_reached ();
     398         [ -  + ]:          1 :         g_assert_no_error (error);
     399                 :            : 
     400         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     401                 :            :                           GCR_CERTIFICATE_CHAIN_INCOMPLETE);
     402                 :            : 
     403                 :          1 :         g_object_unref (chain);
     404                 :          1 : }
     405                 :            : 
     406                 :            : static void
     407                 :          1 : test_empty (Test *test, gconstpointer unused)
     408                 :            : {
     409                 :            :         GcrCertificateChain *chain;
     410                 :          1 :         GError *error = NULL;
     411                 :            : 
     412                 :          1 :         chain = gcr_certificate_chain_new ();
     413                 :            : 
     414                 :            :         /* Add no certificate */
     415                 :            : 
     416         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     417                 :            :                                           NULL, 0, NULL, &error))
     418                 :          0 :                 g_assert_not_reached ();
     419         [ -  + ]:          1 :         g_assert_no_error (error);
     420                 :            : 
     421         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     422                 :            :                           GCR_CERTIFICATE_CHAIN_UNKNOWN);
     423                 :            : 
     424                 :          1 :         g_object_unref (chain);
     425                 :          1 : }
     426                 :            : 
     427                 :            : static void
     428                 :          1 : test_trim_extras (Test *test, gconstpointer unused)
     429                 :            : {
     430                 :            :         GcrCertificateChain *chain;
     431                 :          1 :         GError *error = NULL;
     432                 :            : 
     433                 :          1 :         chain = gcr_certificate_chain_new ();
     434                 :            : 
     435                 :            :         /* Add two unrelated certificates */
     436                 :          1 :         gcr_certificate_chain_add (chain, test->cert_self);
     437                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     438                 :            : 
     439         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
     440                 :            : 
     441         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     442                 :            :                                           NULL, 0, NULL, &error))
     443                 :          0 :                 g_assert_not_reached ();
     444         [ -  + ]:          1 :         g_assert_no_error (error);
     445                 :            : 
     446         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     447                 :            :                           GCR_CERTIFICATE_CHAIN_SELFSIGNED);
     448         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
     449                 :            : 
     450                 :          1 :         g_object_unref (chain);
     451                 :          1 : }
     452                 :            : 
     453                 :            : static void
     454                 :          2 : fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
     455                 :            : {
     456                 :          2 :         *((GAsyncResult**)user_data) = result;
     457                 :          2 :         g_object_ref (result);
     458                 :          2 :         egg_test_wait_stop ();
     459                 :          2 : }
     460                 :            : 
     461                 :            : static void
     462                 :          1 : test_complete_async (Test *test, gconstpointer unused)
     463                 :            : {
     464                 :            :         GcrCertificateChain *chain;
     465                 :          1 :         GError *error = NULL;
     466                 :          1 :         GAsyncResult *result = NULL;
     467                 :            : 
     468                 :          1 :         chain = gcr_certificate_chain_new ();
     469                 :            : 
     470                 :            :         /* Add a whole bunch of certificates */
     471                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     472                 :          1 :         gcr_certificate_chain_add (chain, test->cert_ca);
     473                 :          1 :         gcr_certificate_chain_add (chain, test->cert_self);
     474                 :            : 
     475                 :          1 :         gcr_certificate_chain_build_async (chain, GCR_PURPOSE_CLIENT_AUTH,
     476                 :            :                                            NULL, 0, NULL, fetch_async_result, &result);
     477                 :          1 :         egg_test_wait_until (500);
     478         [ -  + ]:          1 :         if (!gcr_certificate_chain_build_finish (chain, result, &error))
     479                 :          0 :                 g_assert_not_reached ();
     480         [ -  + ]:          1 :         g_assert_no_error (error);
     481                 :          1 :         g_object_unref (result);
     482                 :            : 
     483         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     484                 :            :                           GCR_CERTIFICATE_CHAIN_SELFSIGNED);
     485         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
     486                 :            : 
     487                 :          1 :         g_object_unref (chain);
     488                 :          1 : }
     489                 :            : 
     490                 :            : static void
     491                 :          1 : test_with_anchor (Test *test, gconstpointer unused)
     492                 :            : {
     493                 :            :         GcrCertificateChain *chain;
     494                 :          1 :         GError *error = NULL;
     495                 :            : 
     496                 :          1 :         chain = gcr_certificate_chain_new ();
     497                 :            : 
     498                 :            :         /* Two certificates in chain with ca trust anchor */
     499                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     500                 :          1 :         gcr_certificate_chain_add (chain, test->cert_ca);
     501                 :          1 :         add_anchor_to_module (test->cert_ca, GCR_PURPOSE_CLIENT_AUTH);
     502                 :            : 
     503         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
     504                 :            : 
     505         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     506                 :            :                                           NULL, 0, NULL, &error))
     507                 :          0 :                 g_assert_not_reached ();
     508         [ -  + ]:          1 :         g_assert_no_error (error);
     509                 :            : 
     510         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     511                 :            :                           GCR_CERTIFICATE_CHAIN_ANCHORED);
     512         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
     513         [ -  + ]:          1 :         g_assert (gcr_certificate_chain_get_anchor (chain) == test->cert_ca);
     514                 :            : 
     515                 :          1 :         g_object_unref (chain);
     516                 :          1 : }
     517                 :            : 
     518                 :            : static void
     519                 :          1 : test_with_anchor_and_lookup_ca (Test *test, gconstpointer unused)
     520                 :            : {
     521                 :            :         GcrCertificateChain *chain;
     522                 :          1 :         GError *error = NULL;
     523                 :            : 
     524                 :          1 :         chain = gcr_certificate_chain_new ();
     525                 :            : 
     526                 :            :         /* One signed certificate, with CA in pkcs11, and trust anchor */
     527                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     528                 :          1 :         add_certificate_to_module (test->cert_ca);
     529                 :          1 :         add_anchor_to_module (test->cert_ca, GCR_PURPOSE_CLIENT_AUTH);
     530                 :            : 
     531         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
     532                 :            : 
     533         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     534                 :            :                                           NULL, 0, NULL, &error))
     535                 :          0 :                 g_assert_not_reached ();
     536         [ -  + ]:          1 :         g_assert_no_error (error);
     537                 :            : 
     538         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     539                 :            :                           GCR_CERTIFICATE_CHAIN_ANCHORED);
     540         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
     541         [ -  + ]:          1 :         g_assert (gcr_certificate_chain_get_anchor (chain) != NULL);
     542                 :            : 
     543                 :          1 :         g_object_unref (chain);
     544                 :          1 : }
     545                 :            : 
     546                 :            : static void
     547                 :          1 : test_with_pinned (Test *test, gconstpointer unused)
     548                 :            : {
     549                 :            :         GcrCertificateChain *chain;
     550                 :          1 :         GError *error = NULL;
     551                 :            : 
     552                 :          1 :         chain = gcr_certificate_chain_new ();
     553                 :            : 
     554                 :            :         /* One certificate, and add CA to pkcs11 */
     555                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     556                 :          1 :         gcr_certificate_chain_add (chain, test->cert_ca);
     557                 :          1 :         add_pinned_to_module (test->cert_signed, GCR_PURPOSE_CLIENT_AUTH, "pinned.example.com");
     558                 :            : 
     559         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 2);
     560                 :            : 
     561                 :            :         /* But we don't allow the lookup to happen */
     562         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     563                 :            :                                           "pinned.example.com", 0, NULL, &error))
     564                 :          0 :                 g_assert_not_reached ();
     565         [ -  + ]:          1 :         g_assert_no_error (error);
     566                 :            : 
     567         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     568                 :            :                           GCR_CERTIFICATE_CHAIN_PINNED);
     569         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
     570         [ -  + ]:          1 :         g_assert (gcr_certificate_chain_get_anchor (chain) == NULL);
     571                 :            : 
     572                 :          1 :         g_object_unref (chain);
     573                 :          1 : }
     574                 :            : 
     575                 :            : static void
     576                 :          1 : test_without_lookups (Test *test, gconstpointer unused)
     577                 :            : {
     578                 :            :         GcrCertificateChain *chain;
     579                 :          1 :         GError *error = NULL;
     580                 :            : 
     581                 :          1 :         chain = gcr_certificate_chain_new ();
     582                 :            : 
     583                 :            :         /* One certificate, and add CA to pkcs11 */
     584                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     585                 :          1 :         add_certificate_to_module (test->cert_ca);
     586                 :            : 
     587         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
     588                 :            : 
     589                 :            :         /* But we don't allow the lookup to happen */
     590         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     591                 :            :                                           NULL, GCR_CERTIFICATE_CHAIN_NO_LOOKUPS,
     592                 :            :                                           NULL, &error))
     593                 :          0 :                 g_assert_not_reached ();
     594         [ -  + ]:          1 :         g_assert_no_error (error);
     595                 :            : 
     596         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     597                 :            :                           GCR_CERTIFICATE_CHAIN_INCOMPLETE);
     598         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
     599         [ -  + ]:          1 :         g_assert (gcr_certificate_chain_get_anchor (chain) == NULL);
     600                 :            : 
     601                 :          1 :         g_object_unref (chain);
     602                 :          1 : }
     603                 :            : 
     604                 :            : static void
     605                 :          1 : test_with_lookup_error (Test *test, gconstpointer unused)
     606                 :            : {
     607                 :            :         GcrCertificateChain *chain;
     608                 :          1 :         GError *error = NULL;
     609                 :            : 
     610                 :            :         /* Make the lookup fail */
     611                 :          1 :         test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
     612                 :            : 
     613                 :          1 :         chain = gcr_certificate_chain_new ();
     614                 :            : 
     615                 :            :         /* Two certificates in chain with ca trust anchor */
     616                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     617                 :          1 :         add_certificate_to_module (test->cert_ca);
     618                 :            : 
     619         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 1);
     620                 :            : 
     621         [ -  + ]:          1 :         if (gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     622                 :            :                                          NULL, 0, NULL, &error))
     623                 :          0 :                 g_assert_not_reached ();
     624   [ +  -  +  -  :          1 :         g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
                   -  + ]
     625                 :          1 :         g_clear_error (&error);
     626                 :            : 
     627         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     628                 :            :                           GCR_CERTIFICATE_CHAIN_UNKNOWN);
     629                 :            : 
     630                 :          1 :         g_object_unref (chain);
     631                 :          1 : }
     632                 :            : 
     633                 :            : static void
     634                 :          1 : test_wrong_order_anchor (Test *test, gconstpointer unused)
     635                 :            : {
     636                 :            :         GcrCertificateChain *chain;
     637                 :          1 :         GError *error = NULL;
     638                 :            : 
     639                 :          1 :         chain = gcr_certificate_chain_new ();
     640                 :            : 
     641                 :            :         /* Two certificates in chain with ca trust anchor */
     642                 :          1 :         gcr_certificate_chain_add (chain, test->cert_host);
     643                 :          1 :         gcr_certificate_chain_add (chain, test->cert_root);
     644                 :          1 :         gcr_certificate_chain_add (chain, test->cert_inter);
     645                 :          1 :         add_anchor_to_module (test->cert_root, GCR_PURPOSE_CLIENT_AUTH);
     646                 :            : 
     647         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 3);
     648                 :            : 
     649         [ -  + ]:          1 :         if (!gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     650                 :            :                                           NULL, 0, NULL, &error))
     651                 :          0 :                 g_assert_not_reached ();
     652         [ -  + ]:          1 :         g_assert_no_error (error);
     653                 :            : 
     654         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     655                 :            :                           GCR_CERTIFICATE_CHAIN_ANCHORED);
     656         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_length (chain), ==, 3);
     657         [ -  + ]:          1 :         g_assert (gcr_certificate_chain_get_anchor (chain) == test->cert_root);
     658                 :            : 
     659                 :          1 :         g_object_unref (chain);
     660                 :          1 : }
     661                 :            : 
     662                 :            : static void
     663                 :          1 : test_with_anchor_error (Test *test, gconstpointer unused)
     664                 :            : {
     665                 :            :         GcrCertificateChain *chain;
     666                 :          1 :         GError *error = NULL;
     667                 :            : 
     668                 :            :         /* Make the lookup fail */
     669                 :          1 :         test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
     670                 :            : 
     671                 :          1 :         chain = gcr_certificate_chain_new ();
     672                 :            : 
     673                 :            :         /* Two certificates in chain with ca trust anchor */
     674                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     675                 :          1 :         add_certificate_to_module (test->cert_ca);
     676                 :            : 
     677         [ -  + ]:          1 :         if (gcr_certificate_chain_build (chain, GCR_PURPOSE_CLIENT_AUTH,
     678                 :            :                                          NULL, 0, NULL, &error))
     679                 :          0 :                 g_assert_not_reached ();
     680   [ +  -  +  -  :          1 :         g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
                   -  + ]
     681                 :          1 :         g_clear_error (&error);
     682                 :            : 
     683         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     684                 :            :                           GCR_CERTIFICATE_CHAIN_UNKNOWN);
     685                 :            : 
     686                 :          1 :         g_object_unref (chain);
     687                 :          1 : }
     688                 :            : 
     689                 :            : static void
     690                 :          1 : test_with_anchor_error_async (Test *test, gconstpointer unused)
     691                 :            : {
     692                 :            :         GcrCertificateChain *chain;
     693                 :          1 :         GError *error = NULL;
     694                 :            :         GAsyncResult *result;
     695                 :            : 
     696                 :            :         /* Make the lookup fail */
     697                 :          1 :         test->funcs.C_GetAttributeValue = gck_mock_fail_C_GetAttributeValue;
     698                 :            : 
     699                 :          1 :         chain = gcr_certificate_chain_new ();
     700                 :            : 
     701                 :            :         /* Two certificates in chain with ca trust anchor */
     702                 :          1 :         gcr_certificate_chain_add (chain, test->cert_signed);
     703                 :          1 :         add_certificate_to_module (test->cert_ca);
     704                 :            : 
     705                 :          1 :         gcr_certificate_chain_build_async (chain, GCR_PURPOSE_CLIENT_AUTH,
     706                 :            :                                            NULL, 0, NULL, fetch_async_result, &result);
     707                 :          1 :         egg_test_wait_until (500);
     708         [ -  + ]:          1 :         if (gcr_certificate_chain_build_finish (chain, result, &error))
     709                 :          0 :                 g_assert_not_reached ();
     710   [ +  -  +  -  :          1 :         g_assert_error (error, GCK_ERROR, CKR_FUNCTION_FAILED);
                   -  + ]
     711                 :          1 :         g_clear_error (&error);
     712                 :          1 :         g_object_unref (result);
     713                 :            : 
     714         [ -  + ]:          1 :         g_assert_cmpuint (gcr_certificate_chain_get_status (chain), ==,
     715                 :            :                           GCR_CERTIFICATE_CHAIN_UNKNOWN);
     716                 :            : 
     717                 :          1 :         g_object_unref (chain);
     718                 :          1 : }
     719                 :            : 
     720                 :            : int
     721                 :          1 : main (int argc, char **argv)
     722                 :            : {
     723                 :          1 :         g_test_init (&argc, &argv, NULL);
     724                 :          1 :         g_set_prgname ("test-certificate-chain");
     725                 :            : 
     726                 :          1 :         g_test_add ("/gcr/certificate-chain/new", Test, NULL, setup, test_new, teardown);
     727                 :          1 :         g_test_add ("/gcr/certificate-chain/new_with_cert", Test, NULL, setup, test_new_with_cert, teardown);
     728                 :          1 :         g_test_add ("/gcr/certificate-chain/selfsigned", Test, NULL, setup, test_selfsigned, teardown);
     729                 :          1 :         g_test_add ("/gcr/certificate-chain/incomplete", Test, NULL, setup, test_incomplete, teardown);
     730                 :          1 :         g_test_add ("/gcr/certificate-chain/empty", Test, NULL, setup, test_empty, teardown);
     731                 :          1 :         g_test_add ("/gcr/certificate-chain/trim_extras", Test, NULL, setup, test_trim_extras, teardown);
     732                 :          1 :         g_test_add ("/gcr/certificate-chain/complete_async", Test, NULL, setup, test_complete_async, teardown);
     733                 :          1 :         g_test_add ("/gcr/certificate-chain/with_anchor", Test, NULL, setup, test_with_anchor, teardown);
     734                 :          1 :         g_test_add ("/gcr/certificate-chain/with_anchor_and_lookup_ca", Test, NULL, setup, test_with_anchor_and_lookup_ca, teardown);
     735                 :          1 :         g_test_add ("/gcr/certificate-chain/with_pinned", Test, NULL, setup, test_with_pinned, teardown);
     736                 :          1 :         g_test_add ("/gcr/certificate-chain/without_lookups", Test, NULL, setup, test_without_lookups, teardown);
     737                 :          1 :         g_test_add ("/gcr/certificate-chain/wrong_order_anchor", Test, NULL, setup, test_wrong_order_anchor, teardown);
     738                 :          1 :         g_test_add ("/gcr/certificate-chain/with_lookup_error", Test, NULL, setup, test_with_lookup_error, teardown);
     739                 :          1 :         g_test_add ("/gcr/certificate-chain/with_anchor_error", Test, NULL, setup, test_with_anchor_error, teardown);
     740                 :          1 :         g_test_add ("/gcr/certificate-chain/with_anchor_error_async", Test, NULL, setup, test_with_anchor_error_async, teardown);
     741                 :            : 
     742                 :          1 :         return egg_tests_run_with_loop ();
     743                 :            : }

Generated by: LCOV version 1.14