OpenVAS Libraries  9.0.3
nasl_cert.c
Go to the documentation of this file.
1 /* openvas-libraries/nasl
2  * $Id$
3  * Description: Implementation of an API for X.509 certificates
4  *
5  * Authors:
6  * Werner Koch <wk@gnupg.org>
7  *
8  * Copyright:
9  * Copyright (C) 2012, 2013 Greenbone Networks GmbH
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, see <http://www.gnu.org/licenses/>.
23  */
24 
34 #ifdef HAVE_LIBKSBA
35 #include <stdlib.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <glib.h>
41 #include <glib/gstdio.h>
42 
43 #include <ksba.h>
44 #include <gcrypt.h>
45 #include <gnutls/gnutls.h>
46 #include <gnutls/x509.h>
47 
48 #include "../misc/openvas_logging.h"
49 #include "nasl_tree.h"
50 #include "nasl_global_ctxt.h"
51 #include "nasl_func.h"
52 #include "nasl_var.h"
53 #include "nasl_lex_ctxt.h"
54 #include "nasl_debug.h"
55 
56 #include "nasl_cert.h"
57 
58 
59 #ifndef DIM
60 # define DIM(v) (sizeof(v)/sizeof((v)[0]))
61 # define DIMof(type,member) DIM(((type *)0)->member)
62 #endif
63 
64 /* Useful helper macros to avoid problems with locales. */
65 #define spacep(p) (*(p) == ' ' || *(p) == '\t')
66 #define digitp(p) (*(p) >= '0' && *(p) <= '9')
67 #define hexdigitp(a) (digitp (a) \
68  || (*(a) >= 'A' && *(a) <= 'F') \
69  || (*(a) >= 'a' && *(a) <= 'f'))
70 
71 /* The atoi macros assume that the buffer has only valid digits. */
72 #define atoi_1(p) (*(p) - '0' )
73 #define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
74 #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
75 #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
76  *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
77 #define xtoi_2(p) ((xtoi_1((const unsigned char *)(p)) * 16) \
78  + xtoi_1((const unsigned char *)(p)+1))
79 
80 /* Convert N to a hex digit. N must be in the range 0..15. */
81 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
82 
83 
84 /* This object is used to keep track of KSBA certificate objects.
85  Because they are pointers they can't be mapped easily to the NASL
86  type system. Our solution is to track those objects here and clean
87  up any left over context at the end of a script run. We could use
88  the undocumented "on_exit" feature but that one is not well
89  implemented; thus we use explicit code in the interpreter for the
90  cleanup. The scripts are expected to close the objects, but as
91  long as they don't open too many of them, the system will take care
92  of it at script termination time.
93 
94  We associate each object with an object id, which is a global
95  counter of this process. An object id of 0 marks an unused table
96  entry.
97  */
98 struct object_desc_s;
99 typedef struct object_desc_s *object_desc_t;
101 {
104  ksba_cert_t cert;
105 };
106 
107 /* A linked list of all used certificate objects. */
108 static object_desc_t object_list;
109 
110 
111 
112 /* Return the next object id. */
113 static int
114 next_object_id (void)
115 {
116  static int last;
117  static int wrapped;
118 
119  again:
120  last++;
121  /* Because we don't have an unsigned type, it is better to avoid
122  negative values. Thus if LAST turns negative we wrap around to
123  the 1; this also avoids the verboten zero. */
124  if (last <= 0)
125  {
126  last = 1;
127  wrapped = 1;
128  }
129 
130  /* If the counter wrapped we need to check that we do not return an
131  object id still in use. We use a stupid simple retry algorithm;
132  this could be improved, for example, by remembering gaps in the
133  list of used ids. This code part is anyway not easy to test
134  unless we implement a test feature for this function. */
135  if (wrapped)
136  {
137  object_desc_t obj;
138 
139  for (obj = object_list; obj; obj = obj->next)
140  if (obj->object_id == last)
141  goto again;
142  }
143  return last;
144 }
145 
146 
175 tree_cell *
177 {
178  gpg_error_t err;
179  tree_cell *retc;
180  const char *data;
181  int datalen;
182  ksba_reader_t reader;
183  ksba_cert_t cert;
184  object_desc_t obj;
185 
186  data = get_str_var_by_num (lexic, 0);
187  if (!data || !(datalen = get_var_size_by_num (lexic, 0)))
188  {
189  log_legacy_write ("No certificate passed to cert_open");
190  return NULL;
191  }
192 
193  err = ksba_reader_new (&reader);
194  if (err)
195  {
196  log_legacy_write ("Opening reader object failed: %s",
197  gpg_strerror (err));
198  return NULL;
199  }
200  err = ksba_reader_set_mem (reader, data, datalen);
201  if (err)
202  {
203  log_legacy_write ("ksba_reader_set_mem failed: %s", gpg_strerror (err));
204  ksba_reader_release (reader);
205  return NULL;
206  }
207 
208  err = ksba_cert_new (&cert);
209  if (err)
210  {
211  log_legacy_write ("ksba_cert_new failed: %s", gpg_strerror (err));
212  ksba_reader_release (reader);
213  return NULL;
214  }
215 
216  err = ksba_cert_read_der (cert, reader);
217  if (err)
218  {
219  log_legacy_write ("Certificate parsing failed: %s", gpg_strerror (err));
220  /* FIXME: Try again this time assuming a PEM certificate. */
221  ksba_reader_release (reader);
222  ksba_cert_release (cert);
223  return NULL;
224  }
225  ksba_reader_release (reader);
226 
227  obj = g_try_malloc (sizeof *obj);
228  if (!obj)
229  {
230  log_legacy_write ("malloc failed in %s", __FUNCTION__);
231  ksba_cert_release (cert);
232  return NULL;
233  }
234  obj->object_id = next_object_id ();
235  obj->cert = cert;
236  obj->next = object_list;
237  object_list = obj;
238 
239  /* Return the session id. */
240  retc = alloc_typed_cell (CONST_INT);
241  retc->x.i_val = obj->object_id;
242  return retc;
243 }
244 
245 
263 tree_cell *
265 {
266  int object_id;
267  object_desc_t prevobj, obj;
268 
269  object_id = get_int_var_by_num (lexic, 0, -1);
270  if (!object_id)
271  return FAKE_CELL;
272  if (object_id < 0)
273  {
274  log_legacy_write ("Bad object id %d passed to cert_close", object_id);
275  return FAKE_CELL;
276  }
277 
278  for (prevobj = NULL, obj = object_list; obj; prevobj = obj, obj = obj->next)
279  if (obj->object_id == object_id)
280  break;
281  if (!obj)
282  {
283  log_legacy_write ("Unused object id %d passed to cert_close",
284  object_id);
285  return FAKE_CELL;
286  }
287 
288  if (prevobj)
289  prevobj->next = obj->next;
290  else
291  object_list = obj->next;
292 
293  ksba_cert_release (obj->cert);
294  g_free (obj);
295 
296  return FAKE_CELL;
297 }
298 
299 
300 /* Helper to get the value of the Common Name part. */
301 static const char *
302 parse_dn_part_for_CN (const char *string, char **r_value)
303 {
304  const char *s, *s1;
305  size_t n;
306  char *p = NULL;
307  int found;
308 
309  *r_value = NULL;
310 
311  /* Parse attributeType */
312  for (s = string+1; *s && *s != '='; s++)
313  ;
314  if (!*s)
315  return NULL; /* Error */
316  n = s - string;
317  if (!n)
318  return NULL; /* Empty key */
319 
320  found = (n == 2 && string[0] == 'C' && string[1] == 'N');
321  string = s + 1;
322 
323  if (*string == '#') /* Hex encoded value. */
324  {
325  string++;
326  for (s=string; hexdigitp (s); s++)
327  s++;
328  n = s - string;
329  if (!n || (n & 1))
330  return NULL; /* No or odd number of digits. */
331  n /= 2;
332  if (found)
333  *r_value = p = g_malloc0 (n + 1);
334 
335  for (s1=string; n; s1 += 2, n--, p++)
336  {
337  if (found)
338  {
339  *(unsigned char *)p = xtoi_2 (s1);
340  if (!*p)
341  *p = 0x01; /* Better return a wrong value than
342  truncate the string. */
343  }
344  }
345  if (found)
346  *p = 0;
347  }
348  else /* Regular V3 quoted string */
349  {
350  for (n=0, s=string; *s; s++)
351  {
352  if (*s == '\\') /* Pair */
353  {
354  s++;
355  if (*s == ',' || *s == '=' || *s == '+'
356  || *s == '<' || *s == '>' || *s == '#' || *s == ';'
357  || *s == '\\' || *s == '\"' || *s == ' ')
358  n++;
359  else if (hexdigitp (s) && hexdigitp (s+1))
360  {
361  s++;
362  n++;
363  }
364  else
365  return NULL; /* Invalid escape sequence. */
366  }
367  else if (*s == '\"')
368  return NULL; /* Invalid encoding. */
369  else if (*s == ',' || *s == '=' || *s == '+'
370  || *s == '<' || *s == '>' || *s == ';' )
371  break; /* End of that part. */
372  else
373  n++;
374  }
375 
376  if (found)
377  *r_value = p = g_malloc0 (n + 1);
378 
379  for (s=string; n; s++, n--)
380  {
381  if (*s == '\\')
382  {
383  s++;
384  if (hexdigitp (s))
385  {
386  if (found)
387  {
388  *(unsigned char *)p = xtoi_2 (s);
389  if (!*p)
390  *p = 0x01; /* Better return a wrong value than
391  truncate the string. */
392  p++;
393  }
394  s++;
395  }
396  else if (found)
397  *p++ = *s;
398  }
399  else if (found)
400  *p++ = *s;
401  }
402  if (found)
403  *p = 0;
404  }
405  return s;
406 }
407 
408 
409 /* Parse a DN and return the value of the CommonName. Note that this
410  is not a validating parser and it does not support any old-stylish
411  syntax; this is not a problem because KSBA will always return
412  RFC-2253 compatible strings. The caller must use free to free the
413  returned value. */
414 static char *
415 parse_dn_for_CN (const char *string)
416 {
417  char *value = NULL;
418 
419  while (*string && !value)
420  {
421  while (*string == ' ')
422  string++;
423  if (!*string)
424  break; /* ready */
425  string = parse_dn_part_for_CN (string, &value);
426  if (!string)
427  goto failure;
428  while (*string == ' ')
429  string++;
430  if (*string && *string != ',' && *string != ';' && *string != '+')
431  goto failure; /* Invalid delimiter. */
432  if (*string == '+')
433  goto failure; /* A multivalued CN is not supported. */
434  if (*string)
435  string++;
436  }
437  return value;
438 
439  failure:
440  g_free (value);
441  return NULL;
442 }
443 
444 
445 /* Given a CERT object, build an array with all hostnames identified
446  by the certifciate. */
447 static tree_cell *
448 build_hostname_list (ksba_cert_t cert)
449 {
450  tree_cell *retc;
451  char *name, *value;
452  int arridx;
453  int idx;
454  nasl_array *a;
455  anon_nasl_var v;
456 
457  name = ksba_cert_get_subject (cert, 0);
458  if (!name)
459  return NULL; /* No valid subject. */
460 
461  retc = alloc_tree_cell (0, NULL);
462  retc->type = DYN_ARRAY;
463  retc->x.ref_val = a = g_malloc0 (sizeof *a);
464  arridx = 0;
465 
466  value = parse_dn_for_CN (name);
467  ksba_free (name);
468 
469  /* Add the CN to the array even if it doesn't look like a hostname. */
470  if (value)
471  {
472  memset (&v, 0, sizeof v);
473  v.var_type = VAR2_DATA;
474  v.v.v_str.s_val = (unsigned char*)value;
475  v.v.v_str.s_siz = strlen (value);
476  add_var_to_list (a, arridx++, &v);
477  }
478  g_free (value);
479  value = NULL;
480 
481  for (idx=1; (name = ksba_cert_get_subject (cert, idx)); idx++)
482  {
483  /* Poor man's s-expression parser. Despite it simple code, it
484  is correct in this case because ksba will always return a
485  valid s-expression. */
486  if (*name == '(' && name[1] == '8' && name[2] == ':'
487  && !memcmp (name+3, "dns-name", 8))
488  {
489  char *endp;
490  unsigned long n = strtoul (name+11, &endp, 10);
491 
492  g_assert (*endp == ':');
493  endp++;
494  memset (&v, 0, sizeof v);
495  v.var_type = VAR2_DATA;
496  v.v.v_str.s_val = (unsigned char*)endp;
497  v.v.v_str.s_siz = n;
498  add_var_to_list (a, arridx++, &v);
499  }
500  ksba_free (name);
501  }
502 
503  return retc;
504 }
505 
510 static tree_cell *
511 make_hexstring (const void *buffer, size_t length)
512 {
513  const unsigned char *s;
514  tree_cell *retc;
515  char *p;
516 
517  retc = alloc_typed_cell (CONST_STR);
518  retc->size = length*2;
519  retc->x.str_val = p = g_malloc0 (length*2 + 1);
520 
521  for (s = buffer; length; length--, s++)
522  {
523  *p++ = tohex ((*s>>4)&15);
524  *p++ = tohex (*s&15);
525  }
526  *p = 0;
527 
528  return retc;
529 }
530 
531 
532 
542 static tree_cell *
543 get_fingerprint (ksba_cert_t cert, int algo)
544 {
545  int dlen;
546  const unsigned char *der;
547  size_t derlen;
548  unsigned char digest[32];
549 
550  dlen = gcry_md_get_algo_dlen (algo);
551  if (dlen != 20 && dlen != 32)
552  return NULL; /* We only support SHA-1 and SHA-256. */
553 
554  der = ksba_cert_get_image (cert, &derlen);
555  if (!der)
556  return NULL;
557  gcry_md_hash_buffer (algo, digest, der, derlen);
558 
559  return make_hexstring (digest, dlen);
560 }
561 
562 /*
563  * @brief Return algorithm name from its OID.
564  *
565  * param[in] oid Algorithm ID.
566  *
567  * @return Algorithm name or NULL.
568  */
569 static const char *
570 get_oid_name (const char *oid)
571 {
572  /* Initial list from Wireshark. See epan/dissectors/packet-pkcs1.c */
573  if (!strcmp ("1.2.840.10040.4.1", oid))
574  return "id-dsa";
575  else if (!strcmp ("1.2.840.10046.2.1", oid))
576  return "dhpublicnumber";
577  else if (!strcmp ("2.16.840.1.101.2.1.1.22", oid))
578  return "id-keyExchangeAlgorithm";
579  else if (!strcmp ("1.2.840.10045.2.1", oid))
580  return "id-ecPublicKey";
581  else if (!strcmp ("1.3.132.1.12", oid))
582  return "id-ecDH";
583  else if (!strcmp ("1.2.840.10045.2.13", oid))
584  return "id-ecMQV";
585  else if (!strcmp ("1.2.840.113549.1.1.10", oid))
586  return "id-RSASSA-PSS";
587  else if (!strcmp ("1.2.840.113549.1.1.11", oid))
588  return "sha256WithRSAEncryption";
589  else if (!strcmp ("1.2.840.113549.1.1.12", oid))
590  return "sha384WithRSAEncryption";
591  else if (!strcmp ("1.2.840.113549.1.1.13", oid))
592  return "sha512WithRSAEncryption";
593  else if (!strcmp ("1.2.840.113549.1.1.14", oid))
594  return "sha224WithRSAEncryption";
595  else if (!strcmp ("1.2.840.113549.1.1.8", oid))
596  return "id-mgf1";
597  else if (!strcmp ("1.2.840.113549.2.2", oid))
598  return "md2";
599  else if (!strcmp ("1.2.840.113549.2.4", oid))
600  return "md4";
601  else if (!strcmp ("1.2.840.113549.2.5", oid))
602  return "md5";
603  else if (!strcmp ("1.2.840.113549.1.1.1", oid))
604  return "rsaEncryption";
605  else if (!strcmp ("1.2.840.113549.1.1.2", oid))
606  return "md2WithRSAEncryption";
607  else if (!strcmp ("1.2.840.113549.1.1.3", oid))
608  return "md4WithRSAEncryption";
609  else if (!strcmp ("1.2.840.113549.1.1.4", oid))
610  return "md5WithRSAEncryption";
611  else if (!strcmp ("1.2.840.113549.1.1.5", oid))
612  return "sha1WithRSAEncryption";
613  else if (!strcmp ("1.2.840.113549.1.1.6", oid))
614  return "rsaOAEPEncryptionSET";
615  else if (!strcmp ("1.2.840.10045.3.1.1", oid))
616  return "secp192r1";
617  else if (!strcmp ("1.3.132.0.1", oid))
618  return "sect163k1";
619  else if (!strcmp ("1.3.132.0.15", oid))
620  return "sect163r2";
621  else if (!strcmp ("1.3.132.0.33", oid))
622  return "secp224r1";
623  else if (!strcmp ("1.3.132.0.26", oid))
624  return "sect233k1";
625  else if (!strcmp ("1.3.132.0.27", oid))
626  return "sect233r1";
627  else if (!strcmp ("1.2.840.10045.3.1.7", oid))
628  return "secp256r1";
629  else if (!strcmp ("1.3.132.0.16", oid))
630  return "sect283k1";
631  else if (!strcmp ("1.3.132.0.17", oid))
632  return "sect283r1";
633  else if (!strcmp ("1.3.132.0.34", oid))
634  return "secp384r1";
635  else if (!strcmp ("1.3.132.0.36", oid))
636  return "sect409k1";
637  else if (!strcmp ("1.3.132.0.37", oid))
638  return "sect409r1";
639  else if (!strcmp ("1.3.132.0.35", oid))
640  return "sect521r1";
641  else if (!strcmp ("1.3.132.0.38", oid))
642  return "sect571k1";
643  else if (!strcmp ("1.3.132.0.39", oid))
644  return "sect571r1";
645  else
646  return NULL;
647 }
648 
655 static tree_cell *
656 get_name (const char *string)
657 {
658  tree_cell *retc;
659 
660  if (*string == '(')
661  {
662  /* This is an s-expression in canonical format. We convert it
663  to advanced format. */
664  gcry_sexp_t sexp;
665  size_t len;
666  char *buffer;
667 
668  len = gcry_sexp_canon_len ((const unsigned char*)string, 0, NULL, NULL);
669  if (gcry_sexp_sscan (&sexp, NULL, string, len))
670  return NULL; /* Invalid encoding. */
671  len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
672  g_assert (len);
673  buffer = g_malloc0 (len);
674  len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buffer, len);
675  g_assert (len);
676  len = strlen (buffer);
677  /* Strip a trailing linefeed. */
678  if (len && buffer[len-1] == '\n')
679  buffer[--len] = 0;
680  gcry_sexp_release (sexp);
681  retc = alloc_typed_cell (CONST_STR);
682  retc->x.str_val = buffer;
683  retc->size = len;
684  }
685  else
686  {
687  /* RFC-2822 style mailboxes or RFC-2253 strings are returned
688  verbatim. */
689  retc = alloc_typed_cell (CONST_STR);
690  retc->x.str_val = g_strdup (string);
691  retc->size = strlen (retc->x.str_val);
692  }
693 
694  return retc;
695 }
696 
764 tree_cell *
766 {
767  int object_id;
768  object_desc_t obj;
769  const char *command;
770  int cmdidx;
771  char *result;
772  ksba_isotime_t isotime;
773  ksba_sexp_t sexp;
774  tree_cell *retc;
775 
776  object_id = get_int_var_by_num (lexic, 0, -1);
777  if (object_id <= 0)
778  {
779  log_legacy_write ("Bad object id %d passed to cert_query", object_id);
780  return NULL;
781  }
782 
783  for (obj = object_list; obj; obj = obj->next)
784  if (obj->object_id == object_id)
785  break;
786  if (!obj)
787  {
788  log_legacy_write ("Unused object id %d passed to cert_query", object_id);
789  return NULL;
790  }
791 
792  /* Check that the command is a string. */
793  command = get_str_var_by_num (lexic, 1);
794  if (!command || get_var_type_by_num (lexic, 1) != VAR2_STRING)
795  {
796  log_legacy_write ("No proper command passed to cert_query");
797  return NULL;
798  }
799 
800  /* Get the index which defaults to 0. */
801  cmdidx = get_int_local_var_by_name (lexic, "idx", 0);
802 
803  /* Command dispatcher. */
804  retc = NULL;
805  if (!strcmp (command, "serial"))
806  {
807  const unsigned char *s;
808  char *endp;
809  unsigned long n;
810 
811  sexp = ksba_cert_get_serial (obj->cert);
812  s = sexp;
813  if (!s || *s != '(')
814  return NULL; /* Ooops. */
815  s++;
816  n = strtoul ((const char*)s, &endp, 10);
817  s = (const unsigned char *)endp;
818  if (*s == ':')
819  {
820  s++;
821  retc = make_hexstring (s, n);
822  }
823  ksba_free (sexp);
824  }
825  else if (!strcmp (command, "issuer"))
826  {
827  result = ksba_cert_get_issuer (obj->cert, cmdidx);
828  if (!result)
829  return NULL;
830 
831  retc = get_name (result);
832  ksba_free (result);
833  }
834  else if (!strcmp (command, "subject"))
835  {
836  result = ksba_cert_get_subject (obj->cert, cmdidx);
837  if (!result)
838  return NULL;
839 
840  retc = get_name (result);
841  ksba_free (result);
842  }
843  else if (!strcmp (command, "not-before"))
844  {
845  ksba_cert_get_validity (obj->cert, 0, isotime);
846  retc = alloc_typed_cell (CONST_STR);
847  retc->x.str_val = g_strdup (isotime);
848  retc->size = strlen (isotime);
849  }
850  else if (!strcmp (command, "not-after"))
851  {
852  ksba_cert_get_validity (obj->cert, 1, isotime);
853  retc = alloc_typed_cell (CONST_STR);
854  retc->x.str_val = g_strdup (isotime);
855  retc->size = strlen (isotime);
856  }
857  else if (!strcmp (command, "fpr-sha-256"))
858  {
859  retc = get_fingerprint (obj->cert, GCRY_MD_SHA256);
860  }
861  else if (!strcmp (command, "fpr-sha-1"))
862  {
863  retc = get_fingerprint (obj->cert, GCRY_MD_SHA1);
864  }
865  else if (!strcmp (command, "all"))
866  {
867  /* FIXME */
868  }
869  else if (!strcmp (command, "hostnames"))
870  {
871  retc = build_hostname_list (obj->cert);
872  }
873  else if (!strcmp (command, "image"))
874  {
875  const unsigned char *der;
876  size_t derlen;
877 
878  der = ksba_cert_get_image (obj->cert, &derlen);
879  if (der && derlen)
880  {
881  retc = alloc_typed_cell (CONST_DATA);
882  retc->size = derlen;
883  retc->x.str_val = g_malloc0 (derlen);
884  memcpy (retc->x.str_val, der, derlen);
885  }
886  }
887  else if (!strcmp (command, "algorithm-name"))
888  {
889  const char *digest = ksba_cert_get_digest_algo (obj->cert);
890  if (digest)
891  {
892  const char *name = get_oid_name (digest);
893  if (!name)
894  name = digest;
895  retc = alloc_typed_cell (CONST_STR);
896  retc->x.str_val = g_strdup (name);
897  retc->size = strlen (name);
898  }
899  }
900  else if (!strcmp (command, "modulus"))
901  {
902  gnutls_datum_t datum, m, e;
903  gnutls_x509_crt_t cert = NULL;
904 
905  datum.data = (void *) ksba_cert_get_image (obj->cert, (size_t *)
906  &datum.size);
907  if (!datum.data)
908  return NULL;
909  if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS)
910  return NULL;
911  if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER)
912  != GNUTLS_E_SUCCESS)
913  return NULL;
914  if (gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e) != GNUTLS_E_SUCCESS)
915  return NULL;
916 
917  retc = alloc_typed_cell (CONST_DATA);
918  retc->size = m.size;
919  retc->x.str_val = g_memdup (m.data, m.size);
920  gnutls_free (m.data);
921  gnutls_free (e.data);
922  gnutls_x509_crt_deinit (cert);
923  }
924  else if (!strcmp (command, "exponent"))
925  {
926  gnutls_datum_t datum, m, e;
927  gnutls_x509_crt_t cert = NULL;
928 
929  datum.data = (void *) ksba_cert_get_image (obj->cert, (size_t *)
930  &datum.size);
931  if (!datum.data)
932  return NULL;
933  if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS)
934  return NULL;
935  if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER)
936  != GNUTLS_E_SUCCESS)
937  return NULL;
938  if (gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e) != GNUTLS_E_SUCCESS)
939  return NULL;
940 
941  retc = alloc_typed_cell (CONST_DATA);
942  retc->size = e.size;
943  retc->x.str_val = g_memdup (e.data, e.size);
944  gnutls_free (m.data);
945  gnutls_free (e.data);
946  gnutls_x509_crt_deinit (cert);
947  }
948  else if (!strcmp (command, "key-size"))
949  {
950  gnutls_datum_t datum;
951  gnutls_x509_crt_t cert = NULL;
952  unsigned int bits = 0;
953 
954  datum.data = (void *) ksba_cert_get_image (obj->cert, (size_t *)
955  &datum.size);
956  if (!datum.data)
957  return NULL;
958  if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS)
959  return NULL;
960  if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER)
961  != GNUTLS_E_SUCCESS)
962  return NULL;
963  gnutls_x509_crt_get_pk_algorithm (cert, &bits);
964  gnutls_free (datum.data);
965  gnutls_x509_crt_deinit (cert);
966 
967  retc = alloc_typed_cell (CONST_INT);
968  retc->x.i_val = bits;
969  }
970  else
971  {
972  log_legacy_write ("Unknown command '%s' passed to cert_query", command);
973  }
974 
975  return retc;
976 }
977 
978 
979 #endif /* HAVE_LIBKSBA */
Protos and data structures for CERT functions used by NASL scripts.
#define FAKE_CELL
Definition: nasl_tree.h:120
#define err(x)
short type
Definition: nasl_tree.h:107
union st_a_nasl_var::@9 v
char * str_val
Definition: nasl_tree.h:113
const char * oid
void * ref_val
Definition: nasl_tree.h:115
nasl_string_t v_str
Definition: nasl_var.h:60
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
long int get_int_local_var_by_name(lex_ctxt *, const char *, int)
Definition: nasl_var.c:1240
struct object_desc_s * object_desc_t
Definition: nasl_cert.c:99
union TC::@7 x
int add_var_to_list(nasl_array *a, int i, const anon_nasl_var *v)
Definition: nasl_var.c:1403
tree_cell * nasl_cert_open(lex_ctxt *lexic)
Create a certificate object.
Definition: nasl_cert.c:176
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:53
int var_type
Definition: nasl_var.h:54
#define hexdigitp(a)
Definition: nasl_cert.c:67
Definition: nasl_tree.h:105
int get_var_size_by_num(lex_ctxt *, int)
Definition: nasl_var.c:1305
#define xtoi_2(p)
Definition: nasl_cert.c:77
const char * name
Definition: nasl_init.c:524
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition: nasl_var.c:1226
char * get_str_var_by_num(lex_ctxt *, int)
Definition: nasl_var.c:1248
long int i_val
Definition: nasl_tree.h:114
object_desc_t next
Definition: nasl_cert.c:102
#define tohex(n)
Definition: nasl_cert.c:81
tree_cell * alloc_tree_cell(int lnb, char *s)
Definition: nasl_tree.c:37
gchar * string
tree_cell * nasl_cert_close(lex_ctxt *lexic)
Release a certificate object.
Definition: nasl_cert.c:264
unsigned char * s_val
Definition: nasl_var.h:35
ksba_cert_t cert
Definition: nasl_cert.c:104
tree_cell * nasl_cert_query(lex_ctxt *lexic)
Query a certificate object.
Definition: nasl_cert.c:765
int get_var_type_by_num(lex_ctxt *, int)
Returns NASL variable/cell type, VAR2_UNDEF if value is NULL.
Definition: nasl_var.c:1315
int size
Definition: nasl_tree.h:110