summaryrefslogtreecommitdiff
path: root/tests/test-commit-sign-sh-ext.c
blob: 173a0c6d4781961ca56c009ca18c08c25fd4949e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * Copyright (C) 2021 Red Hat, Inc.
 *
 * SPDX-License-Identifier: LGPL-2.0+
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include "libglnx.h"
#include <ostree.h>

static void
assert_error_contains (GError **error, const char *msg)
{
  g_assert (error != NULL);
  GError *actual = *error;
  g_assert (actual != NULL);
  if (strstr (actual->message, msg) == NULL)
    g_error ("%s does not contain %s", actual->message, msg);
  g_clear_error (error);
}

// Perhaps in the future we hook this up to a fuzzer
static GBytes *
corrupt (GBytes *input)
{
  gsize len = 0;
  const guint8 *buf = g_bytes_get_data (input, &len);
  g_assert_cmpint (len, >, 0);
  g_assert_cmpint (len, <, G_MAXINT);
  g_autofree char *newbuf = g_memdup (buf, len);
  g_assert (newbuf != NULL);
  int o = g_random_int_range (0, len);
  newbuf[o] = (newbuf[0] + 1);

  return g_bytes_new_take (g_steal_pointer (&newbuf), len);
}

static gboolean
run (GError **error)
{
  g_autoptr(OstreeRepo) repo = ostree_repo_open_at (AT_FDCWD, "repo", NULL, error);
  if (!repo)
    return FALSE;

  g_autofree char *rev = NULL;
  if (!ostree_repo_resolve_rev (repo, "origin:main", FALSE, &rev, error))
    return FALSE;
  g_assert (rev);
  g_autoptr(GVariant) commit = NULL;
  if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, &commit, error))
    return FALSE;
  g_assert (commit);

  g_autoptr(GVariant) detached_meta = NULL;
  if (!ostree_repo_read_commit_detached_metadata (repo, rev, &detached_meta, NULL, error))
    return FALSE;
  g_assert (detached_meta);

  g_autoptr(GBytes) commit_bytes = g_variant_get_data_as_bytes (commit);
  g_autoptr(GBytes) detached_meta_bytes = g_variant_get_data_as_bytes (detached_meta);
  g_autofree char *verify_report = NULL;
  if (!ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, detached_meta_bytes, 0, 
                                                 &verify_report, error))
    return FALSE;

  if (ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, detached_meta_bytes, 
                                                OSTREE_REPO_VERIFY_FLAGS_NO_GPG | OSTREE_REPO_VERIFY_FLAGS_NO_SIGNAPI, 
                                                &verify_report, error))
    g_error ("Should not have validated");
  assert_error_contains (error, "No commit verification types enabled");

  // No signatures
  g_autoptr(GBytes) empty = g_bytes_new_static ("", 0);
  if (ostree_repo_signature_verify_commit_data (repo, "origin", commit_bytes, empty, 0, 
                                                 &verify_report, error))
    g_error ("Should not have validated");
  assert_error_contains (error, "no signatures found");
  // No such remote
  if (ostree_repo_signature_verify_commit_data (repo, "nosuchremote", commit_bytes, detached_meta_bytes, 0, 
                                                 &verify_report, error))
    g_error ("Should not have validated");
  assert_error_contains (error, "Remote \"nosuchremote\" not found");

  // Corrupted commit
  g_autoptr(GBytes) corrupted_commit = corrupt (commit_bytes);
  if (ostree_repo_signature_verify_commit_data (repo, "origin", corrupted_commit, detached_meta_bytes, 0, 
                                                 &verify_report, error))
    g_error ("Should not have validated");
  assert_error_contains (error, "BAD signature");

  return TRUE;
}

int
main (int argc, char **argv)
{
  g_autoptr(GError) error = NULL;
  if (!run (&error))
    {
      g_printerr ("error: %s\n", error->message);
      exit (1);
    }
}