Imported Upstream version 1.3.4
[platform/upstream/libksba.git] / tests / cert-basic.c
1 /* cert-basic.c - basic test for the certificate management.
2  *      Copyright (C) 2001, 2002, 2004, 2005 g10 Code GmbH
3  *
4  * This file is part of KSBA.
5  *
6  * KSBA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * KSBA is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <assert.h>
24 #include <errno.h>
25
26 #include "../src/ksba.h"
27 #define _KSBA_VISIBILITY_DEFAULT /*  */
28 #include "../src/keyinfo.h"
29
30 #include "oidtranstbl.h"
31 #include "t-common.h"
32
33 #ifdef __MINGW32CE__
34 #define getenv(a) (NULL)
35 #endif
36
37 #define digitp(p)   (*(p) >= '0' && *(p) <= '9')
38
39 #define fail_if_err(a) do { if(a) {                                       \
40                               fprintf (stderr, "%s:%d: KSBA error: %s\n", \
41                               __FILE__, __LINE__, gpg_strerror(a));   \
42                               exit (1); }                              \
43                            } while(0)
44
45
46 #define fail_if_err2(f, a) do { if(a) {\
47             fprintf (stderr, "%s:%d: KSBA error on file `%s': %s\n", \
48                        __FILE__, __LINE__, (f), gpg_strerror(a));   \
49                             exit (1); }                              \
50                            } while(0)
51
52 #define xfree(a)  ksba_free (a)
53
54 static int verbose;
55 static int errorcount = 0;
56
57
58 static void
59 print_names (int indent, ksba_name_t name)
60 {
61   int idx;
62   const char *s;
63   int indent_all;
64
65   if ((indent_all = (indent < 0)))
66     indent = - indent;
67
68   if (!name)
69     {
70       fputs ("none\n", stdout);
71       return;
72     }
73
74   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
75     {
76       char *p = ksba_name_get_uri (name, idx);
77       printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s);
78       xfree (p);
79     }
80 }
81
82
83 /* Return the description for OID; if no description is available
84    NULL is returned. */
85 static const char *
86 get_oid_desc (const char *oid)
87 {
88   int i;
89
90   if (oid)
91     for (i=0; oidtranstbl[i].oid; i++)
92       if (!strcmp (oidtranstbl[i].oid, oid))
93         return oidtranstbl[i].desc;
94   return NULL;
95 }
96
97
98 static void
99 print_oid_and_desc (const char *oid, int with_lf)
100 {
101   const char *s = get_oid_desc (oid);
102   printf ("%s%s%s%s",
103           oid, s?" (":"", s?s:"", s?")":"");
104   if (with_lf)
105     putchar ('\n');
106 }
107
108
109 static void
110 print_oid_list (int indent, char *list)
111 {
112   char *lf;
113   int indent_all, c;
114   size_t n;
115
116   if ((indent_all = (indent < 0)))
117     indent = - indent;
118
119   while (*list)
120     {
121       printf ("%*s", indent_all?indent:0, "");
122       indent_all = 1;
123
124       if (!(lf = strchr (list, '\n')))
125         lf = list + strlen (list);
126
127       n = strspn (list, "0123456789.");
128       c = list[n];
129       list[n] = 0;
130       print_oid_and_desc (list, 0);
131       list[n] = c;
132
133       c = *lf;
134       *lf = 0;
135       printf ("  %s\n", list+n);
136       *lf = c;
137       list = *lf? (lf+1):lf;
138     }
139 }
140
141
142
143
144 static void
145 list_extensions (ksba_cert_t cert)
146 {
147   gpg_error_t err;
148   const char *oid;
149   int idx, crit, is_ca, pathlen;
150   size_t off, len;
151   unsigned int usage, reason;
152   char *string, *p;
153   ksba_name_t name1, name2;
154   ksba_sexp_t serial;
155   ksba_sexp_t keyid;
156
157   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
158                                              &oid, &crit, &off, &len));idx++)
159     {
160       const char *s = get_oid_desc (oid);
161       printf ("Extn: %s%s%s%s at %d with length %d %s\n",
162               oid, s?" (":"", s?s:"", s?")":"",
163               (int)off, (int)len, crit? "(critical)":"");
164     }
165   if (err && gpg_err_code (err) != GPG_ERR_EOF )
166     {
167       fprintf (stderr,
168                "%s:%d: enumerating extensions failed: %s\n",
169                __FILE__, __LINE__, gpg_strerror (err));
170       errorcount++;
171     }
172
173   /* subjectKeyIdentifier */
174   err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
175   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
176     {
177       fputs ("SubjectKeyIdentifier: ", stdout);
178       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
179         fputs ("none", stdout);
180       else
181         {
182           print_sexp (keyid);
183           ksba_free (keyid);
184         }
185       putchar ('\n');
186     }
187
188
189   /* authorityKeyIdentifier */
190   err = ksba_cert_get_auth_key_id (cert, &keyid, &name1, &serial);
191   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
192     {
193       fputs ("AuthorityKeyIdentifier: ", stdout);
194       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
195         fputs ("none\n", stdout);
196       else
197         {
198           if (name1)
199             {
200               print_names (24, name1);
201               ksba_name_release (name1);
202               fputs ("                serial: ", stdout);
203               print_sexp (serial);
204               ksba_free (serial);
205             }
206           putchar ('\n');
207           if (keyid)
208             {
209               fputs ("         keyIdentifier: ", stdout);
210               print_sexp (keyid);
211               ksba_free (keyid);
212               putchar ('\n');
213             }
214         }
215     }
216   else
217     {
218       fprintf (stderr, "%s:%d: ksba_cert_get_auth_key_id: %s\n",
219                __FILE__, __LINE__, gpg_strerror (err));
220       errorcount++;
221     }
222
223   err = ksba_cert_is_ca (cert, &is_ca, &pathlen);
224   if (err)
225     {
226       fprintf (stderr, "%s:%d: ksba_cert_is_ca failed: %s\n",
227                __FILE__, __LINE__, gpg_strerror (err));
228       errorcount++;
229     }
230   else if (is_ca)
231     printf ("This is a CA certificate with a path length of %d\n", pathlen);
232
233   err = ksba_cert_get_key_usage (cert, &usage);
234   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
235     printf ("KeyUsage: Not specified\n");
236   else if (err)
237     {
238       fprintf (stderr, "%s:%d: ksba_cert_get_key_usage failed: %s\n",
239                __FILE__, __LINE__, gpg_strerror (err));
240       errorcount++;
241     }
242   else
243     {
244       fputs ("KeyUsage:", stdout);
245       if ( (usage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
246         fputs (" digitalSignature", stdout);
247       if ( (usage & KSBA_KEYUSAGE_NON_REPUDIATION))
248         fputs (" nonRepudiation", stdout);
249       if ( (usage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
250         fputs (" keyEncipherment", stdout);
251       if ( (usage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
252         fputs (" dataEncripherment", stdout);
253       if ( (usage & KSBA_KEYUSAGE_KEY_AGREEMENT))
254         fputs (" keyAgreement", stdout);
255       if ( (usage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
256         fputs (" certSign", stdout);
257       if ( (usage & KSBA_KEYUSAGE_CRL_SIGN))
258         fputs (" crlSign", stdout);
259       if ( (usage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
260         fputs (" encipherOnly", stdout);
261       if ( (usage & KSBA_KEYUSAGE_DECIPHER_ONLY))
262         fputs (" decipherOnly", stdout);
263       putchar ('\n');
264     }
265   err = ksba_cert_get_ext_key_usages (cert, &string);
266   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
267     printf ("ExtKeyUsages: none\n");
268   else if (err)
269     {
270       fprintf (stderr, "%s:%d: ksba_cert_ext_key_usages failed: %s\n",
271                __FILE__, __LINE__, gpg_strerror (err));
272       errorcount++;
273     }
274   else
275     {
276       fputs ("ExtKeyUsages: ", stdout);
277       print_oid_list (14, string);
278       xfree (string);
279     }
280
281
282   err = ksba_cert_get_cert_policies (cert, &string);
283   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
284     printf ("CertificatePolicies: none\n");
285   else if (err)
286     {
287       fprintf (stderr, "%s:%d: ksba_cert_get_cert_policies failed: %s\n",
288                __FILE__, __LINE__, gpg_strerror (err));
289       errorcount++;
290     }
291   else
292     {
293       /* for display purposes we replace the linefeeds by commas */
294       for (p=string; *p; p++)
295         {
296           if (*p == '\n')
297             *p = ',';
298         }
299       fputs ("CertificatePolicies: ", stdout);
300       print_oid_list (21, string);
301       xfree (string);
302     }
303
304   /* CRL distribution point */
305   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx,
306                                                   &name1, &name2,
307                                                   &reason));idx++)
308     {
309       fputs ("CRLDistPoint: ", stdout);
310       print_names (14, name1);
311       fputs ("     reasons:", stdout);
312       if ( !reason )
313         fputs (" none", stdout);
314       if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
315         fputs (" unused", stdout);
316       if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
317         fputs (" keyCompromise", stdout);
318       if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
319         fputs (" caCompromise", stdout);
320       if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
321         fputs (" affiliationChanged", stdout);
322       if ( (reason & KSBA_CRLREASON_SUPERSEDED))
323         fputs (" superseded", stdout);
324       if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
325         fputs (" cessationOfOperation", stdout);
326       if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
327         fputs (" certificateHold", stdout);
328       putchar ('\n');
329       fputs ("      issuer: ", stdout);
330       print_names (14, name2);
331       ksba_name_release (name1);
332       ksba_name_release (name2);
333     }
334   if (err && gpg_err_code (err) != GPG_ERR_EOF)
335     {
336       fprintf (stderr, "%s:%d: ksba_cert_get_crl_dist_point failed: %s\n",
337                __FILE__, __LINE__, gpg_strerror (err));
338       errorcount++;
339     }
340
341   /* authorityInfoAccess. */
342   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx,
343                                                          &string, &name1))
344        ; idx++)
345     {
346       fputs ("authorityInfoAccess: ", stdout);
347       print_oid_and_desc (string, 1);
348       print_names (-21, name1);
349       ksba_name_release (name1);
350       ksba_free (string);
351     }
352   if (err && gpg_err_code (err) != GPG_ERR_EOF)
353     {
354       fprintf (stderr, "%s:%d: "
355                "ksba_cert_get_authority_info_access failed: %s\n",
356                __FILE__, __LINE__, gpg_strerror (err));
357       errorcount++;
358     }
359
360   /* subjectInfoAccess. */
361   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx,
362                                                        &string, &name1))
363        ; idx++)
364     {
365       fputs ("subjectInfoAccess: ", stdout);
366       print_oid_and_desc (string, 1);
367       print_names (-19, name1);
368       ksba_name_release (name1);
369       ksba_free (string);
370     }
371   if (err && gpg_err_code (err) != GPG_ERR_EOF)
372     {
373       fprintf (stderr, "%s:%d: "
374                "ksba_cert_get_subject_info_access failed: %s\n",
375                __FILE__, __LINE__, gpg_strerror (err));
376       errorcount++;
377     }
378
379 }
380
381
382 static void
383 one_file (const char *fname)
384 {
385   gpg_error_t err;
386   FILE *fp;
387   ksba_reader_t r;
388   ksba_cert_t cert;
389   char *dn;
390   ksba_isotime_t t;
391   int idx;
392   ksba_sexp_t sexp;
393   const char *oid, *s;
394
395   fp = fopen (fname, "rb");
396   if (!fp)
397     {
398       fprintf (stderr, "%s:%d: can't open `%s': %s\n",
399                __FILE__, __LINE__, fname, strerror (errno));
400       exit (1);
401     }
402
403   err = ksba_reader_new (&r);
404   if (err)
405     fail_if_err (err);
406   err = ksba_reader_set_file (r, fp);
407   fail_if_err (err);
408
409   err = ksba_cert_new (&cert);
410   if (err)
411     fail_if_err (err);
412
413   err = ksba_cert_read_der (cert, r);
414   fail_if_err2 (fname, err);
415
416   printf ("Certificate in `%s':\n", fname);
417
418   sexp = ksba_cert_get_serial (cert);
419   fputs ("  serial....: ", stdout);
420   print_sexp (sexp);
421   ksba_free (sexp);
422   putchar ('\n');
423
424   for (idx=0;(dn = ksba_cert_get_issuer (cert, idx));idx++)
425     {
426       fputs (idx?"         aka: ":"  issuer....: ", stdout);
427       print_dn (dn);
428       ksba_free (dn);
429       putchar ('\n');
430     }
431
432   for (idx=0;(dn = ksba_cert_get_subject (cert, idx));idx++)
433     {
434       fputs (idx?"         aka: ":"  subject...: ", stdout);
435       print_dn (dn);
436       ksba_free (dn);
437       putchar ('\n');
438     }
439
440   ksba_cert_get_validity (cert, 0, t);
441   fputs ("  notBefore.: ", stdout);
442   print_time (t);
443   putchar ('\n');
444   ksba_cert_get_validity (cert, 1, t);
445   fputs ("  notAfter..: ", stdout);
446   print_time (t);
447   putchar ('\n');
448
449   oid = ksba_cert_get_digest_algo (cert);
450   s = get_oid_desc (oid);
451   printf ("  hash algo.: %s%s%s%s\n",
452           oid?oid:"(null)", s?" (":"",s?s:"",s?")":"");
453
454   /* Under Windows the _ksba_keyinfo_from_sexp are not exported.  */
455 #ifndef __WIN32
456   /* check that the sexp to keyinfo conversion works */
457   {
458     ksba_sexp_t public;
459
460     public = ksba_cert_get_public_key (cert);
461     if (!public)
462       {
463         fprintf (stderr, "%s:%d: public key not found\n",
464                  __FILE__, __LINE__);
465         errorcount++;
466       }
467     else
468       {
469         unsigned char *der;
470         size_t derlen;
471
472         if (verbose)
473           {
474             fputs ("  pubkey....: ", stdout);
475             print_sexp (public);
476             putchar ('\n');
477           }
478
479         err = _ksba_keyinfo_from_sexp (public, &der, &derlen);
480         if (err)
481           {
482             fprintf (stderr, "%s:%d: converting public key failed: %s\n",
483                      __FILE__, __LINE__, gpg_strerror (err));
484             errorcount++;
485           }
486         else
487           {
488             ksba_sexp_t tmp;
489
490             if (verbose)
491               {
492                 fputs ("  pubkey-DER: ", stdout);
493                 print_hex (der, derlen);
494                 putchar ('\n');
495               }
496             err = _ksba_keyinfo_to_sexp (der, derlen, &tmp);
497             if (err)
498               {
499                 fprintf (stderr,
500                          "%s:%d: re-converting public key failed: %s\n",
501                          __FILE__, __LINE__, gpg_strerror (err));
502                 errorcount++;
503               }
504             else
505               {
506                 unsigned char *der2;
507                 size_t derlen2;
508
509                 err = _ksba_keyinfo_from_sexp (tmp, &der2, &derlen2);
510                 if (err)
511                   {
512                     fprintf (stderr, "%s:%d: re-re-converting "
513                              "public key failed: %s\n",
514                              __FILE__, __LINE__, gpg_strerror (err));
515                     errorcount++;
516                   }
517                 else if (derlen != derlen2 || memcmp (der, der2, derlen))
518                   {
519                     fprintf (stderr, "%s:%d: mismatch after "
520                              "re-re-converting public key\n",
521                              __FILE__, __LINE__);
522                     errorcount++;
523                     xfree (der2);
524                   } else {
525                     /* Don't leak memory if everything is ok. */
526                     xfree (der2);
527                   }
528                 xfree (tmp);
529               }
530             xfree (der);
531           }
532         ksba_free (public);
533       }
534   }
535 #endif
536
537   if (verbose)
538     {
539       sexp = ksba_cert_get_sig_val (cert);
540       fputs ("  sigval....: ", stdout);
541       print_sexp (sexp);
542       ksba_free (sexp);
543       putchar ('\n');
544     }
545
546   list_extensions (cert);
547
548   ksba_cert_release (cert);
549   err = ksba_cert_new (&cert);
550   if (err)
551     fail_if_err (err);
552
553   err = ksba_cert_read_der (cert, r);
554   if (err && gpg_err_code (err) != GPG_ERR_EOF)
555     {
556       fprintf (stderr, "%s:%d: expected EOF but got: %s\n",
557                __FILE__, __LINE__, gpg_strerror (err));
558       errorcount++;
559     }
560
561   putchar ('\n');
562   ksba_cert_release (cert);
563   ksba_reader_release (r);
564   fclose (fp);
565 }
566
567
568
569
570 int
571 main (int argc, char **argv)
572 {
573   const char *srcdir = getenv ("srcdir");
574
575   if (!srcdir)
576     srcdir = ".";
577
578   if (argc)
579     {
580       argc--; argv++;
581     }
582
583   if (argc && !strcmp (*argv, "--verbose"))
584     {
585       verbose = 1;
586       argc--; argv++;
587     }
588
589
590   if (argc)
591     {
592       for (; argc; argc--, argv++)
593         one_file (*argv);
594     }
595   else
596     {
597       const char *files[] = {
598         "cert_dfn_pca01.der",
599         "cert_dfn_pca15.der",
600         "cert_g10code_test1.der",
601         NULL
602       };
603       int idx;
604
605       for (idx=0; files[idx]; idx++)
606         {
607           char *fname;
608
609           fname = xmalloc (strlen (srcdir) + 1 + strlen (files[idx]) + 1);
610           strcpy (fname, srcdir);
611           strcat (fname, "/");
612           strcat (fname, files[idx]);
613           one_file (fname);
614           ksba_free (fname);
615         }
616     }
617
618   return !!errorcount;
619 }