BIO_printf (bio_err, "-rsigner file	 responder certificate to sign requests with\n"); BIO_printf (bio_err, "-rkey file	 responder key to sign requests with\n");
BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n"); BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
int MAIN(int argc, char **argv)	{	ENGINE *e = NULL;	char **args;	char *host = NULL, *port = NULL, *path = "/";	char *reqin = NULL, *respin = NULL;	char *reqout = NULL, *respout = NULL;	char *signfile = NULL, *keyfile = NULL;	char *rsignfile = NULL, *rkeyfile = NULL;	char *outfile = NULL;	int add_nonce = 1, noverify = 0, use_ssl = -1;	OCSP_REQUEST *req = NULL;	OCSP_RESPONSE *resp = NULL;	OCSP_BASICRESP *bs = NULL;	X509 *issuer = NULL, *cert = NULL;	X509 *signer = NULL, *rsigner = NULL;	EVP_PKEY *key = NULL, *rkey = NULL;	BIO *acbio = NULL, *cbio = NULL;	BIO *derbio = NULL;	BIO *out = NULL;	int req_text = 0, resp_text = 0;	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;	char *CAfile = NULL, *CApath = NULL;	X509_STORE *store = NULL;	SSL_CTX *ctx = NULL;	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;	int ret = 1;	int accept_count = -1;	int badarg = 0;	int i;	STACK *reqnames = NULL;	STACK_OF(OCSP_CERTID) *ids = NULL;	X509 *rca_cert = NULL;	char *ridx_filename = NULL;	char *rca_filename = NULL;	TXT_DB *rdb = NULL;	int nmin = 0, ndays = -1;	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);	if (!load_config(bio_err, NULL))		goto end;	SSL_load_error_strings();	args = argv + 1;	reqnames = sk_new_null();	ids = sk_OCSP_CERTID_new_null();	while (!badarg && *args && *args[0] == '-')		{		if (!strcmp(*args, "-out"))			{			if (args[1])				{				args++;				outfile = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-url"))			{			if (args[1])				{				args++;				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))					{					BIO_printf(bio_err, "Error parsing URL\n");					badarg = 1;					}				}			else badarg = 1;			}		else if (!strcmp(*args, "-host"))			{			if (args[1])				{				args++;				host = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-port"))			{			if (args[1])				{				args++;				port = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-noverify"))			noverify = 1;		else if (!strcmp(*args, "-nonce"))			add_nonce = 2;		else if (!strcmp(*args, "-no_nonce"))			add_nonce = 0;		else if (!strcmp(*args, "-resp_no_certs"))			rflags |= OCSP_NOCERTS;		else if (!strcmp(*args, "-resp_key_id"))			rflags |= OCSP_RESPID_KEY;		else if (!strcmp(*args, "-no_certs"))			sign_flags |= OCSP_NOCERTS;		else if (!strcmp(*args, "-no_signature_verify"))			verify_flags |= OCSP_NOSIGS;		else if (!strcmp(*args, "-no_cert_verify"))			verify_flags |= OCSP_NOVERIFY;		else if (!strcmp(*args, "-no_chain"))			verify_flags |= OCSP_NOCHAIN;		else if (!strcmp(*args, "-no_cert_checks"))			verify_flags |= OCSP_NOCHECKS;		else if (!strcmp(*args, "-no_explicit"))			verify_flags |= OCSP_NOEXPLICIT;		else if (!strcmp(*args, "-trust_other"))			verify_flags |= OCSP_TRUSTOTHER;		else if (!strcmp(*args, "-no_intern"))			verify_flags |= OCSP_NOINTERN;		else if (!strcmp(*args, "-text"))			{			req_text = 1;			resp_text = 1;			}		else if (!strcmp(*args, "-req_text"))			req_text = 1;		else if (!strcmp(*args, "-resp_text"))			resp_text = 1;		else if (!strcmp(*args, "-reqin"))			{			if (args[1])				{				args++;				reqin = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-respin"))			{			if (args[1])				{				args++;				respin = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-signer"))			{			if (args[1])				{				args++;				signfile = *args;				}			else badarg = 1;			}		else if (!strcmp (*args, "-VAfile"))			{			if (args[1])				{				args++;				verify_certfile = *args;				verify_flags |= OCSP_TRUSTOTHER;				}			else badarg = 1;			}		else if (!strcmp(*args, "-sign_other"))			{			if (args[1])				{				args++;				sign_certfile = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-verify_other"))			{			if (args[1])				{				args++;				verify_certfile = *args;				}			else badarg = 1;			}		else if (!strcmp (*args, "-CAfile"))			{			if (args[1])				{				args++;				CAfile = *args;				}			else badarg = 1;			}		else if (!strcmp (*args, "-CApath"))			{			if (args[1])				{				args++;				CApath = *args;				}			else badarg = 1;			}		else if (!strcmp (*args, "-validity_period"))			{			if (args[1])				{				args++;				nsec = atol(*args);				if (nsec < 0)					{					BIO_printf(bio_err,						"Illegal validity period %s\n",						*args);					badarg = 1;					}				}			else badarg = 1;			}		else if (!strcmp (*args, "-status_age"))			{			if (args[1])				{				args++;				maxage = atol(*args);				if (maxage < 0)					{					BIO_printf(bio_err,						"Illegal validity age %s\n",						*args);					badarg = 1;					}				}			else badarg = 1;			}		 else if (!strcmp(*args, "-signkey"))			{			if (args[1])				{				args++;				keyfile = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-reqout"))			{			if (args[1])				{				args++;				reqout = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-respout"))			{			if (args[1])				{				args++;				respout = *args;				}			else badarg = 1;			}		 else if (!strcmp(*args, "-path"))			{			if (args[1])				{				args++;				path = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-issuer"))			{			if (args[1])				{				args++;				X509_free(issuer);				issuer = load_cert(bio_err, *args, FORMAT_PEM,					NULL, e, "issuer certificate");				if(!issuer) goto end;				}			else badarg = 1;			}		else if (!strcmp (*args, "-cert"))			{			if (args[1])				{				args++;				X509_free(cert);				cert = load_cert(bio_err, *args, FORMAT_PEM,					NULL, e, "certificate");				if(!cert) goto end;				if(!add_ocsp_cert(&req, cert, issuer, ids))					goto end;				if(!sk_push(reqnames, *args))					goto end;				}			else badarg = 1;			}		else if (!strcmp(*args, "-serial"))			{			if (args[1])				{				args++;				if(!add_ocsp_serial(&req, *args, issuer, ids))					goto end;				if(!sk_push(reqnames, *args))					goto end;				}			else badarg = 1;			}		else if (!strcmp(*args, "-index"))			{			if (args[1])				{				args++;				ridx_filename = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-CA"))			{			if (args[1])				{				args++;				rca_filename = *args;				}			else badarg = 1;			}		else if (!strcmp (*args, "-nmin"))			{			if (args[1])				{				args++;				nmin = atol(*args);				if (nmin < 0)					{					BIO_printf(bio_err,						"Illegal update period %s\n",						*args);					badarg = 1;					}				}				if (ndays == -1)					ndays = 0;			else badarg = 1;			}		else if (!strcmp (*args, "-nrequest"))			{			if (args[1])				{				args++;				accept_count = atol(*args);				if (accept_count < 0)					{					BIO_printf(bio_err,						"Illegal accept count %s\n",						*args);					badarg = 1;					}				}			else badarg = 1;			}		else if (!strcmp (*args, "-ndays"))			{			if (args[1])				{				args++;				ndays = atol(*args);				if (ndays < 0)					{					BIO_printf(bio_err,						"Illegal update period %s\n",						*args);					badarg = 1;					}				}			else badarg = 1;			}		else if (!strcmp(*args, "-rsigner"))			{			if (args[1])				{				args++;				rsignfile = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-rkey"))			{			if (args[1])				{				args++;				rkeyfile = *args;				}			else badarg = 1;			}		else if (!strcmp(*args, "-rother"))			{			if (args[1])				{				args++;				rcertfile = *args;				}			else badarg = 1;			}		else badarg = 1;		args++;		}	/* Have we anything to do? */	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;	if (badarg)		{		BIO_printf (bio_err, "OCSP utility\n");		BIO_printf (bio_err, "Usage ocsp [options]\n");		BIO_printf (bio_err, "where options are\n");		BIO_printf (bio_err, "-out file          output filename\n");		BIO_printf (bio_err, "-issuer file       issuer certificate\n");		BIO_printf (bio_err, "-cert file         certificate to check\n");		BIO_printf (bio_err, "-serial n          serial number to check\n");		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");		BIO_printf (bio_err, "-sign_certs file   additional certificates to include in signed request\n");		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");		BIO_printf (bio_err, "-req_text          print text form of request\n");		BIO_printf (bio_err, "-resp_text         print text form of response\n");		BIO_printf (bio_err, "-text              print text form of request and response\n");		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");		BIO_printf (bio_err, "-path              path to use in OCSP request\n");		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");		BIO_printf (bio_err, "-noverify          don't verify response at all\n");		BIO_printf (bio_err, "-verify_certs file additional certificates to search for signer\n");		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");		BIO_printf (bio_err, "-no_sig_verify     don't check signature on response\n");		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");		BIO_printf (bio_err, "-port num		 port to run responder on\n");		BIO_printf (bio_err, "-index file	 certificate status index file\n");		BIO_printf (bio_err, "-CA file		 CA certificate\n");		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign requests with\n");		BIO_printf (bio_err, "-rkey file	 responder key to sign requests with\n");		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");		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");		goto end;		}	if(outfile) out = BIO_new_file(outfile, "w");	else out = BIO_new_fp(stdout, BIO_NOCLOSE);	if(!out)		{		BIO_printf(bio_err, "Error opening output file\n");		goto end;		}	if (!req && (add_nonce != 2)) add_nonce = 0;	if (!req && reqin)		{		derbio = BIO_new_file(reqin, "rb");		if (!derbio)			{			BIO_printf(bio_err, "Error Opening OCSP request file\n");			goto end;			}		req = d2i_OCSP_REQUEST_bio(derbio, NULL);		BIO_free(derbio);		if(!req)			{			BIO_printf(bio_err, "Error reading OCSP request\n");			goto end;			}		}	if (!req && port)		{		acbio = init_responder(port);		if (!acbio)			goto end;		}	if (rsignfile && !rdb)		{		if (!rkeyfile) rkeyfile = rsignfile;		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,			NULL, e, "responder certificate");		if (!rsigner)			{			BIO_printf(bio_err, "Error loading responder certificate\n");			goto end;			}		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,			NULL, e, "CA certificate");		if (rcertfile)			{			rother = load_certs(bio_err, sign_certfile, FORMAT_PEM,				NULL, e, "responder other certificates");			if (!sign_other) goto end;			}		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, NULL, NULL,			"responder private key");		if (!rkey)			goto end;		}	if(acbio)		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");	redo_accept:	if (acbio)		{		if (!do_responder(&req, &cbio, acbio, port))			goto end;		if (!req)			{			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);			send_ocsp_response(cbio, resp);			goto done_resp;			}		}	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))		{		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");		goto end;		}	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);	if (signfile)		{		if (!keyfile) keyfile = signfile;		signer = load_cert(bio_err, signfile, FORMAT_PEM,			NULL, e, "signer certificate");		if (!signer)			{			BIO_printf(bio_err, "Error loading signer certificate\n");			goto end;			}		if (sign_certfile)			{			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,				NULL, e, "signer certificates");			if (!sign_other) goto end;			}		key = load_key(bio_err, keyfile, FORMAT_PEM, NULL, NULL,			"signer private key");		if (!key)			goto end;		if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))			{			BIO_printf(bio_err, "Error signing OCSP request\n");			goto end;			}		}	if (req_text && req) OCSP_REQUEST_print(out, req, 0);	if (ridx_filename && (!rkey || !rsigner || !rca_cert))		{		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");		goto end;		}	if (ridx_filename && !rdb)		{		BIO *db_bio = NULL;		db_bio = BIO_new_file(ridx_filename, "r");		if (!db_bio)			{			BIO_printf(bio_err, "Error opening index file %s\n", ridx_filename);			goto end;			}		rdb = TXT_DB_read(db_bio, DB_NUMBER);		BIO_free(db_bio);		if (!rdb)			{			BIO_printf(bio_err, "Error reading index file %s\n", ridx_filename);			goto end;			}		if (!make_serial_index(rdb))			goto end;		}	if (rdb)		{		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);		if (cbio)			send_ocsp_response(cbio, resp);		}	else if (host)		{		cbio = BIO_new_connect(host);		if (!cbio)			{			BIO_printf(bio_err, "Error creating connect BIO\n");			goto end;			}		if (port) BIO_set_conn_port(cbio, port);		if (use_ssl == 1)			{			BIO *sbio;			ctx = SSL_CTX_new(SSLv23_client_method());			SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);			sbio = BIO_new_ssl(ctx, 1);			cbio = BIO_push(sbio, cbio);			}		if (BIO_do_connect(cbio) <= 0)			{			BIO_printf(bio_err, "Error connecting BIO\n");			goto end;			}		resp = OCSP_sendreq_bio(cbio, path, req);		BIO_free_all(cbio);		cbio = NULL;		if (!resp)			{			BIO_printf(bio_err, "Error querying OCSP responsder\n");			goto end;			}		}	else if (respin)		{		derbio = BIO_new_file(respin, "rb");		if (!derbio)			{			BIO_printf(bio_err, "Error Opening OCSP response file\n");			goto end;			}		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);		BIO_free(derbio);		if(!resp)			{			BIO_printf(bio_err, "Error reading OCSP response\n");			goto end;			}			}	else		{		ret = 0;		goto end;		}	done_resp:	if (respout)		{		derbio = BIO_new_file(respout, "wb");		if(!derbio)			{			BIO_printf(bio_err, "Error opening file %s\n", respout);			goto end;			}		i2d_OCSP_RESPONSE_bio(derbio, resp);		BIO_free(derbio);		}	i = OCSP_response_status(resp);	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)		{		BIO_printf(out, "Responder Error: %s (%ld)\n",				OCSP_response_status_str(i), i);		ret = 0;		goto end;		}	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);	/* If running as responder don't verify our own response */	if (cbio)		{		if (accept_count > 0)			accept_count--;		/* Redo if more connections needed */		if (accept_count)			{			BIO_free_all(cbio);			cbio = NULL;			OCSP_REQUEST_free(req);			req = NULL;			OCSP_RESPONSE_free(resp);			resp = NULL;			goto redo_accept;			}		goto end;		}	if (!store)		store = setup_verify(bio_err, CAfile, CApath);	if (verify_certfile)		{		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,			NULL, e, "validator certificate");		if (!verify_other) goto end;		}	bs = OCSP_response_get1_basic(resp);	if (!bs)		{		BIO_printf(bio_err, "Error parsing response\n");		goto end;		}	if (!noverify)		{		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))			{			if (i == -1)				BIO_printf(bio_err, "WARNING: no nonce in response\n");			else				{				BIO_printf(bio_err, "Nonce Verify error\n");				goto end;				}			}		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);                if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);		if(i <= 0)			{			BIO_printf(bio_err, "Response Verify Failure\n", i);			ERR_print_errors(bio_err);			}		else			BIO_printf(bio_err, "Response verify OK\n");		}	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))		goto end;	ret = 0;end:	ERR_print_errors(bio_err);	X509_free(signer);	X509_STORE_free(store);	EVP_PKEY_free(key);	EVP_PKEY_free(rkey);	X509_free(issuer);	X509_free(cert);	X509_free(rsigner);	X509_free(rca_cert);	TXT_DB_free(rdb);	BIO_free_all(cbio);	BIO_free_all(acbio);	BIO_free(out);	OCSP_REQUEST_free(req);	OCSP_RESPONSE_free(resp);	OCSP_BASICRESP_free(bs);	sk_free(reqnames);	sk_OCSP_CERTID_free(ids);	sk_X509_pop_free(sign_other, X509_free);	sk_X509_pop_free(verify_other, X509_free);	if (use_ssl != -1)		{		OPENSSL_free(host);		OPENSSL_free(port);		OPENSSL_free(path);		SSL_CTX_free(ctx);		}	EXIT(ret);}