/*
- * Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* on OpenVMS */
# endif
-# define USE_SOCKETS
-
# include <stdio.h>
# include <stdlib.h>
# include <string.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)
STACK_OF(OPENSSL_STRING) *names,
STACK_OF(OCSP_CERTID) *ids, long nsec,
long maxage);
-static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
+static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req,
CA_DB *db, STACK_OF(X509) *ca, X509 *rcert,
EVP_PKEY *rkey, const EVP_MD *md,
+ STACK_OF(OPENSSL_STRING) *sigopts,
STACK_OF(X509) *rother, unsigned long flags,
int nmin, int ndays, int badsig);
OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT,
OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL,
OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER,
- OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_HEADER,
+ OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_RSIGOPT, OPT_HEADER,
OPT_V_ENUM,
OPT_MD
} OPTION_CHOICE;
{"rkey", OPT_RKEY, '<', "Responder key to sign responses with"},
{"rother", OPT_ROTHER, '<', "Other certificates to include in response"},
{"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"},
+ {"rsigopt", OPT_RSIGOPT, 's', "OCSP response signature parameter in n:v form"},
{"header", OPT_HEADER, 's', "key=value header to add"},
{"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"},
OPT_V_OPTIONS,
{
BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL;
const EVP_MD *cert_id_md = NULL, *rsign_md = NULL;
+ STACK_OF(OPENSSL_STRING) *rsign_sigopts = NULL;
int trailing_md = 0;
CA_DB *rdb = NULL;
EVP_PKEY *key = NULL, *rkey = NULL;
if (!opt_md(opt_arg(), &rsign_md))
goto end;
break;
+ case OPT_RSIGOPT:
+ if (rsign_sigopts == NULL)
+ rsign_sigopts = sk_OPENSSL_STRING_new_null();
+ if (rsign_sigopts == NULL || !sk_OPENSSL_STRING_push(rsign_sigopts, opt_arg()))
+ goto end;
+ break;
case OPT_HEADER:
header = opt_arg();
value = strchr(header, '=');
}
if (rdb != NULL) {
- make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey,
- rsign_md, rother, rflags, nmin, ndays, badsig);
+ make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey,
+ rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, badsig);
if (cbio != NULL)
send_ocsp_response(cbio, resp);
} else if (host != NULL) {
X509_free(signer);
X509_STORE_free(store);
X509_VERIFY_PARAM_free(vpm);
+ sk_OPENSSL_STRING_free(rsign_sigopts);
EVP_PKEY_free(key);
EVP_PKEY_free(rkey);
X509_free(cert);
OPENSSL_free(tport);
OPENSSL_free(tpath);
- return (ret);
+ return ret;
}
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
}
}
-static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
+static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req,
CA_DB *db, STACK_OF(X509) *ca, X509 *rcert,
EVP_PKEY *rkey, const EVP_MD *rmd,
+ STACK_OF(OPENSSL_STRING) *sigopts,
STACK_OF(X509) *rother, unsigned long flags,
int nmin, int ndays, int badsig)
{
OCSP_CERTID *cid;
OCSP_BASICRESP *bs = NULL;
int i, id_count;
+ EVP_MD_CTX *mctx = NULL;
+ EVP_PKEY_CTX *pkctx = NULL;
id_count = OCSP_request_onereq_count(req);
OCSP_copy_nonce(bs, req);
- OCSP_basic_sign(bs, rcert, rkey, rmd, rother, flags);
+ mctx = EVP_MD_CTX_new();
+ if ( mctx == NULL || !EVP_DigestSignInit(mctx, &pkctx, rmd, NULL, rkey)) {
+ *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, NULL);
+ goto end;
+ }
+ for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
+ char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+
+ if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
+ BIO_printf(err, "parameter error \"%s\"\n", sigopt);
+ ERR_print_errors(bio_err);
+ *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
+ NULL);
+ goto end;
+ }
+ }
+ OCSP_basic_sign_ctx(bs, rcert, mctx, rother, flags);
if (badsig) {
const ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs);
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
end:
+ EVP_MD_CTX_free(mctx);
ASN1_TIME_free(thisupd);
ASN1_TIME_free(nextupd);
OCSP_BASICRESP_free(bs);
*pcbio = cbio;
/* Read the request line. */
- len = BIO_gets(cbio, reqbuf, sizeof reqbuf);
+ len = BIO_gets(cbio, reqbuf, sizeof(reqbuf));
if (len <= 0)
return 1;
if (strncmp(reqbuf, "GET ", 4) == 0) {
if (*q == ' ')
break;
if (strncmp(q, " HTTP/1.", 8) != 0) {
- BIO_printf(bio_err, "Invalid request -- bad HTTP vesion\n");
+ BIO_printf(bio_err, "Invalid request -- bad HTTP version\n");
return 1;
}
*q = '\0';
/* Read and skip past the headers. */
for (;;) {
- len = BIO_gets(cbio, inbuf, sizeof inbuf);
+ len = BIO_gets(cbio, inbuf, sizeof(inbuf));
if (len <= 0)
return 1;
if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))