| Index: openssl/apps/ocsp.c
|
| ===================================================================
|
| --- openssl/apps/ocsp.c (revision 105093)
|
| +++ openssl/apps/ocsp.c (working copy)
|
| @@ -56,25 +56,53 @@
|
| *
|
| */
|
| #ifndef OPENSSL_NO_OCSP
|
| +
|
| +#ifdef OPENSSL_SYS_VMS
|
| +#define _XOPEN_SOURCE_EXTENDED /* So fd_set and friends get properly defined
|
| + on OpenVMS */
|
| +#endif
|
| +
|
| #define USE_SOCKETS
|
| +
|
| #include <stdio.h>
|
| #include <stdlib.h>
|
| #include <string.h>
|
| +#include <time.h>
|
| #include "apps.h" /* needs to be included before the openssl headers! */
|
| #include <openssl/e_os2.h>
|
| +#include <openssl/crypto.h>
|
| +#include <openssl/err.h>
|
| #include <openssl/ssl.h>
|
| -#include <openssl/err.h>
|
| +#include <openssl/evp.h>
|
| +#include <openssl/bn.h>
|
| +#include <openssl/x509v3.h>
|
|
|
| +#if defined(NETWARE_CLIB)
|
| +# ifdef NETWARE_BSDSOCK
|
| +# include <sys/socket.h>
|
| +# include <sys/bsdskt.h>
|
| +# else
|
| +# include <novsock2.h>
|
| +# endif
|
| +#elif defined(NETWARE_LIBC)
|
| +# ifdef NETWARE_BSDSOCK
|
| +# include <sys/select.h>
|
| +# else
|
| +# include <novsock2.h>
|
| +# endif
|
| +#endif
|
| +
|
| /* Maximum leeway in validity period: default 5 minutes */
|
| #define MAX_VALIDITY_PERIOD (5 * 60)
|
|
|
| -static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
|
| +static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md, X509 *issuer,
|
| STACK_OF(OCSP_CERTID) *ids);
|
| -static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
|
| +static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD * cert_id_md, X509 *issuer,
|
| STACK_OF(OCSP_CERTID) *ids);
|
| static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
|
| - STACK *names, STACK_OF(OCSP_CERTID) *ids,
|
| - long nsec, long maxage);
|
| + STACK_OF(OPENSSL_STRING) *names,
|
| + STACK_OF(OCSP_CERTID) *ids, long nsec,
|
| + long maxage);
|
|
|
| static int make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req, CA_DB *db,
|
| X509 *ca, X509 *rcert, EVP_PKEY *rkey,
|
| @@ -86,6 +114,7 @@
|
| static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port);
|
| static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
|
| static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
|
| + STACK_OF(CONF_VALUE) *headers,
|
| OCSP_REQUEST *req, int req_timeout);
|
|
|
| #undef PROG
|
| @@ -104,6 +133,7 @@
|
| char *rsignfile = NULL, *rkeyfile = NULL;
|
| char *outfile = NULL;
|
| int add_nonce = 1, noverify = 0, use_ssl = -1;
|
| + STACK_OF(CONF_VALUE) *headers = NULL;
|
| OCSP_REQUEST *req = NULL;
|
| OCSP_RESPONSE *resp = NULL;
|
| OCSP_BASICRESP *bs = NULL;
|
| @@ -126,7 +156,7 @@
|
| int badarg = 0;
|
| int i;
|
| int ignore_err = 0;
|
| - STACK *reqnames = NULL;
|
| + STACK_OF(OPENSSL_STRING) *reqnames = NULL;
|
| STACK_OF(OCSP_CERTID) *ids = NULL;
|
|
|
| X509 *rca_cert = NULL;
|
| @@ -134,6 +164,7 @@
|
| char *rca_filename = NULL;
|
| CA_DB *rdb = NULL;
|
| int nmin = 0, ndays = -1;
|
| + const EVP_MD *cert_id_md = NULL;
|
|
|
| if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
|
|
| @@ -142,7 +173,7 @@
|
| SSL_load_error_strings();
|
| OpenSSL_add_ssl_algorithms();
|
| args = argv + 1;
|
| - reqnames = sk_new_null();
|
| + reqnames = sk_OPENSSL_STRING_new_null();
|
| ids = sk_OCSP_CERTID_new_null();
|
| while (!badarg && *args && *args[0] == '-')
|
| {
|
| @@ -202,6 +233,16 @@
|
| }
|
| else badarg = 1;
|
| }
|
| + else if (!strcmp(*args, "-header"))
|
| + {
|
| + if (args[1] && args[2])
|
| + {
|
| + if (!X509V3_add_value(args[1], args[2], &headers))
|
| + goto end;
|
| + args += 2;
|
| + }
|
| + else badarg = 1;
|
| + }
|
| else if (!strcmp(*args, "-ignore_err"))
|
| ignore_err = 1;
|
| else if (!strcmp(*args, "-noverify"))
|
| @@ -401,9 +442,10 @@
|
| cert = load_cert(bio_err, *args, FORMAT_PEM,
|
| NULL, e, "certificate");
|
| if(!cert) goto end;
|
| - if(!add_ocsp_cert(&req, cert, issuer, ids))
|
| + if (!cert_id_md) cert_id_md = EVP_sha1();
|
| + if(!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
|
| goto end;
|
| - if(!sk_push(reqnames, *args))
|
| + if(!sk_OPENSSL_STRING_push(reqnames, *args))
|
| goto end;
|
| }
|
| else badarg = 1;
|
| @@ -413,9 +455,10 @@
|
| if (args[1])
|
| {
|
| args++;
|
| - if(!add_ocsp_serial(&req, *args, issuer, ids))
|
| + if (!cert_id_md) cert_id_md = EVP_sha1();
|
| + if(!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
|
| goto end;
|
| - if(!sk_push(reqnames, *args))
|
| + if(!sk_OPENSSL_STRING_push(reqnames, *args))
|
| goto end;
|
| }
|
| else badarg = 1;
|
| @@ -515,7 +558,10 @@
|
| }
|
| else badarg = 1;
|
| }
|
| - else badarg = 1;
|
| + else if ((cert_id_md = EVP_get_digestbyname((*args)+1))==NULL)
|
| + {
|
| + badarg = 1;
|
| + }
|
| args++;
|
| }
|
|
|
| @@ -571,6 +617,7 @@
|
| BIO_printf (bio_err, "-ndays n number of days before next update\n");
|
| BIO_printf (bio_err, "-resp_key_id identify reponse by signing certificate key ID\n");
|
| BIO_printf (bio_err, "-nrequest n number of requests to accept (default unlimited)\n");
|
| + BIO_printf (bio_err, "-<dgst alg> use specified digest in the request");
|
| goto end;
|
| }
|
|
|
| @@ -677,7 +724,8 @@
|
| "signer private key");
|
| if (!key)
|
| goto end;
|
| - if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
|
| +
|
| + if (!OCSP_request_sign(req, signer, key, NULL, sign_other, sign_flags))
|
| {
|
| BIO_printf(bio_err, "Error signing OCSP request\n");
|
| goto end;
|
| @@ -721,7 +769,7 @@
|
| {
|
| #ifndef OPENSSL_NO_SOCK
|
| resp = process_responder(bio_err, req, host, path,
|
| - port, use_ssl, req_timeout);
|
| + port, use_ssl, headers, req_timeout);
|
| if (!resp)
|
| goto end;
|
| #else
|
| @@ -866,10 +914,11 @@
|
| OCSP_REQUEST_free(req);
|
| OCSP_RESPONSE_free(resp);
|
| OCSP_BASICRESP_free(bs);
|
| - sk_free(reqnames);
|
| + sk_OPENSSL_STRING_free(reqnames);
|
| sk_OCSP_CERTID_free(ids);
|
| sk_X509_pop_free(sign_other, X509_free);
|
| sk_X509_pop_free(verify_other, X509_free);
|
| + sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
|
|
|
| if (use_ssl != -1)
|
| {
|
| @@ -881,7 +930,7 @@
|
| OPENSSL_EXIT(ret);
|
| }
|
|
|
| -static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer,
|
| +static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, const EVP_MD *cert_id_md,X509 *issuer,
|
| STACK_OF(OCSP_CERTID) *ids)
|
| {
|
| OCSP_CERTID *id;
|
| @@ -892,7 +941,7 @@
|
| }
|
| if(!*req) *req = OCSP_REQUEST_new();
|
| if(!*req) goto err;
|
| - id = OCSP_cert_to_id(NULL, cert, issuer);
|
| + id = OCSP_cert_to_id(cert_id_md, cert, issuer);
|
| if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
|
| if(!OCSP_request_add0_id(*req, id)) goto err;
|
| return 1;
|
| @@ -902,7 +951,7 @@
|
| return 0;
|
| }
|
|
|
| -static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
|
| +static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,const EVP_MD *cert_id_md, X509 *issuer,
|
| STACK_OF(OCSP_CERTID) *ids)
|
| {
|
| OCSP_CERTID *id;
|
| @@ -924,7 +973,7 @@
|
| BIO_printf(bio_err, "Error converting serial number %s\n", serial);
|
| return 0;
|
| }
|
| - id = OCSP_cert_id_new(EVP_sha1(), iname, ikey, sno);
|
| + id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
|
| ASN1_INTEGER_free(sno);
|
| if(!id || !sk_OCSP_CERTID_push(ids, id)) goto err;
|
| if(!OCSP_request_add0_id(*req, id)) goto err;
|
| @@ -936,8 +985,9 @@
|
| }
|
|
|
| static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
|
| - STACK *names, STACK_OF(OCSP_CERTID) *ids,
|
| - long nsec, long maxage)
|
| + STACK_OF(OPENSSL_STRING) *names,
|
| + STACK_OF(OCSP_CERTID) *ids, long nsec,
|
| + long maxage)
|
| {
|
| OCSP_CERTID *id;
|
| char *name;
|
| @@ -947,13 +997,13 @@
|
|
|
| ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
|
|
|
| - if (!bs || !req || !sk_num(names) || !sk_OCSP_CERTID_num(ids))
|
| + if (!bs || !req || !sk_OPENSSL_STRING_num(names) || !sk_OCSP_CERTID_num(ids))
|
| return 1;
|
|
|
| for (i = 0; i < sk_OCSP_CERTID_num(ids); i++)
|
| {
|
| id = sk_OCSP_CERTID_value(ids, i);
|
| - name = sk_value(names, i);
|
| + name = sk_OPENSSL_STRING_value(names, i);
|
| BIO_printf(out, "%s: ", name);
|
|
|
| if(!OCSP_resp_find_status(bs, id, &status, &reason,
|
| @@ -1010,7 +1060,6 @@
|
| OCSP_BASICRESP *bs = NULL;
|
| int i, id_count, ret = 1;
|
|
|
| -
|
| id_count = OCSP_request_onereq_count(req);
|
|
|
| if (id_count <= 0)
|
| @@ -1019,7 +1068,6 @@
|
| goto end;
|
| }
|
|
|
| - ca_id = OCSP_cert_to_id(EVP_sha1(), NULL, ca);
|
|
|
| bs = OCSP_BASICRESP_new();
|
| thisupd = X509_gmtime_adj(NULL, 0);
|
| @@ -1032,8 +1080,23 @@
|
| OCSP_ONEREQ *one;
|
| ASN1_INTEGER *serial;
|
| char **inf;
|
| + ASN1_OBJECT *cert_id_md_oid;
|
| + const EVP_MD *cert_id_md;
|
| one = OCSP_request_onereq_get0(req, i);
|
| cid = OCSP_onereq_get0_id(one);
|
| +
|
| + OCSP_id_get0_info(NULL,&cert_id_md_oid, NULL,NULL, cid);
|
| +
|
| + cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);
|
| + if (! cert_id_md)
|
| + {
|
| + *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
|
| + NULL);
|
| + goto end;
|
| + }
|
| + if (ca_id) OCSP_CERTID_free(ca_id);
|
| + ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
|
| +
|
| /* Is this request about our CA? */
|
| if (OCSP_id_issuer_cmp(ca_id, cid))
|
| {
|
| @@ -1078,8 +1141,8 @@
|
| }
|
|
|
| OCSP_copy_nonce(bs, req);
|
| -
|
| - OCSP_basic_sign(bs, rcert, rkey, EVP_sha1(), rother, flags);
|
| +
|
| + OCSP_basic_sign(bs, rcert, rkey, NULL, rother, flags);
|
|
|
| *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
|
|
|
| @@ -1211,10 +1274,12 @@
|
| }
|
|
|
| static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
|
| + STACK_OF(CONF_VALUE) *headers,
|
| OCSP_REQUEST *req, int req_timeout)
|
| {
|
| int fd;
|
| int rv;
|
| + int i;
|
| OCSP_REQ_CTX *ctx = NULL;
|
| OCSP_RESPONSE *rsp = NULL;
|
| fd_set confds;
|
| @@ -1231,16 +1296,13 @@
|
| return NULL;
|
| }
|
|
|
| - if (req_timeout == -1)
|
| - return OCSP_sendreq_bio(cbio, path, req);
|
| -
|
| if (BIO_get_fd(cbio, &fd) <= 0)
|
| {
|
| BIO_puts(err, "Can't get connection fd\n");
|
| goto err;
|
| }
|
|
|
| - if (rv <= 0)
|
| + if (req_timeout != -1 && rv <= 0)
|
| {
|
| FD_ZERO(&confds);
|
| openssl_fdset(fd, &confds);
|
| @@ -1255,15 +1317,27 @@
|
| }
|
|
|
|
|
| - ctx = OCSP_sendreq_new(cbio, path, req, -1);
|
| + ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
|
| if (!ctx)
|
| return NULL;
|
| +
|
| + for (i = 0; i < sk_CONF_VALUE_num(headers); i++)
|
| + {
|
| + CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
|
| + if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
|
| + goto err;
|
| + }
|
| +
|
| + if (!OCSP_REQ_CTX_set1_req(ctx, req))
|
| + goto err;
|
|
|
| for (;;)
|
| {
|
| rv = OCSP_sendreq_nbio(&rsp, ctx);
|
| if (rv != -1)
|
| break;
|
| + if (req_timeout == -1)
|
| + continue;
|
| FD_ZERO(&confds);
|
| openssl_fdset(fd, &confds);
|
| tv.tv_usec = 0;
|
| @@ -1287,7 +1361,7 @@
|
| BIO_puts(err, "Select error\n");
|
| break;
|
| }
|
| -
|
| +
|
| }
|
| err:
|
| if (ctx)
|
| @@ -1298,6 +1372,7 @@
|
|
|
| OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
|
| char *host, char *path, char *port, int use_ssl,
|
| + STACK_OF(CONF_VALUE) *headers,
|
| int req_timeout)
|
| {
|
| BIO *cbio = NULL;
|
| @@ -1332,14 +1407,14 @@
|
| sbio = BIO_new_ssl(ctx, 1);
|
| cbio = BIO_push(sbio, cbio);
|
| }
|
| - resp = query_responder(err, cbio, path, req, req_timeout);
|
| + resp = query_responder(err, cbio, path, headers, req, req_timeout);
|
| if (!resp)
|
| BIO_printf(bio_err, "Error querying OCSP responsder\n");
|
| end:
|
| + if (cbio)
|
| + BIO_free_all(cbio);
|
| if (ctx)
|
| SSL_CTX_free(ctx);
|
| - if (cbio)
|
| - BIO_free_all(cbio);
|
| return resp;
|
| }
|
|
|
|
|