示例#1
0
/* Create a request for the DER encoded certificate in the file
   CERT_FNAME and its issuer's certificate in the file
   ISSUER_CERT_FNAME. */
void
one_request (const char *cert_fname, const char *issuer_cert_fname)
{
  gpg_error_t err;
  ksba_cert_t cert = get_one_cert (cert_fname);
  ksba_cert_t issuer_cert = get_one_cert (issuer_cert_fname);
  ksba_ocsp_t ocsp;
  unsigned char *request;
  size_t requestlen;

  err = ksba_ocsp_new (&ocsp);
  fail_if_err (err);
  
  err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
  fail_if_err (err);
  ksba_cert_release (cert);
  ksba_cert_release (issuer_cert);

  if (!no_nonce)
    ksba_ocsp_set_nonce (ocsp, "ABCDEFGHIJKLMNOP", 16);

  err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
  fail_if_err (err);
  ksba_ocsp_release (ocsp);

  printf ("OCSP request of length %u created\n", (unsigned int)requestlen);
  {

    FILE *fp = fopen ("a.req", "wb");
    if (!fp)
      fail ("can't create output file `a.req'");
    if (fwrite (request, requestlen, 1, fp) != 1)
      fail ("can't write output");
    fclose (fp);
  }
  
  xfree (request);
}
示例#2
0
文件: ocsp.c 项目: FMayzek/gnupg
/* Construct an OCSP request, send it to the configured OCSP responder
   and parse the response. On success the OCSP context may be used to
   further process the reponse. */
static gpg_error_t
do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
                 const char *url, ksba_cert_t cert, ksba_cert_t issuer_cert)
{
  gpg_error_t err;
  unsigned char *request, *response;
  size_t requestlen, responselen;
  http_t http;
  ksba_ocsp_response_status_t response_status;
  const char *t;
  int redirects_left = 2;
  char *free_this = NULL;

  (void)ctrl;

  if (opt.disable_http)
    {
      log_error (_("OCSP request not possible due to disabled HTTP\n"));
      return gpg_error (GPG_ERR_NOT_SUPPORTED);
    }

  err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
  if (err)
    {
      log_error (_("error setting OCSP target: %s\n"), gpg_strerror (err));
      return err;
    }

  {
    size_t n;
    unsigned char nonce[32];

    n = ksba_ocsp_set_nonce (ocsp, NULL, 0);
    if (n > sizeof nonce)
      n = sizeof nonce;
    gcry_create_nonce (nonce, n);
    ksba_ocsp_set_nonce (ocsp, nonce, n);
  }

  err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
  if (err)
    {
      log_error (_("error building OCSP request: %s\n"), gpg_strerror (err));
      return err;
    }

 once_more:
  err = http_open (&http, HTTP_REQ_POST, url, NULL,
                   (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0),
                   opt.http_proxy, NULL, NULL, NULL);
  if (err)
    {
      log_error (_("error connecting to '%s': %s\n"), url, gpg_strerror (err));
      xfree (free_this);
      return err;
    }

  es_fprintf (http_get_write_ptr (http),
	      "Content-Type: application/ocsp-request\r\n"
	      "Content-Length: %lu\r\n",
	      (unsigned long)requestlen );
  http_start_data (http);
  if (es_fwrite (request, requestlen, 1, http_get_write_ptr (http)) != 1)
    {
      err = gpg_error_from_errno (errno);
      log_error ("error sending request to '%s': %s\n", url, strerror (errno));
      http_close (http, 0);
      xfree (request);
      xfree (free_this);
      return err;
    }
  xfree (request);
  request = NULL;

  err = http_wait_response (http);
  if (err || http_get_status_code (http) != 200)
    {
      if (err)
        log_error (_("error reading HTTP response for '%s': %s\n"),
                   url, gpg_strerror (err));
      else
        {
          switch (http_get_status_code (http))
            {
            case 301:
            case 302:
              {
                const char *s = http_get_header (http, "Location");

                log_info (_("URL '%s' redirected to '%s' (%u)\n"),
                          url, s?s:"[none]", http_get_status_code (http));
                if (s && *s && redirects_left-- )
                  {
                    xfree (free_this); url = NULL;
                    free_this = xtrystrdup (s);
                    if (!free_this)
                      err = gpg_error_from_errno (errno);
                    else
                      {
                        url = free_this;
                        http_close (http, 0);
                        goto once_more;
                      }
                  }
                else
                  err = gpg_error (GPG_ERR_NO_DATA);
                log_error (_("too many redirections\n"));
              }
              break;

            default:
              log_error (_("error accessing '%s': http status %u\n"),
                         url, http_get_status_code (http));
              err = gpg_error (GPG_ERR_NO_DATA);
              break;
            }
        }
      http_close (http, 0);
      xfree (free_this);
      return err;
    }

  err = read_response (http_get_read_ptr (http), &response, &responselen);
  http_close (http, 0);
  if (err)
    {
      log_error (_("error reading HTTP response for '%s': %s\n"),
                 url, gpg_strerror (err));
      xfree (free_this);
      return err;
    }

  err = ksba_ocsp_parse_response (ocsp, response, responselen,
                                  &response_status);
  if (err)
    {
      log_error (_("error parsing OCSP response for '%s': %s\n"),
                 url, gpg_strerror (err));
      xfree (response);
      xfree (free_this);
      return err;
    }

  switch (response_status)
    {
    case KSBA_OCSP_RSPSTATUS_SUCCESS:      t = "success"; break;
    case KSBA_OCSP_RSPSTATUS_MALFORMED:    t = "malformed"; break;
    case KSBA_OCSP_RSPSTATUS_INTERNAL:     t = "internal error"; break;
    case KSBA_OCSP_RSPSTATUS_TRYLATER:     t = "try later"; break;
    case KSBA_OCSP_RSPSTATUS_SIGREQUIRED:  t = "must sign request"; break;
    case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break;
    case KSBA_OCSP_RSPSTATUS_REPLAYED:     t = "replay detected"; break;
    case KSBA_OCSP_RSPSTATUS_OTHER:        t = "other (unknown)"; break;
    case KSBA_OCSP_RSPSTATUS_NONE:         t = "no status"; break;
    default:                               t = "[unknown status]"; break;
    }
  if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS)
    {
      if (opt.verbose)
        log_info (_("OCSP responder at '%s' status: %s\n"), url, t);

      err = ksba_ocsp_hash_response (ocsp, response, responselen,
                                     HASH_FNC, md);
      if (err)
        log_error (_("hashing the OCSP response for '%s' failed: %s\n"),
                   url, gpg_strerror (err));
    }
  else
    {
      log_error (_("OCSP responder at '%s' status: %s\n"), url, t);
      err = gpg_error (GPG_ERR_GENERAL);
    }

  xfree (response);
  xfree (free_this);
  return err;
}
示例#3
0
void 
one_response (const char *cert_fname, const char *issuer_cert_fname,
              char *response_fname)
{
  gpg_error_t err;
  ksba_ocsp_t ocsp;
  unsigned char *request, *response;
  size_t requestlen, responselen;
  ksba_cert_t cert = get_one_cert (cert_fname);
  ksba_cert_t issuer_cert = get_one_cert (issuer_cert_fname);
  ksba_ocsp_response_status_t response_status;
  const char *t;

  err = ksba_ocsp_new (&ocsp);
  fail_if_err (err);

  /* We need to build a request, so that the context is properly
     prepared for the response. */
  err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
  fail_if_err (err);
  ksba_cert_release (issuer_cert);

  if (!no_nonce)
    ksba_ocsp_set_nonce (ocsp, "ABCDEFGHIJKLMNOP", 16);

  err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
  fail_if_err (err);
  xfree (request);

  /* Now for the response. */
  response = read_file (response_fname, &responselen);
  if (!response)
    fail ("file error");

  err = ksba_ocsp_parse_response (ocsp, response, responselen,
                                  &response_status);
  fail_if_err (err);
  switch (response_status)
    {
    case KSBA_OCSP_RSPSTATUS_SUCCESS:      t = "success"; break;
    case KSBA_OCSP_RSPSTATUS_MALFORMED:    t = "malformed"; break;  
    case KSBA_OCSP_RSPSTATUS_INTERNAL:     t = "internal error"; break;  
    case KSBA_OCSP_RSPSTATUS_TRYLATER:     t = "try later"; break;      
    case KSBA_OCSP_RSPSTATUS_SIGREQUIRED:  t = "must sign request"; break;  
    case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break;  
    case KSBA_OCSP_RSPSTATUS_REPLAYED:     t = "replay detected"; break;  
    case KSBA_OCSP_RSPSTATUS_OTHER:        t = "other (unknown)"; break;  
    case KSBA_OCSP_RSPSTATUS_NONE:         t = "no status"; break;
    default: fail ("impossible response_status"); break;
    }
  printf ("response status ..: %s\n", t);

  if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS
      || response_status == KSBA_OCSP_RSPSTATUS_REPLAYED)
    {
      ksba_status_t status;
      ksba_crl_reason_t reason;
      ksba_isotime_t this_update, next_update, revocation_time, produced_at;
      ksba_sexp_t sigval;
      char *name;
      ksba_sexp_t keyid;

      err = ksba_ocsp_get_responder_id (ocsp, &name, &keyid);
      fail_if_err (err);
      printf ("responder id .....: ");
      if (name)
        printf ("`%s'", name);
      else
        print_sexp (keyid);
      putchar ('\n');
      ksba_free (name);
      ksba_free (keyid);

      sigval = ksba_ocsp_get_sig_val (ocsp, produced_at);
      printf ("signature value ..: ");
      print_sexp (sigval);
      printf ("\nproduced at ......: ");
      print_time (produced_at);
      putchar ('\n');
      err = ksba_ocsp_get_status (ocsp, cert,
                                  &status, this_update, next_update,
                                  revocation_time, &reason);
      fail_if_err (err);
      printf ("certificate status: %s\n",
              status == KSBA_STATUS_GOOD? "good":
              status == KSBA_STATUS_REVOKED? "revoked":
              status == KSBA_STATUS_UNKNOWN? "unknown":
              status == KSBA_STATUS_NONE? "none": "?");
      if (status == KSBA_STATUS_REVOKED)
        {
          printf ("revocation time ..: ");
          print_time (revocation_time);
          printf ("\nrevocation reason : %s\n",
                  reason == KSBA_CRLREASON_UNSPECIFIED?   "unspecified":        
                  reason == KSBA_CRLREASON_KEY_COMPROMISE? "key compromise":
                  reason == KSBA_CRLREASON_CA_COMPROMISE?   "CA compromise":
                  reason == KSBA_CRLREASON_AFFILIATION_CHANGED?
                                                       "affiliation changed":
                  reason == KSBA_CRLREASON_SUPERSEDED?   "superseeded":
                  reason == KSBA_CRLREASON_CESSATION_OF_OPERATION?
                                                      "cessation of operation": 
                  reason == KSBA_CRLREASON_CERTIFICATE_HOLD?
                                                      "certificate on hold":   
                  reason == KSBA_CRLREASON_REMOVE_FROM_CRL? "removed from CRL":
                  reason == KSBA_CRLREASON_PRIVILEGE_WITHDRAWN?
                                                       "privilege withdrawn":
                  reason == KSBA_CRLREASON_AA_COMPROMISE? "AA compromise":
                  reason == KSBA_CRLREASON_OTHER?   "other":"?");
        }
      printf ("this update ......: ");
      print_time (this_update);
      printf ("\nnext update ......: ");
      print_time (next_update);
      putchar ('\n');
      {
        int cert_idx;
        ksba_cert_t acert;

        for (cert_idx=0; (acert = ksba_ocsp_get_cert (ocsp, cert_idx));
             cert_idx++)
          ksba_cert_release (acert);
        printf ("extra certificates: %d\n", cert_idx );
      }

      {
        int idx, crit;
        const char *oid;
        const unsigned char *der;
        size_t derlen;
        
        for (idx=0; !(err=ksba_ocsp_get_extension (ocsp, NULL, idx,
                                                   &oid, &crit,
                                                   &der, &derlen)); idx++)
          {
            const char *s = get_oid_desc (oid);
            printf ("%sresp-extn ..%s: %s%s%s%s  (",
                    crit? "crit. ":"", 
                    crit?"":"......", 
                    s?"(":"", s?s:"", s?") ":"", oid);
            print_hex (der, derlen);
            putchar (')');
            putchar ('\n');
          }
        if (err && gpg_err_code (err) != GPG_ERR_EOF)
          fail_if_err (err);

        for (idx=0; !(err=ksba_ocsp_get_extension (ocsp, cert, idx,
                                                   &oid, &crit,
                                                   &der, &derlen)); idx++)
          {
            const char *s = get_oid_desc (oid);
            printf ("%ssngl-extn ..%s: %s%s%s%s  (",
                    crit? "crit. ":"", 
                    crit?"":"......", 
                    s?"(":"", s?s:"", s?") ":"", oid);
            print_hex (der, derlen);
            putchar (')');
            putchar ('\n');
          }
        if (err && gpg_err_code (err) != GPG_ERR_EOF)
          fail_if_err (err);
      }
    }
  

  ksba_cert_release (cert);
  ksba_ocsp_release (ocsp);
  xfree (response);
}