LCOV - code coverage report
Current view: top level - tests - t-ocsp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 225 0.0 %
Date: 2017-03-02 16:39:06 Functions: 0 7 0.0 %

          Line data    Source code
       1             : /* t-ocsp.c - Basic tests for the OCSP subsystem.
       2             :  *      Copyright (C) 2003 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 <sys/stat.h>
      25             : #include <unistd.h>
      26             : #include <time.h>
      27             : #include <errno.h>
      28             : 
      29             : #include "../src/ksba.h"
      30             : 
      31             : 
      32             : #include "t-common.h"
      33             : #include "oidtranstbl.h"
      34             : 
      35             : 
      36             : int verbose;
      37             : int debug;
      38             : int no_nonce;
      39             : 
      40             : /* Return the description for OID; if no description is available
      41             :    NULL is returned. */
      42             : static const char *
      43           0 : get_oid_desc (const char *oid)
      44             : {
      45             :   int i;
      46             : 
      47           0 :   if (oid)
      48           0 :     for (i=0; oidtranstbl[i].oid; i++)
      49           0 :       if (!strcmp (oidtranstbl[i].oid, oid))
      50           0 :         return oidtranstbl[i].desc;
      51           0 :   return NULL;
      52             : }
      53             : 
      54             : 
      55             : static unsigned char *
      56           0 : read_file (const char *fname, size_t *r_length)
      57             : {
      58             :   FILE *fp;
      59             :   struct stat st;
      60             :   char *buf;
      61             :   size_t buflen;
      62             : 
      63           0 :   fp = fopen (fname, "rb");
      64           0 :   if (!fp)
      65             :     {
      66           0 :       fprintf (stderr, "can't open `%s': %s\n", fname, strerror (errno));
      67           0 :       return NULL;
      68             :     }
      69             : 
      70           0 :   if (fstat (fileno(fp), &st))
      71             :     {
      72           0 :       fprintf (stderr, "can't stat `%s': %s\n", fname, strerror (errno));
      73           0 :       fclose (fp);
      74           0 :       return NULL;
      75             :     }
      76             : 
      77           0 :   buflen = st.st_size;
      78           0 :   buf = xmalloc (buflen+1);
      79           0 :   if (fread (buf, buflen, 1, fp) != 1)
      80             :     {
      81           0 :       fprintf (stderr, "error reading `%s': %s\n", fname, strerror (errno));
      82           0 :       fclose (fp);
      83           0 :       xfree (buf);
      84           0 :       return NULL;
      85             :     }
      86           0 :   fclose (fp);
      87             : 
      88           0 :   *r_length = buflen;
      89           0 :   return buf;
      90             : }
      91             : 
      92             : 
      93             : 
      94             : ksba_cert_t
      95           0 : get_one_cert (const char *fname)
      96             : {
      97             :   gpg_error_t err;
      98             :   FILE *fp;
      99             :   ksba_reader_t r;
     100             :   ksba_cert_t cert;
     101             : 
     102           0 :   fp = fopen (fname, "r");
     103           0 :   if (!fp)
     104             :     {
     105           0 :       fprintf (stderr, "%s:%d: can't open `%s': %s\n",
     106           0 :                __FILE__, __LINE__, fname, strerror (errno));
     107           0 :       exit (1);
     108             :     }
     109             : 
     110           0 :   err = ksba_reader_new (&r);
     111           0 :   if (err)
     112           0 :     fail_if_err (err);
     113           0 :   err = ksba_reader_set_file (r, fp);
     114           0 :   fail_if_err (err);
     115             : 
     116           0 :   err = ksba_cert_new (&cert);
     117           0 :   if (err)
     118           0 :     fail_if_err (err);
     119             : 
     120           0 :   err = ksba_cert_read_der (cert, r);
     121           0 :   fail_if_err2 (fname, err);
     122           0 :   return cert;
     123             : }
     124             : 
     125             : 
     126             : /* Create a request for the DER encoded certificate in the file
     127             :    CERT_FNAME and its issuer's certificate in the file
     128             :    ISSUER_CERT_FNAME. */
     129             : void
     130           0 : one_request (const char *cert_fname, const char *issuer_cert_fname)
     131             : {
     132             :   gpg_error_t err;
     133           0 :   ksba_cert_t cert = get_one_cert (cert_fname);
     134           0 :   ksba_cert_t issuer_cert = get_one_cert (issuer_cert_fname);
     135             :   ksba_ocsp_t ocsp;
     136             :   unsigned char *request;
     137             :   size_t requestlen;
     138             : 
     139           0 :   err = ksba_ocsp_new (&ocsp);
     140           0 :   fail_if_err (err);
     141             : 
     142           0 :   err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
     143           0 :   fail_if_err (err);
     144           0 :   ksba_cert_release (cert);
     145           0 :   ksba_cert_release (issuer_cert);
     146             : 
     147           0 :   if (!no_nonce)
     148           0 :     ksba_ocsp_set_nonce (ocsp, "ABCDEFGHIJKLMNOP", 16);
     149             : 
     150           0 :   err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
     151           0 :   fail_if_err (err);
     152           0 :   ksba_ocsp_release (ocsp);
     153             : 
     154           0 :   printf ("OCSP request of length %u created\n", (unsigned int)requestlen);
     155             :   {
     156             : 
     157           0 :     FILE *fp = fopen ("a.req", "wb");
     158           0 :     if (!fp)
     159           0 :       fail ("can't create output file `a.req'");
     160           0 :     if (fwrite (request, requestlen, 1, fp) != 1)
     161           0 :       fail ("can't write output");
     162           0 :     fclose (fp);
     163             :   }
     164             : 
     165           0 :   xfree (request);
     166           0 : }
     167             : 
     168             : 
     169             : void
     170           0 : one_response (const char *cert_fname, const char *issuer_cert_fname,
     171             :               char *response_fname)
     172             : {
     173             :   gpg_error_t err;
     174             :   ksba_ocsp_t ocsp;
     175             :   unsigned char *request, *response;
     176             :   size_t requestlen, responselen;
     177           0 :   ksba_cert_t cert = get_one_cert (cert_fname);
     178           0 :   ksba_cert_t issuer_cert = get_one_cert (issuer_cert_fname);
     179             :   ksba_ocsp_response_status_t response_status;
     180             :   const char *t;
     181             : 
     182           0 :   err = ksba_ocsp_new (&ocsp);
     183           0 :   fail_if_err (err);
     184             : 
     185             :   /* We need to build a request, so that the context is properly
     186             :      prepared for the response. */
     187           0 :   err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
     188           0 :   fail_if_err (err);
     189           0 :   ksba_cert_release (issuer_cert);
     190             : 
     191           0 :   if (!no_nonce)
     192           0 :     ksba_ocsp_set_nonce (ocsp, "ABCDEFGHIJKLMNOP", 16);
     193             : 
     194           0 :   err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
     195           0 :   fail_if_err (err);
     196           0 :   xfree (request);
     197             : 
     198             :   /* Now for the response. */
     199           0 :   response = read_file (response_fname, &responselen);
     200           0 :   if (!response)
     201           0 :     fail ("file error");
     202             : 
     203           0 :   err = ksba_ocsp_parse_response (ocsp, response, responselen,
     204             :                                   &response_status);
     205           0 :   fail_if_err (err);
     206           0 :   switch (response_status)
     207             :     {
     208           0 :     case KSBA_OCSP_RSPSTATUS_SUCCESS:      t = "success"; break;
     209           0 :     case KSBA_OCSP_RSPSTATUS_MALFORMED:    t = "malformed"; break;
     210           0 :     case KSBA_OCSP_RSPSTATUS_INTERNAL:     t = "internal error"; break;
     211           0 :     case KSBA_OCSP_RSPSTATUS_TRYLATER:     t = "try later"; break;
     212           0 :     case KSBA_OCSP_RSPSTATUS_SIGREQUIRED:  t = "must sign request"; break;
     213           0 :     case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break;
     214           0 :     case KSBA_OCSP_RSPSTATUS_REPLAYED:     t = "replay detected"; break;
     215           0 :     case KSBA_OCSP_RSPSTATUS_OTHER:        t = "other (unknown)"; break;
     216           0 :     case KSBA_OCSP_RSPSTATUS_NONE:         t = "no status"; break;
     217           0 :     default: fail ("impossible response_status"); break;
     218             :     }
     219           0 :   printf ("response status ..: %s\n", t);
     220             : 
     221           0 :   if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS
     222           0 :       || response_status == KSBA_OCSP_RSPSTATUS_REPLAYED)
     223             :     {
     224             :       ksba_status_t status;
     225             :       ksba_crl_reason_t reason;
     226             :       ksba_isotime_t this_update, next_update, revocation_time, produced_at;
     227             :       ksba_sexp_t sigval;
     228             :       char *name;
     229             :       ksba_sexp_t keyid;
     230             : 
     231           0 :       err = ksba_ocsp_get_responder_id (ocsp, &name, &keyid);
     232           0 :       fail_if_err (err);
     233           0 :       printf ("responder id .....: ");
     234           0 :       if (name)
     235           0 :         printf ("`%s'", name);
     236             :       else
     237           0 :         print_sexp (keyid);
     238           0 :       putchar ('\n');
     239           0 :       ksba_free (name);
     240           0 :       ksba_free (keyid);
     241             : 
     242           0 :       sigval = ksba_ocsp_get_sig_val (ocsp, produced_at);
     243           0 :       printf ("signature value ..: ");
     244           0 :       print_sexp (sigval);
     245           0 :       printf ("\nproduced at ......: ");
     246           0 :       print_time (produced_at);
     247           0 :       putchar ('\n');
     248           0 :       err = ksba_ocsp_get_status (ocsp, cert,
     249             :                                   &status, this_update, next_update,
     250             :                                   revocation_time, &reason);
     251           0 :       fail_if_err (err);
     252           0 :       printf ("certificate status: %s\n",
     253           0 :               status == KSBA_STATUS_GOOD? "good":
     254           0 :               status == KSBA_STATUS_REVOKED? "revoked":
     255           0 :               status == KSBA_STATUS_UNKNOWN? "unknown":
     256           0 :               status == KSBA_STATUS_NONE? "none": "?");
     257           0 :       if (status == KSBA_STATUS_REVOKED)
     258             :         {
     259           0 :           printf ("revocation time ..: ");
     260           0 :           print_time (revocation_time);
     261           0 :           printf ("\nrevocation reason : %s\n",
     262           0 :                   reason == KSBA_CRLREASON_UNSPECIFIED?   "unspecified":
     263           0 :                   reason == KSBA_CRLREASON_KEY_COMPROMISE? "key compromise":
     264           0 :                   reason == KSBA_CRLREASON_CA_COMPROMISE?   "CA compromise":
     265           0 :                   reason == KSBA_CRLREASON_AFFILIATION_CHANGED?
     266           0 :                                                        "affiliation changed":
     267           0 :                   reason == KSBA_CRLREASON_SUPERSEDED?   "superseeded":
     268           0 :                   reason == KSBA_CRLREASON_CESSATION_OF_OPERATION?
     269           0 :                                                       "cessation of operation":
     270           0 :                   reason == KSBA_CRLREASON_CERTIFICATE_HOLD?
     271           0 :                                                       "certificate on hold":
     272           0 :                   reason == KSBA_CRLREASON_REMOVE_FROM_CRL? "removed from CRL":
     273           0 :                   reason == KSBA_CRLREASON_PRIVILEGE_WITHDRAWN?
     274           0 :                                                        "privilege withdrawn":
     275           0 :                   reason == KSBA_CRLREASON_AA_COMPROMISE? "AA compromise":
     276           0 :                   reason == KSBA_CRLREASON_OTHER?   "other":"?");
     277             :         }
     278           0 :       printf ("this update ......: ");
     279           0 :       print_time (this_update);
     280           0 :       printf ("\nnext update ......: ");
     281           0 :       print_time (next_update);
     282           0 :       putchar ('\n');
     283             :       {
     284             :         int cert_idx;
     285             :         ksba_cert_t acert;
     286             : 
     287           0 :         for (cert_idx=0; (acert = ksba_ocsp_get_cert (ocsp, cert_idx));
     288           0 :              cert_idx++)
     289           0 :           ksba_cert_release (acert);
     290           0 :         printf ("extra certificates: %d\n", cert_idx );
     291             :       }
     292             : 
     293             :       {
     294             :         int idx, crit;
     295             :         const char *oid;
     296             :         const unsigned char *der;
     297             :         size_t derlen;
     298             : 
     299           0 :         for (idx=0; !(err=ksba_ocsp_get_extension (ocsp, NULL, idx,
     300             :                                                    &oid, &crit,
     301           0 :                                                    &der, &derlen)); idx++)
     302             :           {
     303           0 :             const char *s = get_oid_desc (oid);
     304           0 :             printf ("%sresp-extn ..%s: %s%s%s%s  (",
     305           0 :                     crit? "crit. ":"",
     306           0 :                     crit?"":"......",
     307             :                     s?"(":"", s?s:"", s?") ":"", oid);
     308           0 :             print_hex (der, derlen);
     309           0 :             putchar (')');
     310           0 :             putchar ('\n');
     311             :           }
     312           0 :         if (err && gpg_err_code (err) != GPG_ERR_EOF)
     313           0 :           fail_if_err (err);
     314             : 
     315           0 :         for (idx=0; !(err=ksba_ocsp_get_extension (ocsp, cert, idx,
     316             :                                                    &oid, &crit,
     317           0 :                                                    &der, &derlen)); idx++)
     318             :           {
     319           0 :             const char *s = get_oid_desc (oid);
     320           0 :             printf ("%ssngl-extn ..%s: %s%s%s%s  (",
     321           0 :                     crit? "crit. ":"",
     322           0 :                     crit?"":"......",
     323             :                     s?"(":"", s?s:"", s?") ":"", oid);
     324           0 :             print_hex (der, derlen);
     325           0 :             putchar (')');
     326           0 :             putchar ('\n');
     327             :           }
     328           0 :         if (err && gpg_err_code (err) != GPG_ERR_EOF)
     329           0 :           fail_if_err (err);
     330             :       }
     331             :     }
     332             : 
     333             : 
     334           0 :   ksba_cert_release (cert);
     335           0 :   ksba_ocsp_release (ocsp);
     336           0 :   xfree (response);
     337           0 : }
     338             : 
     339             : 
     340             : static gpg_error_t
     341           0 : my_hash_buffer (void *arg, const char *oid,
     342             :                 const void *buffer, size_t length, size_t resultsize,
     343             :                 unsigned char *result, size_t *resultlen)
     344             : {
     345             :   (void)arg; /* Not used.  */
     346             : 
     347           0 :   if (oid && strcmp (oid, "1.3.14.3.2.26"))
     348           0 :     return gpg_error (GPG_ERR_NOT_SUPPORTED); /* We only support SHA-1. */
     349           0 :   if (resultsize < 20)
     350           0 :     return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
     351           0 :   sha1_hash_buffer (result, buffer, length);
     352           0 :   *resultlen = 20;
     353           0 :   return 0;
     354             : }
     355             : 
     356             : 
     357             : 
     358             : 
     359             : /* ( printf "POST / HTTP/1.0\r\nContent-Type: application/ocsp-request\r\nContent-Length: `wc -c <a.req | tr -d ' '`\r\n\r\n"; cat a.req ) |  nc -v ocsp.openvalidation.org 8088   | sed '1,/^\r$/d' >a.rsp
     360             : 
     361             :     Openvalidation test reponders:
     362             : 
     363             :     Port: 80    Standard  configuration. OCSP Responder will accept
     364             :                 all proper requests and send a signed response.
     365             :     Port: 8080  Response does not contain any attached certificates.
     366             :                 Client must accept this response
     367             :     Port: 8081  Never replies nonce. Insecure but standard conform mode.
     368             :                 Client application should warn in case of replay-attacks.
     369             :     Port: 8082  The OCSP Responder will sign the response with randomized
     370             :                 bytecode. Client should NOT accept this response.
     371             :     Port: 8083  OCSP response will always be revoked.
     372             :     Port: 8084  OCSP response will always be unknown.
     373             :     Port: 8085  OCSP response will always be malformed.
     374             :     Port: 8086  OCSP response will always be internal error.
     375             :     Port: 8087  OCSP response will always be try later.
     376             :     Port: 8088  OCSP response will always be signature required.
     377             :     Port: 8089  OCSP response will always be unauth.
     378             :     Port: 8090  Standard configuration with full Debuglogs. Access the
     379             :                 logs at http://www.openvalidation.org/en/test/logs.html
     380             : 
     381             : */
     382             : 
     383             : int
     384           0 : main (int argc, char **argv)
     385             : {
     386           0 :   int last_argc = -1;
     387           0 :   int response_mode = 0;
     388           0 :   const char *srcdir = getenv ("srcdir");
     389             : 
     390           0 :   if (!srcdir)
     391           0 :     srcdir = ".";
     392             : 
     393           0 :   ksba_set_hash_buffer_function (my_hash_buffer, NULL);
     394             : 
     395           0 :   if (argc)
     396             :     {
     397           0 :       argc--; argv++;
     398             :     }
     399           0 :   while (argc && last_argc != argc )
     400             :     {
     401           0 :       last_argc = argc;
     402           0 :       if (!strcmp (*argv, "--help"))
     403             :         {
     404           0 :           puts (
     405             : "usage: ./t-ocsp [options] {CERTFILE ISSUERCERTFILE}\n"
     406             : "       ./t-ocsp [options] --response {CERTFILE ISSUERCERTFILE RESPONSEFILE}\n"
     407             : "\n"
     408             : "       Options are --verbose and --debug");
     409           0 :           exit (0);
     410             :         }
     411           0 :       if (!strcmp (*argv, "--verbose"))
     412             :         {
     413           0 :           verbose = 1;
     414           0 :           argc--; argv++;
     415             :         }
     416           0 :       else if (!strcmp (*argv, "--debug"))
     417             :         {
     418           0 :           verbose = debug = 1;
     419           0 :           argc--; argv++;
     420             :         }
     421           0 :       else if (!strcmp (*argv, "--response"))
     422             :         {
     423           0 :           response_mode = 1;
     424           0 :           argc--; argv++;
     425             :         }
     426           0 :       else if (!strcmp (*argv, "--no-nonce"))
     427             :         {
     428           0 :           no_nonce = 1;
     429           0 :           argc--; argv++;
     430             :         }
     431             :     }
     432             : 
     433             : 
     434           0 :   if (response_mode)
     435             :     {
     436           0 :       for ( ; argc > 2; argc -=3, argv += 3)
     437           0 :         one_response (*argv, argv[1], argv[2]);
     438           0 :       if (argc)
     439           0 :         fputs ("warning: extra argument ignored\n", stderr);
     440             :     }
     441           0 :   else if (argc)
     442             :     {
     443           0 :       for ( ; argc > 1; argc -=2, argv += 2)
     444           0 :         one_request (*argv, argv[1]);
     445           0 :       if (argc)
     446           0 :         fputs ("warning: extra argument ignored\n", stderr);
     447             :     }
     448             :   else
     449             :     {
     450             :       struct {
     451             :         const char *cert_fname;
     452             :         const char *issuer_cert_fname;
     453             :         const char *response_fname;
     454           0 :       } files[] = {
     455             :         { "samples/ov-userrev.crt", "samples/ov-root-ca-cert.crt", NULL },
     456             :         { NULL }
     457             :       };
     458             :       int idx;
     459             : 
     460           0 :       for (idx=0; files[idx].cert_fname; idx++)
     461             :         {
     462             :           char *f1, *f2;
     463             : 
     464           0 :           f1 = prepend_srcdir (files[idx].cert_fname);
     465           0 :           f2 = prepend_srcdir (files[idx].issuer_cert_fname);
     466           0 :           one_request (f1, f2);
     467           0 :           xfree (f2);
     468           0 :           xfree (f1);
     469             :         }
     470             :     }
     471             : 
     472           0 :   return 0;
     473             : }

Generated by: LCOV version 1.13