1109998Smarkm/* ocsp_ext.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 4296341Sdelphij * project. 5296341Sdelphij */ 6109998Smarkm 7296341Sdelphij/* 8296341Sdelphij * History: This file was transfered to Richard Levitte from CertCo by Kathy 9296341Sdelphij * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a 10296341Sdelphij * patch kit. 11296341Sdelphij */ 12109998Smarkm 13109998Smarkm/* ==================================================================== 14109998Smarkm * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 15109998Smarkm * 16109998Smarkm * Redistribution and use in source and binary forms, with or without 17109998Smarkm * modification, are permitted provided that the following conditions 18109998Smarkm * are met: 19109998Smarkm * 20109998Smarkm * 1. Redistributions of source code must retain the above copyright 21296341Sdelphij * notice, this list of conditions and the following disclaimer. 22109998Smarkm * 23109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 24109998Smarkm * notice, this list of conditions and the following disclaimer in 25109998Smarkm * the documentation and/or other materials provided with the 26109998Smarkm * distribution. 27109998Smarkm * 28109998Smarkm * 3. All advertising materials mentioning features or use of this 29109998Smarkm * software must display the following acknowledgment: 30109998Smarkm * "This product includes software developed by the OpenSSL Project 31109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 32109998Smarkm * 33109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 34109998Smarkm * endorse or promote products derived from this software without 35109998Smarkm * prior written permission. For written permission, please contact 36109998Smarkm * openssl-core@openssl.org. 37109998Smarkm * 38109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 39109998Smarkm * nor may "OpenSSL" appear in their names without prior written 40109998Smarkm * permission of the OpenSSL Project. 41109998Smarkm * 42109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 43109998Smarkm * acknowledgment: 44109998Smarkm * "This product includes software developed by the OpenSSL Project 45109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 46109998Smarkm * 47109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 48109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 50109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 51109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 52109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 53109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 56109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 58109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 59109998Smarkm * ==================================================================== 60109998Smarkm * 61109998Smarkm * This product includes cryptographic software written by Eric Young 62109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 63109998Smarkm * Hudson (tjh@cryptsoft.com). 64109998Smarkm * 65109998Smarkm */ 66109998Smarkm 67109998Smarkm#include <stdio.h> 68109998Smarkm#include <cryptlib.h> 69109998Smarkm#include <openssl/objects.h> 70109998Smarkm#include <openssl/x509.h> 71109998Smarkm#include <openssl/ocsp.h> 72109998Smarkm#include <openssl/rand.h> 73109998Smarkm#include <openssl/x509v3.h> 74109998Smarkm 75109998Smarkm/* Standard wrapper functions for extensions */ 76109998Smarkm 77109998Smarkm/* OCSP request extensions */ 78109998Smarkm 79109998Smarkmint OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) 80296341Sdelphij{ 81296341Sdelphij return (X509v3_get_ext_count(x->tbsRequest->requestExtensions)); 82296341Sdelphij} 83109998Smarkm 84109998Smarkmint OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) 85296341Sdelphij{ 86296341Sdelphij return (X509v3_get_ext_by_NID 87296341Sdelphij (x->tbsRequest->requestExtensions, nid, lastpos)); 88296341Sdelphij} 89109998Smarkm 90296341Sdelphijint OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, 91296341Sdelphij int lastpos) 92296341Sdelphij{ 93296341Sdelphij return (X509v3_get_ext_by_OBJ 94296341Sdelphij (x->tbsRequest->requestExtensions, obj, lastpos)); 95296341Sdelphij} 96109998Smarkm 97109998Smarkmint OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) 98296341Sdelphij{ 99296341Sdelphij return (X509v3_get_ext_by_critical 100296341Sdelphij (x->tbsRequest->requestExtensions, crit, lastpos)); 101296341Sdelphij} 102109998Smarkm 103109998SmarkmX509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) 104296341Sdelphij{ 105296341Sdelphij return (X509v3_get_ext(x->tbsRequest->requestExtensions, loc)); 106296341Sdelphij} 107109998Smarkm 108109998SmarkmX509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) 109296341Sdelphij{ 110296341Sdelphij return (X509v3_delete_ext(x->tbsRequest->requestExtensions, loc)); 111296341Sdelphij} 112109998Smarkm 113109998Smarkmvoid *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) 114296341Sdelphij{ 115296341Sdelphij return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); 116296341Sdelphij} 117109998Smarkm 118109998Smarkmint OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, 119296341Sdelphij unsigned long flags) 120296341Sdelphij{ 121296341Sdelphij return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, 122296341Sdelphij crit, flags); 123296341Sdelphij} 124109998Smarkm 125109998Smarkmint OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) 126296341Sdelphij{ 127296341Sdelphij return (X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, loc) != 128296341Sdelphij NULL); 129296341Sdelphij} 130109998Smarkm 131109998Smarkm/* Single extensions */ 132109998Smarkm 133109998Smarkmint OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) 134296341Sdelphij{ 135296341Sdelphij return (X509v3_get_ext_count(x->singleRequestExtensions)); 136296341Sdelphij} 137109998Smarkm 138109998Smarkmint OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) 139296341Sdelphij{ 140296341Sdelphij return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos)); 141296341Sdelphij} 142109998Smarkm 143109998Smarkmint OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) 144296341Sdelphij{ 145296341Sdelphij return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos)); 146296341Sdelphij} 147109998Smarkm 148109998Smarkmint OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) 149296341Sdelphij{ 150296341Sdelphij return (X509v3_get_ext_by_critical 151296341Sdelphij (x->singleRequestExtensions, crit, lastpos)); 152296341Sdelphij} 153109998Smarkm 154109998SmarkmX509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) 155296341Sdelphij{ 156296341Sdelphij return (X509v3_get_ext(x->singleRequestExtensions, loc)); 157296341Sdelphij} 158109998Smarkm 159109998SmarkmX509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) 160296341Sdelphij{ 161296341Sdelphij return (X509v3_delete_ext(x->singleRequestExtensions, loc)); 162296341Sdelphij} 163109998Smarkm 164109998Smarkmvoid *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) 165296341Sdelphij{ 166296341Sdelphij return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); 167296341Sdelphij} 168109998Smarkm 169109998Smarkmint OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, 170296341Sdelphij unsigned long flags) 171296341Sdelphij{ 172296341Sdelphij return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, 173296341Sdelphij flags); 174296341Sdelphij} 175109998Smarkm 176109998Smarkmint OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) 177296341Sdelphij{ 178296341Sdelphij return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL); 179296341Sdelphij} 180109998Smarkm 181109998Smarkm/* OCSP Basic response */ 182109998Smarkm 183109998Smarkmint OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) 184296341Sdelphij{ 185296341Sdelphij return (X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); 186296341Sdelphij} 187109998Smarkm 188109998Smarkmint OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) 189296341Sdelphij{ 190296341Sdelphij return (X509v3_get_ext_by_NID 191296341Sdelphij (x->tbsResponseData->responseExtensions, nid, lastpos)); 192296341Sdelphij} 193109998Smarkm 194296341Sdelphijint OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, 195296341Sdelphij int lastpos) 196296341Sdelphij{ 197296341Sdelphij return (X509v3_get_ext_by_OBJ 198296341Sdelphij (x->tbsResponseData->responseExtensions, obj, lastpos)); 199296341Sdelphij} 200109998Smarkm 201296341Sdelphijint OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, 202296341Sdelphij int lastpos) 203296341Sdelphij{ 204296341Sdelphij return (X509v3_get_ext_by_critical 205296341Sdelphij (x->tbsResponseData->responseExtensions, crit, lastpos)); 206296341Sdelphij} 207109998Smarkm 208109998SmarkmX509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) 209296341Sdelphij{ 210296341Sdelphij return (X509v3_get_ext(x->tbsResponseData->responseExtensions, loc)); 211296341Sdelphij} 212109998Smarkm 213109998SmarkmX509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) 214296341Sdelphij{ 215296341Sdelphij return (X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc)); 216296341Sdelphij} 217109998Smarkm 218296341Sdelphijvoid *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, 219296341Sdelphij int *idx) 220296341Sdelphij{ 221296341Sdelphij return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, 222296341Sdelphij idx); 223296341Sdelphij} 224109998Smarkm 225296341Sdelphijint OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, 226296341Sdelphij int crit, unsigned long flags) 227296341Sdelphij{ 228296341Sdelphij return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, 229296341Sdelphij value, crit, flags); 230296341Sdelphij} 231109998Smarkm 232109998Smarkmint OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) 233296341Sdelphij{ 234296341Sdelphij return (X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, loc) 235296341Sdelphij != NULL); 236296341Sdelphij} 237109998Smarkm 238109998Smarkm/* OCSP single response extensions */ 239109998Smarkm 240109998Smarkmint OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) 241296341Sdelphij{ 242296341Sdelphij return (X509v3_get_ext_count(x->singleExtensions)); 243296341Sdelphij} 244109998Smarkm 245109998Smarkmint OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) 246296341Sdelphij{ 247296341Sdelphij return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos)); 248296341Sdelphij} 249109998Smarkm 250296341Sdelphijint OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, 251296341Sdelphij int lastpos) 252296341Sdelphij{ 253296341Sdelphij return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos)); 254296341Sdelphij} 255109998Smarkm 256296341Sdelphijint OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, 257296341Sdelphij int lastpos) 258296341Sdelphij{ 259296341Sdelphij return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos)); 260296341Sdelphij} 261109998Smarkm 262109998SmarkmX509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) 263296341Sdelphij{ 264296341Sdelphij return (X509v3_get_ext(x->singleExtensions, loc)); 265296341Sdelphij} 266109998Smarkm 267109998SmarkmX509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) 268296341Sdelphij{ 269296341Sdelphij return (X509v3_delete_ext(x->singleExtensions, loc)); 270296341Sdelphij} 271109998Smarkm 272296341Sdelphijvoid *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, 273296341Sdelphij int *idx) 274296341Sdelphij{ 275296341Sdelphij return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); 276296341Sdelphij} 277109998Smarkm 278296341Sdelphijint OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, 279296341Sdelphij int crit, unsigned long flags) 280296341Sdelphij{ 281296341Sdelphij return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); 282296341Sdelphij} 283109998Smarkm 284109998Smarkmint OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) 285296341Sdelphij{ 286296341Sdelphij return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL); 287296341Sdelphij} 288109998Smarkm 289109998Smarkm/* also CRL Entry Extensions */ 290238405Sjkim#if 0 291160814SsimonASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, 292296341Sdelphij void *data, STACK_OF(ASN1_OBJECT) *sk) 293296341Sdelphij{ 294296341Sdelphij int i; 295296341Sdelphij unsigned char *p, *b = NULL; 296109998Smarkm 297296341Sdelphij if (data) { 298296341Sdelphij if ((i = i2d(data, NULL)) <= 0) 299296341Sdelphij goto err; 300296341Sdelphij if (!(b = p = OPENSSL_malloc((unsigned int)i))) 301296341Sdelphij goto err; 302296341Sdelphij if (i2d(data, &p) <= 0) 303296341Sdelphij goto err; 304296341Sdelphij } else if (sk) { 305296341Sdelphij if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL, 306296341Sdelphij (I2D_OF(ASN1_OBJECT)) i2d, 307296341Sdelphij V_ASN1_SEQUENCE, 308296341Sdelphij V_ASN1_UNIVERSAL, 309296341Sdelphij IS_SEQUENCE)) <= 0) 310296341Sdelphij goto err; 311296341Sdelphij if (!(b = p = OPENSSL_malloc((unsigned int)i))) 312296341Sdelphij goto err; 313296341Sdelphij if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p, (I2D_OF(ASN1_OBJECT)) i2d, 314296341Sdelphij V_ASN1_SEQUENCE, 315296341Sdelphij V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0) 316296341Sdelphij goto err; 317296341Sdelphij } else { 318296341Sdelphij OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA); 319296341Sdelphij goto err; 320296341Sdelphij } 321296341Sdelphij if (!s && !(s = ASN1_STRING_new())) 322296341Sdelphij goto err; 323296341Sdelphij if (!(ASN1_STRING_set(s, b, i))) 324296341Sdelphij goto err; 325296341Sdelphij OPENSSL_free(b); 326296341Sdelphij return s; 327296341Sdelphij err: 328296341Sdelphij if (b) 329296341Sdelphij OPENSSL_free(b); 330296341Sdelphij return NULL; 331296341Sdelphij} 332238405Sjkim#endif 333109998Smarkm 334109998Smarkm/* Nonce handling functions */ 335109998Smarkm 336296341Sdelphij/* 337296341Sdelphij * Add a nonce to an extension stack. A nonce can be specificed or if NULL a 338296341Sdelphij * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an 339296341Sdelphij * OCTET STRING containing the nonce, previous versions used the raw nonce. 340109998Smarkm */ 341109998Smarkm 342296341Sdelphijstatic int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, 343296341Sdelphij unsigned char *val, int len) 344296341Sdelphij{ 345296341Sdelphij unsigned char *tmpval; 346296341Sdelphij ASN1_OCTET_STRING os; 347296341Sdelphij int ret = 0; 348296341Sdelphij if (len <= 0) 349296341Sdelphij len = OCSP_DEFAULT_NONCE_LENGTH; 350296341Sdelphij /* 351296341Sdelphij * Create the OCTET STRING manually by writing out the header and 352296341Sdelphij * appending the content octets. This avoids an extra memory allocation 353296341Sdelphij * operation in some cases. Applications should *NOT* do this because it 354296341Sdelphij * relies on library internals. 355296341Sdelphij */ 356296341Sdelphij os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); 357296341Sdelphij os.data = OPENSSL_malloc(os.length); 358296341Sdelphij if (os.data == NULL) 359296341Sdelphij goto err; 360296341Sdelphij tmpval = os.data; 361296341Sdelphij ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); 362296341Sdelphij if (val) 363296341Sdelphij memcpy(tmpval, val, len); 364296341Sdelphij else if (RAND_pseudo_bytes(tmpval, len) < 0) 365296341Sdelphij goto err; 366296341Sdelphij if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, 367296341Sdelphij &os, 0, X509V3_ADD_REPLACE)) 368296341Sdelphij goto err; 369296341Sdelphij ret = 1; 370296341Sdelphij err: 371296341Sdelphij if (os.data) 372296341Sdelphij OPENSSL_free(os.data); 373296341Sdelphij return ret; 374296341Sdelphij} 375109998Smarkm 376109998Smarkm/* Add nonce to an OCSP request */ 377109998Smarkm 378109998Smarkmint OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) 379296341Sdelphij{ 380296341Sdelphij return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); 381296341Sdelphij} 382109998Smarkm 383109998Smarkm/* Same as above but for a response */ 384109998Smarkm 385109998Smarkmint OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) 386296341Sdelphij{ 387296341Sdelphij return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, 388296341Sdelphij len); 389296341Sdelphij} 390109998Smarkm 391296341Sdelphij/*- 392296341Sdelphij * Check nonce validity in a request and response. 393109998Smarkm * Return value reflects result: 394109998Smarkm * 1: nonces present and equal. 395109998Smarkm * 2: nonces both absent. 396109998Smarkm * 3: nonce present in response only. 397109998Smarkm * 0: nonces both present and not equal. 398109998Smarkm * -1: nonce in request only. 399109998Smarkm * 400109998Smarkm * For most responders clients can check return > 0. 401109998Smarkm * If responder doesn't handle nonces return != 0 may be 402109998Smarkm * necessary. return == 0 is always an error. 403109998Smarkm */ 404109998Smarkm 405109998Smarkmint OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) 406296341Sdelphij{ 407296341Sdelphij /* 408296341Sdelphij * Since we are only interested in the presence or absence of 409296341Sdelphij * the nonce and comparing its value there is no need to use 410296341Sdelphij * the X509V3 routines: this way we can avoid them allocating an 411296341Sdelphij * ASN1_OCTET_STRING structure for the value which would be 412296341Sdelphij * freed immediately anyway. 413296341Sdelphij */ 414109998Smarkm 415296341Sdelphij int req_idx, resp_idx; 416296341Sdelphij X509_EXTENSION *req_ext, *resp_ext; 417296341Sdelphij req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 418296341Sdelphij resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); 419296341Sdelphij /* Check both absent */ 420296341Sdelphij if ((req_idx < 0) && (resp_idx < 0)) 421296341Sdelphij return 2; 422296341Sdelphij /* Check in request only */ 423296341Sdelphij if ((req_idx >= 0) && (resp_idx < 0)) 424296341Sdelphij return -1; 425296341Sdelphij /* Check in response but not request */ 426296341Sdelphij if ((req_idx < 0) && (resp_idx >= 0)) 427296341Sdelphij return 3; 428296341Sdelphij /* 429296341Sdelphij * Otherwise nonce in request and response so retrieve the extensions 430296341Sdelphij */ 431296341Sdelphij req_ext = OCSP_REQUEST_get_ext(req, req_idx); 432296341Sdelphij resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); 433296341Sdelphij if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) 434296341Sdelphij return 0; 435296341Sdelphij return 1; 436296341Sdelphij} 437109998Smarkm 438296341Sdelphij/* 439296341Sdelphij * Copy the nonce value (if any) from an OCSP request to a response. 440109998Smarkm */ 441109998Smarkm 442109998Smarkmint OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) 443296341Sdelphij{ 444296341Sdelphij X509_EXTENSION *req_ext; 445296341Sdelphij int req_idx; 446296341Sdelphij /* Check for nonce in request */ 447296341Sdelphij req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 448296341Sdelphij /* If no nonce that's OK */ 449296341Sdelphij if (req_idx < 0) 450296341Sdelphij return 2; 451296341Sdelphij req_ext = OCSP_REQUEST_get_ext(req, req_idx); 452296341Sdelphij return OCSP_BASICRESP_add_ext(resp, req_ext, -1); 453296341Sdelphij} 454109998Smarkm 455109998SmarkmX509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) 456296341Sdelphij{ 457296341Sdelphij X509_EXTENSION *x = NULL; 458296341Sdelphij OCSP_CRLID *cid = NULL; 459109998Smarkm 460296341Sdelphij if (!(cid = OCSP_CRLID_new())) 461296341Sdelphij goto err; 462296341Sdelphij if (url) { 463296341Sdelphij if (!(cid->crlUrl = ASN1_IA5STRING_new())) 464296341Sdelphij goto err; 465296341Sdelphij if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) 466296341Sdelphij goto err; 467296341Sdelphij } 468296341Sdelphij if (n) { 469296341Sdelphij if (!(cid->crlNum = ASN1_INTEGER_new())) 470296341Sdelphij goto err; 471296341Sdelphij if (!(ASN1_INTEGER_set(cid->crlNum, *n))) 472296341Sdelphij goto err; 473296341Sdelphij } 474296341Sdelphij if (tim) { 475296341Sdelphij if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) 476296341Sdelphij goto err; 477296341Sdelphij if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 478296341Sdelphij goto err; 479296341Sdelphij } 480296341Sdelphij x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); 481296341Sdelphij err: 482296341Sdelphij if (cid) 483296341Sdelphij OCSP_CRLID_free(cid); 484296341Sdelphij return x; 485296341Sdelphij} 486296341Sdelphij 487109998Smarkm/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ 488109998SmarkmX509_EXTENSION *OCSP_accept_responses_new(char **oids) 489296341Sdelphij{ 490296341Sdelphij int nid; 491296341Sdelphij STACK_OF(ASN1_OBJECT) *sk = NULL; 492296341Sdelphij ASN1_OBJECT *o = NULL; 493296341Sdelphij X509_EXTENSION *x = NULL; 494109998Smarkm 495296341Sdelphij if (!(sk = sk_ASN1_OBJECT_new_null())) 496296341Sdelphij goto err; 497296341Sdelphij while (oids && *oids) { 498296341Sdelphij if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid))) 499296341Sdelphij sk_ASN1_OBJECT_push(sk, o); 500296341Sdelphij oids++; 501296341Sdelphij } 502296341Sdelphij x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); 503296341Sdelphij err: 504296341Sdelphij if (sk) 505296341Sdelphij sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); 506296341Sdelphij return x; 507296341Sdelphij} 508109998Smarkm 509109998Smarkm/* ArchiveCutoff ::= GeneralizedTime */ 510296341SdelphijX509_EXTENSION *OCSP_archive_cutoff_new(char *tim) 511296341Sdelphij{ 512296341Sdelphij X509_EXTENSION *x = NULL; 513296341Sdelphij ASN1_GENERALIZEDTIME *gt = NULL; 514109998Smarkm 515296341Sdelphij if (!(gt = ASN1_GENERALIZEDTIME_new())) 516296341Sdelphij goto err; 517296341Sdelphij if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) 518296341Sdelphij goto err; 519296341Sdelphij x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); 520296341Sdelphij err: 521296341Sdelphij if (gt) 522296341Sdelphij ASN1_GENERALIZEDTIME_free(gt); 523296341Sdelphij return x; 524296341Sdelphij} 525109998Smarkm 526296341Sdelphij/* 527296341Sdelphij * per ACCESS_DESCRIPTION parameter are oids, of which there are currently 528296341Sdelphij * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method 529296341Sdelphij * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. 530109998Smarkm */ 531296341SdelphijX509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls) 532296341Sdelphij{ 533296341Sdelphij X509_EXTENSION *x = NULL; 534296341Sdelphij ASN1_IA5STRING *ia5 = NULL; 535296341Sdelphij OCSP_SERVICELOC *sloc = NULL; 536296341Sdelphij ACCESS_DESCRIPTION *ad = NULL; 537109998Smarkm 538296341Sdelphij if (!(sloc = OCSP_SERVICELOC_new())) 539296341Sdelphij goto err; 540296341Sdelphij if (!(sloc->issuer = X509_NAME_dup(issuer))) 541296341Sdelphij goto err; 542296341Sdelphij if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) 543296341Sdelphij goto err; 544296341Sdelphij while (urls && *urls) { 545296341Sdelphij if (!(ad = ACCESS_DESCRIPTION_new())) 546296341Sdelphij goto err; 547296341Sdelphij if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP))) 548296341Sdelphij goto err; 549296341Sdelphij if (!(ad->location = GENERAL_NAME_new())) 550296341Sdelphij goto err; 551296341Sdelphij if (!(ia5 = ASN1_IA5STRING_new())) 552296341Sdelphij goto err; 553296341Sdelphij if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1)) 554296341Sdelphij goto err; 555296341Sdelphij ad->location->type = GEN_URI; 556296341Sdelphij ad->location->d.ia5 = ia5; 557296341Sdelphij if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) 558296341Sdelphij goto err; 559296341Sdelphij urls++; 560296341Sdelphij } 561296341Sdelphij x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); 562296341Sdelphij err: 563296341Sdelphij if (sloc) 564296341Sdelphij OCSP_SERVICELOC_free(sloc); 565296341Sdelphij return x; 566296341Sdelphij} 567