OpenVAS Scanner 22.7.9
nasl_signature.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
6#include "nasl_signature.h"
7
8#include "nasl_debug.h"
9#include "nasl_func.h"
10#include "nasl_lex_ctxt.h"
11#include "nasl_tree.h"
12#include "nasl_var.h"
13
14#include <gvm/util/gpgmeutils.h>
15#include <locale.h> /* for LC_CTYPE */
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h> /* for strlen */
19
26static void
27print_gpgme_error (char *function, gpgme_error_t err)
28{
29 nasl_perror (NULL, "%s failed: %s/%s\n", function, gpgme_strsource (err),
30 gpgme_strerror (err));
31}
32
43static int
44examine_signatures (gpgme_verify_result_t result, int sig_count)
45{
46 gpgme_signature_t sig;
47
48 nasl_trace (NULL, "examine_signatures\n");
49
50 sig = result->signatures;
51
52 if (nasl_trace_enabled ())
53 {
54 nasl_trace (NULL, "examine_signatures: signature #%d:\n", sig_count);
55 nasl_trace (NULL, "examine_signatures: summary: %d\n", sig->summary);
56 nasl_trace (NULL, "examine_signatures: validity: %d\n", sig->validity);
57 nasl_trace (NULL, "examine_signatures: status: %s\n",
58 gpg_strerror (sig->status));
59 nasl_trace (NULL, "examine_signatures: timestamp: %ld\n",
60 sig->timestamp);
61 nasl_trace (NULL, "examine_signatures: exp_timestamp: %ld\n",
62 sig->exp_timestamp);
63 nasl_trace (NULL, "examine_signatures: fpr: %s\n", sig->fpr);
64 }
65
66 if (sig->summary & GPGME_SIGSUM_VALID)
67 {
68 nasl_trace (NULL, "examine_signatures: signature is valid\n");
69 return 1;
70 }
71 else
72 {
73 nasl_trace (NULL, "examine_signatures: signature is invalid\n");
74 }
75
76 return 0;
77}
78
97int
98nasl_verify_signature (const char *filename, const char *fcontent, size_t flen)
99{
100 int retcode = -1, sig_count = 0;
101 char *sigfilename = NULL;
102 gsize siglen = 0;
103 gchar *scontent = NULL;
104 gchar *offset = NULL;
105 gchar *endpos = NULL;
106 gchar *path = g_build_filename (OPENVAS_GPG_BASE_DIR, "gnupg", NULL);
107 gboolean success;
108 gpgme_error_t err;
109 gpgme_ctx_t ctx = gvm_init_gpgme_ctx_from_dir (path);
110 gpgme_data_t sig = NULL, text = NULL;
111
112 g_free (path);
113 if (ctx == NULL)
114 {
115 nasl_trace (NULL, "gpgme context could not be initialized.\n");
116 goto fail;
117 }
118
119 /* Signatures file is buffered. */
120 sigfilename = g_malloc0 (strlen (filename) + 4 + 1);
121 strcpy (sigfilename, filename);
122 strcat (sigfilename, ".asc");
123 nasl_trace (NULL, "nasl_verify_signature: loading signature file '%s'\n",
124 sigfilename);
125
126 success = g_file_get_contents (sigfilename, &scontent, NULL, NULL);
127 /* If the signature file doesn't exist, fail without an error message
128 * because an unsigned file is a very common and expected
129 * condition */
130 if (!success)
131 goto fail;
132
133 /* Start to parse the signature file to find signatures. */
134 offset = g_strstr_len (scontent, strlen (scontent), "-----B");
135 if (!offset)
136 {
137 nasl_trace (NULL, "nasl_verify_signature: No signature in '%s'\n",
138 sigfilename);
139 goto fail;
140 }
141 endpos = g_strstr_len (offset, -1, "-----E");
142 if (endpos)
143 siglen = strlen (offset) - strlen (endpos) + 17;
144 else
145 {
146 nasl_trace (NULL, "nasl_verify_signature: No signature in '%s'\n",
147 sigfilename);
148 goto fail;
149 }
150
151 do
152 {
153 sig_count++;
154
155 /* Load file in memory. */
156 err = gpgme_data_new_from_mem (&text, fcontent, flen, 1);
157 if (err)
158 {
159 print_gpgme_error ("gpgme_data_new_from_file", err);
160 goto fail;
161 }
162
163 /* Load a founded signature in memory. */
164 err = gpgme_data_new_from_mem (&sig, offset, siglen, 1);
165 if (err)
166 nasl_trace (NULL, "nasl_verify_signature: %s: %s\n", sigfilename,
167 gpgme_strerror (err));
168
169 /* Verify the signature. */
170 err = gpgme_op_verify (ctx, sig, text, NULL);
171 nasl_trace (NULL,
172 "nasl_verify_signature: gpgme_op_verify "
173 "-> '%d'\n",
174 err);
175 if (err)
176 print_gpgme_error ("gpgme_op_verify", err);
177 else
178 {
179 if (examine_signatures (gpgme_op_verify_result (ctx), sig_count))
180 {
181 retcode = 0;
182 goto fail;
183 }
184 else
185 retcode = 1;
186 }
187
188 /* Search a new signature. */
189 offset = g_strstr_len (offset + 1, strlen (offset), "-----B");
190 if (offset)
191 {
192 if ((endpos = g_strstr_len (offset, strlen (offset), "-----E")))
193 siglen = (strlen (offset) - strlen (endpos) + 17);
194 else
195 {
196 nasl_trace (NULL, "nasl_verify_signature: No signature in '%s'\n",
197 sigfilename);
198 goto fail;
199 }
200 }
201
202 gpgme_data_release (sig);
203 sig = NULL;
204 gpgme_data_release (text);
205 text = NULL;
206 }
207 while (offset);
208
209fail:
210 g_free (scontent);
211 if (sig)
212 gpgme_data_release (sig);
213 if (text)
214 gpgme_data_release (text);
215 if (ctx != NULL)
216 gpgme_release (ctx);
217 g_free (sigfilename);
218
219 return retcode;
220}
int nasl_trace_enabled(void)
Checks if the nasl_trace_fp is set.
Definition: nasl_debug.c:161
void nasl_trace(lex_ctxt *lexic, char *msg,...)
Prints debug message in printf fashion to nasl_trace_fp if it exists.
Definition: nasl_debug.c:175
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:111
static int examine_signatures(gpgme_verify_result_t result, int sig_count)
Checks whether the signature verification result contains one.
int nasl_verify_signature(const char *filename, const char *fcontent, size_t flen)
static void print_gpgme_error(char *function, gpgme_error_t err)
Prints an error message for errors returned by gpgme.