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 80 int 81 OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) 82 { 83 return X509v3_get_ext_count(x->tbsRequest->requestExtensions); 84 } 85 LCRYPTO_ALIAS(OCSP_REQUEST_get_ext_count); 86 87 int 88 OCSP_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 } 93 LCRYPTO_ALIAS(OCSP_REQUEST_get_ext_by_NID); 94 95 int 96 OCSP_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 } 102 LCRYPTO_ALIAS(OCSP_REQUEST_get_ext_by_OBJ); 103 104 int 105 OCSP_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 } 110 LCRYPTO_ALIAS(OCSP_REQUEST_get_ext_by_critical); 111 112 X509_EXTENSION * 113 OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) 114 { 115 return X509v3_get_ext(x->tbsRequest->requestExtensions, loc); 116 } 117 LCRYPTO_ALIAS(OCSP_REQUEST_get_ext); 118 119 X509_EXTENSION * 120 OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) 121 { 122 return X509v3_delete_ext(x->tbsRequest->requestExtensions, loc); 123 } 124 LCRYPTO_ALIAS(OCSP_REQUEST_delete_ext); 125 126 void * 127 OCSP_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 } 131 LCRYPTO_ALIAS(OCSP_REQUEST_get1_ext_d2i); 132 133 int 134 OCSP_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 } 140 LCRYPTO_ALIAS(OCSP_REQUEST_add1_ext_i2d); 141 142 int 143 OCSP_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 } 148 LCRYPTO_ALIAS(OCSP_REQUEST_add_ext); 149 150 /* Single extensions */ 151 152 int 153 OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) 154 { 155 return X509v3_get_ext_count(x->singleRequestExtensions); 156 } 157 LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext_count); 158 159 int 160 OCSP_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 } 164 LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext_by_NID); 165 166 int 167 OCSP_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 } 171 LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext_by_OBJ); 172 173 int 174 OCSP_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 } 179 LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext_by_critical); 180 181 X509_EXTENSION * 182 OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) 183 { 184 return X509v3_get_ext(x->singleRequestExtensions, loc); 185 } 186 LCRYPTO_ALIAS(OCSP_ONEREQ_get_ext); 187 188 X509_EXTENSION * 189 OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) 190 { 191 return X509v3_delete_ext(x->singleRequestExtensions, loc); 192 } 193 LCRYPTO_ALIAS(OCSP_ONEREQ_delete_ext); 194 195 void * 196 OCSP_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 } 200 LCRYPTO_ALIAS(OCSP_ONEREQ_get1_ext_d2i); 201 202 int 203 OCSP_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 } 209 LCRYPTO_ALIAS(OCSP_ONEREQ_add1_ext_i2d); 210 211 int 212 OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) 213 { 214 return X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL; 215 } 216 LCRYPTO_ALIAS(OCSP_ONEREQ_add_ext); 217 218 /* OCSP Basic response */ 219 220 int 221 OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) 222 { 223 return X509v3_get_ext_count(x->tbsResponseData->responseExtensions); 224 } 225 LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext_count); 226 227 int 228 OCSP_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 } 233 LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext_by_NID); 234 235 int 236 OCSP_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 } 242 LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext_by_OBJ); 243 244 int 245 OCSP_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 } 250 LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext_by_critical); 251 252 X509_EXTENSION * 253 OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) 254 { 255 return X509v3_get_ext(x->tbsResponseData->responseExtensions, loc); 256 } 257 LCRYPTO_ALIAS(OCSP_BASICRESP_get_ext); 258 259 X509_EXTENSION * 260 OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) 261 { 262 return X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc); 263 } 264 LCRYPTO_ALIAS(OCSP_BASICRESP_delete_ext); 265 266 void * 267 OCSP_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 } 272 LCRYPTO_ALIAS(OCSP_BASICRESP_get1_ext_d2i); 273 274 int 275 OCSP_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 } 281 LCRYPTO_ALIAS(OCSP_BASICRESP_add1_ext_i2d); 282 283 int 284 OCSP_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 } 289 LCRYPTO_ALIAS(OCSP_BASICRESP_add_ext); 290 291 /* OCSP single response extensions */ 292 293 int 294 OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) 295 { 296 return X509v3_get_ext_count(x->singleExtensions); 297 } 298 LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext_count); 299 300 int 301 OCSP_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 } 305 LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext_by_NID); 306 307 int 308 OCSP_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 } 313 LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext_by_OBJ); 314 315 int 316 OCSP_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 } 320 LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext_by_critical); 321 322 X509_EXTENSION * 323 OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) 324 { 325 return X509v3_get_ext(x->singleExtensions, loc); 326 } 327 LCRYPTO_ALIAS(OCSP_SINGLERESP_get_ext); 328 329 X509_EXTENSION * 330 OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) 331 { 332 return X509v3_delete_ext(x->singleExtensions, loc); 333 } 334 LCRYPTO_ALIAS(OCSP_SINGLERESP_delete_ext); 335 336 void * 337 OCSP_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 } 341 LCRYPTO_ALIAS(OCSP_SINGLERESP_get1_ext_d2i); 342 343 int 344 OCSP_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 } 349 LCRYPTO_ALIAS(OCSP_SINGLERESP_add1_ext_i2d); 350 351 int 352 OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) 353 { 354 return X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL; 355 } 356 LCRYPTO_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 366 static int 367 ocsp_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 395 err: 396 free(os.data); 397 return ret; 398 } 399 400 /* Add nonce to an OCSP request */ 401 int 402 OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) 403 { 404 return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); 405 } 406 LCRYPTO_ALIAS(OCSP_request_add1_nonce); 407 408 /* Same as above but for a response */ 409 int 410 OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) 411 { 412 return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, 413 len); 414 } 415 LCRYPTO_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 */ 429 int 430 OCSP_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 } 461 LCRYPTO_ALIAS(OCSP_check_nonce); 462 463 /* Copy the nonce value (if any) from an OCSP request to 464 * a response. 465 */ 466 int 467 OCSP_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 } 480 LCRYPTO_ALIAS(OCSP_copy_nonce); 481 482 X509_EXTENSION * 483 OCSP_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 510 err: 511 if (cid) 512 OCSP_CRLID_free(cid); 513 return x; 514 } 515 LCRYPTO_ALIAS(OCSP_crlID_new); 516 517 /* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ 518 X509_EXTENSION * 519 OCSP_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 } 541 LCRYPTO_ALIAS(OCSP_accept_responses_new); 542 543 /* ArchiveCutoff ::= GeneralizedTime */ 544 X509_EXTENSION * 545 OCSP_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 556 err: 557 if (gt) 558 ASN1_GENERALIZEDTIME_free(gt); 559 return x; 560 } 561 LCRYPTO_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 */ 567 X509_EXTENSION * 568 OCSP_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 603 err: 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 } 612 LCRYPTO_ALIAS(OCSP_url_svcloc_new); 613