1109998Smarkm/* v3_ocsp.c */
2194206Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3109998Smarkm * project 1999.
4109998Smarkm */
5109998Smarkm/* ====================================================================
6109998Smarkm * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7109998Smarkm *
8109998Smarkm * Redistribution and use in source and binary forms, with or without
9109998Smarkm * modification, are permitted provided that the following conditions
10109998Smarkm * are met:
11109998Smarkm *
12109998Smarkm * 1. Redistributions of source code must retain the above copyright
13109998Smarkm *    notice, this list of conditions and the following disclaimer.
14109998Smarkm *
15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
16109998Smarkm *    notice, this list of conditions and the following disclaimer in
17109998Smarkm *    the documentation and/or other materials provided with the
18109998Smarkm *    distribution.
19109998Smarkm *
20109998Smarkm * 3. All advertising materials mentioning features or use of this
21109998Smarkm *    software must display the following acknowledgment:
22109998Smarkm *    "This product includes software developed by the OpenSSL Project
23109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24109998Smarkm *
25109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26109998Smarkm *    endorse or promote products derived from this software without
27109998Smarkm *    prior written permission. For written permission, please contact
28109998Smarkm *    licensing@OpenSSL.org.
29109998Smarkm *
30109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
31109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
32109998Smarkm *    permission of the OpenSSL Project.
33109998Smarkm *
34109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
35109998Smarkm *    acknowledgment:
36109998Smarkm *    "This product includes software developed by the OpenSSL Project
37109998Smarkm *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38109998Smarkm *
39109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
51109998Smarkm * ====================================================================
52109998Smarkm *
53109998Smarkm * This product includes cryptographic software written by Eric Young
54109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
55109998Smarkm * Hudson (tjh@cryptsoft.com).
56109998Smarkm *
57109998Smarkm */
58109998Smarkm
59111147Snectar#ifndef OPENSSL_NO_OCSP
60111147Snectar
61109998Smarkm#include <stdio.h>
62109998Smarkm#include "cryptlib.h"
63109998Smarkm#include <openssl/conf.h>
64109998Smarkm#include <openssl/asn1.h>
65109998Smarkm#include <openssl/ocsp.h>
66109998Smarkm#include <openssl/x509v3.h>
67109998Smarkm
68109998Smarkm/* OCSP extensions and a couple of CRL entry extensions
69109998Smarkm */
70109998Smarkm
71238405Sjkimstatic int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
72238405Sjkim			  BIO *out, int indent);
73238405Sjkimstatic int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
74238405Sjkim			    BIO *out, int indent);
75238405Sjkimstatic int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
76238405Sjkim		      int indent);
77109998Smarkm
78109998Smarkmstatic void *ocsp_nonce_new(void);
79109998Smarkmstatic int i2d_ocsp_nonce(void *a, unsigned char **pp);
80160814Ssimonstatic void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
81109998Smarkmstatic void ocsp_nonce_free(void *a);
82238405Sjkimstatic int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
83238405Sjkim			  BIO *out, int indent);
84109998Smarkm
85238405Sjkimstatic int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
86238405Sjkim			    void *nocheck, BIO *out, int indent);
87238405Sjkimstatic void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
88238405Sjkim			      const char *str);
89238405Sjkimstatic int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
90238405Sjkim			       BIO *bp, int ind);
91109998Smarkm
92167612Ssimonconst X509V3_EXT_METHOD v3_ocsp_crlid = {
93109998Smarkm	NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
94109998Smarkm	0,0,0,0,
95109998Smarkm	0,0,
96109998Smarkm	0,0,
97109998Smarkm	i2r_ocsp_crlid,0,
98109998Smarkm	NULL
99109998Smarkm};
100109998Smarkm
101167612Ssimonconst X509V3_EXT_METHOD v3_ocsp_acutoff = {
102109998Smarkm	NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
103109998Smarkm	0,0,0,0,
104109998Smarkm	0,0,
105109998Smarkm	0,0,
106109998Smarkm	i2r_ocsp_acutoff,0,
107109998Smarkm	NULL
108109998Smarkm};
109109998Smarkm
110167612Ssimonconst X509V3_EXT_METHOD v3_crl_invdate = {
111109998Smarkm	NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
112109998Smarkm	0,0,0,0,
113109998Smarkm	0,0,
114109998Smarkm	0,0,
115109998Smarkm	i2r_ocsp_acutoff,0,
116109998Smarkm	NULL
117109998Smarkm};
118109998Smarkm
119167612Ssimonconst X509V3_EXT_METHOD v3_crl_hold = {
120109998Smarkm	NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
121109998Smarkm	0,0,0,0,
122109998Smarkm	0,0,
123109998Smarkm	0,0,
124109998Smarkm	i2r_object,0,
125109998Smarkm	NULL
126109998Smarkm};
127109998Smarkm
128167612Ssimonconst X509V3_EXT_METHOD v3_ocsp_nonce = {
129109998Smarkm	NID_id_pkix_OCSP_Nonce, 0, NULL,
130109998Smarkm	ocsp_nonce_new,
131109998Smarkm	ocsp_nonce_free,
132109998Smarkm	d2i_ocsp_nonce,
133109998Smarkm	i2d_ocsp_nonce,
134109998Smarkm	0,0,
135109998Smarkm	0,0,
136109998Smarkm	i2r_ocsp_nonce,0,
137109998Smarkm	NULL
138109998Smarkm};
139109998Smarkm
140167612Ssimonconst X509V3_EXT_METHOD v3_ocsp_nocheck = {
141109998Smarkm	NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
142109998Smarkm	0,0,0,0,
143109998Smarkm	0,s2i_ocsp_nocheck,
144109998Smarkm	0,0,
145109998Smarkm	i2r_ocsp_nocheck,0,
146109998Smarkm	NULL
147109998Smarkm};
148109998Smarkm
149167612Ssimonconst X509V3_EXT_METHOD v3_ocsp_serviceloc = {
150109998Smarkm	NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
151109998Smarkm	0,0,0,0,
152109998Smarkm	0,0,
153109998Smarkm	0,0,
154109998Smarkm	i2r_ocsp_serviceloc,0,
155109998Smarkm	NULL
156109998Smarkm};
157109998Smarkm
158238405Sjkimstatic int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
159238405Sjkim			  int ind)
160109998Smarkm{
161109998Smarkm	OCSP_CRLID *a = in;
162109998Smarkm	if (a->crlUrl)
163109998Smarkm	        {
164205128Ssimon		if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) goto err;
165109998Smarkm		if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err;
166205128Ssimon		if (BIO_write(bp, "\n", 1) <= 0) goto err;
167109998Smarkm		}
168109998Smarkm	if (a->crlNum)
169109998Smarkm	        {
170205128Ssimon		if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) goto err;
171205128Ssimon		if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) goto err;
172205128Ssimon		if (BIO_write(bp, "\n", 1) <= 0) goto err;
173109998Smarkm		}
174109998Smarkm	if (a->crlTime)
175109998Smarkm	        {
176205128Ssimon		if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) goto err;
177109998Smarkm		if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err;
178205128Ssimon		if (BIO_write(bp, "\n", 1) <= 0) goto err;
179109998Smarkm		}
180109998Smarkm	return 1;
181109998Smarkm	err:
182109998Smarkm	return 0;
183109998Smarkm}
184109998Smarkm
185238405Sjkimstatic int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
186238405Sjkim			    BIO *bp, int ind)
187109998Smarkm{
188205128Ssimon	if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
189109998Smarkm	if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0;
190109998Smarkm	return 1;
191109998Smarkm}
192109998Smarkm
193109998Smarkm
194238405Sjkimstatic int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
195238405Sjkim		      int ind)
196109998Smarkm{
197205128Ssimon	if (BIO_printf(bp, "%*s", ind, "") <= 0) return 0;
198205128Ssimon	if(i2a_ASN1_OBJECT(bp, oid) <= 0) return 0;
199109998Smarkm	return 1;
200109998Smarkm}
201109998Smarkm
202109998Smarkm/* OCSP nonce. This is needs special treatment because it doesn't have
203109998Smarkm * an ASN1 encoding at all: it just contains arbitrary data.
204109998Smarkm */
205109998Smarkm
206109998Smarkmstatic void *ocsp_nonce_new(void)
207109998Smarkm{
208109998Smarkm	return ASN1_OCTET_STRING_new();
209109998Smarkm}
210109998Smarkm
211109998Smarkmstatic int i2d_ocsp_nonce(void *a, unsigned char **pp)
212109998Smarkm{
213109998Smarkm	ASN1_OCTET_STRING *os = a;
214109998Smarkm	if(pp) {
215109998Smarkm		memcpy(*pp, os->data, os->length);
216109998Smarkm		*pp += os->length;
217109998Smarkm	}
218109998Smarkm	return os->length;
219109998Smarkm}
220109998Smarkm
221160814Ssimonstatic void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
222109998Smarkm{
223109998Smarkm	ASN1_OCTET_STRING *os, **pos;
224109998Smarkm	pos = a;
225109998Smarkm	if(!pos || !*pos) os = ASN1_OCTET_STRING_new();
226109998Smarkm	else os = *pos;
227109998Smarkm	if(!ASN1_OCTET_STRING_set(os, *pp, length)) goto err;
228109998Smarkm
229109998Smarkm	*pp += length;
230109998Smarkm
231109998Smarkm	if(pos) *pos = os;
232109998Smarkm	return os;
233109998Smarkm
234109998Smarkm	err:
235109998Smarkm	if(os && (!pos || (*pos != os))) M_ASN1_OCTET_STRING_free(os);
236109998Smarkm	OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
237109998Smarkm	return NULL;
238109998Smarkm}
239109998Smarkm
240109998Smarkmstatic void ocsp_nonce_free(void *a)
241109998Smarkm{
242109998Smarkm	M_ASN1_OCTET_STRING_free(a);
243109998Smarkm}
244109998Smarkm
245238405Sjkimstatic int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
246238405Sjkim			  BIO *out, int indent)
247109998Smarkm{
248109998Smarkm	if(BIO_printf(out, "%*s", indent, "") <= 0) return 0;
249109998Smarkm	if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0;
250109998Smarkm	return 1;
251109998Smarkm}
252109998Smarkm
253109998Smarkm/* Nocheck is just a single NULL. Don't print anything and always set it */
254109998Smarkm
255238405Sjkimstatic int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
256238405Sjkim			    BIO *out, int indent)
257109998Smarkm{
258109998Smarkm	return 1;
259109998Smarkm}
260109998Smarkm
261238405Sjkimstatic void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
262238405Sjkim			      const char *str)
263109998Smarkm{
264109998Smarkm	return ASN1_NULL_new();
265109998Smarkm}
266109998Smarkm
267238405Sjkimstatic int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
268238405Sjkim			       BIO *bp, int ind)
269109998Smarkm        {
270109998Smarkm	int i;
271109998Smarkm	OCSP_SERVICELOC *a = in;
272109998Smarkm	ACCESS_DESCRIPTION *ad;
273109998Smarkm
274109998Smarkm        if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) goto err;
275109998Smarkm        if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) goto err;
276109998Smarkm	for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++)
277109998Smarkm	        {
278109998Smarkm				ad = sk_ACCESS_DESCRIPTION_value(a->locator,i);
279109998Smarkm				if (BIO_printf(bp, "\n%*s", (2*ind), "") <= 0)
280109998Smarkm					goto err;
281109998Smarkm				if(i2a_ASN1_OBJECT(bp, ad->method) <= 0) goto err;
282109998Smarkm				if(BIO_puts(bp, " - ") <= 0) goto err;
283109998Smarkm				if(GENERAL_NAME_print(bp, ad->location) <= 0) goto err;
284109998Smarkm		}
285109998Smarkm	return 1;
286109998Smarkmerr:
287109998Smarkm	return 0;
288109998Smarkm	}
289111147Snectar#endif
290