os/ossrv/ssl/libcrypto/src/crypto/ocsp/ocsp_ext.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* ocsp_ext.c */
sl@0
     2
/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
sl@0
     3
 * project. */
sl@0
     4
sl@0
     5
/* History:
sl@0
     6
   This file was transfered to Richard Levitte from CertCo by Kathy
sl@0
     7
   Weinhold in mid-spring 2000 to be included in OpenSSL or released
sl@0
     8
   as a patch kit. */
sl@0
     9
sl@0
    10
/* ====================================================================
sl@0
    11
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
sl@0
    12
 *
sl@0
    13
 * Redistribution and use in source and binary forms, with or without
sl@0
    14
 * modification, are permitted provided that the following conditions
sl@0
    15
 * are met:
sl@0
    16
 *
sl@0
    17
 * 1. Redistributions of source code must retain the above copyright
sl@0
    18
 *    notice, this list of conditions and the following disclaimer. 
sl@0
    19
 *
sl@0
    20
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    21
 *    notice, this list of conditions and the following disclaimer in
sl@0
    22
 *    the documentation and/or other materials provided with the
sl@0
    23
 *    distribution.
sl@0
    24
 *
sl@0
    25
 * 3. All advertising materials mentioning features or use of this
sl@0
    26
 *    software must display the following acknowledgment:
sl@0
    27
 *    "This product includes software developed by the OpenSSL Project
sl@0
    28
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
sl@0
    29
 *
sl@0
    30
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
sl@0
    31
 *    endorse or promote products derived from this software without
sl@0
    32
 *    prior written permission. For written permission, please contact
sl@0
    33
 *    openssl-core@openssl.org.
sl@0
    34
 *
sl@0
    35
 * 5. Products derived from this software may not be called "OpenSSL"
sl@0
    36
 *    nor may "OpenSSL" appear in their names without prior written
sl@0
    37
 *    permission of the OpenSSL Project.
sl@0
    38
 *
sl@0
    39
 * 6. Redistributions of any form whatsoever must retain the following
sl@0
    40
 *    acknowledgment:
sl@0
    41
 *    "This product includes software developed by the OpenSSL Project
sl@0
    42
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
sl@0
    43
 *
sl@0
    44
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
sl@0
    45
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    46
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sl@0
    47
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
sl@0
    48
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
sl@0
    49
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
sl@0
    50
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
sl@0
    51
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    52
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sl@0
    53
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
sl@0
    54
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
sl@0
    55
 * OF THE POSSIBILITY OF SUCH DAMAGE.
sl@0
    56
 * ====================================================================
sl@0
    57
 *
sl@0
    58
 * This product includes cryptographic software written by Eric Young
sl@0
    59
 * (eay@cryptsoft.com).  This product includes software written by Tim
sl@0
    60
 * Hudson (tjh@cryptsoft.com).
sl@0
    61
 *
sl@0
    62
 */
sl@0
    63
sl@0
    64
#include <stdio.h>
sl@0
    65
#include <cryptlib.h>
sl@0
    66
#include <openssl/objects.h>
sl@0
    67
#include <openssl/x509.h>
sl@0
    68
#include <openssl/ocsp.h>
sl@0
    69
#include <openssl/rand.h>
sl@0
    70
#include <openssl/x509v3.h>
sl@0
    71
sl@0
    72
/* Standard wrapper functions for extensions */
sl@0
    73
sl@0
    74
/* OCSP request extensions */
sl@0
    75
sl@0
    76
EXPORT_C int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
sl@0
    77
	{
sl@0
    78
	return(X509v3_get_ext_count(x->tbsRequest->requestExtensions));
sl@0
    79
	}
sl@0
    80
sl@0
    81
EXPORT_C int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
sl@0
    82
	{
sl@0
    83
	return(X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions,nid,lastpos));
sl@0
    84
	}
sl@0
    85
sl@0
    86
EXPORT_C int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos)
sl@0
    87
	{
sl@0
    88
	return(X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions,obj,lastpos));
sl@0
    89
	}
sl@0
    90
sl@0
    91
EXPORT_C int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
sl@0
    92
	{
sl@0
    93
	return(X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions,crit,lastpos));
sl@0
    94
	}
sl@0
    95
sl@0
    96
EXPORT_C X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
sl@0
    97
	{
sl@0
    98
	return(X509v3_get_ext(x->tbsRequest->requestExtensions,loc));
sl@0
    99
	}
sl@0
   100
sl@0
   101
EXPORT_C X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
sl@0
   102
	{
sl@0
   103
	return(X509v3_delete_ext(x->tbsRequest->requestExtensions,loc));
sl@0
   104
	}
sl@0
   105
sl@0
   106
EXPORT_C void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
sl@0
   107
	{
sl@0
   108
	return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx);
sl@0
   109
	}
sl@0
   110
sl@0
   111
EXPORT_C int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
sl@0
   112
							unsigned long flags)
sl@0
   113
	{
sl@0
   114
	return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, crit, flags);
sl@0
   115
	}
sl@0
   116
sl@0
   117
EXPORT_C int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
sl@0
   118
	{
sl@0
   119
	return(X509v3_add_ext(&(x->tbsRequest->requestExtensions),ex,loc) != NULL);
sl@0
   120
	}
sl@0
   121
sl@0
   122
/* Single extensions */
sl@0
   123
sl@0
   124
EXPORT_C int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
sl@0
   125
	{
sl@0
   126
	return(X509v3_get_ext_count(x->singleRequestExtensions));
sl@0
   127
	}
sl@0
   128
sl@0
   129
EXPORT_C int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
sl@0
   130
	{
sl@0
   131
	return(X509v3_get_ext_by_NID(x->singleRequestExtensions,nid,lastpos));
sl@0
   132
	}
sl@0
   133
sl@0
   134
EXPORT_C int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos)
sl@0
   135
	{
sl@0
   136
	return(X509v3_get_ext_by_OBJ(x->singleRequestExtensions,obj,lastpos));
sl@0
   137
	}
sl@0
   138
sl@0
   139
EXPORT_C int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
sl@0
   140
	{
sl@0
   141
	return(X509v3_get_ext_by_critical(x->singleRequestExtensions,crit,lastpos));
sl@0
   142
	}
sl@0
   143
sl@0
   144
EXPORT_C X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
sl@0
   145
	{
sl@0
   146
	return(X509v3_get_ext(x->singleRequestExtensions,loc));
sl@0
   147
	}
sl@0
   148
sl@0
   149
EXPORT_C X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
sl@0
   150
	{
sl@0
   151
	return(X509v3_delete_ext(x->singleRequestExtensions,loc));
sl@0
   152
	}
sl@0
   153
sl@0
   154
EXPORT_C void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
sl@0
   155
	{
sl@0
   156
	return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
sl@0
   157
	}
sl@0
   158
sl@0
   159
EXPORT_C int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
sl@0
   160
							unsigned long flags)
sl@0
   161
	{
sl@0
   162
	return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, flags);
sl@0
   163
	}
sl@0
   164
sl@0
   165
EXPORT_C int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
sl@0
   166
	{
sl@0
   167
	return(X509v3_add_ext(&(x->singleRequestExtensions),ex,loc) != NULL);
sl@0
   168
	}
sl@0
   169
sl@0
   170
/* OCSP Basic response */
sl@0
   171
sl@0
   172
EXPORT_C int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
sl@0
   173
	{
sl@0
   174
	return(X509v3_get_ext_count(x->tbsResponseData->responseExtensions));
sl@0
   175
	}
sl@0
   176
sl@0
   177
EXPORT_C int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
sl@0
   178
	{
sl@0
   179
	return(X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions,nid,lastpos));
sl@0
   180
	}
sl@0
   181
sl@0
   182
EXPORT_C int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos)
sl@0
   183
	{
sl@0
   184
	return(X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions,obj,lastpos));
sl@0
   185
	}
sl@0
   186
sl@0
   187
EXPORT_C int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos)
sl@0
   188
	{
sl@0
   189
	return(X509v3_get_ext_by_critical(x->tbsResponseData->responseExtensions,crit,lastpos));
sl@0
   190
	}
sl@0
   191
sl@0
   192
EXPORT_C X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
sl@0
   193
	{
sl@0
   194
	return(X509v3_get_ext(x->tbsResponseData->responseExtensions,loc));
sl@0
   195
	}
sl@0
   196
sl@0
   197
EXPORT_C X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
sl@0
   198
	{
sl@0
   199
	return(X509v3_delete_ext(x->tbsResponseData->responseExtensions,loc));
sl@0
   200
	}
sl@0
   201
sl@0
   202
EXPORT_C void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx)
sl@0
   203
	{
sl@0
   204
	return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, idx);
sl@0
   205
	}
sl@0
   206
sl@0
   207
EXPORT_C int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
sl@0
   208
							unsigned long flags)
sl@0
   209
	{
sl@0
   210
	return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, value, crit, flags);
sl@0
   211
	}
sl@0
   212
sl@0
   213
EXPORT_C int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
sl@0
   214
	{
sl@0
   215
	return(X509v3_add_ext(&(x->tbsResponseData->responseExtensions),ex,loc) != NULL);
sl@0
   216
	}
sl@0
   217
sl@0
   218
/* OCSP single response extensions */
sl@0
   219
sl@0
   220
EXPORT_C int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
sl@0
   221
	{
sl@0
   222
	return(X509v3_get_ext_count(x->singleExtensions));
sl@0
   223
	}
sl@0
   224
sl@0
   225
EXPORT_C int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
sl@0
   226
	{
sl@0
   227
	return(X509v3_get_ext_by_NID(x->singleExtensions,nid,lastpos));
sl@0
   228
	}
sl@0
   229
sl@0
   230
EXPORT_C int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos)
sl@0
   231
	{
sl@0
   232
	return(X509v3_get_ext_by_OBJ(x->singleExtensions,obj,lastpos));
sl@0
   233
	}
sl@0
   234
sl@0
   235
EXPORT_C int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos)
sl@0
   236
	{
sl@0
   237
	return(X509v3_get_ext_by_critical(x->singleExtensions,crit,lastpos));
sl@0
   238
	}
sl@0
   239
sl@0
   240
EXPORT_C X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
sl@0
   241
	{
sl@0
   242
	return(X509v3_get_ext(x->singleExtensions,loc));
sl@0
   243
	}
sl@0
   244
sl@0
   245
EXPORT_C X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
sl@0
   246
	{
sl@0
   247
	return(X509v3_delete_ext(x->singleExtensions,loc));
sl@0
   248
	}
sl@0
   249
sl@0
   250
EXPORT_C void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx)
sl@0
   251
	{
sl@0
   252
	return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
sl@0
   253
	}
sl@0
   254
sl@0
   255
EXPORT_C int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
sl@0
   256
							unsigned long flags)
sl@0
   257
	{
sl@0
   258
	return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
sl@0
   259
	}
sl@0
   260
sl@0
   261
EXPORT_C int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
sl@0
   262
	{
sl@0
   263
	return(X509v3_add_ext(&(x->singleExtensions),ex,loc) != NULL);
sl@0
   264
	}
sl@0
   265
sl@0
   266
/* also CRL Entry Extensions */
sl@0
   267
sl@0
   268
EXPORT_C ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
sl@0
   269
				void *data, STACK_OF(ASN1_OBJECT) *sk)
sl@0
   270
        {
sl@0
   271
	int i;
sl@0
   272
	unsigned char *p, *b = NULL;
sl@0
   273
sl@0
   274
	if (data)
sl@0
   275
	        {
sl@0
   276
		if ((i=i2d(data,NULL)) <= 0) goto err;
sl@0
   277
		if (!(b=p=OPENSSL_malloc((unsigned int)i)))
sl@0
   278
			goto err;
sl@0
   279
	        if (i2d(data, &p) <= 0) goto err;
sl@0
   280
		}
sl@0
   281
	else if (sk)
sl@0
   282
	        {
sl@0
   283
		if ((i=i2d_ASN1_SET_OF_ASN1_OBJECT(sk,NULL,
sl@0
   284
						   (I2D_OF(ASN1_OBJECT))i2d,
sl@0
   285
						   V_ASN1_SEQUENCE,
sl@0
   286
						   V_ASN1_UNIVERSAL,
sl@0
   287
						   IS_SEQUENCE))<=0) goto err;
sl@0
   288
		if (!(b=p=OPENSSL_malloc((unsigned int)i)))
sl@0
   289
			goto err;
sl@0
   290
		if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk,&p,(I2D_OF(ASN1_OBJECT))i2d,
sl@0
   291
						V_ASN1_SEQUENCE,
sl@0
   292
						V_ASN1_UNIVERSAL,
sl@0
   293
						IS_SEQUENCE)<=0) goto err;
sl@0
   294
		}
sl@0
   295
	else
sl@0
   296
		{
sl@0
   297
		OCSPerr(OCSP_F_ASN1_STRING_ENCODE,OCSP_R_BAD_DATA);
sl@0
   298
		goto err;
sl@0
   299
		}
sl@0
   300
	if (!s && !(s = ASN1_STRING_new())) goto err;
sl@0
   301
	if (!(ASN1_STRING_set(s, b, i))) goto err;
sl@0
   302
	OPENSSL_free(b);
sl@0
   303
	return s;
sl@0
   304
err:
sl@0
   305
	if (b) OPENSSL_free(b);
sl@0
   306
	return NULL;
sl@0
   307
	}
sl@0
   308
sl@0
   309
/* Nonce handling functions */
sl@0
   310
sl@0
   311
/* Add a nonce to an extension stack. A nonce can be specificed or if NULL
sl@0
   312
 * a random nonce will be generated.
sl@0
   313
 * Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the 
sl@0
   314
 * nonce, previous versions used the raw nonce.
sl@0
   315
 */
sl@0
   316
sl@0
   317
static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len)
sl@0
   318
	{
sl@0
   319
	unsigned char *tmpval;
sl@0
   320
	ASN1_OCTET_STRING os;
sl@0
   321
	int ret = 0;
sl@0
   322
	if (len <= 0) len = OCSP_DEFAULT_NONCE_LENGTH;
sl@0
   323
	/* Create the OCTET STRING manually by writing out the header and
sl@0
   324
	 * appending the content octets. This avoids an extra memory allocation
sl@0
   325
	 * operation in some cases. Applications should *NOT* do this because
sl@0
   326
         * it relies on library internals.
sl@0
   327
	 */
sl@0
   328
	os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
sl@0
   329
	os.data = OPENSSL_malloc(os.length);
sl@0
   330
	if (os.data == NULL)
sl@0
   331
		goto err;
sl@0
   332
	tmpval = os.data;
sl@0
   333
	ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
sl@0
   334
	if (val)
sl@0
   335
		memcpy(tmpval, val, len);
sl@0
   336
	else
sl@0
   337
		RAND_pseudo_bytes(tmpval, len);
sl@0
   338
	if(!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
sl@0
   339
			&os, 0, X509V3_ADD_REPLACE))
sl@0
   340
				goto err;
sl@0
   341
	ret = 1;
sl@0
   342
	err:
sl@0
   343
	if (os.data)
sl@0
   344
		OPENSSL_free(os.data);
sl@0
   345
	return ret;
sl@0
   346
	}
sl@0
   347
sl@0
   348
sl@0
   349
/* Add nonce to an OCSP request */
sl@0
   350
sl@0
   351
EXPORT_C int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
sl@0
   352
	{
sl@0
   353
	return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len);
sl@0
   354
	}
sl@0
   355
sl@0
   356
/* Same as above but for a response */
sl@0
   357
sl@0
   358
EXPORT_C int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
sl@0
   359
	{
sl@0
   360
	return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, len);
sl@0
   361
	}
sl@0
   362
sl@0
   363
/* Check nonce validity in a request and response.
sl@0
   364
 * Return value reflects result:
sl@0
   365
 *  1: nonces present and equal.
sl@0
   366
 *  2: nonces both absent.
sl@0
   367
 *  3: nonce present in response only.
sl@0
   368
 *  0: nonces both present and not equal.
sl@0
   369
 * -1: nonce in request only.
sl@0
   370
 *
sl@0
   371
 *  For most responders clients can check return > 0.
sl@0
   372
 *  If responder doesn't handle nonces return != 0 may be
sl@0
   373
 *  necessary. return == 0 is always an error.
sl@0
   374
 */
sl@0
   375
sl@0
   376
EXPORT_C int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
sl@0
   377
	{
sl@0
   378
	/*
sl@0
   379
	 * Since we are only interested in the presence or absence of
sl@0
   380
	 * the nonce and comparing its value there is no need to use
sl@0
   381
	 * the X509V3 routines: this way we can avoid them allocating an
sl@0
   382
	 * ASN1_OCTET_STRING structure for the value which would be
sl@0
   383
	 * freed immediately anyway.
sl@0
   384
	 */
sl@0
   385
sl@0
   386
	int req_idx, resp_idx;
sl@0
   387
	X509_EXTENSION *req_ext, *resp_ext;
sl@0
   388
	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
sl@0
   389
	resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
sl@0
   390
	/* Check both absent */
sl@0
   391
	if((req_idx < 0) && (resp_idx < 0))
sl@0
   392
		return 2;
sl@0
   393
	/* Check in request only */
sl@0
   394
	if((req_idx >= 0) && (resp_idx < 0))
sl@0
   395
		return -1;
sl@0
   396
	/* Check in response but not request */
sl@0
   397
	if((req_idx < 0) && (resp_idx >= 0))
sl@0
   398
		return 3;
sl@0
   399
	/* Otherwise nonce in request and response so retrieve the extensions */
sl@0
   400
	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
sl@0
   401
	resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
sl@0
   402
	if(ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value))
sl@0
   403
		return 0;
sl@0
   404
	return 1;
sl@0
   405
	}
sl@0
   406
sl@0
   407
/* Copy the nonce value (if any) from an OCSP request to 
sl@0
   408
 * a response.
sl@0
   409
 */
sl@0
   410
sl@0
   411
EXPORT_C int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
sl@0
   412
	{
sl@0
   413
	X509_EXTENSION *req_ext;
sl@0
   414
	int req_idx;
sl@0
   415
	/* Check for nonce in request */
sl@0
   416
	req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
sl@0
   417
	/* If no nonce that's OK */
sl@0
   418
	if (req_idx < 0) return 2;
sl@0
   419
	req_ext = OCSP_REQUEST_get_ext(req, req_idx);
sl@0
   420
	return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
sl@0
   421
	}
sl@0
   422
sl@0
   423
EXPORT_C X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim)
sl@0
   424
        {
sl@0
   425
	X509_EXTENSION *x = NULL;
sl@0
   426
	OCSP_CRLID *cid = NULL;
sl@0
   427
	
sl@0
   428
	if (!(cid = OCSP_CRLID_new())) goto err;
sl@0
   429
	if (url)
sl@0
   430
	        {
sl@0
   431
		if (!(cid->crlUrl = ASN1_IA5STRING_new())) goto err;
sl@0
   432
		if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) goto err;
sl@0
   433
		}
sl@0
   434
	if (n)
sl@0
   435
	        {
sl@0
   436
		if (!(cid->crlNum = ASN1_INTEGER_new())) goto err;
sl@0
   437
		if (!(ASN1_INTEGER_set(cid->crlNum, *n))) goto err;
sl@0
   438
		}
sl@0
   439
	if (tim)
sl@0
   440
	        {
sl@0
   441
		if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) goto err;
sl@0
   442
		if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 
sl@0
   443
		        goto err;
sl@0
   444
		}
sl@0
   445
	if (!(x = X509_EXTENSION_new())) goto err;
sl@0
   446
	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_CrlID))) goto err;
sl@0
   447
	if (!(ASN1_STRING_encode_of(OCSP_CRLID,x->value,i2d_OCSP_CRLID,cid,
sl@0
   448
				    NULL)))
sl@0
   449
	        goto err;
sl@0
   450
	OCSP_CRLID_free(cid);
sl@0
   451
	return x;
sl@0
   452
err:
sl@0
   453
	if (x) X509_EXTENSION_free(x);
sl@0
   454
	if (cid) OCSP_CRLID_free(cid);
sl@0
   455
	return NULL;
sl@0
   456
	}
sl@0
   457
sl@0
   458
/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
sl@0
   459
EXPORT_C X509_EXTENSION *OCSP_accept_responses_new(char **oids)
sl@0
   460
        {
sl@0
   461
	int nid;
sl@0
   462
	STACK_OF(ASN1_OBJECT) *sk = NULL;
sl@0
   463
	ASN1_OBJECT *o = NULL;
sl@0
   464
        X509_EXTENSION *x = NULL;
sl@0
   465
sl@0
   466
	if (!(sk = sk_ASN1_OBJECT_new_null())) goto err;
sl@0
   467
	while (oids && *oids)
sl@0
   468
	        {
sl@0
   469
		if ((nid=OBJ_txt2nid(*oids))!=NID_undef&&(o=OBJ_nid2obj(nid))) 
sl@0
   470
		        sk_ASN1_OBJECT_push(sk, o);
sl@0
   471
		oids++;
sl@0
   472
		}
sl@0
   473
	if (!(x = X509_EXTENSION_new())) goto err;
sl@0
   474
	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_acceptableResponses)))
sl@0
   475
		goto err;
sl@0
   476
	if (!(ASN1_STRING_encode_of(ASN1_OBJECT,x->value,i2d_ASN1_OBJECT,NULL,
sl@0
   477
				    sk)))
sl@0
   478
	        goto err;
sl@0
   479
	sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
sl@0
   480
	return x;
sl@0
   481
err:
sl@0
   482
	if (x) X509_EXTENSION_free(x);
sl@0
   483
	if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
sl@0
   484
	return NULL;
sl@0
   485
        }
sl@0
   486
sl@0
   487
/*  ArchiveCutoff ::= GeneralizedTime */
sl@0
   488
EXPORT_C X509_EXTENSION *OCSP_archive_cutoff_new(char* tim)
sl@0
   489
        {
sl@0
   490
	X509_EXTENSION *x=NULL;
sl@0
   491
	ASN1_GENERALIZEDTIME *gt = NULL;
sl@0
   492
sl@0
   493
	if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err;
sl@0
   494
	if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err;
sl@0
   495
	if (!(x = X509_EXTENSION_new())) goto err;
sl@0
   496
	if (!(x->object=OBJ_nid2obj(NID_id_pkix_OCSP_archiveCutoff)))goto err;
sl@0
   497
	if (!(ASN1_STRING_encode_of(ASN1_GENERALIZEDTIME,x->value,
sl@0
   498
				    i2d_ASN1_GENERALIZEDTIME,gt,NULL))) goto err;
sl@0
   499
	ASN1_GENERALIZEDTIME_free(gt);
sl@0
   500
	return x;
sl@0
   501
err:
sl@0
   502
	if (gt) ASN1_GENERALIZEDTIME_free(gt);
sl@0
   503
	if (x) X509_EXTENSION_free(x);
sl@0
   504
	return NULL;
sl@0
   505
	}
sl@0
   506
sl@0
   507
/* per ACCESS_DESCRIPTION parameter are oids, of which there are currently
sl@0
   508
 * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This
sl@0
   509
 * method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
sl@0
   510
 */
sl@0
   511
EXPORT_C X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls)
sl@0
   512
        {
sl@0
   513
	X509_EXTENSION *x = NULL;
sl@0
   514
	ASN1_IA5STRING *ia5 = NULL;
sl@0
   515
	OCSP_SERVICELOC *sloc = NULL;
sl@0
   516
	ACCESS_DESCRIPTION *ad = NULL;
sl@0
   517
	
sl@0
   518
	if (!(sloc = OCSP_SERVICELOC_new())) goto err;
sl@0
   519
	if (!(sloc->issuer = X509_NAME_dup(issuer))) goto err;
sl@0
   520
	if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) goto err;
sl@0
   521
	while (urls && *urls)
sl@0
   522
	        {
sl@0
   523
		if (!(ad = ACCESS_DESCRIPTION_new())) goto err;
sl@0
   524
		if (!(ad->method=OBJ_nid2obj(NID_ad_OCSP))) goto err;
sl@0
   525
		if (!(ad->location = GENERAL_NAME_new())) goto err;
sl@0
   526
	        if (!(ia5 = ASN1_IA5STRING_new())) goto err;
sl@0
   527
		if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1)) goto err;
sl@0
   528
		ad->location->type = GEN_URI;
sl@0
   529
		ad->location->d.ia5 = ia5;
sl@0
   530
		if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err;
sl@0
   531
		urls++;
sl@0
   532
		}
sl@0
   533
	if (!(x = X509_EXTENSION_new())) goto err;
sl@0
   534
	if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_serviceLocator))) 
sl@0
   535
	        goto err;
sl@0
   536
	if (!(ASN1_STRING_encode_of(OCSP_SERVICELOC,x->value,
sl@0
   537
				    i2d_OCSP_SERVICELOC,sloc,NULL))) goto err;
sl@0
   538
	OCSP_SERVICELOC_free(sloc);
sl@0
   539
	return x;
sl@0
   540
err:
sl@0
   541
	if (x) X509_EXTENSION_free(x);
sl@0
   542
	if (sloc) OCSP_SERVICELOC_free(sloc);
sl@0
   543
	return NULL;
sl@0
   544
	}
sl@0
   545