OpenVAS Scanner  22.7.9
nasl_cert.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 
15 #ifdef HAVE_LIBKSBA
16 #include "nasl_cert.h"
17 
18 #include "nasl_debug.h"
19 #include "nasl_func.h"
20 #include "nasl_global_ctxt.h"
21 #include "nasl_lex_ctxt.h"
22 #include "nasl_tree.h"
23 #include "nasl_var.h"
24 
25 #include <errno.h>
26 #include <gcrypt.h>
27 #include <glib.h>
28 #include <glib/gstdio.h>
29 #include <gnutls/gnutls.h>
30 #include <gnutls/x509.h>
31 #include <gvm/base/logging.h>
32 #include <ksba.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 
38 #undef G_LOG_DOMAIN
39 
42 #define G_LOG_DOMAIN "lib nasl"
43 
44 #ifndef DIM
45 #define DIM(v) (sizeof (v) / sizeof ((v)[0]))
46 #define DIMof(type, member) DIM (((type *) 0)->member)
47 #endif
48 
49 /* Useful helper macros to avoid problems with locales. */
50 #define spacep(p) (*(p) == ' ' || *(p) == '\t')
51 #define digitp(p) (*(p) >= '0' && *(p) <= '9')
52 #define hexdigitp(a) \
53  (digitp (a) || (*(a) >= 'A' && *(a) <= 'F') || (*(a) >= 'a' && *(a) <= 'f'))
54 
55 /* The atoi macros assume that the buffer has only valid digits. */
56 #define atoi_1(p) (*(p) - '0')
57 #define atoi_2(p) ((atoi_1 (p) * 10) + atoi_1 ((p) + 1))
58 #define atoi_4(p) ((atoi_2 (p) * 100) + atoi_2 ((p) + 2))
59 #define xtoi_1(p) \
60  (*(p) <= '9' ? (*(p) - '0') \
61  : *(p) <= 'F' ? (*(p) - 'A' + 10) \
62  : (*(p) - 'a' + 10))
63 #define xtoi_2(p) \
64  ((xtoi_1 ((const unsigned char *) (p)) * 16) \
65  + xtoi_1 ((const unsigned char *) (p) + 1))
66 
67 /* Convert N to a hex digit. N must be in the range 0..15. */
68 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) -10) + 'A'))
69 
70 /* This object is used to keep track of KSBA certificate objects.
71  Because they are pointers they can't be mapped easily to the NASL
72  type system. Our solution is to track those objects here and clean
73  up any left over context at the end of a script run. We could use
74  the undocumented "on_exit" feature but that one is not well
75  implemented; thus we use explicit code in the interpreter for the
76  cleanup. The scripts are expected to close the objects, but as
77  long as they don't open too many of them, the system will take care
78  of it at script termination time.
79 
80  We associate each object with an object id, which is a global
81  counter of this process. An object id of 0 marks an unused table
82  entry.
83  */
84 struct object_desc_s;
85 typedef struct object_desc_s *object_desc_t;
86 struct object_desc_s
87 {
88  object_desc_t next;
89  int object_id;
90  ksba_cert_t cert;
91 };
92 
93 /* A linked list of all used certificate objects. */
94 static object_desc_t object_list;
95 
96 /* Return the next object id. */
97 static int
98 next_object_id (void)
99 {
100  static int last;
101  static int wrapped;
102 
103 again:
104  last++;
105  /* Because we don't have an unsigned type, it is better to avoid
106  negative values. Thus if LAST turns negative we wrap around to
107  the 1; this also avoids the verboten zero. */
108  if (last <= 0)
109  {
110  last = 1;
111  wrapped = 1;
112  }
113 
114  /* If the counter wrapped we need to check that we do not return an
115  object id still in use. We use a stupid simple retry algorithm;
116  this could be improved, for example, by remembering gaps in the
117  list of used ids. This code part is anyway not easy to test
118  unless we implement a test feature for this function. */
119  if (wrapped)
120  {
121  object_desc_t obj;
122 
123  for (obj = object_list; obj; obj = obj->next)
124  if (obj->object_id == last)
125  goto again;
126  }
127  return last;
128 }
129 
158 tree_cell *
159 nasl_cert_open (lex_ctxt *lexic)
160 {
161  gpg_error_t err;
162  tree_cell *retc;
163  const char *data;
164  int datalen;
165  ksba_reader_t reader;
166  ksba_cert_t cert;
167  object_desc_t obj;
168 
169  data = get_str_var_by_num (lexic, 0);
170  if (!data || !(datalen = get_var_size_by_num (lexic, 0)))
171  {
172  g_message ("No certificate passed to cert_open");
173  return NULL;
174  }
175 
176  err = ksba_reader_new (&reader);
177  if (err)
178  {
179  g_message ("Opening reader object failed: %s", gpg_strerror (err));
180  return NULL;
181  }
182  err = ksba_reader_set_mem (reader, data, datalen);
183  if (err)
184  {
185  g_message ("ksba_reader_set_mem failed: %s", gpg_strerror (err));
186  ksba_reader_release (reader);
187  return NULL;
188  }
189 
190  err = ksba_cert_new (&cert);
191  if (err)
192  {
193  g_message ("ksba_cert_new failed: %s", gpg_strerror (err));
194  ksba_reader_release (reader);
195  return NULL;
196  }
197 
198  err = ksba_cert_read_der (cert, reader);
199  if (err)
200  {
201  g_message ("Certificate parsing failed: %s", gpg_strerror (err));
202  /* FIXME: Try again this time assuming a PEM certificate. */
203  ksba_reader_release (reader);
204  ksba_cert_release (cert);
205  return NULL;
206  }
207  ksba_reader_release (reader);
208 
209  obj = g_try_malloc (sizeof *obj);
210  if (!obj)
211  {
212  g_message ("malloc failed in %s", __func__);
213  ksba_cert_release (cert);
214  return NULL;
215  }
216  obj->object_id = next_object_id ();
217  obj->cert = cert;
218  obj->next = object_list;
219  object_list = obj;
220 
221  /* Return the session id. */
222  retc = alloc_typed_cell (CONST_INT);
223  retc->x.i_val = obj->object_id;
224  return retc;
225 }
226 
244 tree_cell *
245 nasl_cert_close (lex_ctxt *lexic)
246 {
247  int object_id;
248  object_desc_t prevobj, obj;
249 
250  object_id = get_int_var_by_num (lexic, 0, -1);
251  if (!object_id)
252  return FAKE_CELL;
253  if (object_id < 0)
254  {
255  g_message ("Bad object id %d passed to cert_close", object_id);
256  return FAKE_CELL;
257  }
258 
259  for (prevobj = NULL, obj = object_list; obj; prevobj = obj, obj = obj->next)
260  if (obj->object_id == object_id)
261  break;
262  if (!obj)
263  {
264  g_message ("Unused object id %d passed to cert_close", object_id);
265  return FAKE_CELL;
266  }
267 
268  if (prevobj)
269  prevobj->next = obj->next;
270  else
271  object_list = obj->next;
272 
273  ksba_cert_release (obj->cert);
274  g_free (obj);
275 
276  return FAKE_CELL;
277 }
278 
279 /* Helper to get the value of the Common Name part. */
280 static const char *
281 parse_dn_part_for_CN (const char *string, char **r_value)
282 {
283  const char *s, *s1;
284  size_t n;
285  char *p = NULL;
286  int found;
287 
288  *r_value = NULL;
289 
290  /* Parse attributeType */
291  for (s = string + 1; *s && *s != '='; s++)
292  ;
293  if (!*s)
294  return NULL; /* Error */
295  n = s - string;
296  if (!n)
297  return NULL; /* Empty key */
298 
299  found = (n == 2 && string[0] == 'C' && string[1] == 'N');
300  string = s + 1;
301 
302  if (*string == '#') /* Hex encoded value. */
303  {
304  string++;
305  for (s = string; hexdigitp (s); s++)
306  s++;
307  n = s - string;
308  if (!n || (n & 1))
309  return NULL; /* No or odd number of digits. */
310  n /= 2;
311  if (found)
312  *r_value = p = g_malloc0 (n + 1);
313 
314  for (s1 = string; n; s1 += 2, n--, p++)
315  {
316  if (found)
317  {
318  *(unsigned char *) p = xtoi_2 (s1);
319  if (!*p)
320  *p = 0x01; /* Better return a wrong value than
321  truncate the string. */
322  }
323  }
324  if (found)
325  *p = 0;
326  }
327  else /* Regular V3 quoted string */
328  {
329  for (n = 0, s = string; *s; s++)
330  {
331  if (*s == '\\') /* Pair */
332  {
333  s++;
334  if (*s == ',' || *s == '=' || *s == '+' || *s == '<' || *s == '>'
335  || *s == '#' || *s == ';' || *s == '\\' || *s == '\"'
336  || *s == ' ')
337  n++;
338  else if (hexdigitp (s) && hexdigitp (s + 1))
339  {
340  s++;
341  n++;
342  }
343  else
344  return NULL; /* Invalid escape sequence. */
345  }
346  else if (*s == '\"')
347  return NULL; /* Invalid encoding. */
348  else if (*s == ',' || *s == '=' || *s == '+' || *s == '<' || *s == '>'
349  || *s == ';')
350  break; /* End of that part. */
351  else
352  n++;
353  }
354 
355  if (found)
356  *r_value = p = g_malloc0 (n + 1);
357 
358  for (s = string; n; s++, n--)
359  {
360  if (*s == '\\')
361  {
362  s++;
363  if (hexdigitp (s))
364  {
365  if (found)
366  {
367  *(unsigned char *) p = xtoi_2 (s);
368  if (!*p)
369  *p = 0x01; /* Better return a wrong value than
370  truncate the string. */
371  p++;
372  }
373  s++;
374  }
375  else if (found)
376  *p++ = *s;
377  }
378  else if (found)
379  *p++ = *s;
380  }
381  if (found)
382  *p = 0;
383  }
384  return s;
385 }
386 
387 /* Parse a DN and return the value of the CommonName. Note that this
388  is not a validating parser and it does not support any old-stylish
389  syntax; this is not a problem because KSBA will always return
390  RFC-2253 compatible strings. The caller must use free to free the
391  returned value. */
392 static char *
393 parse_dn_for_CN (const char *string)
394 {
395  char *value = NULL;
396 
397  while (*string && !value)
398  {
399  while (*string == ' ')
400  string++;
401  if (!*string)
402  break; /* ready */
403  string = parse_dn_part_for_CN (string, &value);
404  if (!string)
405  goto failure;
406  while (*string == ' ')
407  string++;
408  if (*string && *string != ',' && *string != ';' && *string != '+')
409  goto failure; /* Invalid delimiter. */
410  if (*string == '+')
411  goto failure; /* A multivalued CN is not supported. */
412  if (*string)
413  string++;
414  }
415  return value;
416 
417 failure:
418  g_free (value);
419  return NULL;
420 }
421 
422 /* Given a CERT object, build an array with all hostnames identified
423  by the certificate. */
424 static tree_cell *
425 build_hostname_list (ksba_cert_t cert)
426 {
427  tree_cell *retc;
428  char *name, *value;
429  int arridx;
430  int idx;
431  nasl_array *a;
432  anon_nasl_var v;
433 
434  name = ksba_cert_get_subject (cert, 0);
435  if (!name)
436  return NULL; /* No valid subject. */
437 
438  retc = alloc_typed_cell (DYN_ARRAY);
439  retc->x.ref_val = a = g_malloc0 (sizeof *a);
440  arridx = 0;
441 
442  value = parse_dn_for_CN (name);
443  ksba_free (name);
444 
445  /* Add the CN to the array even if it doesn't look like a hostname. */
446  if (value)
447  {
448  memset (&v, 0, sizeof v);
449  v.var_type = VAR2_DATA;
450  v.v.v_str.s_val = (unsigned char *) value;
451  v.v.v_str.s_siz = strlen (value);
452  add_var_to_list (a, arridx++, &v);
453  }
454  g_free (value);
455  value = NULL;
456 
457  for (idx = 1; (name = ksba_cert_get_subject (cert, idx)); idx++)
458  {
459  /* Poor man's s-expression parser. Despite it simple code, it
460  is correct in this case because ksba will always return a
461  valid s-expression. */
462  if (*name == '(' && name[1] == '8' && name[2] == ':'
463  && !memcmp (name + 3, "dns-name", 8))
464  {
465  char *endp;
466  unsigned long n = strtoul (name + 11, &endp, 10);
467 
468  if (*endp != ':')
469  {
470  ksba_free (name);
471  return NULL;
472  }
473  endp++;
474  memset (&v, 0, sizeof v);
475  v.var_type = VAR2_DATA;
476  v.v.v_str.s_val = (unsigned char *) endp;
477  v.v.v_str.s_siz = n;
478  add_var_to_list (a, arridx++, &v);
479  }
480  ksba_free (name);
481  }
482 
483  return retc;
484 }
485 
490 static tree_cell *
491 make_hexstring (const void *buffer, size_t length)
492 {
493  const unsigned char *s;
494  tree_cell *retc;
495  char *p;
496 
497  retc = alloc_typed_cell (CONST_STR);
498  retc->size = length * 2;
499  retc->x.str_val = p = g_malloc0 (length * 2 + 1);
500 
501  for (s = buffer; length; length--, s++)
502  {
503  *p++ = tohex ((*s >> 4) & 15);
504  *p++ = tohex (*s & 15);
505  }
506  *p = 0;
507 
508  return retc;
509 }
510 
520 static tree_cell *
521 get_fingerprint (ksba_cert_t cert, int algo)
522 {
523  int dlen;
524  const unsigned char *der;
525  size_t derlen;
526  unsigned char digest[32];
527 
528  dlen = gcry_md_get_algo_dlen (algo);
529  if (dlen != 20 && dlen != 32)
530  return NULL; /* We only support SHA-1 and SHA-256. */
531 
532  der = ksba_cert_get_image (cert, &derlen);
533  if (!der)
534  return NULL;
535  gcry_md_hash_buffer (algo, digest, der, derlen);
536 
537  return make_hexstring (digest, dlen);
538 }
539 
540 /*
541  * @brief Return algorithm name from its OID.
542  *
543  * param[in] oid Algorithm ID.
544  *
545  * @return Algorithm name or NULL.
546  */
547 static const char *
548 get_oid_name (const char *oid)
549 {
550  /* Initial list from Wireshark. See epan/dissectors/packet-pkcs1.c */
551  if (!strcmp ("1.2.840.10040.4.1", oid))
552  return "id-dsa";
553  else if (!strcmp ("1.2.840.10046.2.1", oid))
554  return "dhpublicnumber";
555  else if (!strcmp ("2.16.840.1.101.2.1.1.22", oid))
556  return "id-keyExchangeAlgorithm";
557  else if (!strcmp ("1.2.840.10045.1.1", oid))
558  return "prime-field";
559  else if (!strcmp ("1.2.840.10045.2.1", oid))
560  return "id-ecPublicKey";
561  else if (!strcmp ("1.2.840.10045.4.1", oid))
562  return "ecdsa-with-SHA1";
563  else if (!strcmp ("1.2.840.10045.4.3.1", oid))
564  return "ecdsa-with-SHA224";
565  else if (!strcmp ("1.2.840.10045.4.3.2", oid))
566  return "ecdsa-with-SHA256";
567  else if (!strcmp ("1.2.840.10045.4.3.3", oid))
568  return "ecdsa-with-SHA384";
569  else if (!strcmp ("1.2.840.10045.4.3.4", oid))
570  return "ecdsa-with-SHA512";
571  else if (!strcmp ("1.3.132.1.12", oid))
572  return "id-ecDH";
573  else if (!strcmp ("1.2.840.10045.2.13", oid))
574  return "id-ecMQV";
575  else if (!strcmp ("1.2.840.113549.1.1.10", oid))
576  return "id-RSASSA-PSS";
577  else if (!strcmp ("1.2.840.113549.1.1.11", oid))
578  return "sha256WithRSAEncryption";
579  else if (!strcmp ("1.2.840.113549.1.1.12", oid))
580  return "sha384WithRSAEncryption";
581  else if (!strcmp ("1.2.840.113549.1.1.13", oid))
582  return "sha512WithRSAEncryption";
583  else if (!strcmp ("1.2.840.113549.1.1.14", oid))
584  return "sha224WithRSAEncryption";
585  else if (!strcmp ("1.2.840.113549.1.1.8", oid))
586  return "id-mgf1";
587  else if (!strcmp ("1.2.840.113549.2.2", oid))
588  return "md2";
589  else if (!strcmp ("1.2.840.113549.2.4", oid))
590  return "md4";
591  else if (!strcmp ("1.2.840.113549.2.5", oid))
592  return "md5";
593  else if (!strcmp ("1.2.840.113549.1.1.1", oid))
594  return "rsaEncryption";
595  else if (!strcmp ("1.2.840.113549.1.1.2", oid))
596  return "md2WithRSAEncryption";
597  else if (!strcmp ("1.2.840.113549.1.1.3", oid))
598  return "md4WithRSAEncryption";
599  else if (!strcmp ("1.2.840.113549.1.1.4", oid))
600  return "md5WithRSAEncryption";
601  else if (!strcmp ("1.2.840.113549.1.1.5", oid))
602  return "sha1WithRSAEncryption";
603  else if (!strcmp ("1.2.840.113549.1.1.6", oid))
604  return "rsaOAEPEncryptionSET";
605  else if (!strcmp ("1.2.840.10045.3.1.1", oid))
606  return "secp192r1";
607  else if (!strcmp ("1.3.132.0.1", oid))
608  return "sect163k1";
609  else if (!strcmp ("1.3.132.0.15", oid))
610  return "sect163r2";
611  else if (!strcmp ("1.3.132.0.33", oid))
612  return "secp224r1";
613  else if (!strcmp ("1.3.132.0.26", oid))
614  return "sect233k1";
615  else if (!strcmp ("1.3.132.0.27", oid))
616  return "sect233r1";
617  else if (!strcmp ("1.2.840.10045.3.1.7", oid))
618  return "secp256r1";
619  else if (!strcmp ("1.3.132.0.16", oid))
620  return "sect283k1";
621  else if (!strcmp ("1.3.132.0.17", oid))
622  return "sect283r1";
623  else if (!strcmp ("1.3.132.0.34", oid))
624  return "secp384r1";
625  else if (!strcmp ("1.3.132.0.36", oid))
626  return "sect409k1";
627  else if (!strcmp ("1.3.132.0.37", oid))
628  return "sect409r1";
629  else if (!strcmp ("1.3.132.0.35", oid))
630  return "sect521r1";
631  else if (!strcmp ("1.3.132.0.38", oid))
632  return "sect571k1";
633  else if (!strcmp ("1.3.132.0.39", oid))
634  return "sect571r1";
635  else if (!strcmp ("2.16.840.1.101.3.4.3.1", oid))
636  return "id-dsa-with-sha224";
637  else if (!strcmp ("2.16.840.1.101.3.4.3.2", oid))
638  return "id-dsa-with-sha256";
639  else if (!strcmp ("2.16.840.1.101.3.4.2.1", oid))
640  return "sha256";
641  else if (!strcmp ("2.16.840.1.101.3.4.2.2", oid))
642  return "sha384";
643  else if (!strcmp ("2.16.840.1.101.3.4.2.3", oid))
644  return "sha512";
645  else if (!strcmp ("2.16.840.1.101.3.4.2.4", oid))
646  return "sha224";
647  else
648  return NULL;
649 }
650 
657 static tree_cell *
658 get_name (const char *string)
659 {
660  tree_cell *retc;
661 
662  if (*string == '(')
663  {
664  /* This is an s-expression in canonical format. We convert it
665  to advanced format. */
666  gcry_sexp_t sexp;
667  size_t len;
668  char *buffer;
669 
670  len = gcry_sexp_canon_len ((const unsigned char *) string, 0, NULL, NULL);
671  if (gcry_sexp_sscan (&sexp, NULL, string, len))
672  return NULL; /* Invalid encoding. */
673  len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
674  if (!len)
675  return NULL;
676  buffer = g_malloc0 (len);
677  len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buffer, len);
678  if (!len)
679  return NULL;
680  len = strlen (buffer);
681  /* Strip a trailing linefeed. */
682  if (len && buffer[len - 1] == '\n')
683  buffer[--len] = 0;
684  gcry_sexp_release (sexp);
685  retc = alloc_typed_cell (CONST_STR);
686  retc->x.str_val = buffer;
687  retc->size = len;
688  }
689  else
690  {
691  /* RFC-2822 style mailboxes or RFC-2253 strings are returned
692  verbatim. */
693  retc = alloc_typed_cell (CONST_STR);
694  retc->x.str_val = g_strdup (string);
695  retc->size = strlen (retc->x.str_val);
696  }
697 
698  return retc;
699 }
700 
789 tree_cell *
790 nasl_cert_query (lex_ctxt *lexic)
791 {
792  int object_id;
793  object_desc_t obj;
794  const char *command;
795  int cmdidx;
796  char *result;
797  ksba_isotime_t isotime;
798  ksba_sexp_t sexp;
799  tree_cell *retc;
800 
801  object_id = get_int_var_by_num (lexic, 0, -1);
802  if (object_id <= 0)
803  {
804  g_message ("Bad object id %d passed to cert_query", object_id);
805  return NULL;
806  }
807 
808  for (obj = object_list; obj; obj = obj->next)
809  if (obj->object_id == object_id)
810  break;
811  if (!obj)
812  {
813  g_message ("Unused object id %d passed to cert_query", object_id);
814  return NULL;
815  }
816 
817  /* Check that the command is a string. */
818  command = get_str_var_by_num (lexic, 1);
819  if (!command || get_var_type_by_num (lexic, 1) != VAR2_STRING)
820  {
821  g_message ("No proper command passed to cert_query");
822  return NULL;
823  }
824 
825  /* Get the index which defaults to 0. */
826  cmdidx = get_int_var_by_name (lexic, "idx", 0);
827 
828  /* Command dispatcher. */
829  retc = NULL;
830  if (!strcmp (command, "serial"))
831  {
832  const unsigned char *s;
833  char *endp;
834  unsigned long n;
835 
836  sexp = ksba_cert_get_serial (obj->cert);
837  s = sexp;
838  if (!s || *s != '(')
839  return NULL; /* Ooops. */
840  s++;
841  n = strtoul ((const char *) s, &endp, 10);
842  s = (const unsigned char *) endp;
843  if (*s == ':')
844  {
845  s++;
846  retc = make_hexstring (s, n);
847  }
848  ksba_free (sexp);
849  }
850  else if (!strcmp (command, "issuer"))
851  {
852  result = ksba_cert_get_issuer (obj->cert, cmdidx);
853  if (!result)
854  return NULL;
855 
856  retc = get_name (result);
857  ksba_free (result);
858  }
859  else if (!strcmp (command, "subject"))
860  {
861  result = ksba_cert_get_subject (obj->cert, cmdidx);
862  if (!result)
863  return NULL;
864 
865  retc = get_name (result);
866  ksba_free (result);
867  }
868  else if (!strcmp (command, "not-before"))
869  {
870  ksba_cert_get_validity (obj->cert, 0, isotime);
871  retc = alloc_typed_cell (CONST_STR);
872  retc->x.str_val = g_strdup (isotime);
873  retc->size = strlen (isotime);
874  }
875  else if (!strcmp (command, "not-after"))
876  {
877  ksba_cert_get_validity (obj->cert, 1, isotime);
878  retc = alloc_typed_cell (CONST_STR);
879  retc->x.str_val = g_strdup (isotime);
880  retc->size = strlen (isotime);
881  }
882  else if (!strcmp (command, "fpr-sha-256"))
883  {
884  retc = get_fingerprint (obj->cert, GCRY_MD_SHA256);
885  }
886  else if (!strcmp (command, "fpr-sha-1"))
887  {
888  retc = get_fingerprint (obj->cert, GCRY_MD_SHA1);
889  }
890  else if (!strcmp (command, "all"))
891  {
892  /* FIXME */
893  }
894  else if (!strcmp (command, "hostnames"))
895  {
896  retc = build_hostname_list (obj->cert);
897  }
898  else if (!strcmp (command, "image"))
899  {
900  const unsigned char *der;
901  size_t derlen;
902 
903  der = ksba_cert_get_image (obj->cert, &derlen);
904  if (der && derlen)
905  {
906  retc = alloc_typed_cell (CONST_DATA);
907  retc->size = derlen;
908  retc->x.str_val = g_malloc0 (derlen);
909  memcpy (retc->x.str_val, der, derlen);
910  }
911  }
912  else if (!strcmp (command, "algorithm-name")
913  || !strcmp (command, "signature-algorithm-name"))
914  {
915  const char *digest = ksba_cert_get_digest_algo (obj->cert);
916  if (digest)
917  {
918  const char *name = get_oid_name (digest);
919  if (!name)
920  name = digest;
921  retc = alloc_typed_cell (CONST_STR);
922  retc->x.str_val = g_strdup (name);
923  retc->size = strlen (name);
924  }
925  }
926  else if (!strcmp (command, "public-key-algorithm-name"))
927  {
928  gnutls_datum_t datum;
929  gnutls_x509_crt_t cert = NULL;
930  int algo;
931  char *algo_name;
932 
933  datum.data =
934  (void *) ksba_cert_get_image (obj->cert, (size_t *) &datum.size);
935  if (!datum.data)
936  return NULL;
937  if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS)
938  return NULL;
939  if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER)
940  != GNUTLS_E_SUCCESS)
941  return NULL;
942  if ((algo = gnutls_x509_crt_get_pk_algorithm (cert, NULL)) < 0)
943  {
944  g_message ("%s: Error getting the public key algorithm name.",
945  __func__);
946  return NULL;
947  }
948  algo_name = gnutls_pk_algorithm_get_name (algo)
949  ? g_strdup (gnutls_pk_algorithm_get_name (algo))
950  : g_strdup ("unknown");
951  retc = alloc_typed_cell (CONST_DATA);
952  retc->size = strlen (algo_name);
953  retc->x.str_val = algo_name;
954  }
955  else if (!strcmp (command, "modulus"))
956  {
957  gnutls_datum_t datum, m, e;
958  gnutls_x509_crt_t cert = NULL;
959 
960  datum.data =
961  (void *) ksba_cert_get_image (obj->cert, (size_t *) &datum.size);
962  if (!datum.data)
963  return NULL;
964  if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS)
965  return NULL;
966  if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER)
967  != GNUTLS_E_SUCCESS)
968  return NULL;
969  if (gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e) != GNUTLS_E_SUCCESS)
970  return NULL;
971 
972  retc = alloc_typed_cell (CONST_DATA);
973  retc->size = m.size;
974  retc->x.str_val = g_malloc0 (m.size);
975  memcpy (retc->x.str_val, m.data, m.size);
976 
977  gnutls_free (m.data);
978  gnutls_free (e.data);
979  gnutls_x509_crt_deinit (cert);
980  }
981  else if (!strcmp (command, "exponent"))
982  {
983  gnutls_datum_t datum, m, e;
984  gnutls_x509_crt_t cert = NULL;
985 
986  datum.data =
987  (void *) ksba_cert_get_image (obj->cert, (size_t *) &datum.size);
988  if (!datum.data)
989  return NULL;
990  if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS)
991  return NULL;
992  if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER)
993  != GNUTLS_E_SUCCESS)
994  return NULL;
995  if (gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e) != GNUTLS_E_SUCCESS)
996  return NULL;
997 
998  retc = alloc_typed_cell (CONST_DATA);
999  retc->size = e.size;
1000  retc->x.str_val = g_malloc0 (e.size);
1001  memcpy (retc->x.str_val, e.data, e.size);
1002 
1003  gnutls_free (m.data);
1004  gnutls_free (e.data);
1005  gnutls_x509_crt_deinit (cert);
1006  }
1007  else if (!strcmp (command, "key-size"))
1008  {
1009  gnutls_datum_t datum;
1010  gnutls_x509_crt_t cert = NULL;
1011  unsigned int bits = 0;
1012 
1013  datum.data =
1014  (void *) ksba_cert_get_image (obj->cert, (size_t *) &datum.size);
1015  if (!datum.data)
1016  return NULL;
1017  if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS)
1018  return NULL;
1019  if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER)
1020  != GNUTLS_E_SUCCESS)
1021  return NULL;
1022  gnutls_x509_crt_get_pk_algorithm (cert, &bits);
1023  gnutls_x509_crt_deinit (cert);
1024 
1025  retc = alloc_typed_cell (CONST_INT);
1026  retc->x.i_val = bits;
1027  }
1028  else
1029  {
1030  g_message ("Unknown command '%s' passed to cert_query", command);
1031  }
1032 
1033  return retc;
1034 }
1035 
1036 #endif /* HAVE_LIBKSBA */
st_a_nasl_var
Definition: nasl_var.h:40
CONST_DATA
@ CONST_DATA
Definition: nasl_tree.h:82
nasl_cert.h
Protos and data structures for CERT functions used by NASL scripts.
TC::str_val
char * str_val
Definition: nasl_tree.h:103
CONST_STR
@ CONST_STR
Definition: nasl_tree.h:80
TC::x
union TC::@5 x
DYN_ARRAY
@ DYN_ARRAY
Definition: nasl_tree.h:90
FAKE_CELL
#define FAKE_CELL
Definition: nasl_tree.h:110
st_a_nasl_var::v
union st_a_nasl_var::@7 v
st_a_nasl_var::v_str
nasl_string_t v_str
Definition: nasl_var.h:47
VAR2_STRING
@ VAR2_STRING
Definition: nasl_var.h:17
st_nasl_string::s_siz
int s_siz
Definition: nasl_var.h:27
name
const char * name
Definition: nasl_init.c:411
VAR2_DATA
@ VAR2_DATA
Definition: nasl_var.h:18
st_nasl_array
Definition: nasl_var.h:33
oid
const char * oid
Definition: nasl_builtin_find_service.c:51
nasl_debug.h
TC::size
int size
Definition: nasl_tree.h:99
nasl_lex_ctxt.h
len
uint8_t len
Definition: nasl_packet_forgery.c:1
get_int_var_by_name
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition: nasl_var.c:1104
nasl_func.h
TC::ref_val
void * ref_val
Definition: nasl_tree.h:105
get_int_var_by_num
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1097
get_str_var_by_num
char * get_str_var_by_num(lex_ctxt *, int)
Definition: nasl_var.c:1111
st_a_nasl_var::var_type
int var_type
Definition: nasl_var.h:41
TC
Definition: nasl_tree.h:94
struct_lex_ctxt
Definition: nasl_lex_ctxt.h:23
nasl_var.h
nasl_cert_open
tree_cell * nasl_cert_open(lex_ctxt *lexic)
nasl_cert_close
tree_cell * nasl_cert_close(lex_ctxt *lexic)
nasl_global_ctxt.h
CONST_INT
@ CONST_INT
Definition: nasl_tree.h:79
nasl_cert_query
tree_cell * nasl_cert_query(lex_ctxt *lexic)
get_var_size_by_num
int get_var_size_by_num(lex_ctxt *, int)
Definition: nasl_var.c:1145
get_var_type_by_num
int get_var_type_by_num(lex_ctxt *, int)
Returns NASL variable/cell type, VAR2_UNDEF if value is NULL.
Definition: nasl_var.c:1155
add_var_to_list
int add_var_to_list(nasl_array *a, int i, const anon_nasl_var *v)
Definition: nasl_var.c:1245
alloc_typed_cell
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:28
nasl_tree.h
length
u_short length
Definition: nasl_packet_forgery.c:4
st_nasl_string::s_val
unsigned char * s_val
Definition: nasl_var.h:26
TC::i_val
long int i_val
Definition: nasl_tree.h:104