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