Procházet zdrojové kódy

PR: 2064, 728
Submitted by: steve@openssl.org

Add support for custom headers in OCSP requests.

Dr. Stephen Henson před 14 roky
rodič
revize
18e503f30f
6 změnil soubory, kde provedl 84 přidání a 24 odebrání
  1. 4 0
      CHANGES
  2. 1 0
      apps/apps.h
  3. 34 8
      apps/ocsp.c
  4. 1 1
      apps/s_server.c
  5. 3 0
      crypto/ocsp/ocsp.h
  6. 41 15
      crypto/ocsp/ocsp_ht.c

+ 4 - 0
CHANGES

@@ -4,6 +4,10 @@
 
  Changes between 0.9.8k and 1.0  [xx XXX xxxx]
 
+  *) Update OCSP request code to permit adding custom headers to the request:
+     some responders need this.
+     [Steve Henson]
+
   *) Extensive audit of libcrypto with DEBUG_UNUSED. Fix many cases where
      return value is ignored. NB. The functions RAND_add(), RAND_seed(),
      BIO_set_cipher() and some obscure PEM functions were changed so they

+ 1 - 0
apps/apps.h

@@ -259,6 +259,7 @@ ENGINE *setup_engine(BIO *err, const char *engine, int debug);
 #ifndef OPENSSL_NO_OCSP
 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);
 #endif
 

+ 34 - 8
apps/ocsp.c

@@ -75,6 +75,7 @@
 #include <openssl/ssl.h>
 #include <openssl/evp.h>
 #include <openssl/bn.h>
+#include <openssl/x509v3.h>
 
 #if defined(NETWARE_CLIB)
 #  ifdef NETWARE_BSDSOCK
@@ -113,6 +114,7 @@ static BIO *init_responder(char *port);
 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
@@ -131,6 +133,7 @@ int MAIN(int argc, char **argv)
 	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;
@@ -230,6 +233,16 @@ int MAIN(int argc, char **argv)
 				}
 			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"))
@@ -756,7 +769,7 @@ int MAIN(int argc, char **argv)
 		{
 #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
@@ -905,6 +918,7 @@ end:
 	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)
 		{
@@ -1260,10 +1274,12 @@ 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)
 	{
 	int fd;
 	int rv;
+	int i;
 	OCSP_REQ_CTX *ctx = NULL;
 	OCSP_RESPONSE *rsp = NULL;
 	fd_set confds;
@@ -1280,16 +1296,13 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
 		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);
@@ -1304,15 +1317,27 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
 		}
 
 
-	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;
@@ -1336,7 +1361,7 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
 			BIO_puts(err, "Select error\n");
 			break;
 			}
-			
+
 		}
 	err:
 	if (ctx)
@@ -1347,6 +1372,7 @@ static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path,
 
 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;
@@ -1381,7 +1407,7 @@ OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
 		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:

+ 1 - 1
apps/s_server.c

@@ -787,7 +787,7 @@ BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids));
 		if (!OCSP_REQUEST_add_ext(req, ext, -1))
 			goto err;
 		}
-	resp = process_responder(err, req, host, path, port, use_ssl,
+	resp = process_responder(err, req, host, path, port, use_ssl, NULL,
 					srctx->timeout);
 	if (!resp)
 		{

+ 3 - 0
crypto/ocsp/ocsp.h

@@ -406,6 +406,9 @@ OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
 								int maxline);
 int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
 void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+		const char *name, const char *value);
 
 OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
 

+ 41 - 15
crypto/ocsp/ocsp_ht.c

@@ -118,39 +118,65 @@ void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
 	OPENSSL_free(rctx);
 	}
 
-OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
-								int maxline)
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
 	{
-	static const char post_hdr[] = "POST %s HTTP/1.0\r\n"
+	static const char req_hdr[] =
 	"Content-Type: application/ocsp-request\r\n"
 	"Content-Length: %d\r\n\r\n";
+        if (BIO_printf(rctx->mem, req_hdr, i2d_OCSP_REQUEST(req, NULL)) <= 0)
+		return 0;
+        if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
+		return 0;
+	rctx->state = OHS_ASN1_WRITE;
+	rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
+	return 1;
+	}
+
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+		const char *name, const char *value)
+	{
+	if (!name)
+		return 0;
+	if (BIO_puts(rctx->mem, name) <= 0)
+		return 0;
+	if (value)
+		{
+		if (BIO_write(rctx->mem, ": ", 2) != 2)
+			return 0;
+		if (BIO_puts(rctx->mem, value) <= 0)
+			return 0;
+		}
+	if (BIO_write(rctx->mem, "\r\n", 2) != 2)
+		return 0;
+	return 1;
+	}
+
+OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req,
+								int maxline)
+	{
+	static const char post_hdr[] = "POST %s HTTP/1.0\r\n";
 
 	OCSP_REQ_CTX *rctx;
 	rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX));
-	rctx->state = OHS_FIRSTLINE;
+	rctx->state = OHS_ERROR;
 	rctx->mem = BIO_new(BIO_s_mem());
 	rctx->io = io;
+	rctx->asn1_len = 0;
 	if (maxline > 0)
 		rctx->iobuflen = maxline;
 	else
 		rctx->iobuflen = OCSP_MAX_LINE_LEN;
 	rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
+	if (!rctx->iobuf)
+		return 0;
 	if (!path)
 		path = "/";
 
-        if (BIO_printf(rctx->mem, post_hdr, path,
-				i2d_OCSP_REQUEST(req, NULL)) <= 0)
-		{
-		rctx->state = OHS_ERROR;
+        if (BIO_printf(rctx->mem, post_hdr, path) <= 0)
 		return 0;
-		}
-        if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0)
-		{
-		rctx->state = OHS_ERROR;
+
+	if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
 		return 0;
-		}
-	rctx->state = OHS_ASN1_WRITE;
-	rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
 
 	return rctx;
 	}