OpenVAS Scanner  7.0.0~git
nasl_signature.c
Go to the documentation of this file.
1 /* Copyright (C) 2009-2019 Greenbone Networks GmbH
2  *
3  * SPDX-License-Identifier: GPL-2.0-or-later
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program 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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include "nasl_debug.h"
21 #include "nasl_func.h"
22 #include "nasl_lex_ctxt.h"
23 #include "nasl_tree.h"
24 #include "nasl_var.h"
25 
26 #include <gvm/util/gpgmeutils.h>
27 #include <locale.h> /* for LC_CTYPE */
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h> /* for strlen */
31 
38 static void
39 print_gpgme_error (char *function, gpgme_error_t err)
40 {
41  nasl_perror (NULL, "%s failed: %s/%s\n", function, gpgme_strsource (err),
42  gpgme_strerror (err));
43 }
44 
55 static int
56 examine_signatures (gpgme_verify_result_t result, int sig_count)
57 {
58  gpgme_signature_t sig;
59 
60  nasl_trace (NULL, "examine_signatures\n");
61 
62  sig = result->signatures;
63 
64  if (nasl_trace_enabled ())
65  {
66  nasl_trace (NULL, "examine_signatures: signature #%d:\n", sig_count);
67  nasl_trace (NULL, "examine_signatures: summary: %d\n", sig->summary);
68  nasl_trace (NULL, "examine_signatures: validity: %d\n", sig->validity);
69  nasl_trace (NULL, "examine_signatures: status: %s\n",
70  gpg_strerror (sig->status));
71  nasl_trace (NULL, "examine_signatures: timestamp: %ld\n",
72  sig->timestamp);
73  nasl_trace (NULL, "examine_signatures: exp_timestamp: %ld\n",
74  sig->exp_timestamp);
75  nasl_trace (NULL, "examine_signatures: fpr: %s\n", sig->fpr);
76  }
77 
78  if (sig->summary & GPGME_SIGSUM_VALID)
79  {
80  nasl_trace (NULL, "examine_signatures: signature is valid\n");
81  return 1;
82  }
83  else
84  {
85  nasl_trace (NULL, "examine_signatures: signature is invalid\n");
86  }
87 
88  return 0;
89 }
90 
109 int
110 nasl_verify_signature (const char *filename, const char *fcontent, size_t flen)
111 {
112  int retcode = -1, sig_count = 0;
113  char *sigfilename = NULL;
114  gsize siglen = 0;
115  gchar *scontent = NULL;
116  gchar *offset = NULL;
117  gchar *endpos = NULL;
118  gchar *path = g_build_filename (OPENVAS_SYSCONF_DIR, "gnupg", NULL);
119  gboolean success;
120  gpgme_error_t err;
121  gpgme_ctx_t ctx = gvm_init_gpgme_ctx_from_dir (path);
122  gpgme_data_t sig = NULL, text = NULL;
123 
124  g_free (path);
125  if (ctx == NULL)
126  {
127  nasl_trace (NULL, "gpgme context could not be initialized.\n");
128  goto fail;
129  }
130 
131  /* Signatures file is buffered. */
132  sigfilename = g_malloc0 (strlen (filename) + 4 + 1);
133  strcpy (sigfilename, filename);
134  strcat (sigfilename, ".asc");
135  nasl_trace (NULL, "nasl_verify_signature: loading signature file '%s'\n",
136  sigfilename);
137 
138  success = g_file_get_contents (sigfilename, &scontent, NULL, NULL);
139  /* If the signature file doesn't exist, fail without an error message
140  * because an unsigned file is a very common and expected
141  * condition */
142  if (!success)
143  goto fail;
144 
145  /* Start to parse the signature file to find signatures. */
146  offset = g_strstr_len (scontent, strlen (scontent), "-----B");
147  if (!offset)
148  {
149  nasl_trace (NULL, "nasl_verify_signature: No signature in '%s'\n",
150  sigfilename);
151  goto fail;
152  }
153  endpos = g_strstr_len (offset, -1, "-----E");
154  if (endpos)
155  siglen = strlen (offset) - strlen (endpos) + 17;
156  else
157  {
158  nasl_trace (NULL, "nasl_verify_signature: No signature in '%s'\n",
159  sigfilename);
160  goto fail;
161  }
162 
163  do
164  {
165  sig_count++;
166 
167  /* Load file in memory. */
168  err = gpgme_data_new_from_mem (&text, fcontent, flen, 1);
169  if (err)
170  {
171  print_gpgme_error ("gpgme_data_new_from_file", err);
172  goto fail;
173  }
174 
175  /* Load a founded signature in memory. */
176  err = gpgme_data_new_from_mem (&sig, offset, siglen, 1);
177  if (err)
178  nasl_trace (NULL, "nasl_verify_signature: %s: %s\n", sigfilename,
179  gpgme_strerror (err));
180 
181  /* Verify the signature. */
182  err = gpgme_op_verify (ctx, sig, text, NULL);
183  nasl_trace (NULL,
184  "nasl_verify_signature: gpgme_op_verify "
185  "-> '%d'\n",
186  err);
187  if (err)
188  print_gpgme_error ("gpgme_op_verify", err);
189  else
190  {
191  if (examine_signatures (gpgme_op_verify_result (ctx), sig_count))
192  {
193  retcode = 0;
194  goto fail;
195  }
196  else
197  retcode = 1;
198  }
199 
200  /* Search a new signature. */
201  offset = g_strstr_len (offset + 1, strlen (offset), "-----B");
202  if (offset)
203  {
204  if ((endpos = g_strstr_len (offset, strlen (offset), "-----E")))
205  siglen = (strlen (offset) - strlen (endpos) + 17);
206  else
207  {
208  nasl_trace (NULL, "nasl_verify_signature: No signature in '%s'\n",
209  sigfilename);
210  goto fail;
211  }
212  }
213 
214  gpgme_data_release (sig);
215  sig = NULL;
216  gpgme_data_release (text);
217  text = NULL;
218  }
219  while (offset);
220 
221 fail:
222  g_free (scontent);
223  if (sig)
224  gpgme_data_release (sig);
225  if (text)
226  gpgme_data_release (text);
227  if (ctx != NULL)
228  gpgme_release (ctx);
229  g_free (sigfilename);
230 
231  return retcode;
232 }
nasl_trace
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:184
nasl_debug.h
nasl_perror
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:120
nasl_trace_enabled
int nasl_trace_enabled(void)
Checks if the nasl_trace_fp is set.
Definition: nasl_debug.c:170
nasl_lex_ctxt.h
nasl_func.h
nasl_var.h
examine_signatures
static int examine_signatures(gpgme_verify_result_t result, int sig_count)
Checks whether the signature verification result contains one.
Definition: nasl_signature.c:56
nasl_verify_signature
int nasl_verify_signature(const char *filename, const char *fcontent, size_t flen)
Definition: nasl_signature.c:110
print_gpgme_error
static void print_gpgme_error(char *function, gpgme_error_t err)
Prints an error message for errors returned by gpgme.
Definition: nasl_signature.c:39
nasl_tree.h