os/ossrv/ssl/libcrypto/src/crypto/ocsp/ocsp_ext.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/ocsp/ocsp_ext.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,545 @@
     1.4 +/* ocsp_ext.c */
     1.5 +/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
     1.6 + * project. */
     1.7 +
     1.8 +/* History:
     1.9 +   This file was transfered to Richard Levitte from CertCo by Kathy
    1.10 +   Weinhold in mid-spring 2000 to be included in OpenSSL or released
    1.11 +   as a patch kit. */
    1.12 +
    1.13 +/* ====================================================================
    1.14 + * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
    1.15 + *
    1.16 + * Redistribution and use in source and binary forms, with or without
    1.17 + * modification, are permitted provided that the following conditions
    1.18 + * are met:
    1.19 + *
    1.20 + * 1. Redistributions of source code must retain the above copyright
    1.21 + *    notice, this list of conditions and the following disclaimer. 
    1.22 + *
    1.23 + * 2. Redistributions in binary form must reproduce the above copyright
    1.24 + *    notice, this list of conditions and the following disclaimer in
    1.25 + *    the documentation and/or other materials provided with the
    1.26 + *    distribution.
    1.27 + *
    1.28 + * 3. All advertising materials mentioning features or use of this
    1.29 + *    software must display the following acknowledgment:
    1.30 + *    "This product includes software developed by the OpenSSL Project
    1.31 + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
    1.32 + *
    1.33 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    1.34 + *    endorse or promote products derived from this software without
    1.35 + *    prior written permission. For written permission, please contact
    1.36 + *    openssl-core@openssl.org.
    1.37 + *
    1.38 + * 5. Products derived from this software may not be called "OpenSSL"
    1.39 + *    nor may "OpenSSL" appear in their names without prior written
    1.40 + *    permission of the OpenSSL Project.
    1.41 + *
    1.42 + * 6. Redistributions of any form whatsoever must retain the following
    1.43 + *    acknowledgment:
    1.44 + *    "This product includes software developed by the OpenSSL Project
    1.45 + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
    1.46 + *
    1.47 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    1.48 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.49 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.50 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    1.51 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.52 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    1.53 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    1.54 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.55 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    1.56 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.57 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    1.58 + * OF THE POSSIBILITY OF SUCH DAMAGE.
    1.59 + * ====================================================================
    1.60 + *
    1.61 + * This product includes cryptographic software written by Eric Young
    1.62 + * (eay@cryptsoft.com).  This product includes software written by Tim
    1.63 + * Hudson (tjh@cryptsoft.com).
    1.64 + *
    1.65 + */
    1.66 +
    1.67 +#include <stdio.h>
    1.68 +#include <cryptlib.h>
    1.69 +#include <openssl/objects.h>
    1.70 +#include <openssl/x509.h>
    1.71 +#include <openssl/ocsp.h>
    1.72 +#include <openssl/rand.h>
    1.73 +#include <openssl/x509v3.h>
    1.74 +
    1.75 +/* Standard wrapper functions for extensions */
    1.76 +
    1.77 +/* OCSP request extensions */
    1.78 +
    1.79 +EXPORT_C int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
    1.80 +	{
    1.81 +	return(X509v3_get_ext_count(x->tbsRequest->requestExtensions));
    1.82 +	}
    1.83 +
    1.84 +EXPORT_C int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
    1.85 +	{
    1.86 +	return(X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions,nid,lastpos));
    1.87 +	}
    1.88 +
    1.89 +EXPORT_C int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos)
    1.90 +	{
    1.91 +	return(X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions,obj,lastpos));
    1.92 +	}
    1.93 +
    1.94 +EXPORT_C int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
    1.95 +	{
    1.96 +	return(X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions,crit,lastpos));
    1.97 +	}
    1.98 +
    1.99 +EXPORT_C X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
   1.100 +	{
   1.101 +	return(X509v3_get_ext(x->tbsRequest->requestExtensions,loc));
   1.102 +	}
   1.103 +
   1.104 +EXPORT_C X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
   1.105 +	{
   1.106 +	return(X509v3_delete_ext(x->tbsRequest->requestExtensions,loc));
   1.107 +	}
   1.108 +
   1.109 +EXPORT_C void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
   1.110 +	{
   1.111 +	return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx);
   1.112 +	}
   1.113 +
   1.114 +EXPORT_C int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
   1.115 +							unsigned long flags)
   1.116 +	{
   1.117 +	return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, crit, flags);
   1.118 +	}
   1.119 +
   1.120 +EXPORT_C int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
   1.121 +	{
   1.122 +	return(X509v3_add_ext(&(x->tbsRequest->requestExtensions),ex,loc) != NULL);
   1.123 +	}
   1.124 +
   1.125 +/* Single extensions */
   1.126 +
   1.127 +EXPORT_C int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
   1.128 +	{
   1.129 +	return(X509v3_get_ext_count(x->singleRequestExtensions));
   1.130 +	}
   1.131 +
   1.132 +EXPORT_C int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
   1.133 +	{
   1.134 +	return(X509v3_get_ext_by_NID(x->singleRequestExtensions,nid,lastpos));
   1.135 +	}
   1.136 +
   1.137 +EXPORT_C int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos)
   1.138 +	{
   1.139 +	return(X509v3_get_ext_by_OBJ(x->singleRequestExtensions,obj,lastpos));
   1.140 +	}
   1.141 +
   1.142 +EXPORT_C int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
   1.143 +	{
   1.144 +	return(X509v3_get_ext_by_critical(x->singleRequestExtensions,crit,lastpos));
   1.145 +	}
   1.146 +
   1.147 +EXPORT_C X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
   1.148 +	{
   1.149 +	return(X509v3_get_ext(x->singleRequestExtensions,loc));
   1.150 +	}
   1.151 +
   1.152 +EXPORT_C X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
   1.153 +	{
   1.154 +	return(X509v3_delete_ext(x->singleRequestExtensions,loc));
   1.155 +	}
   1.156 +
   1.157 +EXPORT_C void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
   1.158 +	{
   1.159 +	return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
   1.160 +	}
   1.161 +
   1.162 +EXPORT_C int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
   1.163 +							unsigned long flags)
   1.164 +	{
   1.165 +	return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, flags);
   1.166 +	}
   1.167 +
   1.168 +EXPORT_C int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
   1.169 +	{
   1.170 +	return(X509v3_add_ext(&(x->singleRequestExtensions),ex,loc) != NULL);
   1.171 +	}
   1.172 +
   1.173 +/* OCSP Basic response */
   1.174 +
   1.175 +EXPORT_C int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
   1.176 +	{
   1.177 +	return(X509v3_get_ext_count(x->tbsResponseData->responseExtensions));
   1.178 +	}
   1.179 +
   1.180 +EXPORT_C int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
   1.181 +	{
   1.182 +	return(X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions,nid,lastpos));
   1.183 +	}
   1.184 +
   1.185 +EXPORT_C int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos)
   1.186 +	{
   1.187 +	return(X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions,obj,lastpos));
   1.188 +	}
   1.189 +
   1.190 +EXPORT_C int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos)
   1.191 +	{
   1.192 +	return(X509v3_get_ext_by_critical(x->tbsResponseData->responseExtensions,crit,lastpos));
   1.193 +	}
   1.194 +
   1.195 +EXPORT_C X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
   1.196 +	{
   1.197 +	return(X509v3_get_ext(x->tbsResponseData->responseExtensions,loc));
   1.198 +	}
   1.199 +
   1.200 +EXPORT_C X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
   1.201 +	{
   1.202 +	return(X509v3_delete_ext(x->tbsResponseData->responseExtensions,loc));
   1.203 +	}
   1.204 +
   1.205 +EXPORT_C void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx)
   1.206 +	{
   1.207 +	return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, idx);
   1.208 +	}
   1.209 +
   1.210 +EXPORT_C int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
   1.211 +							unsigned long flags)
   1.212 +	{
   1.213 +	return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, value, crit, flags);
   1.214 +	}
   1.215 +
   1.216 +EXPORT_C int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
   1.217 +	{
   1.218 +	return(X509v3_add_ext(&(x->tbsResponseData->responseExtensions),ex,loc) != NULL);
   1.219 +	}
   1.220 +
   1.221 +/* OCSP single response extensions */
   1.222 +
   1.223 +EXPORT_C int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
   1.224 +	{
   1.225 +	return(X509v3_get_ext_count(x->singleExtensions));
   1.226 +	}
   1.227 +
   1.228 +EXPORT_C int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
   1.229 +	{
   1.230 +	return(X509v3_get_ext_by_NID(x->singleExtensions,nid,lastpos));
   1.231 +	}
   1.232 +
   1.233 +EXPORT_C int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos)
   1.234 +	{
   1.235 +	return(X509v3_get_ext_by_OBJ(x->singleExtensions,obj,lastpos));
   1.236 +	}
   1.237 +
   1.238 +EXPORT_C int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos)
   1.239 +	{
   1.240 +	return(X509v3_get_ext_by_critical(x->singleExtensions,crit,lastpos));
   1.241 +	}
   1.242 +
   1.243 +EXPORT_C X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
   1.244 +	{
   1.245 +	return(X509v3_get_ext(x->singleExtensions,loc));
   1.246 +	}
   1.247 +
   1.248 +EXPORT_C X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
   1.249 +	{
   1.250 +	return(X509v3_delete_ext(x->singleExtensions,loc));
   1.251 +	}
   1.252 +
   1.253 +EXPORT_C void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx)
   1.254 +	{
   1.255 +	return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
   1.256 +	}
   1.257 +
   1.258 +EXPORT_C int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
   1.259 +							unsigned long flags)
   1.260 +	{
   1.261 +	return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
   1.262 +	}
   1.263 +
   1.264 +EXPORT_C int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
   1.265 +	{
   1.266 +	return(X509v3_add_ext(&(x->singleExtensions),ex,loc) != NULL);
   1.267 +	}
   1.268 +
   1.269 +/* also CRL Entry Extensions */
   1.270 +
   1.271 +EXPORT_C ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
   1.272 +				void *data, STACK_OF(ASN1_OBJECT) *sk)
   1.273 +        {
   1.274 +	int i;
   1.275 +	unsigned char *p, *b = NULL;
   1.276 +
   1.277 +	if (data)
   1.278 +	        {
   1.279 +		if ((i=i2d(data,NULL)) <= 0) goto err;
   1.280 +		if (!(b=p=OPENSSL_malloc((unsigned int)i)))
   1.281 +			goto err;
   1.282 +	        if (i2d(data, &p) <= 0) goto err;
   1.283 +		}
   1.284 +	else if (sk)
   1.285 +	        {
   1.286 +		if ((i=i2d_ASN1_SET_OF_ASN1_OBJECT(sk,NULL,
   1.287 +						   (I2D_OF(ASN1_OBJECT))i2d,
   1.288 +						   V_ASN1_SEQUENCE,
   1.289 +						   V_ASN1_UNIVERSAL,
   1.290 +						   IS_SEQUENCE))<=0) goto err;
   1.291 +		if (!(b=p=OPENSSL_malloc((unsigned int)i)))
   1.292 +			goto err;
   1.293 +		if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk,&p,(I2D_OF(ASN1_OBJECT))i2d,
   1.294 +						V_ASN1_SEQUENCE,
   1.295 +						V_ASN1_UNIVERSAL,
   1.296 +						IS_SEQUENCE)<=0) goto err;
   1.297 +		}
   1.298 +	else
   1.299 +		{
   1.300 +		OCSPerr(OCSP_F_ASN1_STRING_ENCODE,OCSP_R_BAD_DATA);
   1.301 +		goto err;
   1.302 +		}
   1.303 +	if (!s && !(s = ASN1_STRING_new())) goto err;
   1.304 +	if (!(ASN1_STRING_set(s, b, i))) goto err;
   1.305 +	OPENSSL_free(b);
   1.306 +	return s;
   1.307 +err:
   1.308 +	if (b) OPENSSL_free(b);
   1.309 +	return NULL;
   1.310 +	}
   1.311 +
   1.312 +/* Nonce handling functions */
   1.313 +
   1.314 +/* Add a nonce to an extension stack. A nonce can be specificed or if NULL
   1.315 + * a random nonce will be generated.
   1.316 + * Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the 
   1.317 + * nonce, previous versions used the raw nonce.
   1.318 + */
   1.319 +
   1.320 +static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len)
   1.321 +	{
   1.322 +	unsigned char *tmpval;
   1.323 +	ASN1_OCTET_STRING os;
   1.324 +	int ret = 0;
   1.325 +	if (len <= 0) len = OCSP_DEFAULT_NONCE_LENGTH;
   1.326 +	/* Create the OCTET STRING manually by writing out the header and
   1.327 +	 * appending the content octets. This avoids an extra memory allocation
   1.328 +	 * operation in some cases. Applications should *NOT* do this because
   1.329 +         * it relies on library internals.
   1.330 +	 */
   1.331 +	os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
   1.332 +	os.data = OPENSSL_malloc(os.length);
   1.333 +	if (os.data == NULL)
   1.334 +		goto err;
   1.335 +	tmpval = os.data;
   1.336 +	ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
   1.337 +	if (val)
   1.338 +		memcpy(tmpval, val, len);
   1.339 +	else
   1.340 +		RAND_pseudo_bytes(tmpval, len);
   1.341 +	if(!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
   1.342 +			&os, 0, X509V3_ADD_REPLACE))
   1.343 +				goto err;
   1.344 +	ret = 1;
   1.345 +	err:
   1.346 +	if (os.data)
   1.347 +		OPENSSL_free(os.data);
   1.348 +	return ret;
   1.349 +	}
   1.350 +
   1.351 +
   1.352 +/* Add nonce to an OCSP request */
   1.353 +
   1.354 +EXPORT_C int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
   1.355 +	{
   1.356 +	return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len);
   1.357 +	}
   1.358 +
   1.359 +/* Same as above but for a response */
   1.360 +
   1.361 +EXPORT_C int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
   1.362 +	{
   1.363 +	return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, len);
   1.364 +	}
   1.365 +
   1.366 +/* Check nonce validity in a request and response.
   1.367 + * Return value reflects result:
   1.368 + *  1: nonces present and equal.
   1.369 + *  2: nonces both absent.
   1.370 + *  3: nonce present in response only.
   1.371 + *  0: nonces both present and not equal.
   1.372 + * -1: nonce in request only.
   1.373 + *
   1.374 + *  For most responders clients can check return > 0.
   1.375 + *  If responder doesn't handle nonces return != 0 may be
   1.376 + *  necessary. return == 0 is always an error.
   1.377 + */
   1.378 +
   1.379 +EXPORT_C int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
   1.380 +	{
   1.381 +	/*
   1.382 +	 * Since we are only interested in the presence or absence of
   1.383 +	 * the nonce and comparing its value there is no need to use
   1.384 +	 * the X509V3 routines: this way we can avoid them allocating an
   1.385 +	 * ASN1_OCTET_STRING structure for the value which would be
   1.386 +	 * freed immediately anyway.
   1.387 +	 */
   1.388 +
   1.389 +	int req_idx, resp_idx;
   1.390 +	X509_EXTENSION *req_ext, *resp_ext;
   1.391 +	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
   1.392 +	resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
   1.393 +	/* Check both absent */
   1.394 +	if((req_idx < 0) && (resp_idx < 0))
   1.395 +		return 2;
   1.396 +	/* Check in request only */
   1.397 +	if((req_idx >= 0) && (resp_idx < 0))
   1.398 +		return -1;
   1.399 +	/* Check in response but not request */
   1.400 +	if((req_idx < 0) && (resp_idx >= 0))
   1.401 +		return 3;
   1.402 +	/* Otherwise nonce in request and response so retrieve the extensions */
   1.403 +	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
   1.404 +	resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
   1.405 +	if(ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value))
   1.406 +		return 0;
   1.407 +	return 1;
   1.408 +	}
   1.409 +
   1.410 +/* Copy the nonce value (if any) from an OCSP request to 
   1.411 + * a response.
   1.412 + */
   1.413 +
   1.414 +EXPORT_C int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
   1.415 +	{
   1.416 +	X509_EXTENSION *req_ext;
   1.417 +	int req_idx;
   1.418 +	/* Check for nonce in request */
   1.419 +	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
   1.420 +	/* If no nonce that's OK */
   1.421 +	if (req_idx < 0) return 2;
   1.422 +	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
   1.423 +	return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
   1.424 +	}
   1.425 +
   1.426 +EXPORT_C X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim)
   1.427 +        {
   1.428 +	X509_EXTENSION *x = NULL;
   1.429 +	OCSP_CRLID *cid = NULL;
   1.430 +	
   1.431 +	if (!(cid = OCSP_CRLID_new())) goto err;
   1.432 +	if (url)
   1.433 +	        {
   1.434 +		if (!(cid->crlUrl = ASN1_IA5STRING_new())) goto err;
   1.435 +		if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) goto err;
   1.436 +		}
   1.437 +	if (n)
   1.438 +	        {
   1.439 +		if (!(cid->crlNum = ASN1_INTEGER_new())) goto err;
   1.440 +		if (!(ASN1_INTEGER_set(cid->crlNum, *n))) goto err;
   1.441 +		}
   1.442 +	if (tim)
   1.443 +	        {
   1.444 +		if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) goto err;
   1.445 +		if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 
   1.446 +		        goto err;
   1.447 +		}
   1.448 +	if (!(x = X509_EXTENSION_new())) goto err;
   1.449 +	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_CrlID))) goto err;
   1.450 +	if (!(ASN1_STRING_encode_of(OCSP_CRLID,x->value,i2d_OCSP_CRLID,cid,
   1.451 +				    NULL)))
   1.452 +	        goto err;
   1.453 +	OCSP_CRLID_free(cid);
   1.454 +	return x;
   1.455 +err:
   1.456 +	if (x) X509_EXTENSION_free(x);
   1.457 +	if (cid) OCSP_CRLID_free(cid);
   1.458 +	return NULL;
   1.459 +	}
   1.460 +
   1.461 +/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
   1.462 +EXPORT_C X509_EXTENSION *OCSP_accept_responses_new(char **oids)
   1.463 +        {
   1.464 +	int nid;
   1.465 +	STACK_OF(ASN1_OBJECT) *sk = NULL;
   1.466 +	ASN1_OBJECT *o = NULL;
   1.467 +        X509_EXTENSION *x = NULL;
   1.468 +
   1.469 +	if (!(sk = sk_ASN1_OBJECT_new_null())) goto err;
   1.470 +	while (oids && *oids)
   1.471 +	        {
   1.472 +		if ((nid=OBJ_txt2nid(*oids))!=NID_undef&&(o=OBJ_nid2obj(nid))) 
   1.473 +		        sk_ASN1_OBJECT_push(sk, o);
   1.474 +		oids++;
   1.475 +		}
   1.476 +	if (!(x = X509_EXTENSION_new())) goto err;
   1.477 +	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_acceptableResponses)))
   1.478 +		goto err;
   1.479 +	if (!(ASN1_STRING_encode_of(ASN1_OBJECT,x->value,i2d_ASN1_OBJECT,NULL,
   1.480 +				    sk)))
   1.481 +	        goto err;
   1.482 +	sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
   1.483 +	return x;
   1.484 +err:
   1.485 +	if (x) X509_EXTENSION_free(x);
   1.486 +	if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
   1.487 +	return NULL;
   1.488 +        }
   1.489 +
   1.490 +/*  ArchiveCutoff ::= GeneralizedTime */
   1.491 +EXPORT_C X509_EXTENSION *OCSP_archive_cutoff_new(char* tim)
   1.492 +        {
   1.493 +	X509_EXTENSION *x=NULL;
   1.494 +	ASN1_GENERALIZEDTIME *gt = NULL;
   1.495 +
   1.496 +	if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err;
   1.497 +	if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err;
   1.498 +	if (!(x = X509_EXTENSION_new())) goto err;
   1.499 +	if (!(x->object=OBJ_nid2obj(NID_id_pkix_OCSP_archiveCutoff)))goto err;
   1.500 +	if (!(ASN1_STRING_encode_of(ASN1_GENERALIZEDTIME,x->value,
   1.501 +				    i2d_ASN1_GENERALIZEDTIME,gt,NULL))) goto err;
   1.502 +	ASN1_GENERALIZEDTIME_free(gt);
   1.503 +	return x;
   1.504 +err:
   1.505 +	if (gt) ASN1_GENERALIZEDTIME_free(gt);
   1.506 +	if (x) X509_EXTENSION_free(x);
   1.507 +	return NULL;
   1.508 +	}
   1.509 +
   1.510 +/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently
   1.511 + * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This
   1.512 + * method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
   1.513 + */
   1.514 +EXPORT_C X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls)
   1.515 +        {
   1.516 +	X509_EXTENSION *x = NULL;
   1.517 +	ASN1_IA5STRING *ia5 = NULL;
   1.518 +	OCSP_SERVICELOC *sloc = NULL;
   1.519 +	ACCESS_DESCRIPTION *ad = NULL;
   1.520 +	
   1.521 +	if (!(sloc = OCSP_SERVICELOC_new())) goto err;
   1.522 +	if (!(sloc->issuer = X509_NAME_dup(issuer))) goto err;
   1.523 +	if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) goto err;
   1.524 +	while (urls && *urls)
   1.525 +	        {
   1.526 +		if (!(ad = ACCESS_DESCRIPTION_new())) goto err;
   1.527 +		if (!(ad->method=OBJ_nid2obj(NID_ad_OCSP))) goto err;
   1.528 +		if (!(ad->location = GENERAL_NAME_new())) goto err;
   1.529 +	        if (!(ia5 = ASN1_IA5STRING_new())) goto err;
   1.530 +		if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1)) goto err;
   1.531 +		ad->location->type = GEN_URI;
   1.532 +		ad->location->d.ia5 = ia5;
   1.533 +		if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err;
   1.534 +		urls++;
   1.535 +		}
   1.536 +	if (!(x = X509_EXTENSION_new())) goto err;
   1.537 +	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_serviceLocator))) 
   1.538 +	        goto err;
   1.539 +	if (!(ASN1_STRING_encode_of(OCSP_SERVICELOC,x->value,
   1.540 +				    i2d_OCSP_SERVICELOC,sloc,NULL))) goto err;
   1.541 +	OCSP_SERVICELOC_free(sloc);
   1.542 +	return x;
   1.543 +err:
   1.544 +	if (x) X509_EXTENSION_free(x);
   1.545 +	if (sloc) OCSP_SERVICELOC_free(sloc);
   1.546 +	return NULL;
   1.547 +	}
   1.548 +