/* ocsp_cl.c */
/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
 * project. */

/* History:
   This file was transfered to Richard Levitte from CertCo by Kathy
   Weinhold in mid-spring 2000 to be included in OpenSSL or released
   as a patch kit. */

/* ====================================================================
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include <time.h>
#include <cryptlib.h>
#include <openssl/objects.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/ocsp.h>

/* Utility functions related to sending OCSP requests and extracting
 * relevant information from the response.
 */

/* Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ 
 * pointer: useful if we want to add extensions.
 */

OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
        {
	OCSP_ONEREQ *one = NULL;

	if (!(one = OCSP_ONEREQ_new())) goto err;
	if (one->reqCert) OCSP_CERTID_free(one->reqCert);
	one->reqCert = cid;
	if (req &&
		!sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
				goto err;
	return one;
err:
	OCSP_ONEREQ_free(one);
	return NULL;
        }

/* Set requestorName from an X509_NAME structure */

int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
	{
	GENERAL_NAME *gen;
	gen = GENERAL_NAME_new();
	if (gen == NULL)
		return 0;
	if (!X509_NAME_set(&gen->d.directoryName, nm))
		{
		GENERAL_NAME_free(gen);
		return 0;
		}
	gen->type = GEN_DIRNAME;
	if (req->tbsRequest->requestorName)
		GENERAL_NAME_free(req->tbsRequest->requestorName);
	req->tbsRequest->requestorName = gen;
	return 1;
	}
	

/* Add a certificate to an OCSP request */

int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
	{
	OCSP_SIGNATURE *sig;
	if (!req->optionalSignature)
		req->optionalSignature = OCSP_SIGNATURE_new();
	sig = req->optionalSignature;
	if (!sig) return 0;
	if (!cert) return 1;
	if (!sig->certs && !(sig->certs = sk_X509_new_null()))
		return 0;

	if(!sk_X509_push(sig->certs, cert)) return 0;
	CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
	return 1;
	}

/* Sign an OCSP request set the requestorName to the subjec
 * name of an optional signers certificate and include one
 * or more optional certificates in the request. Behaves
 * like PKCS7_sign().
 */

int OCSP_request_sign(OCSP_REQUEST   *req,
		      X509           *signer,
		      EVP_PKEY       *key,
		      const EVP_MD   *dgst,
		      STACK_OF(X509) *certs,
		      unsigned long flags)
        {
	int i;
	OCSP_SIGNATURE *sig;
	X509 *x;

	if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
			goto err;

	if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err;
	if (!dgst) dgst = EVP_sha1();
	if (key)
		{
		if (!X509_check_private_key(signer, key))
			{
			OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
			goto err;
			}
		if (!OCSP_REQUEST_sign(req, key, dgst)) goto err;
		}

	if (!(flags & OCSP_NOCERTS))
		{
		if(!OCSP_request_add1_cert(req, signer)) goto err;
		for (i = 0; i < sk_X509_num(certs); i++)
			{
			x = sk_X509_value(certs, i);
			if (!OCSP_request_add1_cert(req, x)) goto err;
			}
		}

	return 1;
err:
	OCSP_SIGNATURE_free(req->optionalSignature);
	req->optionalSignature = NULL;
	return 0;
	}

/* Get response status */

int OCSP_response_status(OCSP_RESPONSE *resp)
	{
	return ASN1_ENUMERATED_get(resp->responseStatus);
	}

/* Extract basic response from OCSP_RESPONSE or NULL if
 * no basic response present.
 */
 

OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
	{
	OCSP_RESPBYTES *rb;
	rb = resp->responseBytes;
	if (!rb)
		{
		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
		return NULL;
		}
	if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic)
		{
		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
		return NULL;
		}

	return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
	}

/* Return number of OCSP_SINGLERESP reponses present in
 * a basic response.
 */

int OCSP_resp_count(OCSP_BASICRESP *bs)
	{
	if (!bs) return -1;
	return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses);
	}

/* Extract an OCSP_SINGLERESP response with a given index */

OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
	{
	if (!bs) return NULL;
	return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx);
	}

/* Look single response matching a given certificate ID */

int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
	{
	int i;
	STACK_OF(OCSP_SINGLERESP) *sresp;
	OCSP_SINGLERESP *single;
	if (!bs) return -1;
	if (last < 0) last = 0;
	else last++;
	sresp = bs->tbsResponseData->responses;
	for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++)
		{
		single = sk_OCSP_SINGLERESP_value(sresp, i);
		if (!OCSP_id_cmp(id, single->certId)) return i;
		}
	return -1;
	}

/* Extract status information from an OCSP_SINGLERESP structure.
 * Note: the revtime and reason values are only set if the 
 * certificate status is revoked. Returns numerical value of
 * status.
 */

int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
				ASN1_GENERALIZEDTIME **revtime,
				ASN1_GENERALIZEDTIME **thisupd,
				ASN1_GENERALIZEDTIME **nextupd)
	{
	int ret;
	OCSP_CERTSTATUS *cst;
	if(!single) return -1;
	cst = single->certStatus;
	ret = cst->type;
	if (ret == V_OCSP_CERTSTATUS_REVOKED)
		{
		OCSP_REVOKEDINFO *rev = cst->value.revoked;
		if (revtime) *revtime = rev->revocationTime;
		if (reason) 
			{
			if(rev->revocationReason)
				*reason = ASN1_ENUMERATED_get(rev->revocationReason);
			else *reason = -1;
			}
		}
	if(thisupd) *thisupd = single->thisUpdate;
	if(nextupd) *nextupd = single->nextUpdate;
	return ret;
	}

/* This function combines the previous ones: look up a certificate ID and
 * if found extract status information. Return 0 is successful.
 */

int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
				int *reason,
				ASN1_GENERALIZEDTIME **revtime,
				ASN1_GENERALIZEDTIME **thisupd,
				ASN1_GENERALIZEDTIME **nextupd)
	{
	int i;
	OCSP_SINGLERESP *single;
	i = OCSP_resp_find(bs, id, -1);
	/* Maybe check for multiple responses and give an error? */
	if(i < 0) return 0;
	single = OCSP_resp_get0(bs, i);
	i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
	if(status) *status = i;
	return 1;
	}

/* Check validity of thisUpdate and nextUpdate fields. It is possible that the request will
 * take a few seconds to process and/or the time wont be totally accurate. Therefore to avoid
 * rejecting otherwise valid time we allow the times to be within 'nsec' of the current time.
 * Also to avoid accepting very old responses without a nextUpdate field an optional maxage
 * parameter specifies the maximum age the thisUpdate field can be.
 */

int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
	{
	int ret = 1;
	time_t t_now, t_tmp;
	time(&t_now);
	/* Check thisUpdate is valid and not more than nsec in the future */
	if (!ASN1_GENERALIZEDTIME_check(thisupd))
		{
		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
		ret = 0;
		}
	else 
		{
			t_tmp = t_now + nsec;
			if (X509_cmp_time(thisupd, &t_tmp) > 0)
			{
			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID);
			ret = 0;
			}

		/* If maxsec specified check thisUpdate is not more than maxsec in the past */
		if (maxsec >= 0)
			{
			t_tmp = t_now - maxsec;
			if (X509_cmp_time(thisupd, &t_tmp) < 0)
				{
				OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD);
				ret = 0;
				}
			}
		}
		

	if (!nextupd) return ret;

	/* Check nextUpdate is valid and not more than nsec in the past */
	if (!ASN1_GENERALIZEDTIME_check(nextupd))
		{
		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
		ret = 0;
		}
	else 
		{
		t_tmp = t_now - nsec;
		if (X509_cmp_time(nextupd, &t_tmp) < 0)
			{
			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED);
			ret = 0;
			}
		}

	/* Also don't allow nextUpdate to precede thisUpdate */
	if (ASN1_STRING_cmp(nextupd, thisupd) < 0)
		{
		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
		ret = 0;
		}

	return ret;
	}
