1109998Smarkm/* ocsp_ext.c */ 2280304Sjkim/* 3280304Sjkim * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 4280304Sjkim * project. 5280304Sjkim */ 6109998Smarkm 7280304Sjkim/* 8280304Sjkim * History: This file was transfered to Richard Levitte from CertCo by Kathy 9280304Sjkim * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a 10280304Sjkim * patch kit. 11280304Sjkim */ 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 21280304Sjkim * 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) 80280304Sjkim{ 81280304Sjkim return (X509v3_get_ext_count(x->tbsRequest->requestExtensions)); 82280304Sjkim} 83109998Smarkm 84109998Smarkmint OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) 85280304Sjkim{ 86280304Sjkim return (X509v3_get_ext_by_NID 87280304Sjkim (x->tbsRequest->requestExtensions, nid, lastpos)); 88280304Sjkim} 89109998Smarkm 90280304Sjkimint OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, 91280304Sjkim int lastpos) 92280304Sjkim{ 93280304Sjkim return (X509v3_get_ext_by_OBJ 94280304Sjkim (x->tbsRequest->requestExtensions, obj, lastpos)); 95280304Sjkim} 96109998Smarkm 97109998Smarkmint OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) 98280304Sjkim{ 99280304Sjkim return (X509v3_get_ext_by_critical 100280304Sjkim (x->tbsRequest->requestExtensions, crit, lastpos)); 101280304Sjkim} 102109998Smarkm 103109998SmarkmX509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) 104280304Sjkim{ 105280304Sjkim return (X509v3_get_ext(x->tbsRequest->requestExtensions, loc)); 106280304Sjkim} 107109998Smarkm 108109998SmarkmX509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) 109280304Sjkim{ 110280304Sjkim return (X509v3_delete_ext(x->tbsRequest->requestExtensions, loc)); 111280304Sjkim} 112109998Smarkm 113109998Smarkmvoid *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) 114280304Sjkim{ 115280304Sjkim return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); 116280304Sjkim} 117109998Smarkm 118109998Smarkmint OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, 119280304Sjkim unsigned long flags) 120280304Sjkim{ 121280304Sjkim return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, 122280304Sjkim crit, flags); 123280304Sjkim} 124109998Smarkm 125109998Smarkmint OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) 126280304Sjkim{ 127280304Sjkim return (X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, loc) != 128280304Sjkim NULL); 129280304Sjkim} 130109998Smarkm 131109998Smarkm/* Single extensions */ 132109998Smarkm 133109998Smarkmint OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) 134280304Sjkim{ 135280304Sjkim return (X509v3_get_ext_count(x->singleRequestExtensions)); 136280304Sjkim} 137109998Smarkm 138109998Smarkmint OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) 139280304Sjkim{ 140280304Sjkim return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos)); 141280304Sjkim} 142109998Smarkm 143109998Smarkmint OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) 144280304Sjkim{ 145280304Sjkim return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos)); 146280304Sjkim} 147109998Smarkm 148109998Smarkmint OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) 149280304Sjkim{ 150280304Sjkim return (X509v3_get_ext_by_critical 151280304Sjkim (x->singleRequestExtensions, crit, lastpos)); 152280304Sjkim} 153109998Smarkm 154109998SmarkmX509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) 155280304Sjkim{ 156280304Sjkim return (X509v3_get_ext(x->singleRequestExtensions, loc)); 157280304Sjkim} 158109998Smarkm 159109998SmarkmX509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) 160280304Sjkim{ 161280304Sjkim return (X509v3_delete_ext(x->singleRequestExtensions, loc)); 162280304Sjkim} 163109998Smarkm 164109998Smarkmvoid *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) 165280304Sjkim{ 166280304Sjkim return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); 167280304Sjkim} 168109998Smarkm 169109998Smarkmint OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, 170280304Sjkim unsigned long flags) 171280304Sjkim{ 172280304Sjkim return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, 173280304Sjkim flags); 174280304Sjkim} 175109998Smarkm 176109998Smarkmint OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) 177280304Sjkim{ 178280304Sjkim return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL); 179280304Sjkim} 180109998Smarkm 181109998Smarkm/* OCSP Basic response */ 182109998Smarkm 183109998Smarkmint OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) 184280304Sjkim{ 185280304Sjkim return (X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); 186280304Sjkim} 187109998Smarkm 188109998Smarkmint OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) 189280304Sjkim{ 190280304Sjkim return (X509v3_get_ext_by_NID 191280304Sjkim (x->tbsResponseData->responseExtensions, nid, lastpos)); 192280304Sjkim} 193109998Smarkm 194280304Sjkimint OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, 195280304Sjkim int lastpos) 196280304Sjkim{ 197280304Sjkim return (X509v3_get_ext_by_OBJ 198280304Sjkim (x->tbsResponseData->responseExtensions, obj, lastpos)); 199280304Sjkim} 200109998Smarkm 201280304Sjkimint OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, 202280304Sjkim int lastpos) 203280304Sjkim{ 204280304Sjkim return (X509v3_get_ext_by_critical 205280304Sjkim (x->tbsResponseData->responseExtensions, crit, lastpos)); 206280304Sjkim} 207109998Smarkm 208109998SmarkmX509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) 209280304Sjkim{ 210280304Sjkim return (X509v3_get_ext(x->tbsResponseData->responseExtensions, loc)); 211280304Sjkim} 212109998Smarkm 213109998SmarkmX509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) 214280304Sjkim{ 215280304Sjkim return (X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc)); 216280304Sjkim} 217109998Smarkm 218280304Sjkimvoid *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, 219280304Sjkim int *idx) 220280304Sjkim{ 221280304Sjkim return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, 222280304Sjkim idx); 223280304Sjkim} 224109998Smarkm 225280304Sjkimint OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, 226280304Sjkim int crit, unsigned long flags) 227280304Sjkim{ 228280304Sjkim return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, 229280304Sjkim value, crit, flags); 230280304Sjkim} 231109998Smarkm 232109998Smarkmint OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) 233280304Sjkim{ 234280304Sjkim return (X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, loc) 235280304Sjkim != NULL); 236280304Sjkim} 237109998Smarkm 238109998Smarkm/* OCSP single response extensions */ 239109998Smarkm 240109998Smarkmint OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) 241280304Sjkim{ 242280304Sjkim return (X509v3_get_ext_count(x->singleExtensions)); 243280304Sjkim} 244109998Smarkm 245109998Smarkmint OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) 246280304Sjkim{ 247280304Sjkim return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos)); 248280304Sjkim} 249109998Smarkm 250280304Sjkimint OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, 251280304Sjkim int lastpos) 252280304Sjkim{ 253280304Sjkim return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos)); 254280304Sjkim} 255109998Smarkm 256280304Sjkimint OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, 257280304Sjkim int lastpos) 258280304Sjkim{ 259280304Sjkim return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos)); 260280304Sjkim} 261109998Smarkm 262109998SmarkmX509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) 263280304Sjkim{ 264280304Sjkim return (X509v3_get_ext(x->singleExtensions, loc)); 265280304Sjkim} 266109998Smarkm 267109998SmarkmX509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) 268280304Sjkim{ 269280304Sjkim return (X509v3_delete_ext(x->singleExtensions, loc)); 270280304Sjkim} 271109998Smarkm 272280304Sjkimvoid *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, 273280304Sjkim int *idx) 274280304Sjkim{ 275280304Sjkim return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); 276280304Sjkim} 277109998Smarkm 278280304Sjkimint OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, 279280304Sjkim int crit, unsigned long flags) 280280304Sjkim{ 281280304Sjkim return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); 282280304Sjkim} 283109998Smarkm 284109998Smarkmint OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) 285280304Sjkim{ 286280304Sjkim return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL); 287280304Sjkim} 288109998Smarkm 289109998Smarkm/* also CRL Entry Extensions */ 290238405Sjkim#if 0 291160814SsimonASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, 292280304Sjkim void *data, STACK_OF(ASN1_OBJECT) *sk) 293280304Sjkim{ 294280304Sjkim int i; 295280304Sjkim unsigned char *p, *b = NULL; 296109998Smarkm 297280304Sjkim if (data) { 298280304Sjkim if ((i = i2d(data, NULL)) <= 0) 299280304Sjkim goto err; 300280304Sjkim if (!(b = p = OPENSSL_malloc((unsigned int)i))) 301280304Sjkim goto err; 302280304Sjkim if (i2d(data, &p) <= 0) 303280304Sjkim goto err; 304280304Sjkim } else if (sk) { 305280304Sjkim if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL, 306280304Sjkim (I2D_OF(ASN1_OBJECT)) i2d, 307280304Sjkim V_ASN1_SEQUENCE, 308280304Sjkim V_ASN1_UNIVERSAL, 309280304Sjkim IS_SEQUENCE)) <= 0) 310280304Sjkim goto err; 311280304Sjkim if (!(b = p = OPENSSL_malloc((unsigned int)i))) 312280304Sjkim goto err; 313280304Sjkim if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p, (I2D_OF(ASN1_OBJECT)) i2d, 314280304Sjkim V_ASN1_SEQUENCE, 315280304Sjkim V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0) 316280304Sjkim goto err; 317280304Sjkim } else { 318280304Sjkim OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA); 319280304Sjkim goto err; 320280304Sjkim } 321280304Sjkim if (!s && !(s = ASN1_STRING_new())) 322280304Sjkim goto err; 323280304Sjkim if (!(ASN1_STRING_set(s, b, i))) 324280304Sjkim goto err; 325280304Sjkim OPENSSL_free(b); 326280304Sjkim return s; 327280304Sjkim err: 328280304Sjkim if (b) 329280304Sjkim OPENSSL_free(b); 330280304Sjkim return NULL; 331280304Sjkim} 332238405Sjkim#endif 333109998Smarkm 334109998Smarkm/* Nonce handling functions */ 335109998Smarkm 336280304Sjkim/* 337280304Sjkim * Add a nonce to an extension stack. A nonce can be specificed or if NULL a 338280304Sjkim * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an 339280304Sjkim * OCTET STRING containing the nonce, previous versions used the raw nonce. 340109998Smarkm */ 341109998Smarkm 342280304Sjkimstatic int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, 343280304Sjkim unsigned char *val, int len) 344280304Sjkim{ 345280304Sjkim unsigned char *tmpval; 346280304Sjkim ASN1_OCTET_STRING os; 347280304Sjkim int ret = 0; 348280304Sjkim if (len <= 0) 349280304Sjkim len = OCSP_DEFAULT_NONCE_LENGTH; 350280304Sjkim /* 351280304Sjkim * Create the OCTET STRING manually by writing out the header and 352280304Sjkim * appending the content octets. This avoids an extra memory allocation 353280304Sjkim * operation in some cases. Applications should *NOT* do this because it 354280304Sjkim * relies on library internals. 355280304Sjkim */ 356280304Sjkim os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); 357280304Sjkim os.data = OPENSSL_malloc(os.length); 358280304Sjkim if (os.data == NULL) 359280304Sjkim goto err; 360280304Sjkim tmpval = os.data; 361280304Sjkim ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); 362280304Sjkim if (val) 363280304Sjkim memcpy(tmpval, val, len); 364284285Sjkim else if (RAND_pseudo_bytes(tmpval, len) < 0) 365284285Sjkim goto err; 366280304Sjkim if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, 367280304Sjkim &os, 0, X509V3_ADD_REPLACE)) 368280304Sjkim goto err; 369280304Sjkim ret = 1; 370280304Sjkim err: 371280304Sjkim if (os.data) 372280304Sjkim OPENSSL_free(os.data); 373280304Sjkim return ret; 374280304Sjkim} 375109998Smarkm 376109998Smarkm/* Add nonce to an OCSP request */ 377109998Smarkm 378109998Smarkmint OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) 379280304Sjkim{ 380280304Sjkim return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); 381280304Sjkim} 382109998Smarkm 383109998Smarkm/* Same as above but for a response */ 384109998Smarkm 385109998Smarkmint OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) 386280304Sjkim{ 387280304Sjkim return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, 388280304Sjkim len); 389280304Sjkim} 390109998Smarkm 391280304Sjkim/*- 392280304Sjkim * 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) 406280304Sjkim{ 407280304Sjkim /* 408280304Sjkim * Since we are only interested in the presence or absence of 409280304Sjkim * the nonce and comparing its value there is no need to use 410280304Sjkim * the X509V3 routines: this way we can avoid them allocating an 411280304Sjkim * ASN1_OCTET_STRING structure for the value which would be 412280304Sjkim * freed immediately anyway. 413280304Sjkim */ 414109998Smarkm 415280304Sjkim int req_idx, resp_idx; 416280304Sjkim X509_EXTENSION *req_ext, *resp_ext; 417280304Sjkim req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 418280304Sjkim resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); 419280304Sjkim /* Check both absent */ 420280304Sjkim if ((req_idx < 0) && (resp_idx < 0)) 421280304Sjkim return 2; 422280304Sjkim /* Check in request only */ 423280304Sjkim if ((req_idx >= 0) && (resp_idx < 0)) 424280304Sjkim return -1; 425280304Sjkim /* Check in response but not request */ 426280304Sjkim if ((req_idx < 0) && (resp_idx >= 0)) 427280304Sjkim return 3; 428280304Sjkim /* 429280304Sjkim * Otherwise nonce in request and response so retrieve the extensions 430280304Sjkim */ 431280304Sjkim req_ext = OCSP_REQUEST_get_ext(req, req_idx); 432280304Sjkim resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); 433280304Sjkim if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) 434280304Sjkim return 0; 435280304Sjkim return 1; 436280304Sjkim} 437109998Smarkm 438280304Sjkim/* 439280304Sjkim * 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) 443280304Sjkim{ 444280304Sjkim X509_EXTENSION *req_ext; 445280304Sjkim int req_idx; 446280304Sjkim /* Check for nonce in request */ 447280304Sjkim req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); 448280304Sjkim /* If no nonce that's OK */ 449280304Sjkim if (req_idx < 0) 450280304Sjkim return 2; 451280304Sjkim req_ext = OCSP_REQUEST_get_ext(req, req_idx); 452280304Sjkim return OCSP_BASICRESP_add_ext(resp, req_ext, -1); 453280304Sjkim} 454109998Smarkm 455109998SmarkmX509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) 456280304Sjkim{ 457280304Sjkim X509_EXTENSION *x = NULL; 458280304Sjkim OCSP_CRLID *cid = NULL; 459109998Smarkm 460280304Sjkim if (!(cid = OCSP_CRLID_new())) 461280304Sjkim goto err; 462280304Sjkim if (url) { 463280304Sjkim if (!(cid->crlUrl = ASN1_IA5STRING_new())) 464280304Sjkim goto err; 465280304Sjkim if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) 466280304Sjkim goto err; 467280304Sjkim } 468280304Sjkim if (n) { 469280304Sjkim if (!(cid->crlNum = ASN1_INTEGER_new())) 470280304Sjkim goto err; 471280304Sjkim if (!(ASN1_INTEGER_set(cid->crlNum, *n))) 472280304Sjkim goto err; 473280304Sjkim } 474280304Sjkim if (tim) { 475280304Sjkim if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) 476280304Sjkim goto err; 477280304Sjkim if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) 478280304Sjkim goto err; 479280304Sjkim } 480280304Sjkim x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); 481280304Sjkim err: 482280304Sjkim if (cid) 483280304Sjkim OCSP_CRLID_free(cid); 484280304Sjkim return x; 485280304Sjkim} 486280304Sjkim 487109998Smarkm/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ 488109998SmarkmX509_EXTENSION *OCSP_accept_responses_new(char **oids) 489280304Sjkim{ 490280304Sjkim int nid; 491280304Sjkim STACK_OF(ASN1_OBJECT) *sk = NULL; 492280304Sjkim ASN1_OBJECT *o = NULL; 493280304Sjkim X509_EXTENSION *x = NULL; 494109998Smarkm 495280304Sjkim if (!(sk = sk_ASN1_OBJECT_new_null())) 496280304Sjkim goto err; 497280304Sjkim while (oids && *oids) { 498280304Sjkim if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid))) 499280304Sjkim sk_ASN1_OBJECT_push(sk, o); 500280304Sjkim oids++; 501280304Sjkim } 502280304Sjkim x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); 503280304Sjkim err: 504280304Sjkim if (sk) 505280304Sjkim sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); 506280304Sjkim return x; 507280304Sjkim} 508109998Smarkm 509109998Smarkm/* ArchiveCutoff ::= GeneralizedTime */ 510280304SjkimX509_EXTENSION *OCSP_archive_cutoff_new(char *tim) 511280304Sjkim{ 512280304Sjkim X509_EXTENSION *x = NULL; 513280304Sjkim ASN1_GENERALIZEDTIME *gt = NULL; 514109998Smarkm 515280304Sjkim if (!(gt = ASN1_GENERALIZEDTIME_new())) 516280304Sjkim goto err; 517280304Sjkim if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) 518280304Sjkim goto err; 519280304Sjkim x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); 520280304Sjkim err: 521280304Sjkim if (gt) 522280304Sjkim ASN1_GENERALIZEDTIME_free(gt); 523280304Sjkim return x; 524280304Sjkim} 525109998Smarkm 526280304Sjkim/* 527280304Sjkim * per ACCESS_DESCRIPTION parameter are oids, of which there are currently 528280304Sjkim * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method 529280304Sjkim * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. 530109998Smarkm */ 531280304SjkimX509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls) 532280304Sjkim{ 533280304Sjkim X509_EXTENSION *x = NULL; 534280304Sjkim ASN1_IA5STRING *ia5 = NULL; 535280304Sjkim OCSP_SERVICELOC *sloc = NULL; 536280304Sjkim ACCESS_DESCRIPTION *ad = NULL; 537109998Smarkm 538280304Sjkim if (!(sloc = OCSP_SERVICELOC_new())) 539280304Sjkim goto err; 540280304Sjkim if (!(sloc->issuer = X509_NAME_dup(issuer))) 541280304Sjkim goto err; 542280304Sjkim if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) 543280304Sjkim goto err; 544280304Sjkim while (urls && *urls) { 545280304Sjkim if (!(ad = ACCESS_DESCRIPTION_new())) 546280304Sjkim goto err; 547280304Sjkim if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP))) 548280304Sjkim goto err; 549280304Sjkim if (!(ad->location = GENERAL_NAME_new())) 550280304Sjkim goto err; 551280304Sjkim if (!(ia5 = ASN1_IA5STRING_new())) 552280304Sjkim goto err; 553280304Sjkim if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1)) 554280304Sjkim goto err; 555280304Sjkim ad->location->type = GEN_URI; 556280304Sjkim ad->location->d.ia5 = ia5; 557280304Sjkim if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) 558280304Sjkim goto err; 559280304Sjkim urls++; 560280304Sjkim } 561280304Sjkim x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); 562280304Sjkim err: 563280304Sjkim if (sloc) 564280304Sjkim OCSP_SERVICELOC_free(sloc); 565280304Sjkim return x; 566280304Sjkim} 567