1
1
/* certdump.c - Dump a certificate for debugging
2
* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
2
* Copyright (C) 2001, 2004, 2007 Free Software Foundation, Inc.
4
4
* This file is part of GnuPG.
6
6
* GnuPG is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
8
* the Free Software Foundation; either version 3 of the License, or
9
9
* (at your option) any later version.
11
11
* GnuPG is distributed in the hope that it will be useful,
14
14
* GNU General Public License for more details.
16
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17
* along with this program; if not, see <http://www.gnu.org/licenses/>.
21
20
#include <config.h>
51
/* print the first element of an S-Expression */
59
/* Print the first element of an S-Expression. */
53
gpgsm_print_serial (FILE *fp, ksba_const_sexp_t sn)
61
gpgsm_print_serial (estream_t fp, ksba_const_sexp_t sn)
55
63
const char *p = (const char *)sn;
60
fputs (_("none"), fp);
68
es_fputs (_("none"), fp);
61
69
else if (*p != '(')
62
fputs ("[Internal error - not an S-expression]", fp);
70
es_fputs ("[Internal error - not an S-expression]", fp);
66
74
n = strtoul (p, &endp, 10);
69
fputs ("[Internal Error - invalid S-expression]", fp);
77
es_fputs ("[Internal Error - invalid S-expression]", fp);
72
for (p++; n; n--, p++)
73
fprintf (fp, "%02X", *(const unsigned char*)p);
79
es_write_hexstring (fp, p, n, 0, NULL);
143
gpgsm_print_time (FILE *fp, ksba_isotime_t t)
148
gpgsm_print_time (estream_t fp, ksba_isotime_t t)
146
fputs (_("none"), fp);
151
es_fputs (_("none"), fp);
148
fprintf (fp, "%.4s-%.2s-%.2s %.2s:%.2s:%s", t, t+4, t+6, t+9, t+11, t+13);
153
es_fprintf (fp, "%.4s-%.2s-%.2s %.2s:%.2s:%s",
154
t, t+4, t+6, t+9, t+11, t+13);
152
159
gpgsm_dump_time (ksba_isotime_t t)
247
/* Return a new string holding the format serial number and issuer
248
("#SN/issuer"). No filtering on invalid characters is done.
249
Caller must release the string. On memory failure NULL is
252
gpgsm_format_sn_issuer (ksba_sexp_t sn, const char *issuer)
258
p1 = gpgsm_format_serial (sn);
260
p = xtrystrdup ("[invalid SN]");
263
p = xtrymalloc (strlen (p1) + strlen (issuer) + 2 + 1);
267
strcpy (stpcpy (stpcpy (p+1, p1),"/"), issuer);
273
p = xtrystrdup ("[invalid SN/issuer]");
278
/* Log the certificate's name in "#SN/ISSUERDN" format along with
281
gpgsm_cert_log_name (const char *text, ksba_cert_t cert)
283
log_info ("%s", text? text:"certificate" );
289
p = ksba_cert_get_issuer (cert, 0);
290
sn = ksba_cert_get_serial (cert);
294
gpgsm_dump_serial (sn);
296
gpgsm_dump_string (p);
299
log_printf (" [invalid]");
241
311
/* helper for the rfc2253 string parser */
242
312
static const unsigned char *
338
408
else if (*s == '\"')
339
409
return NULL; /* invalid encoding */
340
410
else if (*s == ',' || *s == '=' || *s == '+'
341
|| *s == '<' || *s == '>' || *s == '#' || *s == ';' )
411
|| *s == '<' || *s == '>' || *s == ';' )
503
/* Print a DN part to STREAM or if STREAM is NULL to FP. */
434
print_dn_part (FILE *fp, struct dn_array_s *dn, const char *key, int translate)
505
print_dn_part (FILE *fp, estream_t stream,
506
struct dn_array_s *dn, const char *key, int translate)
436
508
struct dn_array_s *first_dn = dn;
450
522
if (!dn->done && dn->value && *dn->value)
452
fprintf (fp, "/%s=", dn->key);
454
print_sanitized_utf8_string (fp, dn->value, '/');
526
es_fprintf (stream, "/%s=", dn->key);
528
es_write_sanitized_utf8_buffer (stream, dn->value,
532
es_write_sanitized (stream, dn->value, strlen (dn->value),
456
print_sanitized_string (fp, dn->value, '/');
537
fprintf (fp, "/%s=", dn->key);
539
print_sanitized_utf8_string (fp, dn->value, '/');
541
print_sanitized_string (fp, dn->value, '/');
459
545
if (dn > first_dn && dn[-1].multivalued)
468
554
/* Print all parts of a DN in a "standard" sequence. We first print
469
555
all the known parts, followed by the uncommon ones */
471
print_dn_parts (FILE *fp, struct dn_array_s *dn, int translate)
557
print_dn_parts (FILE *fp, estream_t stream,
558
struct dn_array_s *dn, int translate)
473
560
const char *stdpart[] = {
474
561
"CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL
478
565
for (i=0; stdpart[i]; i++)
479
print_dn_part (fp, dn, stdpart[i], translate);
566
print_dn_part (fp, stream, dn, stdpart[i], translate);
481
568
/* Now print the rest without any specific ordering */
482
569
for (; dn->key; dn++)
483
print_dn_part (fp, dn, dn->key, translate);
570
print_dn_part (fp, stream, dn, dn->key, translate);
529
616
gcry_sexp_release (sexp);
619
/* Print the S-Expression in BUF to extended STREAM, which has a valid
620
length of BUFLEN, as a human readable string in one line to FP. */
622
pretty_es_print_sexp (estream_t fp, const unsigned char *buf, size_t buflen)
628
if ( gcry_sexp_sscan (&sexp, NULL, (const char*)buf, buflen) )
630
es_fputs (_("[Error - invalid encoding]"), fp);
633
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
635
result = xtrymalloc (len);
638
es_fputs (_("[Error - out of core]"), fp);
639
gcry_sexp_release (sexp);
642
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, len);
644
for (p = result; len; len--, p++)
648
if (len > 1) /* Avoid printing the trailing LF. */
649
es_fputs ("\\n", fp);
652
es_fputs ("\\r", fp);
654
es_fputs ("\\v", fp);
656
es_fputs ("\\t", fp);
661
gcry_sexp_release (sexp);
534
668
gpgsm_print_name2 (FILE *fp, const char *name, int translate)
566
700
fputs (_("[Error - invalid DN]"), fp);
569
print_dn_parts (fp, dn, translate);
703
print_dn_parts (fp, NULL, dn, translate);
570
704
for (i=0; dn[i].key; i++)
572
706
xfree (dn[i].key);
722
/* This is avariant of gpgsm_print_name sending it output to an estream. */
724
gpgsm_es_print_name (estream_t fp, const char *name)
726
const unsigned char *s = (const unsigned char *)name;
731
es_fputs (_("[Error - No name]"), fp);
735
const char *s2 = strchr ( (char*)s+1, '>');
738
es_write_sanitized_utf8_buffer (fp, s + 1, s2 - (char*)s - 1,
743
pretty_es_print_sexp (fp, s, gcry_sexp_canon_len (s, 0, NULL, NULL));
745
else if (!((*s >= '0' && *s < '9')
746
|| (*s >= 'A' && *s <= 'Z')
747
|| (*s >= 'a' && *s <= 'z')))
748
es_fputs (_("[Error - invalid encoding]"), fp);
751
struct dn_array_s *dn = parse_dn (s);
754
es_fputs (_("[Error - invalid DN]"), fp);
757
print_dn_parts (NULL, fp, dn, 1);
758
for (i=0; dn[i].key; i++)
771
#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN)
588
772
/* A cookie structure used for the memory stream. */
589
773
struct format_name_cookie
597
781
/* The writer function for the memory stream. */
599
format_name_writer (void *cookie, const char *buffer, size_t size)
782
static my_funopen_hook_ret_t
783
format_name_writer (void *cookie, const char *buffer,
784
my_funopen_hook_size_t size)
601
786
struct format_name_cookie *c = cookie;
610
795
c->error = errno;
611
796
xfree (c->buffer);
612
797
errno = c->error;
798
return (my_funopen_hook_ret_t)(-1);
616
801
memcpy (p + c->len, buffer, size);
618
803
p[c->len] = 0; /* Terminate string. */
805
return (my_funopen_hook_ret_t)size;
807
#endif /*HAVE_FOPENCOOKIE || HAVE_FUNOPEN*/
623
810
/* Format NAME which is expected to be in rfc2253 format into a better
624
811
human readable format. Caller must free the returned string. NULL
864
/* Return fingerprint and a percent escaped name in a human readable
865
format suitable for status messages like GOODSIG. May return NULL
866
on error (out of core). */
868
gpgsm_fpr_and_name_for_status (ksba_cert_t cert)
870
char *fpr, *name, *p;
873
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
877
name = ksba_cert_get_subject (cert, 0);
884
p = gpgsm_format_name2 (name, 0);
893
buffer = xtrymalloc (strlen (fpr) + 1 + 3*strlen (name) + 1);
898
p = stpcpy (stpcpy (buffer, fpr), " ");
899
for (s = name; *s; s++)
903
sprintf (p, "%%%02X", *(const unsigned char*)s);
677
917
/* Create a key description for the CERT, this may be passed to the
678
918
pinentry. The caller must free the returned string. NULL may be
679
919
returned on error. */
698
939
ksba_free (sexp);
700
941
ksba_cert_get_validity (cert, 0, t);
702
943
sprintf (created, "%.4s-%.2s-%.2s", t, t+4, t+6);
708
/* The Assuan agent protocol requires us to transmit utf-8 strings */
709
orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL);
710
#ifdef HAVE_LANGINFO_CODESET
712
orig_codeset = nl_langinfo (CODESET);
715
{ /* We only switch when we are able to restore the codeset later.
716
Note that bind_textdomain_codeset does only return on memory
717
errors but not if a codeset is not available. Thus we don't
718
bother printing a diagnostic here. */
719
orig_codeset = xstrdup (orig_codeset);
720
if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8"))
946
ksba_cert_get_validity (cert, 1, t);
948
sprintf (expires, "%.4s-%.2s-%.2s", t, t+4, t+6);
952
orig_codeset = i18n_switchto_utf8 ();
726
954
rc = asprintf (&name,
727
955
_("Please enter the passphrase to unlock the"
956
" secret key for the X.509 certificate:\n"
730
"S/N %s, ID %08lX, created %s" ),
958
"S/N %s, ID 0x%08lX,\n"
959
"created %s, expires %s.\n" ),
731
960
subject? subject:"?",
733
962
gpgsm_get_short_fingerprint (cert),
738
bind_textdomain_codeset (PACKAGE_GT, orig_codeset);
740
xfree (orig_codeset);
965
i18n_switchback (orig_codeset);