OpenVAS Scanner 23.32.3
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
14
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
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 */
84struct object_desc_s;
85typedef struct object_desc_s *object_desc_t;
86struct 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. */
94static object_desc_t object_list;
95
96/* Return the next object id. */
97static int
98next_object_id (void)
99{
100 static int last;
101 static int wrapped;
102
103again:
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
158tree_cell *
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. */
223 retc->x.i_val = obj->object_id;
224 return retc;
225}
226
244tree_cell *
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. */
280static const char *
281parse_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. */
392static char *
393parse_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
417failure:
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. */
424static tree_cell *
425build_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;
433
434 name = ksba_cert_get_subject (cert, 0);
435 if (!name)
436 return NULL; /* No valid subject. */
437
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);
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);
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
490static tree_cell *
491make_hexstring (const void *buffer, size_t length)
492{
493 const unsigned char *s;
494 tree_cell *retc;
495 char *p;
496
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
520static tree_cell *
521get_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 */
547static const char *
548get_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
657static tree_cell *
658get_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);
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. */
694 retc->x.str_val = g_strdup (string);
695 retc->size = strlen (retc->x.str_val);
696 }
697
698 return retc;
699}
700
789tree_cell *
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);
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);
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 {
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;
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");
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
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
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 */
const char * oid
Protos and data structures for CERT functions used by NASL scripts.
tree_cell * nasl_cert_open(lex_ctxt *lexic)
tree_cell * nasl_cert_query(lex_ctxt *lexic)
tree_cell * nasl_cert_close(lex_ctxt *lexic)
const char * name
Definition nasl_init.c:439
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
struct struct_lex_ctxt lex_ctxt
int get_var_size_by_num(lex_ctxt *, int)
Definition nasl_var.c:1145
char * get_str_var_by_num(lex_ctxt *, int)
Definition nasl_var.c:1108
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition nasl_var.c:1094
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition nasl_var.c:1101
uint8_t len
u_short length
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_DATA
Definition nasl_tree.h:82
@ DYN_ARRAY
Definition nasl_tree.h:90
@ CONST_STR
Definition nasl_tree.h:80
@ CONST_INT
Definition nasl_tree.h:79
struct TC tree_cell
#define FAKE_CELL
Definition nasl_tree.h:110
int add_var_to_list(nasl_array *a, int i, const anon_nasl_var *v)
Definition nasl_var.c:1245
struct st_a_nasl_var anon_nasl_var
struct st_nasl_array nasl_array
@ VAR2_STRING
Definition nasl_var.h:17
@ VAR2_DATA
Definition nasl_var.h:18
int size
Definition nasl_tree.h:99
long int i_val
Definition nasl_tree.h:104
union TC::@332262321161220155002104006201360276211317150140 x
char * str_val
Definition nasl_tree.h:103
void * ref_val
Definition nasl_tree.h:105
nasl_string_t v_str
Definition nasl_var.h:47
union st_a_nasl_var::@154137074032032170165360023270032033276061363156 v
unsigned char * s_val
Definition nasl_var.h:26
Define a string struct for storing the response.