diff options
Diffstat (limited to 'sm/certdump.c')
-rw-r--r-- | sm/certdump.c | 696 |
1 files changed, 0 insertions, 696 deletions
diff --git a/sm/certdump.c b/sm/certdump.c deleted file mode 100644 index 21581dca3..000000000 --- a/sm/certdump.c +++ /dev/null @@ -1,696 +0,0 @@ -/* certdump.c - Dump a certificate for debugging - * Copyright (C) 2001, 2004 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <time.h> -#include <assert.h> -#ifdef HAVE_LOCALE_H -#include <locale.h> -#endif -#ifdef HAVE_LANGINFO_CODESET -#include <langinfo.h> -#endif - -#include "gpgsm.h" -#include <gcrypt.h> -#include <ksba.h> - -#include "keydb.h" -#include "i18n.h" - -struct dn_array_s { - char *key; - char *value; - int multivalued; - int done; -}; - - -/* print the first element of an S-Expression */ -void -gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - - if (!p) - fputs (_("none"), fp); - else if (*p != '(') - fputs ("[Internal error - not an S-expression]", fp); - else - { - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - fputs ("[Internal Error - invalid S-expression]", fp); - else - { - for (p++; n; n--, p++) - fprintf (fp, "%02X", *p); - } - } -} - - -void -gpgsm_dump_serial (ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - - if (!p) - log_printf ("none"); - else if (*p != '(') - log_printf ("ERROR - not an S-expression"); - else - { - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - log_printf ("ERROR - invalid S-expression"); - else - { - for (p++; n; n--, p++) - log_printf ("%02X", *p); - } - } -} - - -char * -gpgsm_format_serial (ksba_const_sexp_t p) -{ - unsigned long n; - char *endp; - char *buffer; - int i; - - if (!p) - return NULL; - - if (*p != '(') - BUG (); /* Not a valid S-expression. */ - - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p!=':') - BUG (); /* Not a valid S-expression. */ - p++; - - buffer = xtrymalloc (n*2+1); - if (buffer) - { - for (i=0; n; n--, p++, i+=2) - sprintf (buffer+i, "%02X", *(unsigned char *)p); - buffer[i] = 0; - } - return buffer; -} - - - - -void -gpgsm_print_time (FILE *fp, ksba_isotime_t t) -{ - if (!t || !*t) - fputs (_("none"), fp); - else - fprintf (fp, "%.4s-%.2s-%.2s %.2s:%.2s:%s", t, t+4, t+6, t+9, t+11, t+13); -} - -void -gpgsm_dump_time (ksba_isotime_t t) -{ - if (!t || !*t) - log_printf (_("[none]")); - else - log_printf ("%.4s-%.2s-%.2s %.2s:%.2s:%s", - t, t+4, t+6, t+9, t+11, t+13); -} - - - - -void -gpgsm_dump_string (const char *string) -{ - - if (!string) - log_printf ("[error]"); - else - { - const unsigned char *s; - - for (s=string; *s; s++) - { - if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) - break; - } - if (!*s && *string != '[') - log_printf ("%s", string); - else - { - log_printf ( "[ "); - log_printhex (NULL, string, strlen (string)); - log_printf ( " ]"); - } - } -} - - -/* This simple dump function is mainly used for debugging purposes. */ -void -gpgsm_dump_cert (const char *text, ksba_cert_t cert) -{ - ksba_sexp_t sexp; - unsigned char *p; - char *dn; - ksba_isotime_t t; - - log_debug ("BEGIN Certificate `%s':\n", text? text:""); - if (cert) - { - sexp = ksba_cert_get_serial (cert); - log_debug (" serial: "); - gpgsm_dump_serial (sexp); - ksba_free (sexp); - log_printf ("\n"); - - ksba_cert_get_validity (cert, 0, t); - log_debug (" notBefore: "); - gpgsm_dump_time (t); - log_printf ("\n"); - ksba_cert_get_validity (cert, 1, t); - log_debug (" notAfter: "); - gpgsm_dump_time (t); - log_printf ("\n"); - - dn = ksba_cert_get_issuer (cert, 0); - log_debug (" issuer: "); - gpgsm_dump_string (dn); - ksba_free (dn); - log_printf ("\n"); - - dn = ksba_cert_get_subject (cert, 0); - log_debug (" subject: "); - gpgsm_dump_string (dn); - ksba_free (dn); - log_printf ("\n"); - - log_debug (" hash algo: %s\n", ksba_cert_get_digest_algo (cert)); - - p = gpgsm_get_fingerprint_string (cert, 0); - log_debug (" SHA1 Fingerprint: %s\n", p); - xfree (p); - } - log_debug ("END Certificate\n"); -} - - - -/* helper for the rfc2253 string parser */ -static const unsigned char * -parse_dn_part (struct dn_array_s *array, const unsigned char *string) -{ - static struct { - const char *label; - const char *oid; - } label_map[] = { - /* Warning: When adding new labels, make sure that the buffer - below we be allocated large enough. */ - {"EMail", "1.2.840.113549.1.9.1" }, - {"T", "2.5.4.12" }, - {"GN", "2.5.4.42" }, - {"SN", "2.5.4.4" }, - {"NameDistinguisher", "0.2.262.1.10.7.20"}, - {"ADDR", "2.5.4.16" }, - {"BC", "2.5.4.15" }, - {"D", "2.5.4.13" }, - {"PostalCode", "2.5.4.17" }, - {"Pseudo", "2.5.4.65" }, - {"SerialNumber", "2.5.4.5" }, - {NULL, NULL} - }; - const unsigned char *s, *s1; - size_t n; - unsigned char *p; - int i; - - /* Parse attributeType */ - for (s = string+1; *s && *s != '='; s++) - ; - if (!*s) - return NULL; /* error */ - n = s - string; - if (!n) - return NULL; /* empty key */ - - /* We need to allocate a few bytes more due to the possible mapping - from the shorter OID to the longer label. */ - array->key = p = xtrymalloc (n+10); - if (!array->key) - return NULL; - memcpy (p, string, n); - p[n] = 0; - trim_trailing_spaces (p); - - if (digitp (p)) - { - for (i=0; label_map[i].label; i++ ) - if ( !strcmp (p, label_map[i].oid) ) - { - strcpy (p, label_map[i].label); - break; - } - } - string = s + 1; - - if (*string == '#') - { /* hexstring */ - string++; - for (s=string; hexdigitp (s); s++) - s++; - n = s - string; - if (!n || (n & 1)) - return NULL; /* Empty or odd number of digits. */ - n /= 2; - array->value = p = xtrymalloc (n+1); - if (!p) - return NULL; - for (s1=string; n; s1 += 2, n--, p++) - { - *p = xtoi_2 (s1); - if (!*p) - *p = 0x01; /* Better print a wrong value than truncating - the string. */ - } - *p = 0; - } - else - { /* regular v3 quoted string */ - for (n=0, s=string; *s; s++) - { - if (*s == '\\') - { /* pair */ - s++; - if (*s == ',' || *s == '=' || *s == '+' - || *s == '<' || *s == '>' || *s == '#' || *s == ';' - || *s == '\\' || *s == '\"' || *s == ' ') - n++; - else if (hexdigitp (s) && hexdigitp (s+1)) - { - s++; - n++; - } - else - return NULL; /* invalid escape sequence */ - } - else if (*s == '\"') - return NULL; /* invalid encoding */ - else if (*s == ',' || *s == '=' || *s == '+' - || *s == '<' || *s == '>' || *s == '#' || *s == ';' ) - break; - else - n++; - } - - array->value = p = xtrymalloc (n+1); - if (!p) - return NULL; - for (s=string; n; s++, n--) - { - if (*s == '\\') - { - s++; - if (hexdigitp (s)) - { - *p++ = xtoi_2 (s); - s++; - } - else - *p++ = *s; - } - else - *p++ = *s; - } - *p = 0; - } - return s; -} - - -/* Parse a DN and return an array-ized one. This is not a validating - parser and it does not support any old-stylish syntax; KSBA is - expected to return only rfc2253 compatible strings. */ -static struct dn_array_s * -parse_dn (const unsigned char *string) -{ - struct dn_array_s *array; - size_t arrayidx, arraysize; - int i; - - arraysize = 7; /* C,ST,L,O,OU,CN,email */ - arrayidx = 0; - array = xtrymalloc ((arraysize+1) * sizeof *array); - if (!array) - return NULL; - while (*string) - { - while (*string == ' ') - string++; - if (!*string) - break; /* ready */ - if (arrayidx >= arraysize) - { - struct dn_array_s *a2; - - arraysize += 5; - a2 = xtryrealloc (array, (arraysize+1) * sizeof *array); - if (!a2) - goto failure; - array = a2; - } - array[arrayidx].key = NULL; - array[arrayidx].value = NULL; - string = parse_dn_part (array+arrayidx, string); - if (!string) - goto failure; - while (*string == ' ') - string++; - array[arrayidx].multivalued = (*string == '+'); - array[arrayidx].done = 0; - arrayidx++; - if (*string && *string != ',' && *string != ';' && *string != '+') - goto failure; /* invalid delimiter */ - if (*string) - string++; - } - array[arrayidx].key = NULL; - array[arrayidx].value = NULL; - return array; - - failure: - for (i=0; i < arrayidx; i++) - { - xfree (array[i].key); - xfree (array[i].value); - } - xfree (array); - return NULL; -} - - -static void -print_dn_part (FILE *fp, struct dn_array_s *dn, const char *key) -{ - struct dn_array_s *first_dn = dn; - - for (; dn->key; dn++) - { - if (!dn->done && !strcmp (dn->key, key)) - { - /* Forward to the last multi-valued RDN, so that we can - print them all in reverse in the correct order. Note - that this overrides the the standard sequence but that - seems to a reasonable thing to do with multi-valued - RDNs. */ - while (dn->multivalued && dn[1].key) - dn++; - next: - if (!dn->done && dn->value && *dn->value) - { - fprintf (fp, "/%s=", dn->key); - print_sanitized_utf8_string (fp, dn->value, '/'); - } - dn->done = 1; - if (dn > first_dn && dn[-1].multivalued) - { - dn--; - goto next; - } - } - } -} - -/* Print all parts of a DN in a "standard" sequence. We first print - all the known parts, followed by the uncommon ones */ -static void -print_dn_parts (FILE *fp, struct dn_array_s *dn) -{ - const char *stdpart[] = { - "CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL - }; - int i; - - for (i=0; stdpart[i]; i++) - print_dn_part (fp, dn, stdpart[i]); - - /* Now print the rest without any specific ordering */ - for (; dn->key; dn++) - print_dn_part (fp, dn, dn->key); -} - - - -void -gpgsm_print_name (FILE *fp, const char *name) -{ - const unsigned char *s; - int i; - - s = name; - if (!s) - { - fputs (_("[Error - No name]"), fp); - } - else if (*s == '<') - { - const unsigned char *s2 = strchr (s+1, '>'); - if (s2) - print_sanitized_utf8_buffer (fp, s + 1, s2 - s - 1, 0); - } - else if (*s == '(') - fputs (_("[Error - unknown encoding]"), fp); - else if (!((*s >= '0' && *s < '9') - || (*s >= 'A' && *s <= 'Z') - || (*s >= 'a' && *s <= 'z'))) - fputs (_("[Error - invalid encoding]"), fp); - else - { - struct dn_array_s *dn = parse_dn (s); - if (!dn) - fputs (_("[Error - invalid DN]"), fp); - else - { - print_dn_parts (fp, dn); - for (i=0; dn[i].key; i++) - { - xfree (dn[i].key); - xfree (dn[i].value); - } - xfree (dn); - } - } -} - - - -/* A cookie structure used for the memory stream. */ -struct format_name_cookie -{ - char *buffer; /* Malloced buffer with the data to deliver. */ - size_t size; /* Allocated size of this buffer. */ - size_t len; /* strlen (buffer). */ - int error; /* system error code if any. */ -}; - -/* The writer function for the memory stream. */ -static int -format_name_writer (void *cookie, const char *buffer, size_t size) -{ - struct format_name_cookie *c = cookie; - char *p; - - if (c->buffer) - p = xtryrealloc (c->buffer, c->size + size + 1); - else - p = xtrymalloc (size + 1); - if (!p) - { - c->error = errno; - xfree (c->buffer); - errno = c->error; - return -1; - } - c->buffer = p; - memcpy (p + c->len, buffer, size); - c->len += size; - p[c->len] = 0; /* Terminate string. */ - - return size; -} - -/* Format NAME which is expected to be in rfc2253 format into a better - human readable format. Caller must free the returned string. NULL - is returned in case of an error. */ -char * -gpgsm_format_name (const char *name) -{ -#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) - FILE *fp; - struct format_name_cookie cookie; - - memset (&cookie, 0, sizeof cookie); - -#ifdef HAVE_FOPENCOOKIE - { - cookie_io_functions_t io = { NULL }; - io.write = format_name_writer; - - fp = fopencookie (&cookie, "w", io); - } -#else /*!HAVE_FOPENCOOKIE*/ - { - fp = funopen (&cookie, NULL, format_name_writer, NULL, NULL); - } -#endif /*!HAVE_FOPENCOOKIE*/ - if (!fp) - { - int save_errno = errno; - log_error ("error creating memory stream: %s\n", strerror (errno)); - errno = save_errno; - return NULL; - } - gpgsm_print_name (fp, name); - fclose (fp); - if (cookie.error || !cookie.buffer) - { - xfree (cookie.buffer); - errno = cookie.error; - return NULL; - } - return cookie.buffer; -#else /* No fun - use the name verbatim. */ - return xtrystrdup (name); -#endif /* No fun. */ -} - - -/* Create a key description for the CERT, this may be passed to the - pinentry. The caller must free the returned string. NULL may be - returned on error. */ -char * -gpgsm_format_keydesc (ksba_cert_t cert) -{ - int rc; - char *name, *subject, *buffer, *p; - const char *s; - ksba_isotime_t t; - char created[20]; - char *sn; - ksba_sexp_t sexp; - char *orig_codeset = NULL; - - name = ksba_cert_get_subject (cert, 0); - subject = name? gpgsm_format_name (name) : NULL; - ksba_free (name); name = NULL; - - sexp = ksba_cert_get_serial (cert); - sn = sexp? gpgsm_format_serial (sexp) : NULL; - ksba_free (sexp); - - ksba_cert_get_validity (cert, 0, t); - if (t && *t) - sprintf (created, "%.4s-%.2s-%.2s", t, t+4, t+6); - else - *created = 0; - - -#ifdef ENABLE_NLS - /* The Assuan agent protol requires us to transmit utf-8 strings */ - orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL); -#ifdef HAVE_LANGINFO_CODESET - if (!orig_codeset) - orig_codeset = nl_langinfo (CODESET); -#endif - if (orig_codeset) - { /* We only switch when we are able to restore the codeset later. */ - orig_codeset = xstrdup (orig_codeset); - if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8")) - orig_codeset = NULL; - } -#endif - - - rc = asprintf (&name, - _("Please enter the passphrase to unlock the" - " secret key for:\n" - "\"%s\"\n" - "S/N %s, ID %08lX, created %s" ), - subject? subject:"?", - sn? sn: "?", - gpgsm_get_short_fingerprint (cert), - created); - -#ifdef ENABLE_NLS - if (orig_codeset) - bind_textdomain_codeset (PACKAGE_GT, orig_codeset); -#endif - xfree (orig_codeset); - - if (rc < 0) - { - int save_errno = errno; - xfree (subject); - xfree (sn); - errno = save_errno; - return NULL; - } - - xfree (subject); - xfree (sn); - - buffer = p = xtrymalloc (strlen (name) * 3 + 1); - for (s=name; *s; s++) - { - if (*s < ' ' || *s == '+') - { - sprintf (p, "%%%02X", *(unsigned char *)s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; - } - *p = 0; - free (name); - - return buffer; -} |