14ee2ad04344446e610172a0e73949212923014dfSebastian Redl/* ocsp_cl.c */
22cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
32cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * project. */
42cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
52cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/* History:
62cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   This file was transfered to Richard Levitte from CertCo by Kathy
72cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   Weinhold in mid-spring 2000 to be included in OpenSSL or released
82cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor   as a patch kit. */
92cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
10a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl/* ====================================================================
112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor *
132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * Redistribution and use in source and binary forms, with or without
147faa2ec03a7ef120ac165bb45b6c70a8b20c9f1cSebastian Redl * modification, are permitted provided that the following conditions
150eca89e9890db4d8336ce762a5b359a1d58ca02bArgyrios Kyrtzidis * are met:
16e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor *
17e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor * 1. Redistributions of source code must retain the above copyright
182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor *    notice, this list of conditions and the following disclaimer.
192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor *
202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * 2. Redistributions in binary form must reproduce the above copyright
212a7fb27913999d132cf9e10e03dc5271faa2e9d3John McCall *    notice, this list of conditions and the following disclaimer in
2289eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis *    the documentation and/or other materials provided with the
230b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor *    distribution.
247a1fad38256eb4c5129359be85ba1ea1678eb5c9John McCall *
252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * 3. All advertising materials mentioning features or use of this
26a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall *    software must display the following acknowledgment:
276ab7cd853e9c15cf986a8a7c3db1f8d20e275409Sebastian Redl *    "This product includes software developed by the OpenSSL Project
287c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
296a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor *
307c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
3183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff *    endorse or promote products derived from this software without
3214f79002e58556798e86168c63e48d533287eda5Douglas Gregor *    prior written permission. For written permission, please contact
3310e286aa8d39fb51a21412850265d9dae74613eeChris Lattner *    openssl-core@openssl.org.
343251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor *
3514f79002e58556798e86168c63e48d533287eda5Douglas Gregor * 5. Products derived from this software may not be called "OpenSSL"
36bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor *    nor may "OpenSSL" appear in their names without prior written
372bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregor *    permission of the OpenSSL Project.
38ab41e63821dc60ad144d0684df8d79a9eef86b75Douglas Gregor *
390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor * 6. Redistributions of any form whatsoever must retain the following
4017fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor *    acknowledgment:
4117fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor *    "This product includes software developed by the OpenSSL Project
422596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor *
44fbfd180495e7800975c6d9bdc6d24e706ef70e34Michael J. Spencer * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4514f79002e58556798e86168c63e48d533287eda5Douglas Gregor * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4603013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
483c304bd9ec2b4611572d4cbae9e1727bbecb5dc9Chris Lattner * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
528538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner * OF THE POSSIBILITY OF SUCH DAMAGE.
565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner * ====================================================================
575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner *
586e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer * This product includes cryptographic software written by Eric Young
59ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl * (eay@cryptsoft.com).  This product includes software written by Tim
606e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer * Hudson (tjh@cryptsoft.com).
616e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer *
625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner */
635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner
646e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer#include <stdio.h>
65ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl#include <time.h>
66ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl#include <cryptlib.h>
672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <openssl/objects.h>
682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <openssl/rand.h>
692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <openssl/x509.h>
7012b1c7615d4f9a2edc544be499f895f16ac100edChris Lattner#include <openssl/pem.h>
712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <openssl/x509v3.h>
723397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl#include <openssl/ocsp.h>
73a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl
7489eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis/* Utility functions related to sending OCSP requests and extracting
752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * relevant information from the response.
762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor */
772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
788538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl/* Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ
792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * pointer: useful if we want to add extensions.
8089eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis */
818538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl
822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas GregorOCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        {
842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	OCSP_ONEREQ *one = NULL;
852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	if (!(one = OCSP_ONEREQ_new())) goto err;
872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	if (one->reqCert) OCSP_CERTID_free(one->reqCert);
882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	one->reqCert = cid;
892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	if (req &&
902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		!sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor				goto err;
922cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	return one;
933397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlerr:
94b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie	OCSP_ONEREQ_free(one);
952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	return NULL;
962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        }
973397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl
982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/* Set requestorName from an X509_NAME structure */
998538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl
1002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorint OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
1012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	{
1023397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	GENERAL_NAME *gen;
1032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	gen = GENERAL_NAME_new();
1048538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	if (gen == NULL)
1052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		return 0;
1062cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	if (!X509_NAME_set(&gen->d.directoryName, nm))
1073397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl		{
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump		GENERAL_NAME_free(gen);
1098538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl		return 0;
1102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		}
1112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	gen->type = GEN_DIRNAME;
1123397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	if (req->tbsRequest->requestorName)
113df1550fc59b51681d37225934fe4e3acac321621Richard Smith		GENERAL_NAME_free(req->tbsRequest->requestorName);
114df1550fc59b51681d37225934fe4e3acac321621Richard Smith	req->tbsRequest->requestorName = gen;
1158538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	return 1;
1162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	}
1172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1183397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl
119df1550fc59b51681d37225934fe4e3acac321621Richard Smith/* Add a certificate to an OCSP request */
1208538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl
1212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorint OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
1222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	{
1233397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	OCSP_SIGNATURE *sig;
1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump	if (!req->optionalSignature)
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump		req->optionalSignature = OCSP_SIGNATURE_new();
1268538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	sig = req->optionalSignature;
1272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	if (!sig) return 0;
1282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	if (!cert) return 1;
1293397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	if (!sig->certs && !(sig->certs = sk_X509_new_null()))
1302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		return 0;
1312cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1320953e767ff7817f97b3ab20896b229891eeff45bJohn McCall	if(!sk_X509_push(sig->certs, cert)) return 0;
1332cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
1342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	return 1;
1353397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	}
1362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/* Sign an OCSP request set the requestorName to the subjec
1388538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl * name of an optional signers certificate and include one
1392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * or more optional certificates in the request. Behaves
1402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * like PKCS7_sign().
1413397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl */
1422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1438538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlint OCSP_request_sign(OCSP_REQUEST   *req,
1442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		      X509           *signer,
1452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		      EVP_PKEY       *key,
1463397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl		      const EVP_MD   *dgst,
1472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		      STACK_OF(X509) *certs,
1487e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor		      unsigned long flags)
1497e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor        {
150c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor	int i;
1518538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	OCSP_SIGNATURE *sig;
1522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	X509 *x;
1532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1543397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
1552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor			goto err;
1562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
157e86d78cf4754a6aef2cf9a33d847aa15338e276fBob Wilson	if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err;
1588538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	if (key)
1592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		{
1602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		if (!X509_check_private_key(signer, key))
1613397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl			{
1622cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor			OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
1638538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl			goto err;
1642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor			}
1652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		if (!OCSP_REQUEST_sign(req, key, dgst)) goto err;
1663397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl		}
1672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
168264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola	if (!(flags & OCSP_NOCERTS))
169264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola		{
170a49218e17bcbb1acde0245773173e2c0c42f4f19Eli Friedman		if(!OCSP_request_add1_cert(req, signer)) goto err;
171425ef72306d4ff6b3698b744353e5f0e56b4b884Rafael Espindola		for (i = 0; i < sk_X509_num(certs); i++)
172ab8bbf4ebd3e3e6eab913cb044772a62b7581941Douglas Gregor			{
173264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola			x = sk_X509_value(certs, i);
174f85e193739c953358c865005855253af4f68a497John McCall			if (!OCSP_request_add1_cert(req, x)) goto err;
1752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor			}
1762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		}
1773397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl
1782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	return 1;
1798538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlerr:
1802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	OCSP_SIGNATURE_free(req->optionalSignature);
1812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	req->optionalSignature = NULL;
1823397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	return 0;
1832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	}
1842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/* Get response status */
1862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorint OCSP_response_status(OCSP_RESPONSE *resp)
188eefb3d5b49c844347f212073a7e975b8118fe8e9Richard Smith	{
1892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	return ASN1_ENUMERATED_get(resp->responseStatus);
190c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor	}
19160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl
19260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl/* Extract basic response from OCSP_RESPONSE or NULL if
19360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl * no basic response present.
19460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl */
19560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl
19660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl
19760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian RedlOCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
19860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl	{
1998538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	OCSP_RESPBYTES *rb;
2002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	rb = resp->responseBytes;
2012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	if (!rb)
2023397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl		{
203ed97649e9574b9d854fa4d6109c9333ae0993554John McCall		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
2048538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl		return NULL;
205ed97649e9574b9d854fa4d6109c9333ae0993554John McCall		}
206ed97649e9574b9d854fa4d6109c9333ae0993554John McCall	if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic)
2073397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl		{
2082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
2099763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis		return NULL;
2109763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis		}
2118538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl
2122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
2132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	}
2143397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl
215c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor/* Return number of OCSP_SINGLERESP reponses present in
2168538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl * a basic response.
2172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor */
2182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
2193397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlint OCSP_resp_count(OCSP_BASICRESP *bs)
2202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	{
2218538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	if (!bs) return -1;
2222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses);
2232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	}
2243397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl
225f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregor/* Extract an OCSP_SINGLERESP response with a given index */
226395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson
2278538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian RedlOCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
228395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson	{
229395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson	if (!bs) return NULL;
230ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt	return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx);
231ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt	}
232ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
233ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt/* Look single response matching a given certificate ID */
234ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
235ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntint OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
236ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt	{
23734b41d939a1328f484511c6002ba2456db879a29Richard Smith	int i;
23834b41d939a1328f484511c6002ba2456db879a29Richard Smith	STACK_OF(OCSP_SINGLERESP) *sresp;
23934b41d939a1328f484511c6002ba2456db879a29Richard Smith	OCSP_SINGLERESP *single;
24034b41d939a1328f484511c6002ba2456db879a29Richard Smith	if (!bs) return -1;
24134b41d939a1328f484511c6002ba2456db879a29Richard Smith	if (last < 0) last = 0;
2423397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	else last++;
243be191100e034b23a3e13053757a57b7f5068c24aArgyrios Kyrtzidis	sresp = bs->tbsResponseData->responses;
24456ca8a9c0fabd65418e9b2fd85140f4ed7d3c187Douglas Gregor	for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++)
2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump		{
2462cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		single = sk_OCSP_SINGLERESP_value(sresp, i);
2472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		if (!OCSP_id_cmp(id, single->certId)) return i;
2482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		}
2493397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	return -1;
2502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	}
2518538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl
2522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/* Extract status information from an OCSP_SINGLERESP structure.
2532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * Note: the revtime and reason values are only set if the
2543397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl * certificate status is revoked. Returns numerical value of
2552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor * status.
2568538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl */
2572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
2582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorint OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
2599d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall				ASN1_GENERALIZEDTIME **revtime,
2609d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall				ASN1_GENERALIZEDTIME **thisupd,
2619d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall				ASN1_GENERALIZEDTIME **nextupd)
2629d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall	{
2639d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall	int ret;
2649d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall	OCSP_CERTSTATUS *cst;
2659d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall	if(!single) return -1;
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump	cst = single->certStatus;
2673397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	ret = cst->type;
26849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall	if (ret == V_OCSP_CERTSTATUS_REVOKED)
26949a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall		{
27049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall		OCSP_REVOKEDINFO *rev = cst->value.revoked;
2718538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl		if (revtime) *revtime = rev->revocationTime;
27249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall		if (reason)
27349a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall			{
27449a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall			if(rev->revocationReason)
275c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor				*reason = ASN1_ENUMERATED_get(rev->revocationReason);
276c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor			else *reason = -1;
277c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor			}
278c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor		}
279c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor	if(thisupd) *thisupd = single->thisUpdate;
280c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor	if(nextupd) *nextupd = single->nextUpdate;
281c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor	return ret;
282c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor	}
2833397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl
2842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/* This function combines the previous ones: look up a certificate ID and
285be191100e034b23a3e13053757a57b7f5068c24aArgyrios Kyrtzidis * if found extract status information. Return 0 is successful.
28690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis */
28790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis
28890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidisint OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
28990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis				int *reason,
29090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis				ASN1_GENERALIZEDTIME **revtime,
2913e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith				ASN1_GENERALIZEDTIME **thisupd,
2923e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith				ASN1_GENERALIZEDTIME **nextupd)
2939763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis	{
2949763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis	int i;
2958538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	OCSP_SINGLERESP *single;
29690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis	i = OCSP_resp_find(bs, id, -1);
29790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis	/* Maybe check for multiple responses and give an error? */
29890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis	if(i < 0) return 0;
2993397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	single = OCSP_resp_get0(bs, i);
300ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis	i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
301ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis	if(status) *status = i;
302ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis	return 1;
3038538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	}
30490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis
30590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis/* Check validity of thisUpdate and nextUpdate fields. It is possible that the request will
30690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis * take a few seconds to process and/or the time wont be totally accurate. Therefore to avoid
3073397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl * rejecting otherwise valid time we allow the times to be within 'nsec' of the current time.
30890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis * Also to avoid accepting very old responses without a nextUpdate field an optional maxage
30990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis * parameter specifies the maximum age the thisUpdate field can be.
310b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie */
31190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis
31290b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidisint OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
31390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis	{
3143397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	int ret = 1;
31590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis	time_t t_now, t_tmp;
31690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis	time(&t_now);
31790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis	/* Check thisUpdate is valid and not more than nsec in the future */
3184fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth	if (!ASN1_GENERALIZEDTIME_check(thisupd))
3198538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl		{
32090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
32190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis		ret = 0;
32290b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis		}
3233397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl	else
3248dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis		{
3258dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis			t_tmp = t_now + nsec;
3268dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis			if (X509_cmp_time(thisupd, &t_tmp) > 0)
327f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis			{
328f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID);
329f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis			ret = 0;
3308538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl			}
33190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis
33290b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis		/* If maxsec specified check thisUpdate is not more than maxsec in the past */
33390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis		if (maxsec >= 0)
3343397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl			{
33590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis			t_tmp = t_now - maxsec;
3363acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis			if (X509_cmp_time(thisupd, &t_tmp) < 0)
3373acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis				{
3383acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis				OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD);
3393acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis				ret = 0;
3403acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis				}
3413acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis			}
3423acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis		}
3438538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl
3442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
3452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor	if (!nextupd) return ret;
3467536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor
3477536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor	/* Check nextUpdate is valid and not more than nsec in the past */
348cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor	if (!ASN1_GENERALIZEDTIME_check(nextupd))
349cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor		{
350cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
351cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor		ret = 0;
3527536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor		}
3537536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor	else
3547536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor		{
355075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara		t_tmp = t_now - nsec;
356075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara		if (X509_cmp_time(nextupd, &t_tmp) < 0)
357075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara			{
358075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara			OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED);
359075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara			ret = 0;
3603397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl			}
361465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara		}
3623acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis
3633acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis	/* Also don't allow nextUpdate to precede thisUpdate */
3648538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	if (ASN1_STRING_cmp(nextupd, thisupd) < 0)
3652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		{
3662cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor		OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
3673397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl		ret = 0;
3683cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall		}
36931f17ecbef57b5679c017c375db330546b7b5145John McCall
3708538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl	return ret;
3713cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall	}
3723cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall